summaryrefslogtreecommitdiff
path: root/other-licenses/7zstub/src/7zip
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /other-licenses/7zstub/src/7zip
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'other-licenses/7zstub/src/7zip')
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.cpp3
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.h64
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.cpp443
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.h71
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zExtract.cpp265
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp161
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.h57
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.cpp757
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.h234
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.cpp19
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.h96
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zIn.cpp1294
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zIn.h288
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zItem.h181
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.cpp76
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.h29
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.cpp174
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.h36
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.cpp166
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.h22
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Archive.def3
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.cpp121
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.h168
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.cpp359
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.h121
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.cpp15
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.h31
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.cpp242
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.h130
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.cpp59
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.h24
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.cpp23
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.h33
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/IArchive.h173
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp249
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.h96
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.cpp139
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.h17
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp561
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp696
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsw29
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.cpp3
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.h10
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/makefile156
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.h8
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.rc18
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/setup.icobin0 -> 25214 bytes
-rw-r--r--other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.cpp57
-rw-r--r--other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.h10
-rw-r--r--other-licenses/7zstub/src/7zip/Common/FileStreams.cpp251
-rw-r--r--other-licenses/7zstub/src/7zip/Common/FileStreams.h98
-rw-r--r--other-licenses/7zstub/src/7zip/Common/InBuffer.cpp80
-rw-r--r--other-licenses/7zstub/src/7zip/Common/InBuffer.h76
-rw-r--r--other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.cpp122
-rw-r--r--other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.h55
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFDecoder.cpp34
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h127
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFEncoder.cpp29
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFEncoder.h51
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LimitedStreams.cpp24
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LimitedStreams.h23
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LockedStream.cpp23
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LockedStream.h38
-rw-r--r--other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h69
-rw-r--r--other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h59
-rw-r--r--other-licenses/7zstub/src/7zip/Common/OffsetStream.cpp35
-rw-r--r--other-licenses/7zstub/src/7zip/Common/OffsetStream.h25
-rw-r--r--other-licenses/7zstub/src/7zip/Common/OutBuffer.cpp116
-rw-r--r--other-licenses/7zstub/src/7zip/Common/OutBuffer.h64
-rw-r--r--other-licenses/7zstub/src/7zip/Common/ProgressUtils.cpp58
-rw-r--r--other-licenses/7zstub/src/7zip/Common/ProgressUtils.h43
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StdAfx.h9
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp162
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamBinder.h37
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamObjects.cpp102
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamObjects.h156
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamUtils.cpp44
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamUtils.h11
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.cpp18
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.h54
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchTypes.h15
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.c101
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.h13
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/x86.cpp18
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/x86.h19
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.cpp412
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.h133
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.cpp52
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.h31
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.cpp17
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.h56
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZMA/LZMA.h82
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.cpp337
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h251
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoder.h205
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.cpp80
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h120
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBitTree.h161
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderOpt.h31
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/FormatUtils.cpp40
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/FormatUtils.h18
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp175
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h129
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/StdAfx.h16
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.h3
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.rc20
-rw-r--r--other-licenses/7zstub/src/7zip/GuiCommon.rc37
-rw-r--r--other-licenses/7zstub/src/7zip/ICoder.h163
-rw-r--r--other-licenses/7zstub/src/7zip/IPassword.h26
-rw-r--r--other-licenses/7zstub/src/7zip/IProgress.h32
-rw-r--r--other-licenses/7zstub/src/7zip/IStream.h62
-rw-r--r--other-licenses/7zstub/src/7zip/MyVersion.h8
-rw-r--r--other-licenses/7zstub/src/7zip/MyVersionInfo.rc41
-rw-r--r--other-licenses/7zstub/src/7zip/PropID.h51
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.cpp117
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.h87
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp359
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.h66
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/DefaultName.cpp23
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/DefaultName.h11
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.cpp528
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.h134
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.cpp45
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.h24
-rw-r--r--other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.cpp53
-rw-r--r--other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.h30
126 files changed, 14512 insertions, 0 deletions
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.cpp
new file mode 100644
index 0000000000..232c638203
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.cpp
@@ -0,0 +1,3 @@
+// CompressionMethod.cpp
+
+#include "StdAfx.h"
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.h
new file mode 100644
index 0000000000..215d5cbfb4
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.h
@@ -0,0 +1,64 @@
+// 7zCompressionMode.h
+
+#ifndef __7Z_COMPRESSION_MODE_H
+#define __7Z_COMPRESSION_MODE_H
+
+#include "../../../Windows/PropVariant.h"
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CProperty
+{
+ PROPID PropID;
+ NWindows::NCOM::CPropVariant Value;
+};
+
+struct CMethodFull
+{
+ CMethodID MethodID;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ bool IsSimpleCoder() const
+ { return (NumInStreams == 1) && (NumOutStreams == 1); }
+
+ #ifdef EXCLUDE_COM
+ #else
+ CLSID EncoderClassID;
+ CSysString FilePath;
+ #endif
+
+ CObjectVector<CProperty> CoderProperties;
+};
+
+struct CBind
+{
+ UInt32 InCoder;
+ UInt32 InStream;
+ UInt32 OutCoder;
+ UInt32 OutStream;
+};
+
+struct CCompressionMethodMode
+{
+ CObjectVector<CMethodFull> Methods;
+ CRecordVector<CBind> Binds;
+ #ifdef COMPRESS_MT
+ UInt32 NumThreads;
+ #endif
+ bool PasswordIsDefined;
+ UString Password;
+
+ bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
+ CCompressionMethodMode(): PasswordIsDefined(false)
+ #ifdef COMPRESS_MT
+ , NumThreads(1)
+ #endif
+ {}
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.cpp
new file mode 100644
index 0000000000..7f8f149657
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.cpp
@@ -0,0 +1,443 @@
+// 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;
+ _bindInfoExPrevIsDefinded = false;
+ #ifndef EXCLUDE_COM
+ LoadMethodMap();
+ #endif
+}
+
+HRESULT CDecoder::Decode(IInStream *inStream,
+ UInt64 startPos,
+ const UInt64 *packSizes,
+ const CFolder &folderInfo,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
+ )
+{
+ CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
+
+ CLockedInStream lockedInStream;
+ lockedInStream.Init(inStream);
+
+ for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
+ {
+ CLockedSequentialInStreamImp *lockedStreamImpSpec = new
+ CLockedSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
+ lockedStreamImpSpec->Init(&lockedInStream, startPos);
+ startPos += packSizes[j];
+
+ CLimitedSequentialInStream *streamSpec = new
+ CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream = streamSpec;
+ streamSpec->Init(lockedStreamImp, packSizes[j]);
+ inStreams.Add(inStream);
+ }
+
+ int numCoders = folderInfo.Coders.Size();
+
+ CBindInfoEx bindInfo;
+ ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
+ bool createNewCoders;
+ if (!_bindInfoExPrevIsDefinded)
+ createNewCoders = true;
+ else
+ createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
+ if (createNewCoders)
+ {
+ int i;
+ _decoders.Clear();
+ // _decoders2.Clear();
+
+ _mixerCoder.Release();
+
+ if (_multiThread)
+ {
+ _mixerCoderMTSpec = new NCoderMixer2::CCoderMixer2MT;
+ _mixerCoder = _mixerCoderMTSpec;
+ _mixerCoderCommon = _mixerCoderMTSpec;
+ }
+ else
+ {
+ #ifdef _ST_MODE
+ _mixerCoderSTSpec = new NCoderMixer2::CCoderMixer2ST;
+ _mixerCoder = _mixerCoderSTSpec;
+ _mixerCoderCommon = _mixerCoderSTSpec;
+ #endif
+ }
+ _mixerCoderCommon->SetBindInfo(bindInfo);
+
+ for (i = 0; i < numCoders; i++)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ #ifndef EXCLUDE_COM
+ CMethodInfo methodInfo;
+ if (!GetMethodInfo(altCoderInfo.MethodID, methodInfo))
+ return E_NOTIMPL;
+ #endif
+
+ if (coderInfo.IsSimpleCoder())
+ {
+ CMyComPtr<ICompressCoder> decoder;
+ CMyComPtr<ICompressFilter> filter;
+
+ #ifdef COMPRESS_LZMA
+ if (altCoderInfo.MethodID == k_LZMA)
+ decoder = new NCompress::NLZMA::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_PPMD
+ if (altCoderInfo.MethodID == k_PPMD)
+ decoder = new NCompress::NPPMD::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_BCJ_X86
+ if (altCoderInfo.MethodID == k_BCJ_X86)
+ filter = new CBCJ_x86_Decoder;
+ #endif
+
+ #ifdef COMPRESS_DEFLATE_DECODER
+ if (altCoderInfo.MethodID == k_Deflate)
+ decoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
+ #endif
+
+ #ifdef COMPRESS_BZIP2_DECODER
+ if (altCoderInfo.MethodID == k_BZip2)
+ decoder = new NCompress::NBZip2::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_COPY
+ if (altCoderInfo.MethodID == k_Copy)
+ decoder = new NCompress::CCopyCoder;
+ #endif
+
+ #ifdef CRYPTO_7ZAES
+ if (altCoderInfo.MethodID == k_7zAES)
+ filter = new NCrypto::NSevenZ::CDecoder;
+ #endif
+
+ if (filter)
+ {
+ CFilterCoder *coderSpec = new CFilterCoder;
+ decoder = coderSpec;
+ coderSpec->Filter = filter;
+ }
+ #ifndef EXCLUDE_COM
+ if (decoder == 0)
+ {
+ RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath,
+ methodInfo.Decoder, &decoder));
+ }
+ #endif
+
+ if (decoder == 0)
+ return E_NOTIMPL;
+
+ _decoders.Add((IUnknown *)decoder);
+
+ if (_multiThread)
+ _mixerCoderMTSpec->AddCoder(decoder);
+ #ifdef _ST_MODE
+ else
+ _mixerCoderSTSpec->AddCoder(decoder, false);
+ #endif
+ }
+ else
+ {
+ CMyComPtr<ICompressCoder2> decoder;
+
+ #ifdef COMPRESS_BCJ2
+ if (altCoderInfo.MethodID == k_BCJ2)
+ decoder = new CBCJ2_x86_Decoder;
+ #endif
+
+ #ifndef EXCLUDE_COM
+ if (decoder == 0)
+ {
+ RINOK(_libraries.CreateCoder2(methodInfo.FilePath,
+ methodInfo.Decoder, &decoder));
+ }
+ #endif
+
+ if (decoder == 0)
+ return E_NOTIMPL;
+
+ _decoders.Add((IUnknown *)decoder);
+ if (_multiThread)
+ _mixerCoderMTSpec->AddCoder2(decoder);
+ #ifdef _ST_MODE
+ else
+ _mixerCoderSTSpec->AddCoder2(decoder, false);
+ #endif
+ }
+ }
+ _bindInfoExPrev = bindInfo;
+ _bindInfoExPrevIsDefinded = true;
+ }
+ int i;
+ _mixerCoderCommon->ReInit();
+
+ UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
+ UInt32 coderIndex = 0;
+ // UInt32 coder2Index = 0;
+
+ for (i = 0; i < numCoders; i++)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
+
+ {
+ CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
+ HRESULT result = decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
+ if (setDecoderProperties)
+ {
+ const CByteBuffer &properties = altCoderInfo.Properties;
+ size_t size = properties.GetCapacity();
+ if (size > 0xFFFFFFFF)
+ return E_NOTIMPL;
+ if (size > 0)
+ {
+ RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
+ }
+ }
+ }
+
+ #ifdef COMPRESS_MT
+ if (mtMode)
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+ }
+ }
+ #endif
+
+ #ifndef _NO_CRYPTO
+ {
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ HRESULT result = decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+ if (cryptoSetPassword)
+ {
+ if (getTextPassword == 0)
+ return E_FAIL;
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ CByteBuffer buffer;
+ UString unicodePassword(password);
+ const UInt32 sizeInBytes = unicodePassword.Length() * 2;
+ buffer.SetCapacity(sizeInBytes);
+ for (int i = 0; i < unicodePassword.Length(); i++)
+ {
+ wchar_t c = unicodePassword[i];
+ ((Byte *)buffer)[i * 2] = (Byte)c;
+ ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+ }
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const Byte *)buffer, sizeInBytes));
+ }
+ }
+ #endif
+
+ coderIndex++;
+
+ UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
+ UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
+ CRecordVector<const UInt64 *> packSizesPointers;
+ CRecordVector<const UInt64 *> unPackSizesPointers;
+ packSizesPointers.Reserve(numInStreams);
+ unPackSizesPointers.Reserve(numOutStreams);
+ UInt32 j;
+ for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
+ unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
+
+ for (j = 0; j < numInStreams; j++, packStreamIndex++)
+ {
+ int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
+ if (bindPairIndex >= 0)
+ packSizesPointers.Add(
+ &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
+ else
+ {
+ int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
+ if (index < 0)
+ return E_FAIL;
+ packSizesPointers.Add(&packSizes[index]);
+ }
+ }
+
+ _mixerCoderCommon->SetCoderInfo(i,
+ &packSizesPointers.Front(),
+ &unPackSizesPointers.Front());
+ }
+ UInt32 mainCoder, temp;
+ bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
+
+ if (_multiThread)
+ _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
+ /*
+ else
+ _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
+ */
+
+ if (numCoders == 0)
+ return 0;
+ CRecordVector<ISequentialInStream *> inStreamPointers;
+ inStreamPointers.Reserve(inStreams.Size());
+ for (i = 0; i < inStreams.Size(); i++)
+ inStreamPointers.Add(inStreams[i]);
+ ISequentialOutStream *outStreamPointer = outStream;
+ return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
+ inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.h
new file mode 100644
index 0000000000..6620c2ed8d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.h
@@ -0,0 +1,71 @@
+// 7zDecode.h
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+
+#include "../Common/CoderMixer2.h"
+#include "../Common/CoderMixer2MT.h"
+#ifdef _ST_MODE
+#include "../Common/CoderMixer2ST.h"
+#endif
+#ifndef EXCLUDE_COM
+#include "../Common/CoderLoader.h"
+#endif
+
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CBindInfoEx: public NCoderMixer2::CBindInfo
+{
+ CRecordVector<CMethodID> CoderMethodIDs;
+ void Clear()
+ {
+ CBindInfo::Clear();
+ CoderMethodIDs.Clear();
+ }
+};
+
+class CDecoder
+{
+ #ifndef EXCLUDE_COM
+ CCoderLibraries _libraries;
+ #endif
+
+ bool _bindInfoExPrevIsDefinded;
+ CBindInfoEx _bindInfoExPrev;
+
+ bool _multiThread;
+ #ifdef _ST_MODE
+ NCoderMixer2::CCoderMixer2ST *_mixerCoderSTSpec;
+ #endif
+ NCoderMixer2::CCoderMixer2MT *_mixerCoderMTSpec;
+ NCoderMixer2::CCoderMixer2 *_mixerCoderCommon;
+
+ CMyComPtr<ICompressCoder2> _mixerCoder;
+ CObjectVector<CMyComPtr<IUnknown> > _decoders;
+ // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
+public:
+ CDecoder(bool multiThread);
+ HRESULT Decode(IInStream *inStream,
+ UInt64 startPos,
+ const UInt64 *packSizes,
+ const CFolder &folder,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPasswordSpec
+ #endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
+ );
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zExtract.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zExtract.cpp
new file mode 100644
index 0000000000..cc892bc9df
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zExtract.cpp
@@ -0,0 +1,265 @@
+// 7zExtract.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zFolderOutStream.h"
+#include "7zMethods.h"
+#include "7zDecode.h"
+// #include "7z1Decode.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CExtractFolderInfo
+{
+ #ifdef _7Z_VOL
+ int VolumeIndex;
+ #endif
+ CNum FileIndex;
+ CNum FolderIndex;
+ CBoolVector ExtractStatuses;
+ UInt64 UnPackSize;
+ CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ int volumeIndex,
+ #endif
+ CNum fileIndex, CNum folderIndex):
+ #ifdef _7Z_VOL
+ VolumeIndex(volumeIndex),
+ #endif
+ FileIndex(fileIndex),
+ FolderIndex(folderIndex),
+ UnPackSize(0)
+ {
+ if (fileIndex != kNumNoIndex)
+ {
+ ExtractStatuses.Reserve(1);
+ ExtractStatuses.Add(true);
+ }
+ };
+};
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
+{
+ COM_TRY_BEGIN
+ bool testMode = (testModeSpec != 0);
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ UInt64 importantTotalUnPacked = 0;
+
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems =
+ #ifdef _7Z_VOL
+ _refs.Size();
+ #else
+ _database.Files.Size();
+ #endif
+
+ if(numItems == 0)
+ return S_OK;
+
+ /*
+ if(_volumes.Size() != 1)
+ return E_FAIL;
+ const CVolume &volume = _volumes.Front();
+ const CArchiveDatabaseEx &_database = volume.Database;
+ IInStream *_inStream = volume.Stream;
+ */
+
+ CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
+ for(UInt32 ii = 0; ii < numItems; ii++)
+ {
+ // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
+ UInt32 ref2Index = allFilesMode ? ii : indices[ii];
+ // const CRef2 &ref2 = _refs[ref2Index];
+
+ // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
+ {
+ #ifdef _7Z_VOL
+ // const CRef &ref = ref2.Refs[ri];
+ const CRef &ref = _refs[ref2Index];
+
+ int volumeIndex = ref.VolumeIndex;
+ const CVolume &volume = _volumes[volumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ UInt32 fileIndex = ref.ItemIndex;
+ #else
+ const CArchiveDatabaseEx &database = _database;
+ UInt32 fileIndex = ref2Index;
+ #endif
+
+ CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex == kNumNoIndex)
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ volumeIndex,
+ #endif
+ fileIndex, kNumNoIndex));
+ continue;
+ }
+ if (extractFolderInfoVector.IsEmpty() ||
+ folderIndex != extractFolderInfoVector.Back().FolderIndex
+ #ifdef _7Z_VOL
+ || volumeIndex != extractFolderInfoVector.Back().VolumeIndex
+ #endif
+ )
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ volumeIndex,
+ #endif
+ kNumNoIndex, folderIndex));
+ const CFolder &folderInfo = database.Folders[folderIndex];
+ UInt64 unPackSize = folderInfo.GetUnPackSize();
+ importantTotalUnPacked += unPackSize;
+ extractFolderInfoVector.Back().UnPackSize = unPackSize;
+ }
+
+ CExtractFolderInfo &efi = extractFolderInfoVector.Back();
+
+ // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
+ CNum startIndex = database.FolderStartFileIndex[folderIndex];
+ for (CNum index = efi.ExtractStatuses.Size();
+ index <= fileIndex - startIndex; index++)
+ {
+ // UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize;
+ // Count partial_folder_size
+ // efi.UnPackSize += unPackSize;
+ // importantTotalUnPacked += unPackSize;
+ efi.ExtractStatuses.Add(index == fileIndex - startIndex);
+ }
+ }
+ }
+
+ extractCallback->SetTotal(importantTotalUnPacked);
+
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
+ // CDecoder1 decoder;
+
+ UInt64 currentImportantTotalUnPacked = 0;
+ UInt64 totalFolderUnPacked;
+
+ for(int i = 0; i < extractFolderInfoVector.Size(); i++,
+ currentImportantTotalUnPacked += totalFolderUnPacked)
+ {
+ const CExtractFolderInfo &efi = extractFolderInfoVector[i];
+ totalFolderUnPacked = efi.UnPackSize;
+
+ RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked));
+
+ CFolderOutStream *folderOutStream = new CFolderOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+
+ #ifdef _7Z_VOL
+ const CVolume &volume = _volumes[efi.VolumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ #else
+ const CArchiveDatabaseEx &database = _database;
+ #endif
+
+ CNum startIndex;
+ if (efi.FileIndex != kNumNoIndex)
+ startIndex = efi.FileIndex;
+ else
+ startIndex = database.FolderStartFileIndex[efi.FolderIndex];
+
+
+ HRESULT result = folderOutStream->Init(&database,
+ #ifdef _7Z_VOL
+ volume.StartRef2Index,
+ #else
+ 0,
+ #endif
+ startIndex,
+ &efi.ExtractStatuses, extractCallback, testMode);
+
+ RINOK(result);
+
+ if (efi.FileIndex != kNumNoIndex)
+ continue;
+
+ CNum folderIndex = efi.FolderIndex;
+ const CFolder &folderInfo = database.Folders[folderIndex];
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(progress, NULL, &currentImportantTotalUnPacked);
+
+ CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
+ UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (extractCallback)
+ extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
+ #endif
+
+ try
+ {
+ HRESULT result = decoder.Decode(
+ #ifdef _7Z_VOL
+ volume.Stream,
+ #else
+ _inStream,
+ #endif
+ folderStartPackPos,
+ &database.PackSizes[packStreamIndex],
+ folderInfo,
+ outStream,
+ compressProgress
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , true, _numThreads
+ #endif
+ );
+
+ if (result == S_FALSE)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ if (result == E_NOTIMPL)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ if (result != S_OK)
+ return result;
+ if (folderOutStream->WasWritingFinished() != S_OK)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ catch(...)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp
new file mode 100644
index 0000000000..94afc6905e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp
@@ -0,0 +1,161 @@
+// 7zFolderOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderOutStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderOutStream::CFolderOutStream()
+{
+ _outStreamWithHashSpec = new COutStreamWithCRC;
+ _outStreamWithHash = _outStreamWithHashSpec;
+}
+
+HRESULT CFolderOutStream::Init(
+ const CArchiveDatabaseEx *archiveDatabase,
+ UInt32 ref2Offset,
+ UInt32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode)
+{
+ _archiveDatabase = archiveDatabase;
+ _ref2Offset = ref2Offset;
+ _startIndex = startIndex;
+
+ _extractStatuses = extractStatuses;
+ _extractCallback = extractCallback;
+ _testMode = testMode;
+
+ _currentIndex = 0;
+ _fileIsOpen = false;
+ return WriteEmptyFiles();
+}
+
+HRESULT CFolderOutStream::OpenFile()
+{
+ Int32 askMode;
+ if((*_extractStatuses)[_currentIndex])
+ askMode = _testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ else
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ CMyComPtr<ISequentialOutStream> realOutStream;
+
+ UInt32 index = _startIndex + _currentIndex;
+ RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
+
+ _outStreamWithHashSpec->Init(realOutStream);
+ 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/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.h
new file mode 100644
index 0000000000..05a6358c7e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.h
@@ -0,0 +1,57 @@
+// 7zFolderOutStream.h
+
+#ifndef __7Z_FOLDEROUTSTREAM_H
+#define __7Z_FOLDEROUTSTREAM_H
+
+#include "7zIn.h"
+
+#include "../../IStream.h"
+#include "../IArchive.h"
+#include "../Common/OutStreamWithCRC.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CFolderOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ CFolderOutStream();
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+
+ COutStreamWithCRC *_outStreamWithHashSpec;
+ CMyComPtr<ISequentialOutStream> _outStreamWithHash;
+ const CArchiveDatabaseEx *_archiveDatabase;
+ const CBoolVector *_extractStatuses;
+ UInt32 _startIndex;
+ UInt32 _ref2Offset;
+ int _currentIndex;
+ // UInt64 _currentDataPos;
+ CMyComPtr<IArchiveExtractCallback> _extractCallback;
+ bool _testMode;
+
+ bool _fileIsOpen;
+ UInt64 _filePos;
+
+ HRESULT OpenFile();
+ HRESULT WriteEmptyFiles();
+public:
+ HRESULT Init(
+ const CArchiveDatabaseEx *archiveDatabase,
+ UInt32 ref2Offset,
+ UInt32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode);
+ HRESULT FlushCorrupted(Int32 resultEOperationResult);
+ HRESULT WasWritingFinished();
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.cpp
new file mode 100644
index 0000000000..b6f492aea8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.cpp
@@ -0,0 +1,757 @@
+// 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)
+{
+ COM_TRY_BEGIN
+ *numItems =
+ #ifdef _7Z_VOL
+ _refs.Size();
+ #else
+ *numItems = _database.Files.Size();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ value->vt = VT_EMPTY;
+ return S_OK;
+}
+
+#ifdef _SFX
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ return E_NOTIMPL;
+}
+
+#endif
+
+
+STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
+{
+ *numProperties = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ return E_NOTIMPL;
+}
+
+
+static void MySetFileTime(bool timeDefined, FILETIME unixTime,
+ NWindows::NCOM::CPropVariant &propVariant)
+{
+ if (timeDefined)
+ propVariant = unixTime;
+}
+
+/*
+inline static wchar_t GetHex(Byte value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+
+static UString ConvertBytesToHexString(const Byte *data, UInt32 size)
+{
+ UString result;
+ for (UInt32 i = 0; i < size; i++)
+ {
+ Byte b = data[i];
+ result += GetHex(b >> 4);
+ result += GetHex(b & 0xF);
+ }
+ return result;
+}
+*/
+
+
+#ifndef _SFX
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static UString GetStringForSizeValue(UInt32 value)
+{
+ for (int i = 31; i >= 0; i--)
+ if ((UInt32(1) << i) == value)
+ return ConvertUInt32ToString(i);
+ UString result;
+ if (value % (1 << 20) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 20);
+ result += L"m";
+ }
+ else if (value % (1 << 10) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 10);
+ result += L"k";
+ }
+ else
+ {
+ result += ConvertUInt32ToString(value);
+ result += L"b";
+ }
+ return result;
+}
+
+static CMethodID k_Copy = { { 0x0 }, 1 };
+static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+static CMethodID k_BCJ = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
+static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
+static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+
+static inline char GetHex(Byte value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+static inline UString GetHex2(Byte value)
+{
+ UString result;
+ result += GetHex(value >> 4);
+ result += GetHex(value & 0xF);
+ return result;
+}
+
+#endif
+
+static inline UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+ return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+
+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;
+ #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_BZip2)
+ methodName = L"BZip2";
+ else
+ methodIsKnown = false;
+
+ #else
+
+ methodIsKnown = GetMethodInfo(
+ altCoderInfo.MethodID, methodInfo);
+ methodName = methodInfo.Name;
+
+ #endif
+
+ if (methodIsKnown)
+ {
+ methodsString += methodName;
+ if (altCoderInfo.MethodID == k_LZMA)
+ {
+ if (altCoderInfo.Properties.GetCapacity() >= 5)
+ {
+ methodsString += L":";
+ UInt32 dicSize = 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.Properties.GetCapacity() > 0)
+ {
+ methodsString += L":[";
+ for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
+ {
+ if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())
+ {
+ methodsString += L"..";
+ break;
+ }
+ else
+ methodsString += GetHex2(altCoderInfo.Properties[bi]);
+ }
+ methodsString += L"]";
+ }
+ }
+ }
+ else
+ {
+ methodsString += altCoderInfo.MethodID.ConvertToString();
+ }
+ }
+ }
+ propVariant = methodsString;
+ }
+ }
+ break;
+ case kpidBlock:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ propVariant = (UInt32)folderIndex;
+ }
+ break;
+ case kpidPackedSize0:
+ case kpidPackedSize1:
+ case kpidPackedSize2:
+ case kpidPackedSize3:
+ case kpidPackedSize4:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
+ folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
+ {
+ propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
+ }
+ else
+ propVariant = UInt64(0);
+ }
+ else
+ propVariant = UInt64(0);
+ }
+ break;
+ #endif
+ case kpidIsAnti:
+ propVariant = item.IsAnti;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+static const wchar_t *kExt = L"7z";
+static const wchar_t *kAfterPart = L".7z";
+
+#ifdef _7Z_VOL
+
+class CVolumeName
+{
+ bool _first;
+ UString _unchangedPart;
+ UString _changedPart;
+ UString _afterPart;
+public:
+ bool InitName(const UString &name)
+ {
+ _first = true;
+ int dotPos = name.ReverseFind('.');
+ UString basePart = name;
+ if (dotPos >= 0)
+ {
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.CompareNoCase(kExt)==0 ||
+ ext.CompareNoCase(L"EXE") == 0)
+ {
+ _afterPart = kAfterPart;
+ basePart = name.Left(dotPos);
+ }
+ }
+
+ int numLetters = 1;
+ bool splitStyle = false;
+ if (basePart.Right(numLetters) == L"1")
+ {
+ while (numLetters < basePart.Length())
+ {
+ if (basePart[basePart.Length() - numLetters - 1] != '0')
+ break;
+ numLetters++;
+ }
+ }
+ else
+ return false;
+ _unchangedPart = basePart.Left(basePart.Length() - numLetters);
+ _changedPart = basePart.Right(numLetters);
+ return true;
+ }
+
+ UString GetNextName()
+ {
+ UString newName;
+ // if (_newStyle || !_first)
+ {
+ int i;
+ int numLetters = _changedPart.Length();
+ for (i = numLetters - 1; i >= 0; i--)
+ {
+ wchar_t c = _changedPart[i];
+ if (c == L'9')
+ {
+ c = L'0';
+ newName = c + newName;
+ if (i == 0)
+ newName = UString(L'1') + newName;
+ continue;
+ }
+ c++;
+ newName = UString(c) + newName;
+ i--;
+ for (; i >= 0; i--)
+ newName = _changedPart[i] + newName;
+ break;
+ }
+ _changedPart = newName;
+ }
+ _first = false;
+ return _unchangedPart + _changedPart + _afterPart;
+ }
+};
+
+#endif
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ Close();
+ #ifndef _SFX
+ _fileInfoPopIDs.Clear();
+ #endif
+ try
+ {
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
+ #ifdef _7Z_VOL
+ CVolumeName seqName;
+
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ #endif
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (openArchiveCallback)
+ {
+ openArchiveCallbackTemp.QueryInterface(
+ IID_ICryptoGetTextPassword, &getTextPassword);
+ }
+ #endif
+ #ifdef _7Z_VOL
+ if (openArchiveCallback)
+ {
+ openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
+ }
+ while(true)
+ {
+ CMyComPtr<IInStream> inStream;
+ if (!_volumes.IsEmpty())
+ {
+ if (!openVolumeCallback)
+ break;
+ if(_volumes.Size() == 1)
+ {
+ UString baseName;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
+ if (propVariant.vt != VT_BSTR)
+ break;
+ baseName = propVariant.bstrVal;
+ }
+ seqName.InitName(baseName);
+ }
+
+ UString fullName = seqName.GetNextName();
+ HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
+ if (result == S_FALSE)
+ break;
+ if (result != S_OK)
+ return result;
+ if (!stream)
+ break;
+ }
+ else
+ inStream = stream;
+
+ CInArchive archive;
+ RINOK(archive.Open(inStream, maxCheckStartPosition));
+
+ _volumes.Add(CVolume());
+ CVolume &volume = _volumes.Back();
+ CArchiveDatabaseEx &database = volume.Database;
+ volume.Stream = inStream;
+ volume.StartRef2Index = _refs.Size();
+
+ HRESULT result = archive.ReadDatabase(database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ if (result != S_OK)
+ {
+ _volumes.Clear();
+ return result;
+ }
+ database.Fill();
+ for(int i = 0; i < database.Files.Size(); i++)
+ {
+ CRef refNew;
+ refNew.VolumeIndex = _volumes.Size() - 1;
+ refNew.ItemIndex = i;
+ _refs.Add(refNew);
+ /*
+ const CFileItem &file = database.Files[i];
+ int j;
+ */
+ /*
+ for (j = _refs.Size() - 1; j >= 0; j--)
+ {
+ CRef2 &ref2 = _refs[j];
+ const CRef &ref = ref2.Refs.Back();
+ const CVolume &volume2 = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &database2 = volume2.Database;
+ const CFileItem &file2 = database2.Files[ref.ItemIndex];
+ if (file2.Name.CompareNoCase(file.Name) == 0)
+ {
+ if (!file.IsStartPosDefined)
+ continue;
+ if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
+ continue;
+ ref2.Refs.Add(refNew);
+ break;
+ }
+ }
+ */
+ /*
+ j = -1;
+ if (j < 0)
+ {
+ CRef2 ref2New;
+ ref2New.Refs.Add(refNew);
+ j = _refs.Add(ref2New);
+ }
+ CRef2 &ref2 = _refs[j];
+ ref2.UnPackSize += file.UnPackSize;
+ ref2.PackSize += database.GetFilePackSize(i);
+ if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
+ ref2.StartPos = file.StartPos;
+ */
+ }
+ if (database.Files.Size() != 1)
+ break;
+ const CFileItem &file = database.Files.Front();
+ if (!file.IsStartPosDefined)
+ break;
+ }
+ #else
+ CInArchive archive;
+ RINOK(archive.Open(stream, maxCheckStartPosition));
+ HRESULT result = archive.ReadDatabase(_database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ _database.Fill();
+ _inStream = stream;
+ #endif
+ }
+ catch(...)
+ {
+ Close();
+ return S_FALSE;
+ }
+ // _inStream = stream;
+ #ifndef _SFX
+ FillPopIDs();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ COM_TRY_BEGIN
+ #ifdef _7Z_VOL
+ _volumes.Clear();
+ _refs.Clear();
+ #else
+ _inStream.Release();
+ _database.Clear();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+#ifdef _7Z_VOL
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ if (index != 0)
+ return E_INVALIDARG;
+ *stream = 0;
+ CMultiStream *streamSpec = new CMultiStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+
+ UInt64 pos = 0;
+ const UString *fileName;
+ for (int i = 0; i < _refs.Size(); i++)
+ {
+ const CRef &ref = _refs[i];
+ const CVolume &volume = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ const CFileItem &file = database.Files[ref.ItemIndex];
+ if (i == 0)
+ fileName = &file.Name;
+ else
+ if (fileName->Compare(file.Name) != 0)
+ return S_FALSE;
+ if (!file.IsStartPosDefined)
+ return S_FALSE;
+ if (file.StartPos != pos)
+ return S_FALSE;
+ CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
+ if (folderIndex == kNumNoIndex)
+ {
+ if (file.UnPackSize != 0)
+ return E_FAIL;
+ continue;
+ }
+ if (database.NumUnPackStreamsVector[folderIndex] != 1)
+ return S_FALSE;
+ const CFolder &folder = database.Folders[folderIndex];
+ if (folder.Coders.Size() != 1)
+ return S_FALSE;
+ const CCoderInfo &coder = folder.Coders.Front();
+ if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
+ return S_FALSE;
+ const CAltCoderInfo &altCoder = coder.AltCoders.Front();
+ if (altCoder.MethodID.IDSize != 1 || altCoder.MethodID.ID[0] != 0)
+ return S_FALSE;
+
+ pos += file.UnPackSize;
+ CMultiStream::CSubStreamInfo subStreamInfo;
+ subStreamInfo.Stream = volume.Stream;
+ subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
+ subStreamInfo.Size = file.UnPackSize;
+ streamSpec->Streams.Add(subStreamInfo);
+ }
+ streamSpec->Init();
+ *stream = streamTemp.Detach();
+ return S_OK;
+}
+#endif
+
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ COM_TRY_BEGIN
+ const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
+ _numThreads = numProcessors;
+
+ 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)
+ {
+ RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ continue;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+#endif
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.h
new file mode 100644
index 0000000000..3da9b88599
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.h
@@ -0,0 +1,234 @@
+// 7z/Handler.h
+
+#ifndef __7Z_HANDLER_H
+#define __7Z_HANDLER_H
+
+#include "../IArchive.h"
+#include "7zIn.h"
+
+#include "7zCompressionMode.h"
+
+#ifndef _SFX
+#include "7zMethods.h"
+#endif
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+#ifdef _7Z_VOL
+struct CRef
+{
+ int VolumeIndex;
+ int ItemIndex;
+};
+
+/*
+struct CRef2
+{
+ CRecordVector<CRef> Refs;
+ UInt64 UnPackSize;
+ UInt64 PackSize;
+ UInt64 StartPos;
+ CRef2(): UnPackSize(0), PackSize(0), StartPos(0) {}
+};
+*/
+
+struct CVolume
+{
+ int StartRef2Index;
+ CMyComPtr<IInStream> Stream;
+ CArchiveDatabaseEx Database;
+};
+#endif
+
+#ifndef EXTRACT_ONLY
+
+struct COneMethodInfo
+{
+ CObjectVector<CProperty> CoderProperties;
+ UString MethodName;
+};
+#endif
+
+// {23170F69-40C1-278A-1000-000110070000}
+DEFINE_GUID(CLSID_CFormat7z,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+
+#ifndef __7Z_SET_PROPERTIES
+
+#ifdef EXTRACT_ONLY
+#ifdef COMPRESS_MT
+#define __7Z_SET_PROPERTIES
+#endif
+#else
+#define __7Z_SET_PROPERTIES
+#endif
+
+#endif
+
+
+class CHandler:
+ public IInArchive,
+ #ifdef _7Z_VOL
+ public IInArchiveGetStream,
+ #endif
+ #ifdef __7Z_SET_PROPERTIES
+ public ISetProperties,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public IOutArchive,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ 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
+
+ STDMETHOD(Open)(IInStream *stream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback);
+ STDMETHOD(Close)();
+
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback);
+
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+
+ #ifdef _7Z_VOL
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+ #endif
+
+ #ifdef __7Z_SET_PROPERTIES
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ // IOutArchiveHandler
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UInt32 *type);
+
+ // ISetProperties
+
+ HRESULT SetSolidSettings(const UString &s);
+ HRESULT SetSolidSettings(const PROPVARIANT &value);
+ #endif
+
+ CHandler();
+
+private:
+ #ifdef _7Z_VOL
+ CObjectVector<CVolume> _volumes;
+ CObjectVector<CRef> _refs;
+ #else
+ CMyComPtr<IInStream> _inStream;
+ NArchive::N7z::CArchiveDatabaseEx _database;
+ #endif
+
+ #ifdef COMPRESS_MT
+ UInt32 _numThreads;
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ CObjectVector<COneMethodInfo> _methods;
+ CRecordVector<CBind> _binds;
+ bool _removeSfxBlock;
+ UInt64 _numSolidFiles;
+ UInt64 _numSolidBytes;
+ bool _numSolidBytesDefined;
+ bool _solidExtension;
+
+ bool _compressHeaders;
+ bool _compressHeadersFull;
+ bool _encryptHeaders;
+
+ bool _autoFilter;
+ UInt32 _level;
+
+ bool _volumeMode;
+
+
+ HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
+ HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
+
+ HRESULT SetPassword(CCompressionMethodMode &methodMode,
+ IArchiveUpdateCallback *updateCallback);
+
+ HRESULT SetCompressionMethod(CCompressionMethodMode &method,
+ CObjectVector<COneMethodInfo> &methodsInfo
+ #ifdef COMPRESS_MT
+ , UInt32 numThreads
+ #endif
+ );
+
+ HRESULT SetCompressionMethod(
+ CCompressionMethodMode &method,
+ CCompressionMethodMode &headerMethod);
+
+ #endif
+
+ #ifndef _SFX
+
+ CRecordVector<UInt64> _fileInfoPopIDs;
+ void FillPopIDs();
+
+ #endif
+
+ #ifndef EXTRACT_ONLY
+
+ void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); }
+ void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); }
+ void InitSolid()
+ {
+ InitSolidFiles();
+ InitSolidSize();
+ _solidExtension = false;
+ _numSolidBytesDefined = false;
+ }
+
+ void Init()
+ {
+ _removeSfxBlock = false;
+ _compressHeaders = true;
+ _compressHeadersFull = true;
+ _encryptHeaders = false;
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ #endif
+
+ _level = 5;
+ _autoFilter = true;
+ _volumeMode = false;
+ InitSolid();
+ }
+ #endif
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.cpp
new file mode 100644
index 0000000000..7aff58fa47
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.h
new file mode 100644
index 0000000000..f301677267
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.cpp
new file mode 100644
index 0000000000..86709d36d8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.cpp
@@ -0,0 +1,1294 @@
+// 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"
+
+namespace NArchive {
+namespace N7z {
+
+class CStreamSwitch
+{
+ CInArchive *_archive;
+ bool _needRemove;
+public:
+ CStreamSwitch(): _needRemove(false) {}
+ ~CStreamSwitch() { Remove(); }
+ void Remove();
+ void Set(CInArchive *archive, const Byte *data, size_t size);
+ void Set(CInArchive *archive, const CByteBuffer &byteBuffer);
+ HRESULT Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);
+};
+
+void CStreamSwitch::Remove()
+{
+ if (_needRemove)
+ {
+ _archive->DeleteByteStream();
+ _needRemove = false;
+ }
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size)
+{
+ Remove();
+ _archive = archive;
+ _archive->AddByteStream(data, size);
+ _needRemove = true;
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
+{
+ Set(archive, byteBuffer, byteBuffer.GetCapacity());
+}
+
+HRESULT CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
+{
+ Remove();
+ Byte external;
+ RINOK(archive->ReadByte(external));
+ if (external != 0)
+ {
+ CNum dataIndex;
+ RINOK(archive->ReadNum(dataIndex));
+ Set(archive, (*dataVector)[dataIndex]);
+ }
+ return S_OK;
+}
+
+
+CInArchiveException::CInArchiveException(CCauseType cause):
+ Cause(cause)
+{}
+
+HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size,
+ UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = ReadStream(stream, data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ _position += realProcessedSize;
+ return result;
+}
+
+HRESULT CInArchive::ReadDirect(void *data, UInt32 size, UInt32 *processedSize)
+{
+ return ReadDirect(_stream, data, size, processedSize);
+}
+
+HRESULT CInArchive::SafeReadDirect(void *data, UInt32 size)
+{
+ UInt32 realProcessedSize;
+ RINOK(ReadDirect(data, size, &realProcessedSize));
+ if (realProcessedSize != size)
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+ return S_OK;
+}
+
+HRESULT CInArchive::SafeReadDirectByte(Byte &b)
+{
+ return SafeReadDirect(&b, 1);
+}
+
+HRESULT CInArchive::SafeReadDirectUInt32(UInt32 &value)
+{
+ value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(b));
+ value |= (UInt32(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::SafeReadDirectUInt64(UInt64 &value)
+{
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(b));
+ value |= (UInt64(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadNumber(UInt64 &value)
+{
+ Byte firstByte;
+ RINOK(ReadByte(firstByte));
+ Byte mask = 0x80;
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = firstByte & (mask - 1);
+ value += (highPart << (i * 8));
+ return S_OK;
+ }
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt64(b) << (8 * i));
+ mask >>= 1;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadNum(CNum &value)
+{
+ UInt64 value64;
+ RINOK(ReadNumber(value64));
+ if (value64 > kNumMax)
+ return E_FAIL;
+ value = (CNum)value64;
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUInt32(UInt32 &value)
+{
+ value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt32(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUInt64(UInt64 &value)
+{
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt64(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+static inline bool TestSignatureCandidate(const void *testBytes)
+{
+ for (int i = 0; i < kSignatureSize; i++)
+ if (((const Byte *)testBytes)[i] != kSignature[i])
+ return false;
+ return true;
+}
+
+#ifdef _7Z_VOL
+static inline bool TestFinishSignatureCandidate(const void *testBytes)
+{
+ for (int i = 0; i < kSignatureSize; i++)
+ if (((const Byte *)testBytes)[i] != kFinishSignature[i])
+ return false;
+ return true;
+}
+#endif
+
+HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ _position = _arhiveBeginStreamPosition;
+ RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL));
+
+ Byte signature[kSignatureSize];
+ UInt32 processedSize;
+ RINOK(ReadDirect(stream, signature, kSignatureSize, &processedSize));
+ if(processedSize != kSignatureSize)
+ return S_FALSE;
+ if (TestSignatureCandidate(signature))
+ return S_OK;
+
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (1 << 16);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ UInt32 numPrevBytes = kSignatureSize - 1;
+ memmove(buffer, signature + 1, numPrevBytes);
+ UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
+ while(true)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
+ return S_FALSE;
+ UInt32 numReadBytes = kBufferSize - numPrevBytes;
+ RINOK(ReadDirect(stream, buffer + numPrevBytes, numReadBytes, &processedSize));
+ UInt32 numBytesInBuffer = numPrevBytes + processedSize;
+ if (numBytesInBuffer < kSignatureSize)
+ return S_FALSE;
+ UInt32 numTests = numBytesInBuffer - kSignatureSize + 1;
+ for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
+ {
+ if (TestSignatureCandidate(buffer + pos))
+ {
+ _arhiveBeginStreamPosition = curTestPos;
+ _position = curTestPos + kSignatureSize;
+ return stream->Seek(_position, STREAM_SEEK_SET, NULL);
+ }
+ }
+ numPrevBytes = numBytesInBuffer - numTests;
+ memmove(buffer, buffer + numTests, numPrevBytes);
+ }
+}
+
+// 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)
+{
+ while(true)
+ {
+ 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();
+
+ while (true)
+ {
+ coder.AltCoders.Add(CAltCoderInfo());
+ CAltCoderInfo &altCoder = coder.AltCoders.Back();
+ Byte mainByte;
+ RINOK(ReadByte(mainByte));
+ altCoder.MethodID.IDSize = 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)
+{
+ while(true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == attribute)
+ return S_OK;
+ if (type == NID::kEnd)
+ return S_FALSE;
+ RINOK(SkeepData());
+ }
+}
+
+HRESULT CInArchive::ReadHashDigests(int numItems,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ RINOK(ReadBoolVector2(numItems, digestsDefined));
+ digests.Clear();
+ digests.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ {
+ UInt32 crc;
+ if (digestsDefined[i])
+ RINOK(ReadUInt32(crc));
+ digests.Add(crc);
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadPackInfo(
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs)
+{
+ RINOK(ReadNumber(dataOffset));
+ CNum numPackStreams;
+ RINOK(ReadNum(numPackStreams));
+
+ RINOK(WaitAttribute(NID::kSize));
+ packSizes.Clear();
+ packSizes.Reserve(numPackStreams);
+ for(CNum i = 0; i < numPackStreams; i++)
+ {
+ UInt64 size;
+ RINOK(ReadNumber(size));
+ packSizes.Add(size);
+ }
+
+ UInt64 type;
+ while(true)
+ {
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ if (type == NID::kCRC)
+ {
+ RINOK(ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs));
+ continue;
+ }
+ RINOK(SkeepData());
+ }
+ if (packCRCsDefined.IsEmpty())
+ {
+ packCRCsDefined.Reserve(numPackStreams);
+ packCRCsDefined.Clear();
+ packCRCs.Reserve(numPackStreams);
+ packCRCs.Clear();
+ for(CNum i = 0; i < numPackStreams; i++)
+ {
+ packCRCsDefined.Add(false);
+ packCRCs.Add(0);
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUnPackInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ CObjectVector<CFolder> &folders)
+{
+ RINOK(WaitAttribute(NID::kFolder));
+ CNum numFolders;
+ RINOK(ReadNum(numFolders));
+
+ {
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, dataVector));
+ folders.Clear();
+ folders.Reserve((UInt32)numFolders);
+ for(CNum i = 0; i < numFolders; i++)
+ {
+ folders.Add(CFolder());
+ RINOK(GetNextFolderItem(folders.Back()));
+ }
+ }
+
+ RINOK(WaitAttribute(NID::kCodersUnPackSize));
+
+ CNum i;
+ for(i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ CNum numOutStreams = folder.GetNumOutStreams();
+ folder.UnPackSizes.Reserve(numOutStreams);
+ for(CNum j = 0; j < numOutStreams; j++)
+ {
+ UInt64 unPackSize;
+ RINOK(ReadNumber(unPackSize));
+ folder.UnPackSizes.Add(unPackSize);
+ }
+ }
+
+ while(true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> crcsDefined;
+ CRecordVector<UInt32> crcs;
+ RINOK(ReadHashDigests(numFolders, crcsDefined, crcs));
+ for(i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ folder.UnPackCRCDefined = crcsDefined[i];
+ folder.UnPackCRC = crcs[i];
+ }
+ continue;
+ }
+ RINOK(SkeepData());
+ }
+}
+
+HRESULT CInArchive::ReadSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ numUnPackStreamsInFolders.Clear();
+ numUnPackStreamsInFolders.Reserve(folders.Size());
+ UInt64 type;
+ while(true)
+ {
+ 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;
+ }
+
+ while(true)
+ {
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> digestsDefined2;
+ CRecordVector<UInt32> digests2;
+ RINOK(ReadHashDigests(numDigests, digestsDefined2, digests2));
+ int digestIndex = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ const CFolder &folder = folders[i];
+ if (numSubstreams == 1 && folder.UnPackCRCDefined)
+ {
+ digestsDefined.Add(true);
+ digests.Add(folder.UnPackCRC);
+ }
+ else
+ for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
+ {
+ digestsDefined.Add(digestsDefined2[digestIndex]);
+ digests.Add(digests2[digestIndex]);
+ }
+ }
+ }
+ else if (type == NID::kEnd)
+ {
+ if (digestsDefined.IsEmpty())
+ {
+ digestsDefined.Clear();
+ digests.Clear();
+ for (int i = 0; i < numDigestsTotal; i++)
+ {
+ digestsDefined.Add(false);
+ digests.Add(0);
+ }
+ }
+ return S_OK;
+ }
+ else
+ {
+ RINOK(SkeepData());
+ }
+ RINOK(ReadID(type));
+ }
+}
+
+HRESULT CInArchive::ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ while(true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ switch(type)
+ {
+ case NID::kEnd:
+ return S_OK;
+ case NID::kPackInfo:
+ {
+ RINOK(ReadPackInfo(dataOffset, packSizes,
+ packCRCsDefined, packCRCs));
+ break;
+ }
+ case NID::kUnPackInfo:
+ {
+ RINOK(ReadUnPackInfo(dataVector, folders));
+ break;
+ }
+ case NID::kSubStreamsInfo:
+ {
+ RINOK(ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
+ unPackSizes, digestsDefined, digests));
+ break;
+ }
+ }
+ }
+}
+
+HRESULT CInArchive::ReadFileNames(CObjectVector<CFileItem> &files)
+{
+ for(int i = 0; i < files.Size(); i++)
+ {
+ UString &name = files[i].Name;
+ name.Empty();
+ while (true)
+ {
+ 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;
+ Byte mask = 0;
+ for(int i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ RINOK(ReadByte(b));
+ mask = 0x80;
+ }
+ v.Add((b & mask) != 0);
+ mask >>= 1;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
+{
+ Byte allAreDefined;
+ RINOK(ReadByte(allAreDefined));
+ if (allAreDefined == 0)
+ return ReadBoolVector(numItems, v);
+ v.Clear();
+ v.Reserve(numItems);
+ for (int i = 0; i < numItems; i++)
+ v.Add(true);
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt64 type)
+{
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+
+ for(int i = 0; i < files.Size(); i++)
+ {
+ CFileItem &file = files[i];
+ CArchiveFileTime fileTime;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ UInt32 low, high;
+ RINOK(ReadUInt32(low));
+ RINOK(ReadUInt32(high));
+ fileTime.dwLowDateTime = low;
+ fileTime.dwHighDateTime = high;
+ }
+ switch(type)
+ {
+ case NID::kCreationTime:
+ file.IsCreationTimeDefined = defined;
+ if (defined)
+ file.CreationTime = fileTime;
+ break;
+ case NID::kLastWriteTime:
+ file.IsLastWriteTimeDefined = defined;
+ if (defined)
+ file.LastWriteTime = fileTime;
+ break;
+ case NID::kLastAccessTime:
+ file.IsLastAccessTimeDefined = defined;
+ if (defined)
+ file.LastAccessTime = fileTime;
+ break;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
+ UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ CRecordVector<UInt64> packSizes;
+ CRecordVector<bool> packCRCsDefined;
+ CRecordVector<UInt32> packCRCs;
+ CObjectVector<CFolder> folders;
+
+ CRecordVector<CNum> numUnPackStreamsInFolders;
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+
+ RINOK(ReadStreamsInfo(NULL,
+ dataOffset,
+ packSizes,
+ packCRCsDefined,
+ packCRCs,
+ folders,
+ numUnPackStreamsInFolders,
+ unPackSizes,
+ digestsDefined,
+ digests));
+
+ // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+
+ CNum packIndex = 0;
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
+ UInt64 dataStartPos = baseOffset + dataOffset;
+ for(int i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ dataVector.Add(CByteBuffer());
+ CByteBuffer &data = dataVector.Back();
+ UInt64 unPackSize = folder.GetUnPackSize();
+ if (unPackSize > kNumMax)
+ return E_FAIL;
+ if (unPackSize > 0xFFFFFFFF)
+ return E_FAIL;
+ data.SetCapacity((size_t)unPackSize);
+
+ CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ outStreamSpec->Init(data, (size_t)unPackSize);
+
+ HRESULT result = decoder.Decode(_stream, dataStartPos,
+ &packSizes[packIndex], folder, outStream, NULL
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , false, 1
+ #endif
+ );
+ RINOK(result);
+
+ if (folder.UnPackCRCDefined)
+ if (!CCRC::VerifyDigest(folder.UnPackCRC, data, (UInt32)unPackSize))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ for (int j = 0; j < folder.PackStreams.Size(); j++)
+ dataStartPos += packSizes[packIndex++];
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ UInt64 type;
+ RINOK(ReadID(type));
+
+ if (type == NID::kArchiveProperties)
+ {
+ RINOK(ReadArchiveProperties(database.ArchiveInfo));
+ RINOK(ReadID(type));
+ }
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ if (type == NID::kAdditionalStreamsInfo)
+ {
+ HRESULT result = ReadAndDecodePackedStreams(
+ database.ArchiveInfo.StartPositionAfterHeader,
+ database.ArchiveInfo.DataStartPosition2,
+ dataVector
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+ RINOK(ReadID(type));
+ }
+
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+
+ if (type == NID::kMainStreamsInfo)
+ {
+ RINOK(ReadStreamsInfo(&dataVector,
+ database.ArchiveInfo.DataStartPosition,
+ database.PackSizes,
+ database.PackCRCsDefined,
+ database.PackCRCs,
+ database.Folders,
+ database.NumUnPackStreamsVector,
+ unPackSizes,
+ digestsDefined,
+ digests));
+ database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader;
+ RINOK(ReadID(type));
+ }
+ else
+ {
+ for(int i = 0; i < database.Folders.Size(); i++)
+ {
+ database.NumUnPackStreamsVector.Add(1);
+ CFolder &folder = database.Folders[i];
+ unPackSizes.Add(folder.GetUnPackSize());
+ digestsDefined.Add(folder.UnPackCRCDefined);
+ digests.Add(folder.UnPackCRC);
+ }
+ }
+
+ database.Files.Clear();
+
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type != NID::kFilesInfo)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ CNum numFiles;
+ RINOK(ReadNum(numFiles));
+ database.Files.Reserve(numFiles);
+ CNum i;
+ for(i = 0; i < numFiles; i++)
+ database.Files.Add(CFileItem());
+
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
+ if (!database.PackSizes.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+ if (numFiles > 0 && !digests.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.Reserve((int)numFiles);
+ for(i = 0; i < numFiles; i++)
+ emptyStreamVector.Add(false);
+ CBoolVector emptyFileVector;
+ CBoolVector antiFileVector;
+ CNum numEmptyStreams = 0;
+
+ // int sizePrev = -1;
+ // int posPrev = 0;
+
+ while(true)
+ {
+ /*
+ if (sizePrev >= 0)
+ if (sizePrev != _inByteBack->GetProcessedSize() - posPrev)
+ throw 2;
+ */
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ UInt64 size;
+ RINOK(ReadNumber(size));
+
+ // sizePrev = size;
+ // posPrev = _inByteBack->GetProcessedSize();
+
+ database.ArchiveInfo.FileInfoPopIDs.Add(type);
+ switch(type)
+ {
+ case NID::kName:
+ {
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+ RINOK(ReadFileNames(database.Files))
+ break;
+ }
+ case NID::kWinAttributes:
+ {
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(database.Files.Size(), boolVector))
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ if (file.AreAttributesDefined = boolVector[i])
+ {
+ 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];
+ if (file.IsStartPosDefined = boolVector[i])
+ {
+ 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
+ while(true)
+ {
+ 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;
+ RINOK(SafeReadDirectUInt32(crcFromArchive));
+
+ UInt64 nextHeaderOffset;
+ UInt64 nextHeaderSize;
+ UInt32 nextHeaderCRC;
+ CCRC crc;
+ RINOK(SafeReadDirectUInt64(nextHeaderOffset));
+ crc.UpdateUInt64(nextHeaderOffset);
+ RINOK(SafeReadDirectUInt64(nextHeaderSize));
+ crc.UpdateUInt64(nextHeaderSize);
+ RINOK(SafeReadDirectUInt32(nextHeaderCRC));
+ crc.UpdateUInt32(nextHeaderCRC);
+
+ #ifdef _7Z_VOL
+ UInt64 archiveStartOffset; // data offset from end if that struct
+ UInt64 additionalStartBlockSize; // start signature & start header size
+ if (_finishSignature)
+ {
+ RINOK(SafeReadDirectUInt64(archiveStartOffset));
+ crc.UpdateUInt64(archiveStartOffset);
+ RINOK(SafeReadDirectUInt64(additionalStartBlockSize));
+ crc.UpdateUInt64(additionalStartBlockSize);
+ database.ArchiveInfo.StartPositionAfterHeader = _position + archiveStartOffset;
+ }
+ else
+ #endif
+ {
+ database.ArchiveInfo.StartPositionAfterHeader = _position;
+ }
+ if (crc.GetDigest() != crcFromArchive)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ if (nextHeaderSize == 0)
+ return S_OK;
+
+ if (nextHeaderSize >= 0xFFFFFFFF)
+ return E_FAIL;
+
+ RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, &_position));
+
+ CByteBuffer buffer2;
+ buffer2.SetCapacity((size_t)nextHeaderSize);
+ RINOK(SafeReadDirect(buffer2, (UInt32)nextHeaderSize));
+ if (!CCRC::VerifyDigest(nextHeaderCRC, buffer2, (UInt32)nextHeaderSize))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, buffer2);
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ while (true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kHeader)
+ break;
+ if (type != NID::kEncodedHeader)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ HRESULT result = ReadAndDecodePackedStreams(
+ database.ArchiveInfo.StartPositionAfterHeader,
+ database.ArchiveInfo.DataStartPosition2,
+ dataVector
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ if (dataVector.Size() == 0)
+ return S_OK;
+ if (dataVector.Size() > 1)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ streamSwitch.Remove();
+ streamSwitch.Set(this, dataVector.Front());
+ }
+
+ return ReadHeader(database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.h
new file mode 100644
index 0000000000..a6c5ef032d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.h
@@ -0,0 +1,288 @@
+// 7zIn.h
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+#include "../../../Common/MyCom.h"
+#include "../../Common/InBuffer.h"
+
+#include "7zHeader.h"
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CInArchiveException
+{
+public:
+ enum CCauseType
+ {
+ kUnsupportedVersion = 0,
+ kUnexpectedEndOfArchive = 0,
+ kIncorrectHeader,
+ } Cause;
+ CInArchiveException(CCauseType cause);
+};
+
+struct CInArchiveInfo
+{
+ CArchiveVersion Version;
+ UInt64 StartPosition;
+ UInt64 StartPositionAfterHeader;
+ UInt64 DataStartPosition;
+ UInt64 DataStartPosition2;
+ CRecordVector<UInt64> FileInfoPopIDs;
+ void Clear()
+ {
+ FileInfoPopIDs.Clear();
+ }
+};
+
+
+struct CArchiveDatabaseEx: public CArchiveDatabase
+{
+ CInArchiveInfo ArchiveInfo;
+ CRecordVector<UInt64> PackStreamStartPositions;
+ CRecordVector<CNum> FolderStartPackStreamIndex;
+ CRecordVector<CNum> FolderStartFileIndex;
+ CRecordVector<CNum> FileIndexToFolderIndexMap;
+
+ void Clear()
+ {
+ CArchiveDatabase::Clear();
+ ArchiveInfo.Clear();
+ PackStreamStartPositions.Clear();
+ FolderStartPackStreamIndex.Clear();
+ FolderStartFileIndex.Clear();
+ FileIndexToFolderIndexMap.Clear();
+ }
+
+ void FillFolderStartPackStream();
+ void FillStartPos();
+ void FillFolderStartFileIndex();
+
+ void Fill()
+ {
+ FillFolderStartPackStream();
+ FillStartPos();
+ FillFolderStartFileIndex();
+ }
+
+ UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
+ {
+ return ArchiveInfo.DataStartPosition +
+ PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] +
+ indexInFolder];
+ }
+
+ UInt64 GetFolderFullPackSize(int folderIndex) const
+ {
+ CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
+ const CFolder &folder = Folders[folderIndex];
+ UInt64 size = 0;
+ for (int i = 0; i < folder.PackStreams.Size(); i++)
+ size += PackSizes[packStreamIndex + i];
+ return size;
+ }
+
+ UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+ {
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+ }
+
+ UInt64 GetFilePackSize(CNum fileIndex) const
+ {
+ CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex >= 0)
+ {
+ if (FolderStartFileIndex[folderIndex] == fileIndex)
+ return GetFolderFullPackSize(folderIndex);
+ }
+ return 0;
+ }
+};
+
+class CInByte2
+{
+ const Byte *_buffer;
+ size_t _size;
+ size_t _pos;
+public:
+ void Init(const Byte *buffer, size_t size)
+ {
+ _buffer = buffer;
+ _size = size;
+ _pos = 0;
+ }
+ bool ReadByte(Byte &b)
+ {
+ if(_pos >= _size)
+ return false;
+ b = _buffer[_pos++];
+ return true;
+ }
+ void ReadBytes(void *data, size_t size, size_t &processedSize)
+ {
+ for(processedSize = 0; processedSize < size && _pos < _size; processedSize++)
+ ((Byte *)data)[processedSize] = _buffer[_pos++];
+ }
+
+ bool ReadBytes(void *data, size_t size)
+ {
+ size_t processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+
+ size_t GetProcessedSize() const { return _pos; }
+};
+
+class CStreamSwitch;
+class CInArchive
+{
+ friend class CStreamSwitch;
+
+ CMyComPtr<IInStream> _stream;
+ #ifdef _7Z_VOL
+ bool _finishSignature;
+ #endif
+
+ CObjectVector<CInByte2> _inByteVector;
+ CInByte2 *_inByteBack;
+
+ UInt64 _arhiveBeginStreamPosition;
+ UInt64 _position;
+
+ void AddByteStream(const Byte *buffer, size_t size)
+ {
+ _inByteVector.Add(CInByte2());
+ _inByteBack = &_inByteVector.Back();
+ _inByteBack->Init(buffer, size);
+ }
+
+ void DeleteByteStream()
+ {
+ _inByteVector.DeleteBack();
+ if (!_inByteVector.IsEmpty())
+ _inByteBack = &_inByteVector.Back();
+ }
+
+private:
+ HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ #ifdef _7Z_VOL
+ HRESULT FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ #endif
+
+ HRESULT ReadFileNames(CObjectVector<CFileItem> &files);
+
+ HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size,
+ UInt32 *processedSize);
+ HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize);
+ HRESULT SafeReadDirect(void *data, UInt32 size);
+ HRESULT SafeReadDirectByte(Byte &b);
+ HRESULT SafeReadDirectUInt32(UInt32 &value);
+ HRESULT SafeReadDirectUInt64(UInt64 &value);
+
+ HRESULT ReadBytes(void *data, size_t size)
+ {
+ if (!_inByteBack->ReadBytes(data, size))
+ return E_FAIL;
+ return S_OK;
+ }
+
+ HRESULT ReadByte(Byte &b)
+ {
+ if (!_inByteBack->ReadByte(b))
+ return E_FAIL;
+ return S_OK;
+ }
+
+ HRESULT ReadWideCharLE(wchar_t &c)
+ {
+ Byte b1;
+ if (!_inByteBack->ReadByte(b1))
+ return E_FAIL;
+ Byte b2;
+ if (!_inByteBack->ReadByte(b2))
+ return E_FAIL;
+ c = (wchar_t(b2) << 8) + b1;
+ return S_OK;
+ }
+
+ HRESULT ReadNumber(UInt64 &value);
+ HRESULT ReadNum(CNum &value);
+ HRESULT ReadID(UInt64 &value) { return ReadNumber(value); }
+ HRESULT ReadUInt32(UInt32 &value);
+ HRESULT ReadUInt64(UInt64 &value);
+
+ HRESULT SkeepData(UInt64 size);
+ HRESULT SkeepData();
+ HRESULT WaitAttribute(UInt64 attribute);
+
+ HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo);
+ HRESULT GetNextFolderItem(CFolder &itemInfo);
+ HRESULT ReadHashDigests(int numItems,
+ CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
+
+ HRESULT ReadPackInfo(
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs);
+
+ HRESULT ReadUnPackInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ CObjectVector<CFolder> &folders);
+
+ HRESULT ReadSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests);
+
+ HRESULT ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests);
+
+
+ HRESULT GetNextFileItem(CFileItem &itemInfo);
+ HRESULT ReadBoolVector(int numItems, CBoolVector &v);
+ HRESULT ReadBoolVector2(int numItems, CBoolVector &v);
+ HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt64 type);
+ HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset,
+ CObjectVector<CByteBuffer> &dataVector
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+ HRESULT ReadHeader(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+public:
+ HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ void Close();
+
+ HRESULT ReadDatabase(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zItem.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zItem.h
new file mode 100644
index 0000000000..c50a0bcf41
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zItem.h
@@ -0,0 +1,181 @@
+// 7zItem.h
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "../../../Common/Buffer.h"
+#include "7zMethodID.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CAltCoderInfo
+{
+ CMethodID MethodID;
+ CByteBuffer Properties;
+};
+
+typedef UInt32 CNum;
+const CNum kNumMax = 0x7FFFFFFF;
+const CNum kNumNoIndex = 0xFFFFFFFF;
+
+struct CCoderInfo
+{
+ CNum NumInStreams;
+ CNum NumOutStreams;
+ CObjectVector<CAltCoderInfo> AltCoders;
+ bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+};
+
+struct CBindPair
+{
+ CNum InIndex;
+ CNum OutIndex;
+};
+
+struct CFolder
+{
+ CObjectVector<CCoderInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<CNum> PackStreams;
+ CRecordVector<UInt64> UnPackSizes;
+ UInt32 UnPackCRC;
+ bool UnPackCRCDefined;
+
+ CFolder(): UnPackCRCDefined(false) {}
+
+ UInt64 GetUnPackSize() const // test it
+ {
+ if (UnPackSizes.IsEmpty())
+ return 0;
+ for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
+ if (FindBindPairForOutStream(i) < 0)
+ return UnPackSizes[i];
+ throw 1;
+ }
+
+ CNum GetNumOutStreams() const
+ {
+ CNum result = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ result += Coders[i].NumOutStreams;
+ return result;
+ }
+
+ int FindBindPairForInStream(CNum inStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindBindPairForOutStream(CNum outStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindPackStreamArrayIndex(CNum inStreamIndex) const
+ {
+ for(int i = 0; i < PackStreams.Size(); i++)
+ if (PackStreams[i] == inStreamIndex)
+ return i;
+ return -1;
+ }
+};
+
+typedef FILETIME CArchiveFileTime;
+
+class CFileItem
+{
+public:
+ CArchiveFileTime CreationTime;
+ CArchiveFileTime LastWriteTime;
+ CArchiveFileTime LastAccessTime;
+ UInt64 UnPackSize;
+ UInt64 StartPos;
+ UInt32 Attributes;
+ UInt32 FileCRC;
+ UString Name;
+
+ bool HasStream; // Test it !!! it means that there is
+ // stream in some folder. It can be empty stream
+ bool IsDirectory;
+ bool IsAnti;
+ bool IsFileCRCDefined;
+ bool AreAttributesDefined;
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+ bool IsStartPosDefined;
+
+ /*
+ const bool HasStream() const {
+ return !IsDirectory && !IsAnti && UnPackSize != 0; }
+ */
+ CFileItem():
+ HasStream(true),
+ IsDirectory(false),
+ IsAnti(false),
+ IsFileCRCDefined(false),
+ AreAttributesDefined(false),
+ IsCreationTimeDefined(false),
+ IsLastWriteTimeDefined(false),
+ IsLastAccessTimeDefined(false),
+ IsStartPosDefined(false)
+ {}
+ void SetAttributes(UInt32 attributes)
+ {
+ AreAttributesDefined = true;
+ Attributes = attributes;
+ }
+ void SetCreationTime(const CArchiveFileTime &creationTime)
+ {
+ IsCreationTimeDefined = true;
+ CreationTime = creationTime;
+ }
+ void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
+ {
+ IsLastWriteTimeDefined = true;
+ LastWriteTime = lastWriteTime;
+ }
+ void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
+ {
+ IsLastAccessTimeDefined = true;
+ LastAccessTime = lastAccessTime;
+ }
+};
+
+struct CArchiveDatabase
+{
+ CRecordVector<UInt64> PackSizes;
+ CRecordVector<bool> PackCRCsDefined;
+ CRecordVector<UInt32> PackCRCs;
+ CObjectVector<CFolder> Folders;
+ CRecordVector<CNum> NumUnPackStreamsVector;
+ CObjectVector<CFileItem> Files;
+ void Clear()
+ {
+ PackSizes.Clear();
+ PackCRCsDefined.Clear();
+ PackCRCs.Clear();
+ Folders.Clear();
+ NumUnPackStreamsVector.Clear();
+ Files.Clear();
+ }
+ bool IsEmpty() const
+ {
+ return (PackSizes.IsEmpty() &&
+ PackCRCsDefined.IsEmpty() &&
+ PackCRCs.IsEmpty() &&
+ Folders.IsEmpty() &&
+ NumUnPackStreamsVector.IsEmpty() &&
+ Files.IsEmpty());
+ }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.cpp
new file mode 100644
index 0000000000..a7b1296e9f
--- /dev/null
+++ b/other-licenses/7zstub/src/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 (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+
+static bool HexCharToInt(wchar_t value, Byte &result)
+{
+ if (value >= '0' && value <= '9')
+ result = value - '0';
+ else if (value >= 'a' && value <= 'f')
+ result = 10 + value - 'a';
+ else if (value >= 'A' && value <= 'F')
+ result = 10 + value - 'A';
+ else
+ return false;
+ return true;
+}
+
+static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, Byte &result)
+{
+ Byte resultHigh, resultLow;
+ if (!HexCharToInt(valueHigh, resultHigh))
+ return false;
+ if (!HexCharToInt(valueLow, resultLow))
+ return false;
+ result = (resultHigh << 4) + resultLow;
+ return true;
+}
+
+UString CMethodID::ConvertToString() const
+{
+ UString result;
+ for (int i = 0; i < IDSize; i++)
+ {
+ Byte b = ID[i];
+ result += GetHex(b >> 4);
+ result += GetHex(b & 0xF);
+ }
+ return result;
+}
+
+bool CMethodID::ConvertFromString(const UString &srcString)
+{
+ int length = srcString.Length();
+ if ((length & 1) != 0 || (length >> 1) > kMethodIDSize)
+ return false;
+ IDSize = 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/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.h
new file mode 100644
index 0000000000..6bff152d6c
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.cpp
new file mode 100644
index 0000000000..32f59003b2
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.cpp
@@ -0,0 +1,174 @@
+// 7zMethods.cpp
+
+#include "StdAfx.h"
+
+#include "7zMethods.h"
+
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/Synchronization.h"
+
+#include "../../ICoder.h"
+#include "../Common/CodecsPath.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+static CObjectVector<CMethodInfo2> g_Methods;
+static bool g_Loaded = false;
+
+typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
+
+typedef UInt32 (WINAPI *GetMethodPropertyFunc)(
+ UInt32 index, PROPID propID, PROPVARIANT *value);
+
+static void Load(const CSysString &folderPrefix)
+{
+ NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
+ NFile::NFind::CFileInfo fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ CSysString filePath = folderPrefix + fileInfo.Name;
+ {
+ NDLL::CLibrary library;
+ if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
+ continue;
+ }
+ NDLL::CLibrary library;
+ if (!library.Load(filePath))
+ continue;
+ GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc)
+ library.GetProcAddress("GetMethodProperty");
+ if (getMethodProperty == NULL)
+ continue;
+
+ UInt32 numMethods = 1;
+ GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)
+ library.GetProcAddress("GetNumberOfMethods");
+ if (getNumberOfMethodsFunc != NULL)
+ if (getNumberOfMethodsFunc(&numMethods) != S_OK)
+ continue;
+
+ for(UInt32 i = 0; i < numMethods; i++)
+ {
+ CMethodInfo2 info;
+ info.FilePath = filePath;
+
+ NWindows::NCOM::CPropVariant propVariant;
+ if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt != VT_BSTR)
+ continue;
+ info.MethodID.IDSize = SysStringByteLen(propVariant.bstrVal);
+ memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize);
+ propVariant.Clear();
+
+ if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ {
+ }
+ else if (propVariant.vt == VT_BSTR)
+ info.Name = propVariant.bstrVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.EncoderIsAssigned = false;
+ else if (propVariant.vt == VT_BSTR)
+ {
+ info.EncoderIsAssigned = true;
+ info.Encoder = *(const GUID *)propVariant.bstrVal;
+ }
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.DecoderIsAssigned = false;
+ else if (propVariant.vt == VT_BSTR)
+ {
+ info.DecoderIsAssigned = true;
+ info.Decoder = *(const GUID *)propVariant.bstrVal;
+ }
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.NumInStreams = 1;
+ else if (propVariant.vt == VT_UI4)
+ info.NumInStreams = propVariant.ulVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.NumOutStreams = 1;
+ else if (propVariant.vt == VT_UI4)
+ info.NumOutStreams = propVariant.ulVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ g_Methods.Add(info);
+ }
+ }
+}
+
+static NSynchronization::CCriticalSection g_CriticalSection;
+
+void LoadMethodMap()
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ if (g_Loaded)
+ return;
+ g_Loaded = true;
+ Load(GetCodecsFolderPrefix());
+}
+
+bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo)
+{
+ for(int i = 0; i < g_Methods.Size(); i++)
+ {
+ const CMethodInfo2 &method = g_Methods[i];
+ if (method.MethodID == methodID)
+ {
+ methodInfo = (CMethodInfo)method;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
+{
+ for(int i = 0; i < g_Methods.Size(); i++)
+ {
+ const CMethodInfo2 &method = g_Methods[i];
+ if (method.Name.CompareNoCase(name) == 0)
+ {
+ methodInfo = method;
+ return true;
+ }
+ }
+ return false;
+}
+
+}}
+
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.h
new file mode 100644
index 0000000000..429199d044
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.cpp
new file mode 100644
index 0000000000..d474be0957
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.cpp
@@ -0,0 +1,166 @@
+// 7zProperties.cpp
+
+#include "StdAfx.h"
+
+#include "7zProperties.h"
+#include "7zHeader.h"
+#include "7zHandler.h"
+
+// #define _MULTI_PACK
+
+namespace NArchive {
+namespace N7z {
+
+struct CPropMap
+{
+ UInt64 FilePropID;
+ STATPROPSTG StatPROPSTG;
+};
+
+CPropMap kPropMap[] =
+{
+ { NID::kName, NULL, kpidPath, VT_BSTR},
+ { NID::kSize, NULL, kpidSize, VT_UI8},
+ { NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
+
+ #ifdef _MULTI_PACK
+ { 100, L"Pack0", kpidPackedSize0, VT_UI8},
+ { 101, L"Pack1", kpidPackedSize1, VT_UI8},
+ { 102, L"Pack2", kpidPackedSize2, VT_UI8},
+ { 103, L"Pack3", kpidPackedSize3, VT_UI8},
+ { 104, L"Pack4", kpidPackedSize4, VT_UI8},
+ #endif
+
+ { NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
+ { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
+ { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
+ { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
+ { NID::kStartPos, NULL, kpidPosition, VT_UI4},
+
+
+ { NID::kCRC, NULL, kpidCRC, VT_UI4},
+
+ { NID::kAnti, L"Anti", kpidIsAnti, VT_BOOL},
+ // { 97, NULL, kpidSolid, VT_BOOL},
+ #ifndef _SFX
+ { 98, NULL, kpidMethod, VT_BSTR},
+ { 99, L"Block", kpidBlock, VT_UI4}
+ #endif
+ // { L"ID", kpidID, VT_BSTR},
+ // { L"UnPack Version", kpidUnPackVersion, VT_UI1},
+ // { L"Host OS", kpidHostOS, VT_BSTR}
+};
+
+static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
+
+static int FindPropInMap(UInt64 filePropID)
+{
+ for (int i = 0; i < kPropMapSize; i++)
+ if (kPropMap[i].FilePropID == filePropID)
+ return i;
+ return -1;
+}
+
+static void CopyOneItem(CRecordVector<UInt64> &src,
+ CRecordVector<UInt64> &dest, UInt32 item)
+{
+ for (int i = 0; i < src.Size(); i++)
+ if (src[i] == item)
+ {
+ dest.Add(item);
+ src.Delete(i);
+ return;
+ }
+}
+
+static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
+{
+ for (int i = 0; i < src.Size(); i++)
+ if (src[i] == item)
+ {
+ src.Delete(i);
+ return;
+ }
+}
+
+static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
+{
+ for (int i = 0; i < dest.Size(); i++)
+ if (dest[i] == item)
+ {
+ dest.Delete(i);
+ break;
+ }
+ dest.Insert(0, item);
+}
+
+void CHandler::FillPopIDs()
+{
+ _fileInfoPopIDs.Clear();
+
+ #ifdef _7Z_VOL
+ if(_volumes.Size() < 1)
+ return;
+ const CVolume &volume = _volumes.Front();
+ const CArchiveDatabaseEx &_database = volume.Database;
+ #endif
+
+ CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
+
+ RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
+ RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
+
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
+ _fileInfoPopIDs += fileInfoPopIDs;
+
+ #ifndef _SFX
+ _fileInfoPopIDs.Add(98);
+ _fileInfoPopIDs.Add(99);
+ #endif
+ #ifdef _MULTI_PACK
+ _fileInfoPopIDs.Add(100);
+ _fileInfoPopIDs.Add(101);
+ _fileInfoPopIDs.Add(102);
+ _fileInfoPopIDs.Add(103);
+ _fileInfoPopIDs.Add(104);
+ #endif
+
+ #ifndef _SFX
+ InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
+ InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
+ InsertToHead(_fileInfoPopIDs, NID::kSize);
+ InsertToHead(_fileInfoPopIDs, NID::kName);
+ #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = _fileInfoPopIDs.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if((int)index >= _fileInfoPopIDs.Size())
+ return E_INVALIDARG;
+ int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
+ if (indexInMap == -1)
+ return E_INVALIDARG;
+ const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
+ *propID = srcItem.propid;
+ *varType = srcItem.vt;
+ *name = 0;
+ return S_OK;
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.h
new file mode 100644
index 0000000000..2149e327ea
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Archive/Archive.def b/other-licenses/7zstub/src/7zip/Archive/Archive.def
new file mode 100644
index 0000000000..f06b0816d7
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Archive.def
@@ -0,0 +1,3 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.cpp
new file mode 100644
index 0000000000..4a552bf097
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.cpp
@@ -0,0 +1,121 @@
+// CoderMixer2.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2.h"
+
+namespace NCoderMixer2 {
+
+CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
+ _srcBindInfo(srcBindInfo)
+{
+ srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
+
+ UInt32 j;
+ for (j = 0; j < NumSrcInStreams; j++)
+ {
+ _srcInToDestOutMap.Add(0);
+ DestOutToSrcInMap.Add(0);
+ }
+ for (j = 0; j < _numSrcOutStreams; j++)
+ {
+ _srcOutToDestInMap.Add(0);
+ _destInToSrcOutMap.Add(0);
+ }
+
+ UInt32 destInOffset = 0;
+ UInt32 destOutOffset = 0;
+ UInt32 srcInOffset = NumSrcInStreams;
+ UInt32 srcOutOffset = _numSrcOutStreams;
+
+ for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];
+
+ srcInOffset -= srcCoderInfo.NumInStreams;
+ srcOutOffset -= srcCoderInfo.NumOutStreams;
+
+ UInt32 j;
+ for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
+ {
+ UInt32 index = srcInOffset + j;
+ _srcInToDestOutMap[index] = destOutOffset;
+ DestOutToSrcInMap[destOutOffset] = index;
+ }
+ for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)
+ {
+ UInt32 index = srcOutOffset + j;
+ _srcOutToDestInMap[index] = destInOffset;
+ _destInToSrcOutMap[destInOffset] = index;
+ }
+ }
+}
+
+void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
+{
+ destBindInfo.Coders.Clear();
+ destBindInfo.BindPairs.Clear();
+ destBindInfo.InStreams.Clear();
+ destBindInfo.OutStreams.Clear();
+
+ int i;
+ for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
+ CCoderStreamsInfo destCoderInfo;
+ destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
+ destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
+ destBindInfo.Coders.Add(destCoderInfo);
+ }
+ for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
+ {
+ const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
+ CBindPair destBindPair;
+ destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
+ destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
+ destBindInfo.BindPairs.Add(destBindPair);
+ }
+ for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
+ destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
+ for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
+ destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
+}
+
+CCoderInfo::CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams):
+ NumInStreams(numInStreams),
+ NumOutStreams(numOutStreams)
+{
+ InSizes.Reserve(NumInStreams);
+ InSizePointers.Reserve(NumInStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+ sizes.Clear();
+ sizePointers.Clear();
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (srcSizes == 0 || srcSizes[i] == NULL)
+ {
+ sizes.Add(0);
+ sizePointers.Add(NULL);
+ }
+ else
+ {
+ sizes.Add(*srcSizes[i]);
+ sizePointers.Add(&sizes.Back());
+ }
+ }
+}
+
+void CCoderInfo::SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes)
+{
+ SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+ SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.h b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.h
new file mode 100644
index 0000000000..00cca2190d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.h
@@ -0,0 +1,168 @@
+// CoderMixer2.h
+
+#ifndef __CODER_MIXER2_H
+#define __CODER_MIXER2_H
+
+#include "../../../Common/Vector.h"
+#include "../../../Common/Types.h"
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+namespace NCoderMixer2 {
+
+struct CBindPair
+{
+ UInt32 InIndex;
+ UInt32 OutIndex;
+};
+
+struct CCoderStreamsInfo
+{
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+};
+
+struct CBindInfo
+{
+ CRecordVector<CCoderStreamsInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<UInt32> InStreams;
+ CRecordVector<UInt32> OutStreams;
+
+ void Clear()
+ {
+ Coders.Clear();
+ BindPairs.Clear();
+ InStreams.Clear();
+ OutStreams.Clear();
+ }
+
+ /*
+ UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
+ {
+ UInt32 numOutStreams = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ numOutStreams += Coders[i].NumOutStreams;
+ return numOutStreams;
+ }
+ */
+
+
+ void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
+ {
+ numInStreams = 0;
+ numOutStreams = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ {
+ const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
+ numInStreams += coderStreamsInfo.NumInStreams;
+ numOutStreams += coderStreamsInfo.NumOutStreams;
+ }
+ }
+
+ int FindBinderForInStream(UInt32 inStream) const
+ {
+ for (int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStream)
+ return i;
+ return -1;
+ }
+ int FindBinderForOutStream(UInt32 outStream) const
+ {
+ for (int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStream)
+ return i;
+ return -1;
+ }
+
+ UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
+ {
+ UInt32 streamIndex = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ streamIndex += Coders[i].NumInStreams;
+ return streamIndex;
+ }
+
+ UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
+ {
+ UInt32 streamIndex = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ streamIndex += Coders[i].NumOutStreams;
+ return streamIndex;
+ }
+
+
+ void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
+ UInt32 &coderStreamIndex) const
+ {
+ for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+ {
+ UInt32 curSize = Coders[coderIndex].NumInStreams;
+ if (streamIndex < curSize)
+ {
+ coderStreamIndex = streamIndex;
+ return;
+ }
+ streamIndex -= curSize;
+ }
+ throw 1;
+ }
+ void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
+ UInt32 &coderStreamIndex) const
+ {
+ for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+ {
+ UInt32 curSize = Coders[coderIndex].NumOutStreams;
+ if (streamIndex < curSize)
+ {
+ coderStreamIndex = streamIndex;
+ return;
+ }
+ streamIndex -= curSize;
+ }
+ throw 1;
+ }
+};
+
+class CBindReverseConverter
+{
+ UInt32 _numSrcOutStreams;
+ const NCoderMixer2::CBindInfo _srcBindInfo;
+ CRecordVector<UInt32> _srcInToDestOutMap;
+ CRecordVector<UInt32> _srcOutToDestInMap;
+ CRecordVector<UInt32> _destInToSrcOutMap;
+public:
+ UInt32 NumSrcInStreams;
+ CRecordVector<UInt32> DestOutToSrcInMap;
+
+ CBindReverseConverter(const NCoderMixer2::CBindInfo &srcBindInfo);
+ void CreateReverseBindInfo(NCoderMixer2::CBindInfo &destBindInfo);
+};
+
+struct CCoderInfo
+{
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ICompressCoder2> Coder2;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+
+ CRecordVector<UInt64> InSizes;
+ CRecordVector<UInt64> OutSizes;
+ CRecordVector<const UInt64 *> InSizePointers;
+ CRecordVector<const UInt64 *> OutSizePointers;
+
+ CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams);
+ void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+};
+
+class CCoderMixer2
+{
+public:
+ virtual void SetBindInfo(const CBindInfo &bindInfo) = 0;
+ virtual void ReInit() = 0;
+ virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
+};
+
+}
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.cpp
new file mode 100644
index 0000000000..7b3ff73835
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.cpp
@@ -0,0 +1,359 @@
+// CoderMixer2MT.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2MT.h"
+#include "CrossThreadProgress.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+namespace NCoderMixer2 {
+
+CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams):
+ ExitEvent(NULL),
+ CompressEvent(NULL),
+ CompressionCompletedEvent(NULL),
+ CCoderInfo(numInStreams, numOutStreams)
+{
+ InStreams.Reserve(NumInStreams);
+ InStreamPointers.Reserve(NumInStreams);
+ OutStreams.Reserve(NumOutStreams);
+ OutStreamPointers.Reserve(NumOutStreams);
+}
+
+void CThreadCoderInfo::CreateEvents()
+{
+ CompressEvent = new CAutoResetEvent(false);
+ CompressionCompletedEvent = new CAutoResetEvent(false);
+}
+
+CThreadCoderInfo::~CThreadCoderInfo()
+{
+ if (CompressEvent != NULL)
+ delete CompressEvent;
+ if (CompressionCompletedEvent != NULL)
+ delete CompressionCompletedEvent;
+}
+
+class CCoderInfoFlusher2
+{
+ CThreadCoderInfo *m_CoderInfo;
+public:
+ CCoderInfoFlusher2(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {}
+ ~CCoderInfoFlusher2()
+ {
+ int i;
+ for (i = 0; i < m_CoderInfo->InStreams.Size(); i++)
+ m_CoderInfo->InStreams[i].Release();
+ for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++)
+ m_CoderInfo->OutStreams[i].Release();
+ m_CoderInfo->CompressionCompletedEvent->Set();
+ }
+};
+
+bool CThreadCoderInfo::WaitAndCode()
+{
+ HANDLE events[2] = { ExitEvent, *CompressEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ return false;
+
+ {
+ InStreamPointers.Clear();
+ OutStreamPointers.Clear();
+ UInt32 i;
+ for (i = 0; i < NumInStreams; i++)
+ {
+ if (InSizePointers[i] != NULL)
+ InSizePointers[i] = &InSizes[i];
+ InStreamPointers.Add(InStreams[i]);
+ }
+ for (i = 0; i < NumOutStreams; i++)
+ {
+ if (OutSizePointers[i] != NULL)
+ OutSizePointers[i] = &OutSizes[i];
+ OutStreamPointers.Add(OutStreams[i]);
+ }
+ CCoderInfoFlusher2 coderInfoFlusher(this);
+ if (Coder)
+ Result = Coder->Code(InStreamPointers[0],
+ OutStreamPointers[0],
+ InSizePointers[0],
+ OutSizePointers[0],
+ Progress);
+ else
+ Result = Coder2->Code(&InStreamPointers.Front(),
+ &InSizePointers.Front(),
+ NumInStreams,
+ &OutStreamPointers.Front(),
+ &OutSizePointers.Front(),
+ NumOutStreams,
+ Progress);
+ }
+ return true;
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+ sizes.Clear();
+ sizePointers.Clear();
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (srcSizes == 0 || srcSizes[i] == NULL)
+ {
+ sizes.Add(0);
+ sizePointers.Add(NULL);
+ }
+ else
+ {
+ sizes.Add(*srcSizes[i]);
+ sizePointers.Add(&sizes.Back());
+ }
+ }
+}
+
+
+void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes, ICompressProgressInfo *progress)
+{
+ Progress = progress;
+ SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+ SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+static DWORD WINAPI CoderThread(void *threadCoderInfo)
+{
+ while(true)
+ {
+ if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode())
+ return 0;
+ }
+}
+
+//////////////////////////////////////
+// CCoderMixer2MT
+
+static DWORD WINAPI MainCoderThread(void *threadCoderInfo)
+{
+ while(true)
+ {
+ if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode())
+ return 0;
+ }
+}
+
+CCoderMixer2MT::CCoderMixer2MT()
+{
+ if (!_mainThread.Create(MainCoderThread, this))
+ throw 271825;
+}
+
+CCoderMixer2MT::~CCoderMixer2MT()
+{
+ _exitEvent.Set();
+ _mainThread.Wait();
+ for(int i = 0; i < _threads.Size(); i++)
+ {
+ _threads[i].Wait();
+ _threads[i].Close();
+ }
+}
+
+void CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
+{
+ _bindInfo = bindInfo;
+ _streamBinders.Clear();
+ for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ _streamBinders.Add(CStreamBinder());
+ _streamBinders.Back().CreateEvents();
+ }
+}
+
+void CCoderMixer2MT::AddCoderCommon()
+{
+ int index = _coderInfoVector.Size();
+ const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index];
+
+ CThreadCoderInfo threadCoderInfo(CoderStreamsInfo.NumInStreams,
+ CoderStreamsInfo.NumOutStreams);
+ _coderInfoVector.Add(threadCoderInfo);
+ _coderInfoVector.Back().CreateEvents();
+ _coderInfoVector.Back().ExitEvent = _exitEvent;
+ _compressingCompletedEvents.Add(*_coderInfoVector.Back().CompressionCompletedEvent);
+
+ NWindows::CThread newThread;
+ _threads.Add(newThread);
+ if (!_threads.Back().Create(CoderThread, &_coderInfoVector.Back()))
+ throw 271824;
+}
+
+void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
+{
+ AddCoderCommon();
+ _coderInfoVector.Back().Coder = coder;
+}
+
+void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
+{
+ AddCoderCommon();
+ _coderInfoVector.Back().Coder2 = coder;
+}
+
+/*
+void CCoderMixer2MT::FinishAddingCoders()
+{
+ for(int i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ DWORD id;
+ HANDLE newThread = ::CreateThread(NULL, 0, CoderThread,
+ &_coderInfoVector[i], 0, &id);
+ if (newThread == 0)
+ throw 271824;
+ _threads.Add(newThread);
+ }
+}
+*/
+
+void CCoderMixer2MT::ReInit()
+{
+ for(int i = 0; i < _streamBinders.Size(); i++)
+ _streamBinders[i].ReInit();
+}
+
+
+STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams,
+ ISequentialOutStream **outStreams)
+{
+ if (_coderInfoVector.Size() != _bindInfo.Coders.Size())
+ throw 0;
+ int i;
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ CThreadCoderInfo &coderInfo = _coderInfoVector[i];
+ const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
+ coderInfo.InStreams.Clear();
+ UInt32 j;
+ for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
+ coderInfo.InStreams.Add(NULL);
+ coderInfo.OutStreams.Clear();
+ for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
+ coderInfo.OutStreams.Add(NULL);
+ }
+
+ for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ const CBindPair &bindPair = _bindInfo.BindPairs[i];
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ UInt32 outCoderIndex, outCoderStreamIndex;
+ _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
+ _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
+
+ _streamBinders[i].CreateStreams(
+ &_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex],
+ &_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]);
+ }
+
+ for(i = 0; i < _bindInfo.InStreams.Size(); i++)
+ {
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
+ _coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
+ }
+
+ for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ UInt32 outCoderIndex, outCoderStreamIndex;
+ _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
+ _coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
+ }
+ return S_OK;
+}
+
+
+bool CCoderMixer2MT::MyCode()
+{
+ HANDLE events[2] = { _exitEvent, _startCompressingEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ return false;
+
+ for(int i = 0; i < _coderInfoVector.Size(); i++)
+ _coderInfoVector[i].CompressEvent->Set();
+ DWORD result = ::WaitForMultipleObjects(_compressingCompletedEvents.Size(),
+ &_compressingCompletedEvents.Front(), TRUE, INFINITE);
+
+ _compressingFinishedEvent.Set();
+
+ return true;
+}
+
+
+STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
+ numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
+ return E_INVALIDARG;
+
+ Init(inStreams, outStreams);
+
+ _compressingFinishedEvent.Reset(); // ?
+
+ CCrossThreadProgress *progressSpec = new CCrossThreadProgress;
+ CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec;
+ progressSpec->Init();
+ _coderInfoVector[_progressCoderIndex].Progress = crossProgress;
+
+ _startCompressingEvent.Set();
+
+
+ while (true)
+ {
+ HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ break;
+ if (progress != NULL)
+ progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize,
+ progressSpec->OutSize);
+ else
+ progressSpec->Result = S_OK;
+ progressSpec->WaitEvent.Set();
+ }
+
+ int i;
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result == S_FALSE)
+ return result;
+ }
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result != S_OK && result != E_FAIL)
+ return result;
+ }
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+UInt64 CCoderMixer2MT::GetWriteProcessedSize(UInt32 binderIndex) const
+{
+ return _streamBinders[binderIndex].ProcessedSize;
+}
+
+}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.h b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.h
new file mode 100644
index 0000000000..9a72219654
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.h
@@ -0,0 +1,121 @@
+// CoderMixer2MT.h
+
+#ifndef __CODER_MIXER2_MT_H
+#define __CODER_MIXER2_MT_H
+
+#include "CoderMixer2.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Windows/Thread.h"
+#include "../../Common/StreamBinder.h"
+
+namespace NCoderMixer2 {
+
+// CreateEvents();
+// {
+// SetCoderInfo()
+// Init Streams
+// set CompressEvent()
+// wait CompressionCompletedEvent
+// }
+
+struct CThreadCoderInfo: public CCoderInfo
+{
+ NWindows::NSynchronization::CAutoResetEvent *CompressEvent;
+ HANDLE ExitEvent;
+ NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent;
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
+ CRecordVector<ISequentialInStream *> InStreamPointers;
+ CRecordVector<ISequentialOutStream *> OutStreamPointers;
+
+ CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr
+ HRESULT Result;
+
+ CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams);
+ void SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes, ICompressProgressInfo *progress);
+ ~CThreadCoderInfo();
+ bool WaitAndCode();
+ void CreateEvents();
+};
+
+
+// SetBindInfo()
+// for each coder
+// {
+// AddCoder[2]()
+// }
+//
+// for each file
+// {
+// ReInit()
+// for each coder
+// {
+// SetCoderInfo
+// }
+// SetProgressIndex(UInt32 coderIndex);
+// Code
+// }
+
+
+class CCoderMixer2MT:
+ public ICompressCoder2,
+ public CCoderMixer2,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP
+
+public:
+ STDMETHOD(Init)(ISequentialInStream **inStreams,
+ ISequentialOutStream **outStreams);
+
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+
+
+ CCoderMixer2MT();
+ ~CCoderMixer2MT();
+ void AddCoderCommon();
+ void AddCoder(ICompressCoder *coder);
+ void AddCoder2(ICompressCoder2 *coder);
+
+ void ReInit();
+ void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
+ { _coderInfoVector[coderIndex].SetCoderInfo(inSizes, outSizes, NULL); }
+ void SetProgressCoderIndex(UInt32 coderIndex)
+ { _progressCoderIndex = coderIndex; }
+
+
+ UInt64 GetWriteProcessedSize(UInt32 binderIndex) const;
+
+
+ bool MyCode();
+
+private:
+ CBindInfo _bindInfo;
+ CObjectVector<CStreamBinder> _streamBinders;
+ CObjectVector<CThreadCoderInfo> _coderInfoVector;
+ CRecordVector<NWindows::CThread> _threads;
+ NWindows::CThread _mainThread;
+
+ NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent;
+ CRecordVector<HANDLE> _compressingCompletedEvents;
+ NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent;
+
+ NWindows::NSynchronization::CManualResetEvent _exitEvent;
+ UInt32 _progressCoderIndex;
+
+public:
+ void SetBindInfo(const CBindInfo &bindInfo);
+
+};
+
+}
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.cpp
new file mode 100644
index 0000000000..62d05afdd7
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.h b/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.h
new file mode 100644
index 0000000000..0504b93064
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.cpp
new file mode 100644
index 0000000000..fa8aba2e4b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.cpp
@@ -0,0 +1,242 @@
+// 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;
+ if (_outSizeIsDefined = (outSize != 0))
+ _outSize = *outSize;
+
+ while(NeedMore())
+ {
+ UInt32 processedSize;
+
+ // Change it: It can be optimized using ReadPart
+ RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize));
+
+ UInt32 endPos = bufferPos + processedSize;
+
+ bufferPos = Filter->Filter(_buffer, endPos);
+ if (bufferPos > endPos)
+ {
+ for (; endPos< bufferPos; endPos++)
+ _buffer[endPos] = 0;
+ bufferPos = Filter->Filter(_buffer, endPos);
+ }
+
+ if (bufferPos == 0)
+ {
+ if (endPos > 0)
+ return WriteWithLimit(outStream, endPos);
+ return S_OK;
+ }
+ RINOK(WriteWithLimit(outStream, bufferPos));
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
+ }
+ UInt32 i = 0;
+ while(bufferPos < endPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+ return S_OK;
+}
+
+// #ifdef _ST_MODE
+STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
+{
+ _bufferPos = 0;
+ _outStream = outStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseOutStream()
+{
+ _outStream.Release();
+ return S_OK;
+};
+
+
+STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ UInt32 sizeMax = kBufferSize - _bufferPos;
+ UInt32 sizeTemp = size;
+ if (sizeTemp > sizeMax)
+ sizeTemp = sizeMax;
+ memmove(_buffer + _bufferPos, data, sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ data = (const Byte *)data + sizeTemp;
+ UInt32 endPos = _bufferPos + sizeTemp;
+ _bufferPos = Filter->Filter(_buffer, endPos);
+ if (_bufferPos == 0)
+ {
+ _bufferPos = endPos;
+ break;
+ }
+ if (_bufferPos > endPos)
+ {
+ if (size != 0)
+ return E_FAIL;
+ break;
+ }
+ RINOK(WriteWithLimit(_outStream, _bufferPos));
+ UInt32 i = 0;
+ while(_bufferPos < endPos)
+ _buffer[i++] = _buffer[_bufferPos++];
+ _bufferPos = i;
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+STDMETHODIMP CFilterCoder::Flush()
+{
+ if (_bufferPos != 0)
+ {
+ UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
+ if (endPos > _bufferPos)
+ {
+ for (; _bufferPos < endPos; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ if (Filter->Filter(_buffer, endPos) != endPos)
+ return E_FAIL;
+ }
+ UInt32 processedSize;
+ RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
+ if (_bufferPos != processedSize)
+ return E_FAIL;
+ _bufferPos = 0;
+ }
+ CMyComPtr<IOutStreamFlush> flush;
+ _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
+ if (flush)
+ return flush->Flush();
+ return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+ _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
+ _inStream = inStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseInStream()
+{
+ _inStream.Release();
+ return S_OK;
+};
+
+STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ if (_convertedPosBegin != _convertedPosEnd)
+ {
+ UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
+ memmove(data, _buffer + _convertedPosBegin, sizeTemp);
+ _convertedPosBegin += sizeTemp;
+ data = (void *)((Byte *)data + sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ break;
+ }
+ int i;
+ for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
+ _buffer[i] = _buffer[i + _convertedPosEnd];
+ _bufferPos = i;
+ _convertedPosBegin = _convertedPosEnd = 0;
+ UInt32 processedSizeTemp;
+ UInt32 size0 = kBufferSize - _bufferPos;
+ // Optimize it:
+ RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
+ _bufferPos = _bufferPos + processedSizeTemp;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ if (_convertedPosEnd == 0)
+ {
+ if (_bufferPos == 0)
+ break;
+ else
+ {
+ _convertedPosEnd = _bufferPos; // check it
+ continue;
+ }
+ }
+ if (_convertedPosEnd > _bufferPos)
+ {
+ for (; _bufferPos < _convertedPosEnd; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+// #endif // _ST_MODE
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ return _setPassword->CryptoSetPassword(data, size);
+}
+#endif
+
+#ifndef EXTRACT_ONLY
+STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ return _writeCoderProperties->WriteCoderProperties(outStream);
+}
+#endif
+
+STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ return _setDecoderProperties->SetDecoderProperties2(data, size);
+}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.h b/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.h
new file mode 100644
index 0000000000..cf0033ab6e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.h
@@ -0,0 +1,130 @@
+// FilterCoder.h
+
+#ifndef __FILTERCODER_H
+#define __FILTERCODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
+{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+*outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+class CFilterCoder:
+ public ICompressCoder,
+ // #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ISequentialInStream,
+ public ICompressSetOutStream,
+ public ISequentialOutStream,
+ public IOutStreamFlush,
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ public ICryptoSetPassword,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public ICompressWriteCoderProperties,
+ #endif
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+protected:
+ Byte *_buffer;
+ // #ifdef _ST_MODE
+ CMyComPtr<ISequentialInStream> _inStream;
+ CMyComPtr<ISequentialOutStream> _outStream;
+ UInt32 _bufferPos;
+ UInt32 _convertedPosBegin;
+ UInt32 _convertedPosEnd;
+ // #endif
+ bool _outSizeIsDefined;
+ UInt64 _outSize;
+ UInt64 _nowPos64;
+
+ HRESULT Init()
+ {
+ _nowPos64 = 0;
+ _outSizeIsDefined = false;
+ return Filter->Init();
+ }
+
+ CMyComPtr<ICryptoSetPassword> _setPassword;
+ #ifndef EXTRACT_ONLY
+ CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
+ #endif
+ CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;
+public:
+ CMyComPtr<ICompressFilter> Filter;
+
+ CFilterCoder();
+ ~CFilterCoder();
+ HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);
+ bool NeedMore() const
+ { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); }
+
+public:
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(ICompressCoder)
+ // #ifdef _ST_MODE
+ MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
+ MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)
+ #endif
+
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ // #ifdef _ST_MODE
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+ STDMETHOD(ReleaseOutStream)();
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Flush)();
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+ #endif
+ #ifndef EXTRACT_ONLY
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ #endif
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+// #ifdef _ST_MODE
+class CInStreamReleaser
+{
+public:
+ CFilterCoder *FilterCoder;
+ CInStreamReleaser(): FilterCoder(0) {}
+ ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
+};
+
+class COutStreamReleaser
+{
+public:
+ CFilterCoder *FilterCoder;
+ COutStreamReleaser(): FilterCoder(0) {}
+ ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
+};
+// #endif
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.cpp
new file mode 100644
index 0000000000..46f2cee3e1
--- /dev/null
+++ b/other-licenses/7zstub/src/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(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/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.h b/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.h
new file mode 100644
index 0000000000..51e5d93f03
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.cpp
new file mode 100644
index 0000000000..6199562ee1
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.cpp
@@ -0,0 +1,23 @@
+// 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);
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.h b/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.h
new file mode 100644
index 0000000000..11c5c579bf
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.h
@@ -0,0 +1,33 @@
+// 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:
+ CCRC _crc;
+ CMyComPtr<ISequentialOutStream> _stream;
+public:
+ void Init(ISequentialOutStream *stream)
+ {
+ _stream = stream;
+ _crc.Init();
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt32 GetCRC() const { return _crc.GetDigest(); }
+ void InitCRC() { _crc.Init(); }
+
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/IArchive.h b/other-licenses/7zstub/src/7zip/Archive/IArchive.h
new file mode 100644
index 0000000000..12f9a3c4af
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp
new file mode 100644
index 0000000000..8a06ec1384
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/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
+ while(true)
+ {
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ if(!ProgressDialog.ProgressSynch.GetPaused())
+ break;
+ ::Sleep(100);
+ }
+ if (completeValue != NULL)
+ ProgressDialog.ProgressSynch.SetPos(*completeValue);
+ #endif
+ return S_OK;
+}
+
+void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
+{
+ UString fullPath = _directoryPath;
+ for(int i = 0; i < dirPathParts.Size(); i++)
+ {
+ fullPath += dirPathParts[i];
+ NDirectory::MyCreateDirectory(fullPath);
+ fullPath += NName::kDirDelimiter;
+ }
+}
+
+STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
+ ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+ #ifndef _NO_PROGRESS
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ #endif
+ _outFileStream.Release();
+ NCOM::CPropVariant propVariantName;
+ RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariantName));
+ UString fullPath;
+ if(propVariantName.vt == VT_EMPTY)
+ fullPath = _itemDefaultName;
+ else
+ {
+ if(propVariantName.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath = propVariantName.bstrVal;
+ }
+ _filePath = fullPath;
+
+ // m_CurrentFilePath = GetSystemString(fullPath, _codePage);
+
+ if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ _processedFileInfo.Attributes = _attributesDefault;
+ else
+ {
+ if (propVariant.vt != VT_UI4)
+ return E_FAIL;
+ _processedFileInfo.Attributes = propVariant.ulVal;
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidIsFolder, &propVariant));
+ _processedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal);
+
+ bool isAnti = false;
+ {
+ NCOM::CPropVariant propVariantTemp;
+ RINOK(_archiveHandler->GetProperty(index, kpidIsAnti,
+ &propVariantTemp));
+ if (propVariantTemp.vt == VT_BOOL)
+ isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal);
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
+ switch(propVariant.vt)
+ {
+ case VT_EMPTY:
+ _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault;
+ break;
+ case VT_FILETIME:
+ _processedFileInfo.UTCLastWriteTime = propVariant.filetime;
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ UStringVector pathParts;
+ SplitPathToParts(fullPath, pathParts);
+ if(pathParts.IsEmpty())
+ return E_FAIL;
+
+ UString processedPath = fullPath;
+
+ if(!_processedFileInfo.IsDirectory)
+ pathParts.DeleteBack();
+ if (!pathParts.IsEmpty())
+ {
+ if (!isAnti)
+ CreateComplexDirectory(pathParts);
+ }
+
+ UString fullProcessedPath = _directoryPath + processedPath;
+
+ if(_processedFileInfo.IsDirectory)
+ {
+ _diskFilePath = fullProcessedPath;
+
+ if (isAnti)
+ NDirectory::MyRemoveDirectory(_diskFilePath);
+ return S_OK;
+ }
+
+ NFind::CFileInfoW fileInfo;
+ if(NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ if (!NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ _message = kCantDeleteFile;
+ return E_FAIL;
+ }
+ }
+
+ if (!isAnti)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Create(fullProcessedPath, true))
+ {
+ _message = kCantOpenFile;
+ return E_FAIL;
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ _diskFilePath = fullProcessedPath;
+ }
+ else
+ {
+ *outStream = NULL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)
+{
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ _extractMode = true;
+ break;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)
+{
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ {
+ break;
+ }
+ default:
+ {
+ _outFileStream.Release();
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ _message = kUnsupportedMethod;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ _isCorrupt = true;
+ // _message = kCRCFailed;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ _isCorrupt = true;
+ // _message = kDataError;
+ break;
+ default:
+ _isCorrupt = true;
+ }
+ return E_FAIL;
+ }
+ }
+ if(_outFileStream != NULL)
+ _outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
+ _outFileStream.Release();
+ if (_extractMode)
+ NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ return S_OK;
+}
+
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.h b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.h
new file mode 100644
index 0000000000..d77ffd74e5
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.h
@@ -0,0 +1,96 @@
+// ExtractCallback.h
+
+#ifndef __EXTRACTCALLBACK_H
+#define __EXTRACTCALLBACK_H
+
+#include "resource.h"
+
+#include "Common/String.h"
+#include "Windows/ResourceString.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../ICoder.h"
+
+#ifndef _NO_PROGRESS
+#include "../../FileManager/Resource/ProgressDialog/ProgressDialog.h"
+#endif
+
+class CExtractCallbackImp:
+ public IArchiveExtractCallback,
+ public CMyUnknownImp
+{
+public:
+
+ MY_UNKNOWN_IMP
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IExtractCallback
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,
+ Int32 askExtractMode);
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+private:
+ CMyComPtr<IInArchive> _archiveHandler;
+ UString _directoryPath;
+
+ UString _filePath;
+
+ UString _diskFilePath;
+
+ bool _extractMode;
+ struct CProcessedFileInfo
+ {
+ FILETIME UTCLastWriteTime;
+ bool IsDirectory;
+ UInt32 Attributes;
+ } _processedFileInfo;
+
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+
+ UString _itemDefaultName;
+ FILETIME _utcLastWriteTimeDefault;
+ UInt32 _attributesDefault;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts);
+public:
+ #ifndef _NO_PROGRESS
+ CProgressDialog ProgressDialog;
+ #endif
+
+ bool _isCorrupt;
+ UString _message;
+
+ void Init(IInArchive *archiveHandler,
+ const UString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault);
+
+ #ifndef _NO_PROGRESS
+ HRESULT StartProgressDialog(const UString &title)
+ {
+ ProgressDialog.Create(title, 0);
+ {
+ #ifdef LANG
+ ProgressDialog.SetText(LangLoadString(IDS_PROGRESS_EXTRACTING, 0x02000890));
+ #else
+ ProgressDialog.SetText(NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING));
+ #endif
+ }
+
+ ProgressDialog.Show(SW_SHOWNORMAL);
+ return S_OK;
+ }
+ virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); }
+ #endif
+
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.cpp
new file mode 100644
index 0000000000..855f7aea91
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.cpp
@@ -0,0 +1,139 @@
+// ExtractEngine.cpp
+
+#include "StdAfx.h"
+
+#include "ExtractEngine.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Thread.h"
+
+#include "../../UI/Common/OpenArchive.h"
+
+#include "../../UI/Explorer/MyMessages.h"
+#include "../../FileManager/FormatUtils.h"
+
+#include "ExtractCallback.h"
+
+using namespace NWindows;
+
+struct CThreadExtracting
+{
+ CArchiveLink ArchiveLink;
+
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IArchiveExtractCallback> ExtractCallback;
+
+ #ifndef _NO_PROGRESS
+ HRESULT Result;
+
+ HRESULT Extract()
+ {
+ return ArchiveLink.GetArchive()->Extract(0, (UInt32)-1 , BoolToInt(false), ExtractCallback);
+ }
+ DWORD Process()
+ {
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ Result = Extract();
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtracting *)param)->Process();
+ }
+ #endif
+};
+
+static const LPCWSTR kCantFindArchive = L"Can not find archive file";
+static const LPCWSTR kCantOpenArchive = L"File is not correct archive";
+
+HRESULT ExtractArchive(
+ const UString &fileName,
+ const UString &folderName,
+ COpenCallbackGUI *openCallback,
+ bool showProgress,
+ bool &isCorrupt,
+ UString &errorMessage)
+{
+ isCorrupt = false;
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(fileName, archiveFileInfo))
+ {
+ errorMessage = kCantFindArchive;
+ return E_FAIL;
+ }
+
+ CThreadExtracting extracter;
+
+ HRESULT result = MyOpenArchive(fileName, extracter.ArchiveLink, openCallback);
+
+ if (result != S_OK)
+ {
+ errorMessage = kCantOpenArchive;
+ return result;
+ }
+
+ UString directoryPath = folderName;
+ NFile::NName::NormalizeDirPathPrefix(directoryPath);
+
+ /*
+ UString directoryPath;
+ {
+ UString fullPath;
+ int fileNamePartStartIndex;
+ if (!NWindows::NFile::NDirectory::MyGetFullPathName(fileName, fullPath, fileNamePartStartIndex))
+ {
+ MessageBox(NULL, "Error 1329484", "7-Zip", 0);
+ return E_FAIL;
+ }
+ directoryPath = fullPath.Left(fileNamePartStartIndex);
+ }
+ */
+
+ if(!NFile::NDirectory::CreateComplexDirectory(directoryPath))
+ {
+ errorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
+ #ifdef LANG
+ 0x02000603,
+ #endif
+ directoryPath);
+ return E_FAIL;
+ }
+
+ extracter.ExtractCallbackSpec = new CExtractCallbackImp;
+ extracter.ExtractCallback = extracter.ExtractCallbackSpec;
+
+ extracter.ExtractCallbackSpec->Init(
+ extracter.ArchiveLink.GetArchive(),
+ directoryPath, L"Default", archiveFileInfo.LastWriteTime, 0);
+
+ #ifndef _NO_PROGRESS
+
+ if (showProgress)
+ {
+ CThread thread;
+ if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter))
+ throw 271824;
+
+ UString title;
+ #ifdef LANG
+ title = LangLoadString(IDS_PROGRESS_EXTRACTING, 0x02000890);
+ #else
+ title = NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING);
+ #endif
+ extracter.ExtractCallbackSpec->StartProgressDialog(title);
+ result = extracter.Result;
+ }
+ else
+
+ #endif
+ {
+ result = extracter.Extract();
+ }
+ errorMessage = extracter.ExtractCallbackSpec->_message;
+ isCorrupt = extracter.ExtractCallbackSpec->_isCorrupt;
+ return result;
+}
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.h b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.h
new file mode 100644
index 0000000000..609cd7290e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/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/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp
new file mode 100644
index 0000000000..1de7d6893e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp
@@ -0,0 +1,561 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/StringConvert.h"
+#include "Common/Random.h"
+#include "Common/TextConfig.h"
+#include "Common/CommandLineParser.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/DLL.h"
+#include "Windows/ResourceString.h"
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+#include "../../Archive/IArchive.h"
+#include "../../UI/Explorer/MyMessages.h"
+
+// #include "../../UI/GUI/ExtractGUI.h"
+
+#include "ExtractEngine.h"
+
+#include "resource.h"
+
+using namespace NWindows;
+
+HINSTANCE g_hInstance;
+
+static LPCTSTR kTempDirPrefix = TEXT("7zS");
+
+#define _SHELL_EXECUTE
+
+/* BEGIN Mozilla customizations */
+
+static char const *
+FindStrInBuf(char const * buf, size_t bufLen, char const * str)
+{
+ size_t index = 0;
+ while (index < bufLen) {
+ char const * result = strstr(buf + index, str);
+ if (result) {
+ return result;
+ }
+ while ((buf[index] != '\0') && (index < bufLen)) {
+ index++;
+ }
+ index++;
+ }
+ return NULL;
+}
+
+static bool
+ReadPostSigningDataFromView(char const * view, DWORD size, AString& data)
+{
+ // Find the offset and length of the certificate table,
+ // so we know the valid range to look for the token.
+ if (size < (0x3c + sizeof(UInt32))) {
+ return false;
+ }
+ UInt32 PEHeaderOffset = *(UInt32*)(view + 0x3c);
+ UInt32 optionalHeaderOffset = PEHeaderOffset + 24;
+ UInt32 certDirEntryOffset = 0;
+ if (size < (optionalHeaderOffset + sizeof(UInt16))) {
+ return false;
+ }
+ UInt16 magic = *(UInt16*)(view + optionalHeaderOffset);
+ if (magic == 0x010b) {
+ // 32-bit executable
+ certDirEntryOffset = optionalHeaderOffset + 128;
+ } else if (magic == 0x020b) {
+ // 64-bit executable; certain header fields are wider
+ certDirEntryOffset = optionalHeaderOffset + 144;
+ } else {
+ // Unknown executable
+ return false;
+ }
+ if (size < certDirEntryOffset + 8) {
+ return false;
+ }
+ UInt32 certTableOffset = *(UInt32*)(view + certDirEntryOffset);
+ UInt32 certTableLen = *(UInt32*)(view + certDirEntryOffset + sizeof(UInt32));
+ if (certTableOffset == 0 || certTableLen == 0 ||
+ size < (certTableOffset + certTableLen)) {
+ return false;
+ }
+
+ char const token[] = "__MOZCUSTOM__:";
+ // We're searching for a string inside a binary blob,
+ // so a normal strstr that bails on the first NUL won't work.
+ char const * tokenPos = FindStrInBuf(view + certTableOffset,
+ certTableLen, token);
+ if (tokenPos) {
+ size_t tokenLen = (sizeof(token) / sizeof(token[0])) - 1;
+ data = AString(tokenPos + tokenLen);
+ return true;
+ }
+ return false;
+}
+
+static bool
+ReadPostSigningData(UString exePath, AString& data)
+{
+ bool retval = false;
+ HANDLE exeFile = CreateFileW(exePath, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (exeFile != INVALID_HANDLE_VALUE) {
+ HANDLE mapping = CreateFileMapping(exeFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (mapping != INVALID_HANDLE_VALUE) {
+ // MSDN claims the return value on failure is NULL,
+ // but I've also seen it returned on success, so double-check.
+ if (mapping || GetLastError() == ERROR_SUCCESS) {
+ char * view = (char*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
+ if (view) {
+ DWORD fileSize = GetFileSize(exeFile, NULL);
+ retval = ReadPostSigningDataFromView(view, fileSize, data);
+ }
+ CloseHandle(mapping);
+ }
+ }
+ CloseHandle(exeFile);
+ }
+ return retval;
+}
+
+/* END Mozilla customizations */
+
+
+static bool ReadDataString(LPCWSTR fileName, LPCSTR startID,
+ LPCSTR endID, AString &stringResult)
+{
+ stringResult.Empty();
+ NFile::NIO::CInFile inFile;
+ if (!inFile.Open(fileName))
+ return false;
+ const int kBufferSize = (1 << 12);
+
+ Byte buffer[kBufferSize];
+ int signatureStartSize = lstrlenA(startID);
+ int signatureEndSize = lstrlenA(endID);
+
+ UInt32 numBytesPrev = 0;
+ bool writeMode = false;
+ UInt64 posTotal = 0;
+ while(true)
+ {
+ if (posTotal > (1 << 20))
+ return (stringResult.IsEmpty());
+ UInt32 numReadBytes = kBufferSize - numBytesPrev;
+ UInt32 processedSize;
+ if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize))
+ return false;
+ if (processedSize == 0)
+ return true;
+ UInt32 numBytesInBuffer = numBytesPrev + processedSize;
+ UInt32 pos = 0;
+ while (true)
+ {
+ if (writeMode)
+ {
+ if (pos > numBytesInBuffer - signatureEndSize)
+ break;
+ if (memcmp(buffer + pos, endID, signatureEndSize) == 0)
+ return true;
+ char b = buffer[pos];
+ if (b == 0)
+ return false;
+ stringResult += b;
+ pos++;
+ }
+ else
+ {
+ if (pos > numBytesInBuffer - signatureStartSize)
+ break;
+ if (memcmp(buffer + pos, startID, signatureStartSize) == 0)
+ {
+ writeMode = true;
+ pos += signatureStartSize;
+ }
+ else
+ pos++;
+ }
+ }
+ numBytesPrev = numBytesInBuffer - pos;
+ posTotal += pos;
+ memmove(buffer, buffer + pos, numBytesPrev);
+ }
+}
+
+static char kStartID[] = ",!@Install@!UTF-8!";
+static char kEndID[] = ",!@InstallEnd@!";
+
+class CInstallIDInit
+{
+public:
+ CInstallIDInit()
+ {
+ kStartID[0] = ';';
+ kEndID[0] = ';';
+ };
+} g_CInstallIDInit;
+
+
+class CCurrentDirRestorer
+{
+ CSysString m_CurrentDirectory;
+public:
+ CCurrentDirRestorer()
+ { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
+ ~CCurrentDirRestorer()
+ { RestoreDirectory();}
+ bool RestoreDirectory()
+ { return BOOLToBool(::SetCurrentDirectory(m_CurrentDirectory)); }
+};
+
+#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
+
+// Delayed load libraries are loaded when the first symbol is used.
+// The following ensures that we load the delayed loaded libraries from the
+// system directory.
+struct AutoLoadSystemDependencies
+{
+ AutoLoadSystemDependencies()
+ {
+ HMODULE module = ::GetModuleHandleW(L"kernel32.dll");
+ if (module) {
+ // SetDefaultDllDirectories is always available on Windows 8 and above. It
+ // is also available on Windows Vista, Windows Server 2008, and
+ // Windows 7 when MS KB2533623 has been applied.
+ typedef BOOL (WINAPI *SetDefaultDllDirectoriesType)(DWORD);
+ SetDefaultDllDirectoriesType setDefaultDllDirectories =
+ (SetDefaultDllDirectoriesType) GetProcAddress(module, "SetDefaultDllDirectories");
+ if (setDefaultDllDirectories) {
+ setDefaultDllDirectories(0x0800 /* LOAD_LIBRARY_SEARCH_SYSTEM32 */ );
+ return;
+ }
+ }
+
+ static LPCWSTR delayDLLs[] = { L"dwmapi.dll", L"cryptbase.dll",
+ L"SHCore.dll", L"uxtheme.dll",
+ L"oleacc.dll", L"apphelp.dll" };
+ WCHAR systemDirectory[MAX_PATH + 1] = { L'\0' };
+ // If GetSystemDirectory fails we accept that we'll load the DLLs from the
+ // normal search path.
+ GetSystemDirectoryW(systemDirectory, MAX_PATH + 1);
+ size_t systemDirLen = wcslen(systemDirectory);
+
+ // Make the system directory path terminate with a slash
+ if (systemDirectory[systemDirLen - 1] != L'\\' && systemDirLen) {
+ systemDirectory[systemDirLen] = L'\\';
+ ++systemDirLen;
+ // No need to re-NULL terminate
+ }
+
+ // For each known DLL ensure it is loaded from the system32 directory
+ for (size_t i = 0; i < sizeof(delayDLLs) / sizeof(delayDLLs[0]); ++i) {
+ size_t fileLen = wcslen(delayDLLs[i]);
+ wcsncpy(systemDirectory + systemDirLen, delayDLLs[i],
+ MAX_PATH - systemDirLen);
+ if (systemDirLen + fileLen <= MAX_PATH) {
+ systemDirectory[systemDirLen + fileLen] = L'\0';
+ } else {
+ systemDirectory[MAX_PATH] = L'\0';
+ }
+ LPCWSTR fullModulePath = systemDirectory; // just for code readability
+ LoadLibraryW(fullModulePath);
+ }
+ }
+} loadDLLs;
+
+BOOL
+RemoveCurrentDirFromSearchPath()
+{
+ // kernel32.dll is in the knownDLL list so it is safe to load without a full path
+ HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
+ if (!kernel32) {
+ return FALSE;
+ }
+
+ typedef BOOL (WINAPI *SetDllDirectoryType)(LPCWSTR);
+ SetDllDirectoryType SetDllDirectoryFn =
+ (SetDllDirectoryType)GetProcAddress(kernel32, "SetDllDirectoryW");
+ if (!SetDllDirectoryFn) {
+ FreeLibrary(kernel32);
+ return FALSE;
+ }
+
+ // If this call fails we can't do much about it, so ignore it.
+ // It is unlikely to fail and this is just a precaution anyway.
+ SetDllDirectoryFn(L"");
+ FreeLibrary(kernel32);
+ return TRUE;
+}
+
+int APIENTRY WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ // Disable current directory from being in the search path.
+ // This call does not help with implicitly loaded DLLs.
+ if (!RemoveCurrentDirFromSearchPath()) {
+ WCHAR minOSTitle[512] = { '\0' };
+ WCHAR minOSText[512] = { '\0' };
+ LoadStringW(NULL, IDS_MIN_OS_TITLE, minOSTitle,
+ sizeof(minOSTitle) / sizeof(minOSTitle[0]));
+ LoadStringW(NULL, IDS_MIN_OS_TEXT, minOSText,
+ sizeof(minOSText) / sizeof(minOSText[0]));
+ MessageBoxW(NULL, minOSText, minOSTitle, MB_OK | MB_ICONERROR);
+ return 1;
+ }
+
+ 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();
+ }
+
+ /* BEGIN Mozilla customizations */
+ bool showProgress = true;
+ bool extractOnly = false;
+ if (switches.Left(3).CompareNoCase(UString(L"-ms")) == 0 ||
+ switches.Left(4).CompareNoCase(UString(L"/ini")) == 0 ||
+ switches.Left(2).CompareNoCase(UString(L"/s")) == 0) {
+ showProgress = false;
+ } else if (switches.Left(12).CompareNoCase(UString(L"/extractdir=")) == 0) {
+ assumeYes = true;
+ showProgress = false;
+ extractOnly = true;
+ }
+ /* END Mozilla customizations */
+
+ AString config;
+ if (!ReadDataString(fullPath, kStartID, kEndID, config))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can't load config info");
+ return 1;
+ }
+
+ UString dirPrefix = L".\\";
+ UString appLaunched;
+ if (!config.IsEmpty())
+ {
+ CObjectVector<CTextConfigPair> pairs;
+ if (!GetTextConfig(config, pairs))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Config failed");
+ return 1;
+ }
+ UString friendlyName = GetTextConfigValue(pairs, L"Title");
+ UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt");
+ UString progress = GetTextConfigValue(pairs, L"Progress");
+ if (progress.CompareNoCase(L"no") == 0)
+ showProgress = false;
+ int index = FindTextConfigItem(pairs, L"Directory");
+ if (index >= 0)
+ dirPrefix = pairs[index].String;
+ if (!installPrompt.IsEmpty() && !assumeYes)
+ {
+ if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO |
+ MB_ICONQUESTION) != IDYES)
+ return 0;
+ }
+ appLaunched = GetTextConfigValue(pairs, L"RunProgram");
+
+ #ifdef _SHELL_EXECUTE
+ executeFile = GetTextConfigValue(pairs, L"ExecuteFile");
+ executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters") + switches;
+ #endif
+ }
+
+ NFile::NDirectory::CTempDirectory tempDir;
+ /* Mozilla customizations - Added !extractOnly */
+ if (!extractOnly && !tempDir.Create(kTempDirPrefix))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can not create temp folder archive");
+ return 1;
+ }
+
+ /* BEGIN Mozilla customizations */
+ UString tempDirPath = (extractOnly ? switches.Mid(12) : GetUnicodeString(tempDir.GetPath()));
+ /* END Mozilla customizations */
+
+ COpenCallbackGUI openCallback;
+
+ 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;
+ }
+
+ /* BEGIN Mozilla customizations */
+ // Retrieve and store any data added to this file after signing.
+ {
+ AString postSigningData;
+ if (ReadPostSigningData(fullPath, postSigningData)) {
+ NFile::NName::CParsedPath postSigningDataFilePath;
+ postSigningDataFilePath.ParsePath(tempDirPath);
+ postSigningDataFilePath.PathParts.Add(L"postSigningData");
+
+ NFile::NIO::COutFile postSigningDataFile;
+ postSigningDataFile.Create(postSigningDataFilePath.MergePath(), true);
+
+ UInt32 written = 0;
+ postSigningDataFile.Write(postSigningData, postSigningData.Length(), written);
+ }
+ }
+
+ if (extractOnly) {
+ return 0;
+ }
+ /* END Mozilla customizations */
+
+ 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 = BOOLToBool(::ShellExecuteEx(&execInfo));
+ result = (UINT32)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/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp
new file mode 100644
index 0000000000..e9ff6ad48b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp
@@ -0,0 +1,696 @@
+# Microsoft Developer Studio Project File - Name="SFXSetup-moz" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=SFXSetup-moz - 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-moz.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-moz.mak" CFG="SFXSetup-moz - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SFXSetup-moz - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "SFXSetup-moz - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "SFXSetup-moz - 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-moz - 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 shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXSetup-moz - 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 comctl32.lib kernel32.lib user32.lib shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll
+
+!ELSEIF "$(CFG)" == "SFXSetup-moz - 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 shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /out:"ReleaseD\7zSD.sfx" /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXSetup-moz - Win32 Release"
+# Name "SFXSetup-moz - Win32 Debug"
+# Name "SFXSetup-moz - 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/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsw b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsw
new file mode 100644
index 0000000000..2b6b8243c4
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.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-moz"=.\SFXSetup-moz.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.cpp
new file mode 100644
index 0000000000..c6d3b1fa62
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.h b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.h
new file mode 100644
index 0000000000..85536206d0
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.h
@@ -0,0 +1,10 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+#include <commctrl.h>
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/makefile b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/makefile
new file mode 100644
index 0000000000..89cae1d5bc
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/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/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.h b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.h
new file mode 100644
index 0000000000..9d58c410dd
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.h
@@ -0,0 +1,8 @@
+#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
+#define IDS_MIN_OS_TITLE 70
+#define IDS_MIN_OS_TEXT 71
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.rc b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.rc
new file mode 100644
index 0000000000..ff1e2347cb
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.rc
@@ -0,0 +1,18 @@
+#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"
+ IDS_MIN_OS_TITLE "Setup Error"
+ IDS_MIN_OS_TEXT "Microsoft Windows XP SP2 or newer is required."
+END
+
+#include "../../FileManager/Resource/ProgressDialog/resource.rc"
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/setup.ico b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/setup.ico
new file mode 100644
index 0000000000..9801fed54f
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/setup.ico
Binary files differ
diff --git a/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.cpp b/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.cpp
new file mode 100644
index 0000000000..9dae03d121
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.h b/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.h
new file mode 100644
index 0000000000..10197428d8
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/FileStreams.cpp b/other-licenses/7zstub/src/7zip/Common/FileStreams.cpp
new file mode 100644
index 0000000000..7a32c6e702
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/FileStreams.cpp
@@ -0,0 +1,251 @@
+// FileStreams.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#include "FileStreams.h"
+
+static inline HRESULT ConvertBoolToHRESULT(bool result)
+{
+ // return result ? S_OK: E_FAIL;
+ #ifdef _WIN32
+ return result ? S_OK: (::GetLastError());
+ #else
+ return result ? S_OK: E_FAIL;
+ #endif
+}
+
+bool CInFileStream::Open(LPCTSTR fileName)
+{
+ return File.Open(fileName);
+}
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool CInFileStream::Open(LPCWSTR fileName)
+{
+ return File.Open(fileName);
+}
+#endif
+#endif
+
+STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+
+ UInt32 realProcessedSize;
+ bool result = File.ReadPart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Read(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
+ data, size, (DWORD *)&realProcessedSize, NULL);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
+ return S_OK;
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res;
+ do
+ {
+ res = read(0, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#endif
+
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+
+ #ifdef _WIN32
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
+{
+ return ConvertBoolToHRESULT(File.GetLength(*size));
+}
+
+
+//////////////////////////
+// COutFileStream
+
+bool COutFileStream::Create(LPCTSTR fileName, bool createAlways)
+{
+ return File.Create(fileName, createAlways);
+}
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool COutFileStream::Create(LPCWSTR fileName, bool createAlways)
+{
+ return File.Create(fileName, createAlways);
+}
+#endif
+#endif
+
+STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+
+ UInt32 realProcessedSize;
+ bool result = File.WritePart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Write(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ #ifdef _WIN32
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
+{
+ #ifdef _WIN32
+ UInt64 currentPos;
+ if(!File.Seek(0, FILE_CURRENT, currentPos))
+ return E_FAIL;
+ bool result = File.SetLength(newSize);
+ UInt64 currentPos2;
+ result = result && File.Seek(currentPos, currentPos2);
+ return result ? S_OK : E_FAIL;
+ #else
+ return E_FAIL;
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = TRUE;
+ if (size > 0)
+ {
+ // Seems that Windows doesn't like big amounts writing to stdout.
+ // So we limit portions by 32KB.
+ UInt32 sizeTemp = (1 << 15);
+ if (sizeTemp > size)
+ sizeTemp = size;
+ res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
+ data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
+ size -= realProcessedSize;
+ data = (const void *)((const Byte *)data + realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize += realProcessedSize;
+ }
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ ssize_t res;
+ do
+ {
+ res = write(1, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ return S_OK;
+ #endif
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/FileStreams.h b/other-licenses/7zstub/src/7zip/Common/FileStreams.h
new file mode 100644
index 0000000000..e6494f679b
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/InBuffer.cpp b/other-licenses/7zstub/src/7zip/Common/InBuffer.cpp
new file mode 100644
index 0000000000..17280b5b6c
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/InBuffer.h b/other-licenses/7zstub/src/7zip/Common/InBuffer.h
new file mode 100644
index 0000000000..a59ecefacd
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/InBuffer.h
@@ -0,0 +1,76 @@
+// InBuffer.h
+
+#ifndef __INBUFFER_H
+#define __INBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+class CInBufferException
+{
+public:
+ HRESULT ErrorCode;
+ CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class CInBuffer
+{
+ Byte *_buffer;
+ Byte *_bufferLimit;
+ Byte *_bufferBase;
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _processedSize;
+ UInt32 _bufferSize;
+ bool _wasFinished;
+
+ bool ReadBlock();
+ Byte ReadBlock2();
+
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ CInBuffer();
+ ~CInBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetStream(ISequentialInStream *stream);
+ void Init();
+ void ReleaseStream() { _stream.Release(); }
+
+ bool ReadByte(Byte &b)
+ {
+ if(_buffer >= _bufferLimit)
+ if(!ReadBlock())
+ return false;
+ b = *_buffer++;
+ return true;
+ }
+ Byte ReadByte()
+ {
+ if(_buffer >= _bufferLimit)
+ return ReadBlock2();
+ return *_buffer++;
+ }
+ void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+ {
+ for(processedSize = 0; processedSize < size; processedSize++)
+ if (!ReadByte(((Byte *)data)[processedSize]))
+ return;
+ }
+ bool ReadBytes(void *data, UInt32 size)
+ {
+ UInt32 processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+ UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.cpp b/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.cpp
new file mode 100644
index 0000000000..06fde8ff33
--- /dev/null
+++ b/other-licenses/7zstub/src/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;
+ while(true)
+ {
+ 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/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.h b/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.h
new file mode 100644
index 0000000000..17f3e8826a
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.cpp b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.cpp
new file mode 100644
index 0000000000..ada5890be8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.cpp
@@ -0,0 +1,34 @@
+// Stream/LSBFDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LSBFDecoder.h"
+
+namespace NStream {
+namespace NLSBF {
+
+Byte kInvertTable[256];
+
+class CInverterTableInitializer
+{
+public:
+ CInverterTableInitializer()
+ {
+ for(int i = 0; i < 256; i++)
+ {
+ Byte b = Byte(i);
+ Byte bInvert = 0;
+ for(int j = 0; j < 8; j++)
+ {
+ bInvert <<= 1;
+ if (b & 1)
+ bInvert |= 1;
+ b >>= 1;
+ }
+ kInvertTable[i] = bInvert;
+ }
+ }
+} g_InverterTableInitializer;
+
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h
new file mode 100644
index 0000000000..6e506859c6
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h
@@ -0,0 +1,127 @@
+// LSBFDecoder.h
+
+#ifndef __STREAM_LSBFDECODER_H
+#define __STREAM_LSBFDECODER_H
+
+#include "../IStream.h"
+
+namespace NStream {
+namespace NLSBF {
+
+const int kNumBigValueBits = 8 * 4;
+
+const int kNumValueBytes = 3;
+const int kNumValueBits = 8 * kNumValueBytes;
+
+const UInt32 kMask = (1 << kNumValueBits) - 1;
+
+extern Byte kInvertTable[256];
+// the Least Significant Bit of byte is First
+
+template<class TInByte>
+class CBaseDecoder
+{
+protected:
+ int m_BitPos;
+ UInt32 m_Value;
+ TInByte m_Stream;
+public:
+ UInt32 NumExtraBytes;
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); }
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ m_Value = 0;
+ NumExtraBytes = 0;
+ }
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UInt64 GetProcessedBitsSize() const
+ { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
+ int GetBitPosition() const { return (m_BitPos & 7); }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ {
+ Byte b;
+ if (!m_Stream.ReadByte(b))
+ {
+ b = 0xFF; // check it
+ NumExtraBytes++;
+ }
+ m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value;
+ }
+ }
+
+ UInt32 ReadBits(int numBits)
+ {
+ Normalize();
+ UInt32 res = m_Value & ((1 << numBits) - 1);
+ m_BitPos += numBits;
+ m_Value >>= numBits;
+ return res;
+ }
+
+ bool ExtraBitsWereRead() const
+ {
+ if (NumExtraBytes == 0)
+ return false;
+ return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
+ }
+};
+
+template<class TInByte>
+class CDecoder: public CBaseDecoder<TInByte>
+{
+ UInt32 m_NormalValue;
+
+public:
+ void Init()
+ {
+ CBaseDecoder<TInByte>::Init();
+ m_NormalValue = 0;
+ }
+
+ void Normalize()
+ {
+ for (;this->m_BitPos >= 8; this->m_BitPos -= 8)
+ {
+ Byte b;
+ 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/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.cpp b/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.cpp
new file mode 100644
index 0000000000..a0ed300c6e
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.h b/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.h
new file mode 100644
index 0000000000..1c50b8e766
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/LimitedStreams.cpp b/other-licenses/7zstub/src/7zip/Common/LimitedStreams.cpp
new file mode 100644
index 0000000000..c210c9560d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LimitedStreams.cpp
@@ -0,0 +1,24 @@
+// LimitedStreams.cpp
+
+#include "StdAfx.h"
+
+#include "LimitedStreams.h"
+#include "../../Common/Defs.h"
+
+void CLimitedSequentialInStream::Init(ISequentialInStream *stream, UInt64 streamSize)
+{
+ _stream = stream;
+ _size = streamSize;
+}
+
+STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeReal;
+ UInt32 sizeToRead = UInt32(MyMin(_size, UInt64(size)));
+ HRESULT result = _stream->Read(data, sizeToRead, &processedSizeReal);
+ _size -= processedSizeReal;
+ if(processedSize != NULL)
+ *processedSize = processedSizeReal;
+ return result;
+}
+
diff --git a/other-licenses/7zstub/src/7zip/Common/LimitedStreams.h b/other-licenses/7zstub/src/7zip/Common/LimitedStreams.h
new file mode 100644
index 0000000000..7658b620d1
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LimitedStreams.h
@@ -0,0 +1,23 @@
+// LimitedStreams.h
+
+#ifndef __LIMITEDSTREAMS_H
+#define __LIMITEDSTREAMS_H
+
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLimitedSequentialInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ UInt64 _size;
+ CMyComPtr<ISequentialInStream> _stream;
+public:
+ void Init(ISequentialInStream *stream, UInt64 streamSize);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/LockedStream.cpp b/other-licenses/7zstub/src/7zip/Common/LockedStream.cpp
new file mode 100644
index 0000000000..637c8980cd
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/LockedStream.h b/other-licenses/7zstub/src/7zip/Common/LockedStream.h
new file mode 100644
index 0000000000..d61f6a3723
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LockedStream.h
@@ -0,0 +1,38 @@
+// LockedStream.h
+
+#ifndef __LOCKEDSTREAM_H
+#define __LOCKEDSTREAM_H
+
+#include "../../Windows/Synchronization.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLockedInStream
+{
+ CMyComPtr<IInStream> _stream;
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+public:
+ void Init(IInStream *stream)
+ { _stream = stream; }
+ HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CLockedSequentialInStreamImp:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CLockedInStream *_lockedInStream;
+ UInt64 _pos;
+public:
+ void Init(CLockedInStream *lockedInStream, UInt64 startPos)
+ {
+ _lockedInStream = lockedInStream;
+ _pos = startPos;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h b/other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h
new file mode 100644
index 0000000000..dad00ecab6
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h
@@ -0,0 +1,69 @@
+// MSBFDecoder.h
+// the Most Significant Bit of byte is First
+
+#ifndef __STREAM_MSBFDECODER_H
+#define __STREAM_MSBFDECODER_H
+
+#include "../../Common/Types.h"
+#include "../IStream.h"
+
+namespace NStream {
+namespace NMSBF {
+
+const int kNumBigValueBits = 8 * 4;
+const int kNumValueBytes = 3;
+const int kNumValueBits = 8 * kNumValueBytes;
+
+const UInt32 kMask = (1 << kNumValueBits) - 1;
+
+template<class TInByte>
+class CDecoder
+{
+ UInt32 m_BitPos;
+ UInt32 m_Value;
+public:
+ TInByte m_Stream;
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);}
+ void ReleaseStream() { m_Stream.ReleaseStream();}
+
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ Normalize();
+ }
+
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UInt32 GetBitPosition() const { return (m_BitPos & 7); }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ m_Value = (m_Value << 8) | m_Stream.ReadByte();
+ }
+
+ UInt32 GetValue(UInt32 numBits) const
+ {
+ // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits);
+ return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(UInt32 numBits)
+ {
+ m_BitPos += numBits;
+ Normalize();
+ }
+
+ UInt32 ReadBits(UInt32 numBits)
+ {
+ UInt32 res = GetValue(numBits);
+ MovePos(numBits);
+ return res;
+ }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h b/other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h
new file mode 100644
index 0000000000..b141e55459
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h
@@ -0,0 +1,59 @@
+// Stream/MSBFEncoder.h
+
+#ifndef __STREAM_MSBFENCODER_H
+#define __STREAM_MSBFENCODER_H
+
+#include "Common/Defs.h"
+#include "../IStream.h"
+#include "OutBuffer.h"
+
+namespace NStream {
+namespace NMSBF {
+
+template<class TOutByte>
+class CEncoder
+{
+ TOutByte m_Stream;
+ int m_BitPos;
+ Byte m_CurByte;
+public:
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream);}
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ HRESULT Flush()
+ {
+ if(m_BitPos < 8)
+ WriteBits(0, m_BitPos);
+ return m_Stream.Flush();
+ }
+
+ void WriteBits(UInt32 value, int numBits)
+ {
+ while(numBits > 0)
+ {
+ if (numBits < m_BitPos)
+ {
+ m_CurByte |= ((Byte)value << (m_BitPos -= numBits));
+ return;
+ }
+ numBits -= m_BitPos;
+ UInt32 newBits = (value >> numBits);
+ value -= (newBits << numBits);
+ m_Stream.WriteByte(m_CurByte | (Byte)newBits);
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ }
+ UInt64 GetProcessedSize() const {
+ return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) / 8; }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/OffsetStream.cpp b/other-licenses/7zstub/src/7zip/Common/OffsetStream.cpp
new file mode 100644
index 0000000000..177401f383
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/OffsetStream.h b/other-licenses/7zstub/src/7zip/Common/OffsetStream.h
new file mode 100644
index 0000000000..6eaa25928e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/OffsetStream.h
@@ -0,0 +1,25 @@
+// OffsetStream.h
+
+#ifndef __OFFSETSTREAM_H
+#define __OFFSETSTREAM_H
+
+#include "Common/MyCom.h"
+#include "../IStream.h"
+
+class COffsetOutStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ UInt64 _offset;
+ CMyComPtr<IOutStream> _stream;
+public:
+ HRESULT Init(IOutStream *stream, UInt64 offset);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/OutBuffer.cpp b/other-licenses/7zstub/src/7zip/Common/OutBuffer.cpp
new file mode 100644
index 0000000000..45da6d7f00
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/OutBuffer.h b/other-licenses/7zstub/src/7zip/Common/OutBuffer.h
new file mode 100644
index 0000000000..37eefbdfcd
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/OutBuffer.h
@@ -0,0 +1,64 @@
+// OutBuffer.h
+
+#ifndef __OUTBUFFER_H
+#define __OUTBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+struct COutBufferException
+{
+ HRESULT ErrorCode;
+ COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class COutBuffer
+{
+protected:
+ Byte *_buffer;
+ UInt32 _pos;
+ UInt32 _limitPos;
+ UInt32 _streamPos;
+ UInt32 _bufferSize;
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _processedSize;
+ Byte *_buffer2;
+ bool _overDict;
+
+ HRESULT FlushPart();
+ void FlushWithCheck();
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+ ~COutBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
+ void SetStream(ISequentialOutStream *stream);
+ void Init();
+ HRESULT Flush();
+ void ReleaseStream() { _stream.Release(); }
+
+ void WriteByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if(_pos == _limitPos)
+ FlushWithCheck();
+ }
+ void WriteBytes(const void *data, size_t size)
+ {
+ for (size_t i = 0; i < size; i++)
+ WriteByte(((const Byte *)data)[i]);
+ }
+
+ UInt64 GetProcessedSize() const;
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/ProgressUtils.cpp b/other-licenses/7zstub/src/7zip/Common/ProgressUtils.cpp
new file mode 100644
index 0000000000..ac598cd545
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/ProgressUtils.cpp
@@ -0,0 +1,58 @@
+// ProgressUtils.h
+
+#include "StdAfx.h"
+
+#include "ProgressUtils.h"
+
+void CLocalCompressProgressInfo::Init(ICompressProgressInfo *progress,
+ const UInt64 *inStartValue, const UInt64 *outStartValue)
+{
+ _progress = progress;
+ _inStartValueIsAssigned = (inStartValue != NULL);
+ if (_inStartValueIsAssigned)
+ _inStartValue = *inStartValue;
+ _outStartValueIsAssigned = (outStartValue != NULL);
+ if (_outStartValueIsAssigned)
+ _outStartValue = *outStartValue;
+}
+
+STDMETHODIMP CLocalCompressProgressInfo::SetRatioInfo(
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ UInt64 inSizeNew, outSizeNew;
+ const UInt64 *inSizeNewPointer;
+ const UInt64 *outSizeNewPointer;
+ if (_inStartValueIsAssigned && inSize != NULL)
+ {
+ inSizeNew = _inStartValue + (*inSize);
+ inSizeNewPointer = &inSizeNew;
+ }
+ else
+ inSizeNewPointer = NULL;
+
+ if (_outStartValueIsAssigned && outSize != NULL)
+ {
+ outSizeNew = _outStartValue + (*outSize);
+ outSizeNewPointer = &outSizeNew;
+ }
+ else
+ outSizeNewPointer = NULL;
+ return _progress->SetRatioInfo(inSizeNewPointer, outSizeNewPointer);
+}
+
+
+///////////////////////////////////
+//
+
+void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
+{
+ _progress = progress;
+ _inSizeIsMain = inSizeIsMain;
+}
+
+STDMETHODIMP CLocalProgress::SetRatioInfo(
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ return _progress->SetCompleted(_inSizeIsMain ? inSize : outSize);
+}
+
diff --git a/other-licenses/7zstub/src/7zip/Common/ProgressUtils.h b/other-licenses/7zstub/src/7zip/Common/ProgressUtils.h
new file mode 100644
index 0000000000..92e628528d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/ProgressUtils.h
@@ -0,0 +1,43 @@
+// ProgressUtils.h
+
+#ifndef __PROGRESSUTILS_H
+#define __PROGRESSUTILS_H
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+#include "../IProgress.h"
+
+class CLocalCompressProgressInfo:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<ICompressProgressInfo> _progress;
+ bool _inStartValueIsAssigned;
+ bool _outStartValueIsAssigned;
+ UInt64 _inStartValue;
+ UInt64 _outStartValue;
+public:
+ void Init(ICompressProgressInfo *progress,
+ const UInt64 *inStartValue, const UInt64 *outStartValue);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+class CLocalProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<IProgress> _progress;
+ bool _inSizeIsMain;
+public:
+ void Init(IProgress *progress, bool inSizeIsMain);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/StdAfx.h b/other-licenses/7zstub/src/7zip/Common/StdAfx.h
new file mode 100644
index 0000000000..d7d9211b09
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp b/other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp
new file mode 100644
index 0000000000..dc11de8e5a
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp
@@ -0,0 +1,162 @@
+// StreamBinder.cpp
+
+#include "StdAfx.h"
+
+#include "StreamBinder.h"
+#include "../../Common/Defs.h"
+#include "../../Common/MyCom.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+class CSequentialInStreamForBinder:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CStreamBinder *m_StreamBinder;
+public:
+ ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
+ void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+ { return m_StreamBinder->Read(data, size, processedSize); }
+
+class CSequentialOutStreamForBinder:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+
+private:
+ CStreamBinder *m_StreamBinder;
+public:
+ ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); }
+ void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+ { return m_StreamBinder->Write(data, size, processedSize); }
+
+
+//////////////////////////
+// CStreamBinder
+// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
+
+void CStreamBinder::CreateEvents()
+{
+ _allBytesAreWritenEvent = new CManualResetEvent(true);
+ _thereAreBytesToReadEvent = new CManualResetEvent(false);
+ _readStreamIsClosedEvent = new CManualResetEvent(false);
+}
+
+void CStreamBinder::ReInit()
+{
+ _thereAreBytesToReadEvent->Reset();
+ _readStreamIsClosedEvent->Reset();
+ ProcessedSize = 0;
+}
+
+CStreamBinder::~CStreamBinder()
+{
+ if (_allBytesAreWritenEvent != NULL)
+ delete _allBytesAreWritenEvent;
+ if (_thereAreBytesToReadEvent != NULL)
+ delete _thereAreBytesToReadEvent;
+ if (_readStreamIsClosedEvent != NULL)
+ delete _readStreamIsClosedEvent;
+}
+
+
+
+
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
+ ISequentialOutStream **outStream)
+{
+ CSequentialInStreamForBinder *inStreamSpec = new
+ CSequentialInStreamForBinder;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ inStreamSpec->SetBinder(this);
+ *inStream = inStreamLoc.Detach();
+
+ CSequentialOutStreamForBinder *outStreamSpec = new
+ CSequentialOutStreamForBinder;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
+ outStreamSpec->SetBinder(this);
+ *outStream = outStreamLoc.Detach();
+
+ _buffer = NULL;
+ _bufferSize= 0;
+ ProcessedSize = 0;
+}
+
+HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 sizeToRead = size;
+ if (size > 0)
+ {
+ if(!_thereAreBytesToReadEvent->Lock())
+ return E_FAIL;
+ sizeToRead = MyMin(_bufferSize, size);
+ if (_bufferSize > 0)
+ {
+ MoveMemory(data, _buffer, sizeToRead);
+ _buffer = ((const Byte *)_buffer) + sizeToRead;
+ _bufferSize -= sizeToRead;
+ if (_bufferSize == 0)
+ {
+ _thereAreBytesToReadEvent->Reset();
+ _allBytesAreWritenEvent->Set();
+ }
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = sizeToRead;
+ ProcessedSize += sizeToRead;
+ return S_OK;
+}
+
+void CStreamBinder::CloseRead()
+{
+ _readStreamIsClosedEvent->Set();
+}
+
+HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (size > 0)
+ {
+ _buffer = data;
+ _bufferSize = size;
+ _allBytesAreWritenEvent->Reset();
+ _thereAreBytesToReadEvent->Set();
+
+ HANDLE events[2];
+ events[0] = *_allBytesAreWritenEvent;
+ events[1] = *_readStreamIsClosedEvent;
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult != WAIT_OBJECT_0 + 0)
+ {
+ // ReadingWasClosed = true;
+ return E_FAIL;
+ }
+ // if(!_allBytesAreWritenEvent.Lock())
+ // return E_FAIL;
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+void CStreamBinder::CloseWrite()
+{
+ // _bufferSize must be = 0
+ _thereAreBytesToReadEvent->Set();
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/StreamBinder.h b/other-licenses/7zstub/src/7zip/Common/StreamBinder.h
new file mode 100644
index 0000000000..7899f0ff04
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/StreamObjects.cpp b/other-licenses/7zstub/src/7zip/Common/StreamObjects.cpp
new file mode 100644
index 0000000000..459df66cf8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamObjects.cpp
@@ -0,0 +1,102 @@
+// 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 CSequentialInStreamRollback::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (_currentPos != _currentSize)
+ {
+ size_t curSize = _currentSize - _currentPos;
+ if (size > curSize)
+ size = (UInt32)curSize;
+ memmove(data, _buffer + _currentPos, size);
+ _currentPos += size;
+ if (processedSize != 0)
+ *processedSize = size;
+ return S_OK;
+ }
+ UInt32 realProcessedSize;
+ if (size > _bufferSize)
+ size = (UInt32)_bufferSize;
+ HRESULT result = _stream->Read(_buffer, size, &realProcessedSize);
+ memmove(data, _buffer, realProcessedSize);
+ _size += realProcessedSize;
+ _currentSize = realProcessedSize;
+ _currentPos = realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+HRESULT CSequentialInStreamRollback::Rollback(size_t rollbackSize)
+{
+ if (rollbackSize > _currentPos)
+ return E_INVALIDARG;
+ _currentPos -= rollbackSize;
+ return S_OK;
+}
+
+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/other-licenses/7zstub/src/7zip/Common/StreamObjects.h b/other-licenses/7zstub/src/7zip/Common/StreamObjects.h
new file mode 100644
index 0000000000..b028a2114c
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamObjects.h
@@ -0,0 +1,156 @@
+// 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;
+public:
+ size_t _size;
+ size_t _pos;
+
+ void Init(Byte *buffer, size_t size)
+ {
+ _buffer = buffer;
+ _pos = 0;
+ _size = size;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialInStreamSizeCount:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+public:
+ void Init(ISequentialInStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialInStreamRollback:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ Byte *_buffer;
+ size_t _bufferSize;
+ UInt64 _size;
+
+ size_t _currentSize;
+ size_t _currentPos;
+public:
+ CSequentialInStreamRollback(size_t bufferSize):
+ _bufferSize(bufferSize),
+ _buffer(0)
+ {
+ _buffer = new Byte[bufferSize];
+ }
+ ~CSequentialInStreamRollback()
+ {
+ delete _buffer;
+ }
+
+ void Init(ISequentialInStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ _currentSize = 0;
+ _currentPos = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ HRESULT Rollback(size_t rollbackSize);
+};
+
+class CSequentialOutStreamSizeCount:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+public:
+ void Init(ISequentialOutStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/StreamUtils.cpp b/other-licenses/7zstub/src/7zip/Common/StreamUtils.cpp
new file mode 100644
index 0000000000..712a78585a
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Common/StreamUtils.h b/other-licenses/7zstub/src/7zip/Common/StreamUtils.h
new file mode 100644
index 0000000000..c8cd8cef1a
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.cpp b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.cpp
new file mode 100644
index 0000000000..68e938bde9
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.h b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.h
new file mode 100644
index 0000000000..b64562dfc3
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/Branch/BranchTypes.h b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchTypes.h
new file mode 100644
index 0000000000..7300875625
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchTypes.h
@@ -0,0 +1,15 @@
+/* BranchTypes.h */
+
+#ifndef __BRANCHTYPES_H
+#define __BRANCHTYPES_H
+
+typedef unsigned char Byte;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.c b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.c
new file mode 100644
index 0000000000..2d2c03d2d8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.c
@@ -0,0 +1,101 @@
+/* BranchX86.c */
+
+#include "BranchX86.h"
+
+/*
+static int inline Test86MSByte(Byte b)
+{
+ return (b == 0 || b == 0xFF);
+}
+*/
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+/*
+void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos)
+{
+ *prevMask = 0;
+ *prevPos = (UInt32)(-5);
+}
+*/
+
+UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
+ UInt32 *prevMask, UInt32 *prevPos, int encoding)
+{
+ UInt32 bufferPos = 0;
+ UInt32 limit;
+
+ if (endPos < 5)
+ return 0;
+
+ if (nowPos - *prevPos > 5)
+ *prevPos = nowPos - 5;
+
+ limit = endPos - 5;
+ while(bufferPos <= limit)
+ {
+ Byte b = buffer[bufferPos];
+ UInt32 offset;
+ if (b != 0xE8 && b != 0xE9)
+ {
+ bufferPos++;
+ continue;
+ }
+ offset = (nowPos + bufferPos - *prevPos);
+ *prevPos = (nowPos + bufferPos);
+ if (offset > 5)
+ *prevMask = 0;
+ else
+ {
+ UInt32 i;
+ for (i = 0; i < offset; i++)
+ {
+ *prevMask &= 0x77;
+ *prevMask <<= 1;
+ }
+ }
+ b = buffer[bufferPos + 4];
+ if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] &&
+ (*prevMask >> 1) < 0x10)
+ {
+ UInt32 src =
+ ((UInt32)(b) << 24) |
+ ((UInt32)(buffer[bufferPos + 3]) << 16) |
+ ((UInt32)(buffer[bufferPos + 2]) << 8) |
+ (buffer[bufferPos + 1]);
+
+ UInt32 dest;
+ while(1)
+ {
+ UInt32 index;
+ if (encoding)
+ dest = (nowPos + bufferPos + 5) + src;
+ else
+ dest = src - (nowPos + bufferPos + 5);
+ if (*prevMask == 0)
+ break;
+ index = kMaskToBitNumber[*prevMask >> 1];
+ b = (Byte)(dest >> (24 - index * 8));
+ if (!Test86MSByte(b))
+ break;
+ src = dest ^ ((1 << (32 - index * 8)) - 1);
+ }
+ buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1));
+ buffer[bufferPos + 3] = (Byte)(dest >> 16);
+ buffer[bufferPos + 2] = (Byte)(dest >> 8);
+ buffer[bufferPos + 1] = (Byte)dest;
+ bufferPos += 5;
+ *prevMask = 0;
+ }
+ else
+ {
+ bufferPos++;
+ *prevMask |= 1;
+ if (Test86MSByte(b))
+ *prevMask |= 0x10;
+ }
+ }
+ return bufferPos;
+}
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.h b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.h
new file mode 100644
index 0000000000..ff9c71cbe8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.h
@@ -0,0 +1,13 @@
+/* BranchX86.h */
+
+#ifndef __BRANCHX86_H
+#define __BRANCHX86_H
+
+#include "BranchTypes.h"
+
+#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); }
+
+UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
+ UInt32 *prevMask, UInt32 *prevPos, int encoding);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/x86.cpp b/other-licenses/7zstub/src/7zip/Compress/Branch/x86.cpp
new file mode 100644
index 0000000000..929484ad6d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/x86.cpp
@@ -0,0 +1,18 @@
+// x86.cpp
+
+#include "StdAfx.h"
+#include "x86.h"
+
+#include "Windows/Defs.h"
+
+#include "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/other-licenses/7zstub/src/7zip/Compress/Branch/x86.h b/other-licenses/7zstub/src/7zip/Compress/Branch/x86.h
new file mode 100644
index 0000000000..85882d9149
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/x86.h
@@ -0,0 +1,19 @@
+// x86.h
+
+#ifndef __X86_H
+#define __X86_H
+
+#include "BranchCoder.h"
+#include "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/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.cpp b/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.cpp
new file mode 100644
index 0000000000..fc87bd937d
--- /dev/null
+++ b/other-licenses/7zstub/src/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;
+ if (inSizes != NULL)
+ if (inSizes[0] != NULL)
+ {
+ inSize = *inSizes[0];
+ if (inSize <= kDefaultLimit)
+ sizeIsDefined = true;
+ }
+
+ ISequentialInStream *inStream = inStreams[0];
+
+ _mainStream.SetStream(outStreams[0]);
+ _mainStream.Init();
+ _callStream.SetStream(outStreams[1]);
+ _callStream.Init();
+ _jumpStream.SetStream(outStreams[2]);
+ _jumpStream.Init();
+ _rangeEncoder.SetStream(outStreams[3]);
+ _rangeEncoder.Init();
+ for (int i = 0; i < 256; i++)
+ _statusE8Encoder[i].Init();
+ _statusE9Encoder.Init();
+ _statusJccEncoder.Init();
+ CCoderReleaser releaser(this);
+
+ CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
+ {
+ inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
+ }
+
+ UInt32 nowPos = 0;
+ UInt64 nowPos64 = 0;
+ UInt32 bufferPos = 0;
+
+ Byte prevByte = 0;
+
+ UInt64 subStreamIndex = 0;
+ UInt64 subStreamStartPos = 0;
+ UInt64 subStreamEndPos = 0;
+
+ while(true)
+ {
+ UInt32 processedSize = 0;
+ while(true)
+ {
+ UInt32 size = kBufferSize - (bufferPos + processedSize);
+ UInt32 processedSizeLoc;
+ if (size == 0)
+ break;
+ RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
+ if (processedSizeLoc == 0)
+ break;
+ processedSize += processedSizeLoc;
+ }
+ UInt32 endPos = bufferPos + processedSize;
+
+ if (endPos < 5)
+ {
+ // 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;
+ while(true)
+ {
+ if (processedBytes > (1 << 20) && progress != NULL)
+ {
+ UInt64 nowPos64 = _outStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(NULL, &nowPos64));
+ processedBytes = 0;
+ }
+ processedBytes++;
+ Byte b;
+ if (!_mainInStream.ReadByte(b))
+ return Flush();
+ _outStream.WriteByte(b);
+ if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
+ {
+ prevByte = b;
+ continue;
+ }
+ bool status;
+ if (b == 0xE8)
+ status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1);
+ else if (b == 0xE9)
+ status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1);
+ else
+ status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
+ if (status)
+ {
+ UInt32 src;
+ if (b == 0xE8)
+ {
+ 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 = (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/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.h b/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.h
new file mode 100644
index 0000000000..9e7780c80b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.h
@@ -0,0 +1,133 @@
+// x86_2.h
+
+#ifndef __BRANCH_X86_2_H
+#define __BRANCH_X86_2_H
+
+#include "../../../Common/MyCom.h"
+#include "../RangeCoder/RangeCoderBit.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278B-0303-010100000100}
+#define MyClass2_a(Name, id, subId, encodingId) \
+DEFINE_GUID(CLSID_CCompressConvert ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClass_a(Name, id, subId) \
+MyClass2_a(Name ## _Encoder, id, subId, 0x01) \
+MyClass2_a(Name ## _Decoder, id, subId, 0x00)
+
+MyClass_a(BCJ2_x86, 0x01, 0x1B)
+
+const int kNumMoveBits = 5;
+
+#ifndef EXTRACT_ONLY
+
+class CBCJ2_x86_Encoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ CBCJ2_x86_Encoder(): _buffer(0) {};
+ ~CBCJ2_x86_Encoder();
+ bool Create();
+
+ COutBuffer _mainStream;
+ COutBuffer _callStream;
+ COutBuffer _jumpStream;
+ NCompress::NRangeCoder::CEncoder _rangeEncoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE8Encoder[256];
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE9Encoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder;
+
+ HRESULT Flush();
+ void ReleaseStreams()
+ {
+ _mainStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeEncoder.ReleaseStream();
+ }
+
+ class CCoderReleaser
+ {
+ CBCJ2_x86_Encoder *_coder;
+ public:
+ CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+
+ MY_UNKNOWN_IMP
+
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
+
+class CBCJ2_x86_Decoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+public:
+ CInBuffer _mainInStream;
+ CInBuffer _callStream;
+ CInBuffer _jumpStream;
+ NCompress::NRangeCoder::CDecoder _rangeDecoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE8Decoder[256];
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE9Decoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusJccDecoder;
+
+ COutBuffer _outStream;
+
+ void ReleaseStreams()
+ {
+ _mainInStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeDecoder.ReleaseStream();
+ _outStream.ReleaseStream();
+ }
+
+ HRESULT Flush() { return _outStream.Flush(); }
+ class CCoderReleaser
+ {
+ CBCJ2_x86_Decoder *_coder;
+ public:
+ CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+ MY_UNKNOWN_IMP
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.cpp b/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.cpp
new file mode 100644
index 0000000000..9ced211586
--- /dev/null
+++ b/other-licenses/7zstub/src/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;
+ while(true)
+ {
+ 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/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.h b/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.h
new file mode 100644
index 0000000000..c82e469a45
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.cpp b/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.cpp
new file mode 100644
index 0000000000..329a7db35b
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.h b/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.h
new file mode 100644
index 0000000000..b64cb927f8
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMA.h b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMA.h
new file mode 100644
index 0000000000..d53296ee70
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.cpp b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.cpp
new file mode 100644
index 0000000000..e5dfb27027
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.cpp
@@ -0,0 +1,337 @@
+// 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);
+
+ while (true)
+ {
+ 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)
+{
+ if (_outSizeDefined = (outSize != NULL))
+ _outSize = *outSize;
+ _remainLen = kLenIdNeedInit;
+ _outWindowStream.Init();
+ return S_OK;
+}
+
+#ifdef _ST_MODE
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ 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/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h
new file mode 100644
index 0000000000..d6370e250f
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h
@@ -0,0 +1,251 @@
+// LZMA/Decoder.h
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
+
+class CLiteralDecoder2
+{
+ CMyBitDecoder _decoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _decoders[i].Init();
+ }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ UInt32 matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
+ // symbol = (symbol << 1) | bit;
+ UInt32 bit;
+ RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
+ bit = 0, bit = 1)
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+};
+
+class CLiteralDecoder
+{
+ CLiteralDecoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralDecoder(): _coders(0) {}
+ ~CLiteralDecoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) !=
+ (_numPrevBits + _numPosBits) )
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ UInt32 GetState(UInt32 pos, Byte prevByte) const
+ { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
+ { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
+ { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+};
+
+namespace NLength {
+
+class CDecoder
+{
+ CMyBitDecoder _choice;
+ CMyBitDecoder _choice2;
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates)
+ {
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+ }
+ UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
+ {
+ if(_choice.Decode(rangeDecoder) == 0)
+ return _lowCoder[posState].Decode(rangeDecoder);
+ if(_choice2.Decode(rangeDecoder) == 0)
+ return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
+ return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
+ }
+};
+
+}
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public ICompressGetInStreamProcessedSize,
+ #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ CLZOutWindow _outWindowStream;
+ NRangeCoder::CDecoder _rangeDecoder;
+
+ CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
+ CMyBitDecoder _isRep[kNumStates];
+ CMyBitDecoder _isRepG0[kNumStates];
+ CMyBitDecoder _isRepG1[kNumStates];
+ CMyBitDecoder _isRepG2[kNumStates];
+ CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
+
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
+
+ CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
+
+ NLength::CDecoder _lenDecoder;
+ NLength::CDecoder _repMatchLenDecoder;
+
+ CLiteralDecoder _literalDecoder;
+
+ UInt32 _posStateMask;
+
+ ///////////////////
+ // State
+ UInt32 _reps[4];
+ CState _state;
+ Int32 _remainLen; // -1 means end of stream. // -2 means need Init
+ UInt64 _outSize;
+ bool _outSizeDefined;
+
+ void Init();
+ HRESULT CodeSpec(UInt32 size);
+public:
+
+ #ifdef _ST_MODE
+ MY_UNKNOWN_IMP5(
+ ICompressSetDecoderProperties2,
+ ICompressGetInStreamProcessedSize,
+ ICompressSetInStream,
+ ICompressSetOutStreamSize,
+ ISequentialInStream)
+ #else
+ MY_UNKNOWN_IMP2(
+ ICompressSetDecoderProperties2,
+ ICompressGetInStreamProcessedSize)
+ #endif
+
+ void ReleaseStreams()
+ {
+ _outWindowStream.ReleaseStream();
+ ReleaseInStream();
+ }
+
+ class CDecoderFlusher
+ {
+ CDecoder *_decoder;
+ public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ _decoder->Flush();
+ _decoder->ReleaseStreams();
+ }
+ };
+
+ HRESULT Flush() { return _outWindowStream.Flush(); }
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ #ifdef _ST_MODE
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+
+ CDecoder(): _outSizeDefined(false) {}
+ virtual ~CDecoder() {}
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoder.h b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoder.h
new file mode 100644
index 0000000000..9828bc4b94
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.cpp
new file mode 100644
index 0000000000..8d273c8f93
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h
new file mode 100644
index 0000000000..64538e6879
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h
@@ -0,0 +1,120 @@
+// Compress/RangeCoder/RangeCoderBit.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_H
+#define __COMPRESS_RANGECODER_BIT_H
+
+#include "RangeCoder.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumBitModelTotalBits = 11;
+const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+const int kNumBitPriceShiftBits = 6;
+const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
+
+class CPriceTables
+{
+public:
+ static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ static void Init();
+ CPriceTables();
+};
+
+template <int numMoveBits>
+class CBitModel
+{
+public:
+ UInt32 Prob;
+ void UpdateModel(UInt32 symbol)
+ {
+ /*
+ Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
+ Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
+ */
+ if (symbol == 0)
+ Prob += (kBitModelTotal - Prob) >> numMoveBits;
+ else
+ Prob -= (Prob) >> numMoveBits;
+ }
+public:
+ void Init() { Prob = kBitModelTotal / 2; }
+};
+
+template <int numMoveBits>
+class CBitEncoder: public CBitModel<numMoveBits>
+{
+public:
+ void Encode(CEncoder *encoder, UInt32 symbol)
+ {
+ /*
+ encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
+ this->UpdateModel(symbol);
+ */
+ UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (symbol == 0)
+ {
+ encoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ }
+ else
+ {
+ encoder->Low += newBound;
+ encoder->Range -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ }
+ if (encoder->Range < kTopValue)
+ {
+ encoder->Range <<= 8;
+ encoder->ShiftLow();
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ return CPriceTables::ProbPrices[
+ (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+ UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
+ UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
+};
+
+
+template <int numMoveBits>
+class CBitDecoder: public CBitModel<numMoveBits>
+{
+public:
+ UInt32 Decode(CDecoder *decoder)
+ {
+ UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (decoder->Code < newBound)
+ {
+ decoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ decoder->Range -= newBound;
+ decoder->Code -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 1;
+ }
+ }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBitTree.h
new file mode 100644
index 0000000000..1fa023f3b8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBitTree.h
@@ -0,0 +1,161 @@
+// Compress/RangeCoder/RangeCoderBitTree.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
+#define __COMPRESS_RANGECODER_BIT_TREE_H
+
+#include "RangeCoderBit.h"
+#include "RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeEncoder
+{
+ CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ void Encode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
+ {
+ bitIndex--;
+ UInt32 bit = (symbol >> bitIndex) & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ };
+ void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ symbol |= (1 << NumBitLevels);
+ UInt32 price = 0;
+ while (symbol != 1)
+ {
+ price += Models[symbol >> 1].GetPrice(symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+ }
+ UInt32 ReverseGetPrice(UInt32 symbol) const
+ {
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+ }
+};
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeDecoder
+{
+ CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ UInt32 Decode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ RC_INIT_VAR
+ for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+ {
+ // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+ RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
+ }
+ RC_FLUSH_VAR
+ return modelIndex - (1 << NumBitLevels);
+ };
+ UInt32 ReverseDecode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+ }
+};
+
+template <int numMoveBits>
+void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
+ CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
+{
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
+ UInt32 NumBitLevels, UInt32 symbol)
+{
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
+ CDecoder *rangeDecoder, int NumBitLevels)
+{
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+}
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderOpt.h b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderOpt.h
new file mode 100644
index 0000000000..829fc83d77
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.cpp b/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.cpp
new file mode 100644
index 0000000000..04f27f4276
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.h b/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.h
new file mode 100644
index 0000000000..825ff6d2ed
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp
new file mode 100644
index 0000000000..b421e8ccef
--- /dev/null
+++ b/other-licenses/7zstub/src/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_YESNO);
+ ProgressSynch.SetPaused(paused);
+ if (res == IDNO)
+ return true;
+ break;
+ }
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
diff --git a/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h
new file mode 100644
index 0000000000..d0d8db56f0
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/StdAfx.h b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/StdAfx.h
new file mode 100644
index 0000000000..6447c20642
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.h b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.h
new file mode 100644
index 0000000000..7f9828126f
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.h
@@ -0,0 +1,3 @@
+#define IDD_DIALOG_PROGRESS 500
+
+#define IDC_PROGRESS1 1000
diff --git a/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.rc b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.rc
new file mode 100644
index 0000000000..71a76fe9e6
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/GuiCommon.rc b/other-licenses/7zstub/src/7zip/GuiCommon.rc
new file mode 100644
index 0000000000..fb65dce844
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/GuiCommon.rc
@@ -0,0 +1,37 @@
+#include <winnt.h>
+#include <WinUser.h>
+#include <CommCtrl.h>
+
+#define marg 7
+#undef bXSize
+#undef bYSize
+#define bXSize 64
+#define bYSize 14
+#define bDotsSize 20
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+#undef xSize2
+#undef ySize2
+#undef xSize
+#undef ySize
+#undef bXPos
+#undef bYPos
+#undef b1XPos
+#undef b1YPos
+#undef b2XPos
+#undef b2YPos
+#undef b3XPos
+#undef b3YPos
+#undef gPos
+#undef gPos2
+#undef gSpace
+#undef gSize
+#undef marg2
+#undef marg3
+
+
+#define MY_MODAL_DIALOG_STYLE STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+#define MY_PAGE_STYLE STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+
+#define MY_FONT FONT 8, "MS Shell Dlg"
diff --git a/other-licenses/7zstub/src/7zip/ICoder.h b/other-licenses/7zstub/src/7zip/ICoder.h
new file mode 100644
index 0000000000..508dac3fd0
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/IPassword.h b/other-licenses/7zstub/src/7zip/IPassword.h
new file mode 100644
index 0000000000..ba8acb0ec7
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/IProgress.h b/other-licenses/7zstub/src/7zip/IProgress.h
new file mode 100644
index 0000000000..fa2070dc7c
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/IStream.h b/other-licenses/7zstub/src/7zip/IStream.h
new file mode 100644
index 0000000000..d92b89aa70
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/MyVersion.h b/other-licenses/7zstub/src/7zip/MyVersion.h
new file mode 100644
index 0000000000..2bed0462a1
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/MyVersion.h
@@ -0,0 +1,8 @@
+#define MY_VER_MAJOR 4
+#define MY_VER_MINOR 42
+#define MY_VER_BUILD 0
+#define MY_VERSION "4.42"
+#define MY_7ZIP_VERSION "7-Zip 4.42"
+#define MY_DATE "2006-05-14"
+#define MY_COPYRIGHT "Copyright (c) 1999-2006 Igor Pavlov"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
diff --git a/other-licenses/7zstub/src/7zip/MyVersionInfo.rc b/other-licenses/7zstub/src/7zip/MyVersionInfo.rc
new file mode 100644
index 0000000000..b0a5c338c3
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/MyVersionInfo.rc
@@ -0,0 +1,41 @@
+#include <WinVer.h>
+#include "MyVersion.h"
+
+#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0
+
+#ifdef DEBUG
+#define DBG_FL VS_FF_DEBUG
+#else
+#define DBG_FL 0
+#endif
+
+#define MY_VERSION_INFO(fileType, descr, intName, origName) \
+LANGUAGE 9, 1 \
+1 VERSIONINFO \
+ FILEVERSION MY_VER \
+ PRODUCTVERSION MY_VER \
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK \
+ FILEFLAGS DBG_FL \
+ FILEOS VOS_NT_WINDOWS32 \
+ FILETYPE fileType \
+ FILESUBTYPE 0x0L \
+BEGIN \
+ BLOCK "StringFileInfo" \
+ BEGIN \
+ BLOCK "040904b0" \
+ BEGIN \
+ VALUE "CompanyName", "Igor Pavlov" \
+ VALUE "FileDescription", descr \
+ VALUE "FileVersion", MY_VERSION \
+ VALUE "InternalName", intName \
+ VALUE "LegalCopyright", MY_COPYRIGHT \
+ VALUE "OriginalFilename", origName \
+ VALUE "ProductName", "7-Zip" \
+ VALUE "ProductVersion", MY_VERSION \
+ END \
+ END \
+END
+
+#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(VFT_APP, descr, intName, intName ".exe")
+
+#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(VFT_DLL, descr, intName, intName ".dll")
diff --git a/other-licenses/7zstub/src/7zip/PropID.h b/other-licenses/7zstub/src/7zip/PropID.h
new file mode 100644
index 0000000000..1dd6ed8213
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.cpp b/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.cpp
new file mode 100644
index 0000000000..bef05786b3
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.cpp
@@ -0,0 +1,117 @@
+// ArchiveOpenCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveOpenCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+using namespace NWindows;
+
+STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
+{
+ return Callback->SetTotal(files, bytes);
+}
+
+STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
+{
+ return Callback->SetTotal(files, bytes);
+}
+
+STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ 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;
+}
+
+int COpenCallbackImp::FindName(const UString &name)
+{
+ for (int i = 0; i < FileNames.Size(); i++)
+ if (name.CompareNoCase(FileNames[i]) == 0)
+ return i;
+ return -1;
+}
+
+struct CInFileStreamVol: public CInFileStream
+{
+ UString Name;
+ COpenCallbackImp *OpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
+ ~CInFileStreamVol()
+ {
+ int index = OpenCallbackImp->FindName(Name);
+ if (index >= 0)
+ OpenCallbackImp->FileNames.Delete(index);
+ }
+};
+
+STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name,
+ IInStream **inStream)
+{
+ if (_subArchiveMode)
+ return S_FALSE;
+ RINOK(Callback->CheckBreak());
+ *inStream = NULL;
+ UString fullPath = _folderPrefix + name;
+ if (!NFile::NFind::FindFile(fullPath, _fileInfo))
+ return S_FALSE;
+ if (_fileInfo.IsDirectory())
+ return S_FALSE;
+ CInFileStreamVol *inFile = new CInFileStreamVol;
+ CMyComPtr<IInStream> inStreamTemp = inFile;
+ if (!inFile->Open(fullPath))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ inFile->Name = name;
+ inFile->OpenCallbackImp = this;
+ inFile->OpenCallbackRef = this;
+ FileNames.Add(name);
+ return S_OK;
+}
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ return Callback->CryptoGetTextPassword(password);
+}
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.h b/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.h
new file mode 100644
index 0000000000..84d13edc56
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.h
@@ -0,0 +1,87 @@
+// 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;
+ #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/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp b/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp
new file mode 100644
index 0000000000..08c352190d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp
@@ -0,0 +1,359 @@
+// 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 void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
+{
+ bb.SetCapacity(size);
+ memmove((Byte *)bb, data, size);
+}
+#endif
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
+{
+ archivers.Clear();
+
+ #ifdef EXCLUDE_COM
+
+ #ifdef FORMAT_7Z
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"7z";
+ item.Extensions.Add(CArchiverExtInfo(L"7z"));
+ #ifndef _SFX
+ const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C};
+ SetBuffer(item.StartSignature, kSig, 6);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_BZIP2
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.KeepName = true;
+ item.Name = L"BZip2";
+ item.Extensions.Add(CArchiverExtInfo(L"bz2"));
+ item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar"));
+ #ifndef _SFX
+ const unsigned char sig[] = {'B' , 'Z', 'h' };
+ SetBuffer(item.StartSignature, sig, 3);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_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/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.h b/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.h
new file mode 100644
index 0000000000..8c42f7c5b8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.h
@@ -0,0 +1,66 @@
+// ArchiverInfo.h
+
+#ifndef __ARCHIVERINFO_H
+#define __ARCHIVERINFO_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+#include "Common/Buffer.h"
+
+struct CArchiverExtInfo
+{
+ UString Ext;
+ UString AddExt;
+ CArchiverExtInfo() {}
+ CArchiverExtInfo(const UString &ext): Ext(ext) {}
+ CArchiverExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
+};
+
+struct CArchiverInfo
+{
+ #ifndef EXCLUDE_COM
+ UString FilePath;
+ CLSID ClassID;
+ #endif
+ UString Name;
+ CObjectVector<CArchiverExtInfo> Extensions;
+ #ifndef _SFX
+ CByteBuffer StartSignature;
+ CByteBuffer FinishSignature;
+ bool Associate;
+ #endif
+ int FindExtension(const UString &ext) const
+ {
+ for (int i = 0; i < Extensions.Size(); i++)
+ if (ext.CompareNoCase(Extensions[i].Ext) == 0)
+ return i;
+ return -1;
+ }
+ UString GetAllExtensions() const
+ {
+ UString s;
+ for (int i = 0; i < Extensions.Size(); i++)
+ {
+ if (i > 0)
+ s += ' ';
+ s += Extensions[i].Ext;
+ }
+ return s;
+ }
+ const UString &GetMainExtension() const
+ {
+ return Extensions[0].Ext;
+ }
+ bool UpdateEnabled;
+ bool KeepName;
+
+ CArchiverInfo(): UpdateEnabled(false), KeepName(false)
+ #ifndef _SFX
+ ,Associate(true)
+ #endif
+ {}
+};
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.cpp b/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.cpp
new file mode 100644
index 0000000000..1ada83a89b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.cpp
@@ -0,0 +1,23 @@
+// 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;
+ }
+ return kEmptyFileAlias;
+}
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.h b/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.h
new file mode 100644
index 0000000000..1788cb8560
--- /dev/null
+++ b/other-licenses/7zstub/src/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/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.cpp b/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.cpp
new file mode 100644
index 0000000000..59cb31cc59
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.cpp
@@ -0,0 +1,528 @@
+// 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_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 =
+#ifdef _WIN32
+1 << 20;
+#else
+1 << 22;
+#endif
+
+
+HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ inStreamSpec->Open(fileName);
+ return archive->Open(inStream, &kMaxCheckStartPosition, NULL);
+}
+
+#ifndef _SFX
+static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ if (p1[i] != p2[i])
+ return false;
+ return true;
+}
+#endif
+
+HRESULT OpenArchive(
+ IInStream *inStream,
+ const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfoResult,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ *archiveResult = NULL;
+ CObjectVector<CArchiverInfo> archiverInfoList;
+ ReadArchiverInfoList(archiverInfoList);
+ UString extension;
+ {
+ int dotPos = fileName.ReverseFind(L'.');
+ if (dotPos >= 0)
+ extension = fileName.Mid(dotPos + 1);
+ }
+ CIntVector orderIndices;
+ int i;
+ bool finded = false;
+ for(i = 0; i < archiverInfoList.Size(); i++)
+ {
+ if (archiverInfoList[i].FindExtension(extension) >= 0)
+ {
+ orderIndices.Insert(0, i);
+ finded = true;
+ }
+ else
+ orderIndices.Add(i);
+ }
+
+ #ifndef _SFX
+ if (!finded)
+ {
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (200 << 10);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize));
+ int numFinded = 0;
+ for (int pos = (int)processedSize; pos >= 0 ; pos--)
+ {
+ for(int i = numFinded; i < orderIndices.Size(); i++)
+ {
+ int index = orderIndices[i];
+ const CArchiverInfo &ai = archiverInfoList[index];
+ const CByteBuffer &sig = ai.StartSignature;
+ if (sig.GetCapacity() == 0)
+ continue;
+ if (pos + sig.GetCapacity() > processedSize)
+ continue;
+ if (TestSignature(buffer + pos, sig, sig.GetCapacity()))
+ {
+ orderIndices.Delete(i);
+ orderIndices.Insert(0, index);
+ numFinded++;
+ }
+ }
+ }
+ }
+ #endif
+
+ HRESULT badResult = S_OK;
+ for(i = 0; i < orderIndices.Size(); i++)
+ {
+ inStream->Seek(0, STREAM_SEEK_SET, NULL);
+ const CArchiverInfo &archiverInfo = archiverInfoList[orderIndices[i]];
+ #ifndef EXCLUDE_COM
+ CHandlerLoader loader;
+ #endif
+ CMyComPtr<IInArchive> archive;
+
+ #ifdef FORMAT_7Z
+ if (archiverInfo.Name.CompareNoCase(L"7z") == 0)
+ archive = new NArchive::N7z::CHandler;
+ #endif
+
+ #ifdef FORMAT_BZIP2
+ if (archiverInfo.Name.CompareNoCase(L"BZip2") == 0)
+ archive = new NArchive::NBZip2::CHandler;
+ #endif
+
+ #ifdef FORMAT_GZIP
+ if (archiverInfo.Name.CompareNoCase(L"GZip") == 0)
+ archive = new NArchive::NGZip::CHandler;
+ #endif
+
+ #ifdef FORMAT_SPLIT
+ if (archiverInfo.Name.CompareNoCase(L"Split") == 0)
+ archive = new NArchive::NSplit::CHandler;
+ #endif
+
+ #ifdef FORMAT_TAR
+ if (archiverInfo.Name.CompareNoCase(L"Tar") == 0)
+ archive = new NArchive::NTar::CHandler;
+ #endif
+
+ #ifdef FORMAT_ZIP
+ if (archiverInfo.Name.CompareNoCase(L"Zip") == 0)
+ archive = new NArchive::NZip::CHandler;
+ #endif
+
+ #ifdef FORMAT_Z
+ if (archiverInfo.Name.CompareNoCase(L"Z") == 0)
+ archive = new NArchive::NZ::CHandler;
+ #endif
+
+
+ #ifndef EXCLUDE_COM
+ if (!archive)
+ {
+ HRESULT result = loader.CreateHandler(archiverInfo.FilePath,
+ archiverInfo.ClassID, (void **)&archive, false);
+ if (result != S_OK)
+ continue;
+ }
+ #endif
+
+ if (!archive)
+ return E_FAIL;
+
+ HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+ if(result == S_FALSE)
+ continue;
+ if(result != S_OK)
+ {
+ badResult = result;
+ if(result == E_ABORT)
+ break;
+ continue;
+ }
+ *archiveResult = archive.Detach();
+ #ifndef EXCLUDE_COM
+ *module = loader.Detach();
+ #endif
+ archiverInfoResult = archiverInfo;
+ int subExtIndex = archiverInfo.FindExtension(extension);
+ if (subExtIndex < 0)
+ subExtIndex = 0;
+ defaultItemName = GetDefaultName2(fileName,
+ archiverInfo.Extensions[subExtIndex].Ext,
+ archiverInfo.Extensions[subExtIndex].AddExt);
+
+ return S_OK;
+ }
+ if (badResult != S_OK)
+ return badResult;
+ return S_FALSE;
+}
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfo,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ if (!inStreamSpec->Open(filePath))
+ return GetLastError();
+ return OpenArchive(inStream, ExtractFileNameFromPath(filePath),
+ #ifndef EXCLUDE_COM
+ module,
+ #endif
+ archiveResult, archiverInfo,
+ defaultItemName, openArchiveCallback);
+}
+
+static void MakeDefaultName(UString &name)
+{
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos < 0)
+ return;
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.IsEmpty())
+ return;
+ for (int pos = 0; pos < ext.Length(); pos++)
+ if (ext[pos] < L'0' || ext[pos] > L'9')
+ return;
+ name = name.Left(dotPos);
+}
+
+HRESULT OpenArchive(const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ CArchiverInfo &archiverInfo0,
+ CArchiverInfo &archiverInfo1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ HRESULT result = OpenArchive(fileName,
+ #ifndef EXCLUDE_COM
+ module0,
+ #endif
+ archive0, archiverInfo0, defaultItemName0, openArchiveCallback);
+ RINOK(result);
+ CMyComPtr<IInArchiveGetStream> getStream;
+ result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream);
+ if (result != S_OK || getStream == 0)
+ return S_OK;
+
+ CMyComPtr<ISequentialInStream> subSeqStream;
+ result = getStream->GetStream(0, &subSeqStream);
+ if (result != S_OK)
+ return S_OK;
+
+ CMyComPtr<IInStream> subStream;
+ if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK)
+ return S_OK;
+ if (!subStream)
+ return S_OK;
+
+ UInt32 numItems;
+ RINOK((*archive0)->GetNumberOfItems(&numItems));
+ if (numItems < 1)
+ return S_OK;
+
+ UString subPath;
+ RINOK(GetArchiveItemPath(*archive0, 0, subPath))
+ if (subPath.IsEmpty())
+ {
+ MakeDefaultName(defaultItemName0);
+ subPath = defaultItemName0;
+ if (archiverInfo0.Name.CompareNoCase(L"7z") == 0)
+ {
+ if (subPath.Right(3).CompareNoCase(L".7z") != 0)
+ subPath += L".7z";
+ }
+ }
+ else
+ subPath = ExtractFileNameFromPath(subPath);
+
+ CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
+ openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+ if (setSubArchiveName)
+ setSubArchiveName->SetSubArchiveName(subPath);
+
+ result = OpenArchive(subStream, subPath,
+ #ifndef EXCLUDE_COM
+ module1,
+ #endif
+ archive1, archiverInfo1, defaultItemName1, openArchiveCallback);
+ return S_OK;
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ UString &defaultItemName,
+ IOpenCallbackUI *openCallbackUI)
+{
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->Callback = openCallbackUI;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ openCallbackSpec->Init(
+ fullName.Left(fileNamePartStartIndex),
+ fullName.Mid(fileNamePartStartIndex));
+
+ CArchiverInfo archiverInfo;
+ return OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ module,
+ #endif
+ archive,
+ archiverInfo,
+ defaultItemName,
+ openCallback);
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ UStringVector &volumePaths,
+ IOpenCallbackUI *openCallbackUI)
+{
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->Callback = openCallbackUI;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ UString prefix = fullName.Left(fileNamePartStartIndex);
+ UString name = fullName.Mid(fileNamePartStartIndex);
+ openCallbackSpec->Init(prefix, name);
+
+ CArchiverInfo archiverInfo0, archiverInfo1;
+ HRESULT result = OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ module0,
+ module1,
+ #endif
+ archive0,
+ archive1,
+ archiverInfo0,
+ archiverInfo1,
+ defaultItemName0,
+ defaultItemName1,
+ openCallback);
+ RINOK(result);
+ volumePaths.Add(prefix + name);
+ for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
+ volumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
+ return S_OK;
+}
+
+HRESULT CArchiveLink::Close()
+{
+ if (Archive1 != 0)
+ RINOK(Archive1->Close());
+ if (Archive0 != 0)
+ RINOK(Archive0->Close());
+ return S_OK;
+}
+
+void CArchiveLink::Release()
+{
+ if (Archive1 != 0)
+ Archive1.Release();
+ if (Archive0 != 0)
+ Archive0.Release();
+ #ifndef EXCLUDE_COM
+ Library1.Free();
+ Library0.Free();
+ #endif
+}
+
+HRESULT OpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IArchiveOpenCallback *openCallback)
+{
+ return OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ &archiveLink.Library0, &archiveLink.Library1,
+ #endif
+ &archiveLink.Archive0, &archiveLink.Archive1,
+ archiveLink.ArchiverInfo0, archiveLink.ArchiverInfo1,
+ archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
+ openCallback);
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IOpenCallbackUI *openCallbackUI)
+{
+ return MyOpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ &archiveLink.Library0, &archiveLink.Library1,
+ #endif
+ &archiveLink.Archive0, &archiveLink.Archive1,
+ archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
+ archiveLink.VolumePaths,
+ openCallbackUI);
+}
+
+HRESULT ReOpenArchive(CArchiveLink &archiveLink,
+ const UString &fileName)
+{
+ if (archiveLink.GetNumLevels() > 1)
+ return E_NOTIMPL;
+ if (archiveLink.GetNumLevels() == 0)
+ return MyOpenArchive(fileName, archiveLink, 0);
+ return ReOpenArchive(archiveLink.GetArchive(), fileName);
+}
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.h b/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.h
new file mode 100644
index 0000000000..be6d757d7f
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.h
@@ -0,0 +1,134 @@
+// OpenArchive.h
+
+#ifndef __OPENARCHIVE_H
+#define __OPENARCHIVE_H
+
+#include "Common/String.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+#include "ArchiverInfo.h"
+#include "ArchiveOpenCallback.h"
+
+#ifndef EXCLUDE_COM
+#include "Windows/DLL.h"
+#endif
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result);
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result);
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
+ const FILETIME &defaultFileTime, FILETIME &fileTime);
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result);
+
+struct ISetSubArchiveName
+{
+ virtual void SetSubArchiveName(const wchar_t *name) = 0;
+};
+
+HRESULT OpenArchive(
+ IInStream *inStream,
+ const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfoResult,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ CArchiverInfo &archiverInfo,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ CArchiverInfo &archiverInfo0,
+ CArchiverInfo &archiverInfo1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ IArchiveOpenCallback *openArchiveCallback);
+
+
+HRESULT ReOpenArchive(IInArchive *archive,
+ const UString &fileName);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ UString &defaultItemName,
+ IOpenCallbackUI *openCallbackUI);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ UStringVector &volumePaths,
+ IOpenCallbackUI *openCallbackUI);
+
+struct CArchiveLink
+{
+ #ifndef EXCLUDE_COM
+ NWindows::NDLL::CLibrary Library0;
+ NWindows::NDLL::CLibrary Library1;
+ #endif
+ CMyComPtr<IInArchive> Archive0;
+ CMyComPtr<IInArchive> Archive1;
+ UString DefaultItemName0;
+ UString DefaultItemName1;
+
+ CArchiverInfo ArchiverInfo0;
+ CArchiverInfo ArchiverInfo1;
+
+ UStringVector VolumePaths;
+
+ int GetNumLevels() const
+ {
+ int result = 0;
+ if (Archive0)
+ {
+ result++;
+ if (Archive1)
+ result++;
+ }
+ return result;
+ }
+
+
+ IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; }
+ UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; }
+ const CArchiverInfo &GetArchiverInfo() { return Archive1 != 0 ? ArchiverInfo1: ArchiverInfo0; }
+ HRESULT Close();
+ void Release();
+};
+
+HRESULT OpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IArchiveOpenCallback *openCallback);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IOpenCallbackUI *openCallbackUI);
+
+HRESULT ReOpenArchive(CArchiveLink &archiveLink,
+ const UString &fileName);
+
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.cpp b/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.cpp
new file mode 100644
index 0000000000..92558930d8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.cpp
@@ -0,0 +1,45 @@
+// MyMessages.cpp
+
+#include "StdAfx.h"
+
+#include "MyMessages.h"
+#include "Common/String.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Error.h"
+#include "Windows/ResourceString.h"
+
+#ifdef LANG
+#include "../../FileManager/LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+void MyMessageBox(HWND window, LPCWSTR message)
+{
+ ::MessageBoxW(window, message, L"7-Zip", 0);
+}
+
+void MyMessageBox(UINT32 id
+ #ifdef LANG
+ ,UINT32 langID
+ #endif
+ )
+{
+ #ifdef LANG
+ MyMessageBox(LangString(id, langID));
+ #else
+ MyMessageBox(MyLoadStringW(id));
+ #endif
+}
+
+void ShowErrorMessage(HWND window, DWORD message)
+{
+ MyMessageBox(window, NError::MyFormatMessageW(message));
+}
+
+void ShowLastErrorMessage(HWND window)
+{
+ ShowErrorMessage(window, ::GetLastError());
+}
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.h b/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.h
new file mode 100644
index 0000000000..e3a755eef8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.h
@@ -0,0 +1,24 @@
+// 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 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/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.cpp b/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.cpp
new file mode 100644
index 0000000000..98afce4ca1
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.cpp
@@ -0,0 +1,53 @@
+// 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)
+{
+ 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;
+}
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.h b/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.h
new file mode 100644
index 0000000000..76a6ec41cf
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.h
@@ -0,0 +1,30 @@
+// 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 PasswordIsDefined;
+ UString Password;
+ #endif
+
+ HWND ParentWindow;
+
+ COpenCallbackGUI():
+ #ifndef _NO_CRYPTO
+ PasswordIsDefined(false),
+ #endif
+ ParentWindow(0) {}
+};
+
+#endif