mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-17 08:11:49 -06:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ec42ff829 | ||
|
|
631462beb2 | ||
|
|
bd9a40b0ed | ||
|
|
3415684502 | ||
|
|
83911c8529 | ||
|
|
cb9eea7264 | ||
|
|
8304895f29 | ||
|
|
191cf6781a | ||
|
|
0f60a4933b | ||
|
|
02516d3fce | ||
|
|
e8d0636d7a | ||
|
|
acac987575 | ||
|
|
e18587ba51 | ||
|
|
bcd1db2f5a | ||
|
|
32c73adef4 | ||
|
|
d66cf2fcf3 | ||
|
|
31e7b924e8 | ||
|
|
af1fe52701 | ||
|
|
47f4915611 |
@@ -43,7 +43,7 @@ RSC=rc.exe
|
|||||||
# PROP Ignore_Export_Lib 1
|
# PROP Ignore_Export_Lib 1
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
|
||||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c
|
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
|||||||
# PROP Ignore_Export_Lib 1
|
# PROP Ignore_Export_Lib 1
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||||
@@ -93,7 +93,7 @@ LINK32=link.exe
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\7z.def
|
SOURCE=..\Archive.def
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -254,10 +254,6 @@ SOURCE=..\..\ICoder.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\ICoderProperties.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\IMyUnknown.h
|
SOURCE=..\..\IMyUnknown.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -436,6 +432,14 @@ SOURCE=..\Common\OutStreamWithCRC.cpp
|
|||||||
|
|
||||||
SOURCE=..\Common\OutStreamWithCRC.h
|
SOURCE=..\Common\OutStreamWithCRC.h
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ParseProperties.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ParseProperties.h
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "7-Zip Common"
|
# Begin Group "7-Zip Common"
|
||||||
|
|
||||||
@@ -496,6 +500,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
|
|||||||
|
|
||||||
SOURCE=..\..\Common\StreamObjects.h
|
SOURCE=..\..\Common\StreamObjects.h
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.h
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Windows"
|
# Begin Group "Windows"
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,18 @@ struct CCompressionMethodMode
|
|||||||
{
|
{
|
||||||
CObjectVector<CMethodFull> Methods;
|
CObjectVector<CMethodFull> Methods;
|
||||||
CRecordVector<CBind> Binds;
|
CRecordVector<CBind> Binds;
|
||||||
bool MultiThread;
|
#ifdef COMPRESS_MT
|
||||||
|
UInt32 NumThreads;
|
||||||
|
#endif
|
||||||
bool PasswordIsDefined;
|
bool PasswordIsDefined;
|
||||||
UString Password;
|
UString Password;
|
||||||
|
|
||||||
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
||||||
CCompressionMethodMode(): PasswordIsDefined(false), MultiThread(false) {}
|
CCompressionMethodMode(): PasswordIsDefined(false)
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
, NumThreads(1)
|
||||||
|
#endif
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Decode.cpp
|
// 7zDecode.cpp
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
@@ -136,10 +136,10 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
|
|||||||
|
|
||||||
CDecoder::CDecoder(bool multiThread)
|
CDecoder::CDecoder(bool multiThread)
|
||||||
{
|
{
|
||||||
_multiThread = true;
|
#ifndef _ST_MODE
|
||||||
#ifdef _ST_MODE
|
multiThread = true;
|
||||||
_multiThread = multiThread;
|
|
||||||
#endif
|
#endif
|
||||||
|
_multiThread = multiThread;
|
||||||
_bindInfoExPrevIsDefinded = false;
|
_bindInfoExPrevIsDefinded = false;
|
||||||
#ifndef EXCLUDE_COM
|
#ifndef EXCLUDE_COM
|
||||||
LoadMethodMap();
|
LoadMethodMap();
|
||||||
@@ -155,6 +155,9 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
|||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
, ICryptoGetTextPassword *getTextPassword
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
, bool mtMode, UInt32 numThreads
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
||||||
@@ -329,48 +332,60 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
|||||||
{
|
{
|
||||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
||||||
CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
|
CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
|
||||||
HRESULT result = _decoders[coderIndex].QueryInterface(
|
|
||||||
IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
|
|
||||||
|
|
||||||
if (result == S_OK)
|
|
||||||
{
|
{
|
||||||
const CByteBuffer &properties = altCoderInfo.Properties;
|
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
|
||||||
UInt32 size = properties.GetCapacity();
|
HRESULT result = decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
|
||||||
if (size > 0)
|
if (setDecoderProperties)
|
||||||
{
|
{
|
||||||
RINOK(compressSetDecoderProperties->SetDecoderProperties2((const Byte *)properties, size));
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (result != E_NOINTERFACE)
|
|
||||||
return result;
|
#ifdef COMPRESS_MT
|
||||||
|
if (mtMode)
|
||||||
|
{
|
||||||
|
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||||
|
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||||
|
if (setCoderMt)
|
||||||
|
{
|
||||||
|
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
|
||||||
result = _decoders[coderIndex].QueryInterface(
|
|
||||||
IID_ICryptoSetPassword, &cryptoSetPassword);
|
|
||||||
|
|
||||||
if (result == S_OK)
|
|
||||||
{
|
{
|
||||||
if (getTextPassword == 0)
|
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||||
return E_FAIL;
|
HRESULT result = decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||||
CMyComBSTR password;
|
if (cryptoSetPassword)
|
||||||
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];
|
if (getTextPassword == 0)
|
||||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
return E_FAIL;
|
||||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
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));
|
||||||
}
|
}
|
||||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
|
||||||
(const Byte *)buffer, sizeInBytes));
|
|
||||||
}
|
}
|
||||||
else if (result != E_NOINTERFACE)
|
|
||||||
return result;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
coderIndex++;
|
coderIndex++;
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ public:
|
|||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPasswordSpec
|
, ICryptoGetTextPassword *getTextPasswordSpec
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
, bool mtMode, UInt32 numThreads
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,10 @@ static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
|
|||||||
#include "../../Compress/Copy/CopyCoder.h"
|
#include "../../Compress/Copy/CopyCoder.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||||
|
|
||||||
#ifdef COMPRESS_LZMA
|
#ifdef COMPRESS_LZMA
|
||||||
#include "../../Compress/LZMA/LZMAEncoder.h"
|
#include "../../Compress/LZMA/LZMAEncoder.h"
|
||||||
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMPRESS_PPMD
|
#ifdef COMPRESS_PPMD
|
||||||
@@ -114,7 +115,7 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindI
|
|||||||
folder.PackStreams.Add(bindInfo.InStreams[i]);
|
folder.PackStreams.Add(bindInfo.InStreams[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CEncoder::CreateMixerCoder()
|
HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
|
||||||
{
|
{
|
||||||
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT;
|
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT;
|
||||||
_mixerCoder = _mixerCoderSpec;
|
_mixerCoder = _mixerCoderSpec;
|
||||||
@@ -203,7 +204,44 @@ HRESULT CEncoder::CreateMixerCoder()
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tryReduce = false;
|
||||||
|
UInt32 reducedDictionarySize = 1 << 10;
|
||||||
|
if (inSizeForReduce != 0 && methodFull.MethodID == k_LZMA)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const UInt32 step = (reducedDictionarySize >> 1);
|
||||||
|
if (reducedDictionarySize >= *inSizeForReduce)
|
||||||
|
{
|
||||||
|
tryReduce = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
reducedDictionarySize += step;
|
||||||
|
if (reducedDictionarySize >= *inSizeForReduce)
|
||||||
|
{
|
||||||
|
tryReduce = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (reducedDictionarySize >= ((UInt32)11 << 30))
|
||||||
|
break;
|
||||||
|
reducedDictionarySize += step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMyComPtr<IUnknown> encoderCommon = methodFull.IsSimpleCoder() ? (IUnknown *)encoder : (IUnknown *)encoder2;
|
||||||
|
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
{
|
||||||
|
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||||
|
encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||||
|
if (setCoderMt)
|
||||||
|
{
|
||||||
|
RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (methodFull.CoderProperties.Size() > 0)
|
if (methodFull.CoderProperties.Size() > 0)
|
||||||
{
|
{
|
||||||
CRecordVector<PROPID> propIDs;
|
CRecordVector<PROPID> propIDs;
|
||||||
@@ -215,19 +253,13 @@ HRESULT CEncoder::CreateMixerCoder()
|
|||||||
{
|
{
|
||||||
const CProperty &property = methodFull.CoderProperties[i];
|
const CProperty &property = methodFull.CoderProperties[i];
|
||||||
propIDs.Add(property.PropID);
|
propIDs.Add(property.PropID);
|
||||||
values[i] = property.Value;
|
NWindows::NCOM::CPropVariant value = property.Value;
|
||||||
|
if (tryReduce && property.PropID == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
|
||||||
|
value.ulVal = reducedDictionarySize;
|
||||||
|
values[i] = value;
|
||||||
}
|
}
|
||||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||||
if (methodFull.IsSimpleCoder())
|
RINOK(encoderCommon.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||||
{
|
|
||||||
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties,
|
|
||||||
&setCoderProperties));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
|
|
||||||
&setCoderProperties));
|
|
||||||
}
|
|
||||||
RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
|
RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
@@ -240,16 +272,7 @@ HRESULT CEncoder::CreateMixerCoder()
|
|||||||
|
|
||||||
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
||||||
|
|
||||||
if (methodFull.IsSimpleCoder())
|
encoderCommon.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
|
||||||
{
|
|
||||||
encoder.QueryInterface(IID_ICompressWriteCoderProperties,
|
|
||||||
&writeCoderProperties);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
encoder2.QueryInterface(IID_ICompressWriteCoderProperties,
|
|
||||||
&writeCoderProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (writeCoderProperties != NULL)
|
if (writeCoderProperties != NULL)
|
||||||
{
|
{
|
||||||
@@ -258,7 +281,7 @@ HRESULT CEncoder::CreateMixerCoder()
|
|||||||
outStreamSpec->Init();
|
outStreamSpec->Init();
|
||||||
writeCoderProperties->WriteCoderProperties(outStream);
|
writeCoderProperties->WriteCoderProperties(outStream);
|
||||||
|
|
||||||
UInt32 size = outStreamSpec->GetSize();
|
size_t size = outStreamSpec->GetSize();
|
||||||
|
|
||||||
// encodingInfo.Properties.SetCapacity(size);
|
// encodingInfo.Properties.SetCapacity(size);
|
||||||
if (encodingInfo.AltCoders.Size() == 0)
|
if (encodingInfo.AltCoders.Size() == 0)
|
||||||
@@ -270,14 +293,7 @@ HRESULT CEncoder::CreateMixerCoder()
|
|||||||
}
|
}
|
||||||
|
|
||||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||||
if (methodFull.IsSimpleCoder())
|
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||||
{
|
|
||||||
encoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
encoder2.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cryptoSetPassword)
|
if (cryptoSetPassword)
|
||||||
{
|
{
|
||||||
@@ -290,25 +306,19 @@ HRESULT CEncoder::CreateMixerCoder()
|
|||||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||||
}
|
}
|
||||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
|
||||||
(const Byte *)buffer, sizeInBytes));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public ICompressWriteCoderProperties,
|
|
||||||
if (methodFull.IsSimpleCoder())
|
if (methodFull.IsSimpleCoder())
|
||||||
{
|
|
||||||
_mixerCoderSpec->AddCoder(encoder);
|
_mixerCoderSpec->AddCoder(encoder);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
_mixerCoderSpec->AddCoder2(encoder2);
|
_mixerCoderSpec->AddCoder2(encoder2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
||||||
const UInt64 *inStreamSize,
|
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
|
||||||
CFolder &folderItem,
|
CFolder &folderItem,
|
||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
CRecordVector<UInt64> &packSizes,
|
CRecordVector<UInt64> &packSizes,
|
||||||
@@ -316,7 +326,7 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
|||||||
{
|
{
|
||||||
if (_mixerCoderSpec == NULL)
|
if (_mixerCoderSpec == NULL)
|
||||||
{
|
{
|
||||||
RINOK(CreateMixerCoder());
|
RINOK(CreateMixerCoder(inSizeForReduce));
|
||||||
}
|
}
|
||||||
_mixerCoderSpec->ReInit();
|
_mixerCoderSpec->ReInit();
|
||||||
// _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
|
// _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ class CEncoder
|
|||||||
NCoderMixer2::CBindReverseConverter *_bindReverseConverter;
|
NCoderMixer2::CBindReverseConverter *_bindReverseConverter;
|
||||||
CRecordVector<CMethodID> _decompressionMethods;
|
CRecordVector<CMethodID> _decompressionMethods;
|
||||||
|
|
||||||
HRESULT CreateMixerCoder();
|
HRESULT CreateMixerCoder(const UInt64 *inSizeForReduce);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CEncoder(const CCompressionMethodMode &options);
|
CEncoder(const CCompressionMethodMode &options);
|
||||||
~CEncoder();
|
~CEncoder();
|
||||||
HRESULT Encode(ISequentialInStream *inStream,
|
HRESULT Encode(ISequentialInStream *inStream,
|
||||||
const UInt64 *inStreamSize,
|
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
|
||||||
CFolder &folderItem,
|
CFolder &folderItem,
|
||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
CRecordVector<UInt64> &packSizes,
|
CRecordVector<UInt64> &packSizes,
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
bool testMode = (testModeSpec != 0);
|
bool testMode = (testModeSpec != 0);
|
||||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||||
UInt64 importantTotalUnPacked = 0;
|
UInt64 importantTotalUnPacked = 0;
|
||||||
UInt64 censoredTotalUnPacked = 0, censoredTotalPacked = 0;
|
|
||||||
|
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
bool allFilesMode = (numItems == UInt32(-1));
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
@@ -142,7 +141,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
extractCallback->SetTotal(importantTotalUnPacked);
|
extractCallback->SetTotal(importantTotalUnPacked);
|
||||||
|
|
||||||
CDecoder decoder(true);
|
CDecoder decoder(
|
||||||
|
#ifdef _ST_MODE
|
||||||
|
false
|
||||||
|
#else
|
||||||
|
true
|
||||||
|
#endif
|
||||||
|
);
|
||||||
// CDecoder1 decoder;
|
// CDecoder1 decoder;
|
||||||
|
|
||||||
UInt64 currentImportantTotalUnPacked = 0;
|
UInt64 currentImportantTotalUnPacked = 0;
|
||||||
@@ -224,6 +229,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
, true, _numThreads
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result == S_FALSE)
|
if (result == S_FALSE)
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ HRESULT CFolderInStream::CloseStream()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
UInt32 realProcessedSize = 0;
|
UInt32 realProcessedSize = 0;
|
||||||
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
|
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
|
||||||
@@ -87,7 +87,7 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processe
|
|||||||
if (_fileIsOpen)
|
if (_fileIsOpen)
|
||||||
{
|
{
|
||||||
UInt32 localProcessedSize;
|
UInt32 localProcessedSize;
|
||||||
RINOK(_inStreamWithHash->ReadPart(
|
RINOK(_inStreamWithHash->Read(
|
||||||
((Byte *)data) + realProcessedSize, size, &localProcessedSize));
|
((Byte *)data) + realProcessedSize, size, &localProcessedSize));
|
||||||
if (localProcessedSize == 0)
|
if (localProcessedSize == 0)
|
||||||
{
|
{
|
||||||
@@ -109,30 +109,12 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processe
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize = 0;
|
|
||||||
while (size > 0)
|
|
||||||
{
|
|
||||||
UInt32 localProcessedSize;
|
|
||||||
RINOK(ReadPart(((Byte *)data) + realProcessedSize, size, &localProcessedSize));
|
|
||||||
if (localProcessedSize == 0)
|
|
||||||
break;
|
|
||||||
size -= localProcessedSize;
|
|
||||||
realProcessedSize += localProcessedSize;
|
|
||||||
}
|
|
||||||
if (processedSize != 0)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
||||||
{
|
{
|
||||||
*value = 0;
|
*value = 0;
|
||||||
if (subStream < Sizes.Size())
|
if (subStream < Sizes.Size())
|
||||||
{
|
{
|
||||||
*value= Sizes[(size_t)subStream];
|
*value= Sizes[(int)(size_t)subStream];
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
if (subStream > Sizes.Size())
|
if (subStream > Sizes.Size())
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ public:
|
|||||||
CFolderInStream();
|
CFolderInStream();
|
||||||
|
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
|
|
||||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
|
|||||||
UInt64(size - realProcessedSize));
|
UInt64(size - realProcessedSize));
|
||||||
|
|
||||||
UInt32 processedSizeLocal;
|
UInt32 processedSizeLocal;
|
||||||
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal));
|
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
|
||||||
|
numBytesToWrite, &processedSizeLocal));
|
||||||
|
|
||||||
_filePos += processedSizeLocal;
|
_filePos += processedSizeLocal;
|
||||||
realProcessedSize += processedSizeLocal;
|
realProcessedSize += processedSizeLocal;
|
||||||
@@ -130,12 +131,6 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CFolderOutStream::WritePart(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
return Write(data, size, processedSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
||||||
{
|
{
|
||||||
while(_currentIndex < _extractStatuses->Size())
|
while(_currentIndex < _extractStatuses->Size())
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ public:
|
|||||||
CFolderOutStream();
|
CFolderOutStream();
|
||||||
|
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
COutStreamWithCRC *_outStreamWithHashSpec;
|
COutStreamWithCRC *_outStreamWithHashSpec;
|
||||||
|
|||||||
@@ -14,6 +14,12 @@
|
|||||||
#include "../Common/MultiStream.h"
|
#include "../Common/MultiStream.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
|
#ifdef EXTRACT_ONLY
|
||||||
|
#include "../Common/ParseProperties.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
@@ -21,6 +27,9 @@ namespace N7z {
|
|||||||
|
|
||||||
CHandler::CHandler()
|
CHandler::CHandler()
|
||||||
{
|
{
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||||
|
#endif
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
Init();
|
Init();
|
||||||
#endif
|
#endif
|
||||||
@@ -708,4 +717,41 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
#include "7zMethods.h"
|
#include "7zMethods.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
#include "../../../Windows/System.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
@@ -50,18 +54,33 @@ struct COneMethodInfo
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-000110050000}
|
// {23170F69-40C1-278A-1000-000110070000}
|
||||||
DEFINE_GUID(CLSID_CFormat7z,
|
DEFINE_GUID(CLSID_CFormat7z,
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
|
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
|
||||||
|
|
||||||
|
#ifndef __7Z_SET_PROPERTIES
|
||||||
|
|
||||||
|
#ifdef EXTRACT_ONLY
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
#define __7Z_SET_PROPERTIES
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define __7Z_SET_PROPERTIES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
public IInArchiveGetStream,
|
public IInArchiveGetStream,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
|
public ISetProperties,
|
||||||
|
#endif
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
public IOutArchive,
|
public IOutArchive,
|
||||||
public ISetProperties,
|
|
||||||
#endif
|
#endif
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
@@ -70,9 +89,11 @@ public:
|
|||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
|
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||||
|
#endif
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
MY_QUERYINTERFACE_ENTRY(IOutArchive)
|
MY_QUERYINTERFACE_ENTRY(IOutArchive)
|
||||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
|
||||||
#endif
|
#endif
|
||||||
MY_QUERYINTERFACE_END
|
MY_QUERYINTERFACE_END
|
||||||
MY_ADDREF_RELEASE
|
MY_ADDREF_RELEASE
|
||||||
@@ -101,6 +122,10 @@ public:
|
|||||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
|
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
// IOutArchiveHandler
|
// IOutArchiveHandler
|
||||||
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
|
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
|
||||||
@@ -109,7 +134,6 @@ public:
|
|||||||
STDMETHOD(GetFileTimeType)(UInt32 *type);
|
STDMETHOD(GetFileTimeType)(UInt32 *type);
|
||||||
|
|
||||||
// ISetProperties
|
// ISetProperties
|
||||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
|
||||||
|
|
||||||
HRESULT SetSolidSettings(const UString &s);
|
HRESULT SetSolidSettings(const UString &s);
|
||||||
HRESULT SetSolidSettings(const PROPVARIANT &value);
|
HRESULT SetSolidSettings(const PROPVARIANT &value);
|
||||||
@@ -126,6 +150,10 @@ private:
|
|||||||
NArchive::N7z::CArchiveDatabaseEx _database;
|
NArchive::N7z::CArchiveDatabaseEx _database;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
UInt32 _numThreads;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
CObjectVector<COneMethodInfo> _methods;
|
CObjectVector<COneMethodInfo> _methods;
|
||||||
CRecordVector<CBind> _binds;
|
CRecordVector<CBind> _binds;
|
||||||
@@ -139,14 +167,7 @@ private:
|
|||||||
bool _compressHeadersFull;
|
bool _compressHeadersFull;
|
||||||
bool _encryptHeaders;
|
bool _encryptHeaders;
|
||||||
|
|
||||||
bool _copyMode;
|
|
||||||
UInt32 _defaultDicSize;
|
|
||||||
UInt32 _defaultAlgorithm;
|
|
||||||
UInt32 _defaultFastBytes;
|
|
||||||
UString _defaultMatchFinder;
|
|
||||||
UInt32 _defaultBZip2Passes;
|
|
||||||
bool _autoFilter;
|
bool _autoFilter;
|
||||||
bool _multiThread;
|
|
||||||
UInt32 _level;
|
UInt32 _level;
|
||||||
|
|
||||||
bool _volumeMode;
|
bool _volumeMode;
|
||||||
@@ -159,8 +180,11 @@ private:
|
|||||||
IArchiveUpdateCallback *updateCallback);
|
IArchiveUpdateCallback *updateCallback);
|
||||||
|
|
||||||
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
|
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
|
||||||
CObjectVector<COneMethodInfo> &methodsInfo,
|
CObjectVector<COneMethodInfo> &methodsInfo
|
||||||
bool multiThread);
|
#ifdef COMPRESS_MT
|
||||||
|
, UInt32 numThreads
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
HRESULT SetCompressionMethod(
|
HRESULT SetCompressionMethod(
|
||||||
CCompressionMethodMode &method,
|
CCompressionMethodMode &method,
|
||||||
@@ -186,30 +210,6 @@ private:
|
|||||||
_solidExtension = false;
|
_solidExtension = false;
|
||||||
_numSolidBytesDefined = false;
|
_numSolidBytesDefined = false;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void InitSolidPart()
|
|
||||||
{
|
|
||||||
if (_numSolidFiles <= 1)
|
|
||||||
InitSolidFiles();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void SetSolidBytesLimit()
|
|
||||||
{
|
|
||||||
_numSolidBytes = ((UInt64)_defaultDicSize) << 7;
|
|
||||||
const UInt64 kMinSize = (1<<24);
|
|
||||||
if (_numSolidBytes < kMinSize)
|
|
||||||
_numSolidBytes = kMinSize;
|
|
||||||
}
|
|
||||||
void CheckAndSetSolidBytesLimit()
|
|
||||||
{
|
|
||||||
if (!_numSolidBytesDefined)
|
|
||||||
{
|
|
||||||
if (_copyMode)
|
|
||||||
_numSolidBytes = 0;
|
|
||||||
else
|
|
||||||
SetSolidBytesLimit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
@@ -217,18 +217,14 @@ private:
|
|||||||
_compressHeaders = true;
|
_compressHeaders = true;
|
||||||
_compressHeadersFull = true;
|
_compressHeadersFull = true;
|
||||||
_encryptHeaders = false;
|
_encryptHeaders = false;
|
||||||
_multiThread = false;
|
#ifdef COMPRESS_MT
|
||||||
_copyMode = false;
|
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||||
_defaultDicSize = (1 << 21);
|
#endif
|
||||||
_defaultBZip2Passes = 1;
|
|
||||||
_defaultAlgorithm = 1;
|
|
||||||
_defaultFastBytes = 32;
|
|
||||||
_defaultMatchFinder = L"BT4";
|
|
||||||
_level = 5;
|
_level = 5;
|
||||||
_autoFilter = true;
|
_autoFilter = true;
|
||||||
_volumeMode = false;
|
_volumeMode = false;
|
||||||
InitSolid();
|
InitSolid();
|
||||||
SetSolidBytesLimit();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,12 +8,14 @@
|
|||||||
#include "7zMethods.h"
|
#include "7zMethods.h"
|
||||||
|
|
||||||
#include "../../../Windows/PropVariant.h"
|
#include "../../../Windows/PropVariant.h"
|
||||||
|
|
||||||
#include "../../../Common/ComTry.h"
|
#include "../../../Common/ComTry.h"
|
||||||
#include "../../../Common/StringToInt.h"
|
#include "../../../Common/StringToInt.h"
|
||||||
#include "../../IPassword.h"
|
#include "../../IPassword.h"
|
||||||
#include "../../ICoder.h"
|
#include "../../ICoder.h"
|
||||||
|
|
||||||
#include "../Common/ItemNameUtils.h"
|
#include "../Common/ItemNameUtils.h"
|
||||||
|
#include "../Common/ParseProperties.h"
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
@@ -63,25 +65,60 @@ static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
|||||||
const wchar_t *kCopyMethod = L"Copy";
|
const wchar_t *kCopyMethod = L"Copy";
|
||||||
const wchar_t *kLZMAMethodName = L"LZMA";
|
const wchar_t *kLZMAMethodName = L"LZMA";
|
||||||
const wchar_t *kBZip2MethodName = L"BZip2";
|
const wchar_t *kBZip2MethodName = L"BZip2";
|
||||||
|
const wchar_t *kPpmdMethodName = L"PPMd";
|
||||||
|
const wchar_t *kDeflateMethodName = L"Deflate";
|
||||||
|
const wchar_t *kDeflate64MethodName = L"Deflate64";
|
||||||
|
|
||||||
const UInt32 kAlgorithmForX7 = 2;
|
static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
|
||||||
const UInt32 kDicSizeForX7 = 1 << 23;
|
static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
|
||||||
const UInt32 kFastBytesForX7 = 64;
|
|
||||||
|
|
||||||
const UInt32 kAlgorithmForX9 = 2;
|
static const UInt32 kLzmaAlgorithmX1 = 0;
|
||||||
const UInt32 kDicSizeForX9 = 1 << 25;
|
static const UInt32 kLzmaAlgorithmX5 = 1;
|
||||||
const UInt32 kFastBytesForX9 = 64;
|
|
||||||
static const wchar_t *kMatchFinderForX9 = L"BT4b";
|
|
||||||
|
|
||||||
const UInt32 kAlgorithmForFast = 0;
|
static const UInt32 kLzmaDicSizeX1 = 1 << 16;
|
||||||
const UInt32 kDicSizeForFast = 1 << 15;
|
static const UInt32 kLzmaDicSizeX3 = 1 << 20;
|
||||||
static const wchar_t *kMatchFinderForFast = L"HC3";
|
static const UInt32 kLzmaDicSizeX5 = 1 << 22;
|
||||||
|
static const UInt32 kLzmaDicSizeX7 = 1 << 24;
|
||||||
|
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
|
||||||
|
|
||||||
|
static const UInt32 kLzmaFastBytesX1 = 32;
|
||||||
|
static const UInt32 kLzmaFastBytesX7 = 64;
|
||||||
|
|
||||||
|
static const UInt32 kPpmdMemSizeX1 = (1 << 22);
|
||||||
|
static const UInt32 kPpmdMemSizeX5 = (1 << 24);
|
||||||
|
static const UInt32 kPpmdMemSizeX7 = (1 << 26);
|
||||||
|
static const UInt32 kPpmdMemSizeX9 = (192 << 20);
|
||||||
|
|
||||||
|
static const UInt32 kPpmdOrderX1 = 4;
|
||||||
|
static const UInt32 kPpmdOrderX5 = 6;
|
||||||
|
static const UInt32 kPpmdOrderX7 = 16;
|
||||||
|
static const UInt32 kPpmdOrderX9 = 32;
|
||||||
|
|
||||||
|
static const UInt32 kDeflateFastBytesX1 = 32;
|
||||||
|
static const UInt32 kDeflateFastBytesX7 = 64;
|
||||||
|
static const UInt32 kDeflateFastBytesX9 = 128;
|
||||||
|
|
||||||
|
static const UInt32 kDeflatePassesX1 = 1;
|
||||||
|
static const UInt32 kDeflatePassesX7 = 3;
|
||||||
|
static const UInt32 kDeflatePassesX9 = 10;
|
||||||
|
|
||||||
|
static const UInt32 kBZip2NumPassesX1 = 1;
|
||||||
|
static const UInt32 kBZip2NumPassesX7 = 2;
|
||||||
|
static const UInt32 kBZip2NumPassesX9 = 7;
|
||||||
|
|
||||||
|
static const UInt32 kBZip2DicSizeX1 = 100000;
|
||||||
|
static const UInt32 kBZip2DicSizeX3 = 500000;
|
||||||
|
static const UInt32 kBZip2DicSizeX5 = 900000;
|
||||||
|
|
||||||
const wchar_t *kDefaultMethodName = kLZMAMethodName;
|
const wchar_t *kDefaultMethodName = kLZMAMethodName;
|
||||||
|
|
||||||
static const wchar_t *kMatchFinderForHeaders = L"BT2";
|
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
|
||||||
static const UInt32 kDictionaryForHeaders = 1 << 20;
|
static const UInt32 kDictionaryForHeaders = 1 << 20;
|
||||||
static const UInt32 kNumFastBytesForHeaders = 254;
|
static const UInt32 kNumFastBytesForHeaders = 273;
|
||||||
|
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
|
||||||
|
|
||||||
|
static bool IsCopyMethod(const UString &methodName)
|
||||||
|
{ return (methodName.CompareNoCase(kCopyMethod) == 0); }
|
||||||
|
|
||||||
static bool IsLZMAMethod(const UString &methodName)
|
static bool IsLZMAMethod(const UString &methodName)
|
||||||
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
|
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
|
||||||
@@ -91,6 +128,13 @@ static bool IsLZMethod(const UString &methodName)
|
|||||||
static bool IsBZip2Method(const UString &methodName)
|
static bool IsBZip2Method(const UString &methodName)
|
||||||
{ return (methodName.CompareNoCase(kBZip2MethodName) == 0); }
|
{ return (methodName.CompareNoCase(kBZip2MethodName) == 0); }
|
||||||
|
|
||||||
|
static bool IsPpmdMethod(const UString &methodName)
|
||||||
|
{ return (methodName.CompareNoCase(kPpmdMethodName) == 0); }
|
||||||
|
|
||||||
|
static bool IsDeflateMethod(const UString &methodName)
|
||||||
|
{ return (methodName.CompareNoCase(kDeflateMethodName) == 0) ||
|
||||||
|
(methodName.CompareNoCase(kDeflate64MethodName) == 0); }
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
||||||
{
|
{
|
||||||
*type = NFileTimeType::kWindows;
|
*type = NFileTimeType::kWindows;
|
||||||
@@ -137,9 +181,10 @@ CNameToPropID g_NameToPropID[] =
|
|||||||
|
|
||||||
{ NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
|
{ NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
|
||||||
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
|
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
|
||||||
|
{ NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
|
||||||
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" },
|
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" },
|
||||||
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
|
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
|
||||||
{ NCoderPropID::kMultiThread, VT_BOOL, L"mt" }
|
{ NCoderPropID::kNumThreads, VT_UI4, L"mt" }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
|
bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
|
||||||
@@ -178,7 +223,12 @@ HRESULT CHandler::SetCompressionMethod(
|
|||||||
CCompressionMethodMode &methodMode,
|
CCompressionMethodMode &methodMode,
|
||||||
CCompressionMethodMode &headerMethod)
|
CCompressionMethodMode &headerMethod)
|
||||||
{
|
{
|
||||||
RINOK(SetCompressionMethod(methodMode, _methods, _multiThread));
|
HRESULT res = SetCompressionMethod(methodMode, _methods
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
, _numThreads
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
RINOK(res);
|
||||||
methodMode.Binds = _binds;
|
methodMode.Binds = _binds;
|
||||||
if (_compressHeadersFull)
|
if (_compressHeadersFull)
|
||||||
_compressHeaders = true;
|
_compressHeaders = true;
|
||||||
@@ -193,13 +243,13 @@ HRESULT CHandler::SetCompressionMethod(
|
|||||||
{
|
{
|
||||||
CProperty property;
|
CProperty property;
|
||||||
property.PropID = NCoderPropID::kMatchFinder;
|
property.PropID = NCoderPropID::kMatchFinder;
|
||||||
property.Value = kMatchFinderForHeaders;
|
property.Value = kLzmaMatchFinderForHeaders;
|
||||||
oneMethodInfo.CoderProperties.Add(property);
|
oneMethodInfo.CoderProperties.Add(property);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CProperty property;
|
CProperty property;
|
||||||
property.PropID = NCoderPropID::kAlgorithm;
|
property.PropID = NCoderPropID::kAlgorithm;
|
||||||
property.Value = kAlgorithmForX9;
|
property.Value = kAlgorithmForHeaders;
|
||||||
oneMethodInfo.CoderProperties.Add(property);
|
oneMethodInfo.CoderProperties.Add(property);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -215,7 +265,12 @@ HRESULT CHandler::SetCompressionMethod(
|
|||||||
oneMethodInfo.CoderProperties.Add(property);
|
oneMethodInfo.CoderProperties.Add(property);
|
||||||
}
|
}
|
||||||
headerMethodInfoVector.Add(oneMethodInfo);
|
headerMethodInfoVector.Add(oneMethodInfo);
|
||||||
RINOK(SetCompressionMethod(headerMethod, headerMethodInfoVector, false));
|
HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
,1
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
RINOK(res);
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -237,8 +292,11 @@ static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
|
|||||||
|
|
||||||
HRESULT CHandler::SetCompressionMethod(
|
HRESULT CHandler::SetCompressionMethod(
|
||||||
CCompressionMethodMode &methodMode,
|
CCompressionMethodMode &methodMode,
|
||||||
CObjectVector<COneMethodInfo> &methodsInfo,
|
CObjectVector<COneMethodInfo> &methodsInfo
|
||||||
bool multiThread)
|
#ifdef COMPRESS_MT
|
||||||
|
, UInt32 numThreads
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#ifndef EXCLUDE_COM
|
#ifndef EXCLUDE_COM
|
||||||
/*
|
/*
|
||||||
@@ -249,40 +307,103 @@ HRESULT CHandler::SetCompressionMethod(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
UInt32 level = _level;
|
||||||
|
|
||||||
if (methodsInfo.IsEmpty())
|
if (methodsInfo.IsEmpty())
|
||||||
{
|
{
|
||||||
COneMethodInfo oneMethodInfo;
|
COneMethodInfo oneMethodInfo;
|
||||||
oneMethodInfo.MethodName = _copyMode ? kCopyMethod : kDefaultMethodName;
|
oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
|
||||||
methodsInfo.Add(oneMethodInfo);
|
methodsInfo.Add(oneMethodInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool needSolid = false;
|
||||||
for(int i = 0; i < methodsInfo.Size(); i++)
|
for(int i = 0; i < methodsInfo.Size(); i++)
|
||||||
{
|
{
|
||||||
COneMethodInfo &oneMethodInfo = methodsInfo[i];
|
COneMethodInfo &oneMethodInfo = methodsInfo[i];
|
||||||
if (oneMethodInfo.MethodName.IsEmpty())
|
if (oneMethodInfo.MethodName.IsEmpty())
|
||||||
oneMethodInfo.MethodName = kDefaultMethodName;
|
oneMethodInfo.MethodName = kDefaultMethodName;
|
||||||
|
|
||||||
if (IsLZMethod(oneMethodInfo.MethodName))
|
if (!IsCopyMethod(oneMethodInfo.MethodName))
|
||||||
|
needSolid = true;
|
||||||
|
|
||||||
|
if (IsLZMAMethod(oneMethodInfo.MethodName))
|
||||||
{
|
{
|
||||||
if (IsLZMAMethod(oneMethodInfo.MethodName))
|
UInt32 dicSize =
|
||||||
{
|
(level >= 9 ? kLzmaDicSizeX9 :
|
||||||
SetOneMethodProp(oneMethodInfo,
|
(level >= 7 ? kLzmaDicSizeX7 :
|
||||||
NCoderPropID::kDictionarySize, _defaultDicSize);
|
(level >= 5 ? kLzmaDicSizeX5 :
|
||||||
SetOneMethodProp(oneMethodInfo,
|
(level >= 3 ? kLzmaDicSizeX3 :
|
||||||
NCoderPropID::kAlgorithm, _defaultAlgorithm);
|
kLzmaDicSizeX1))));
|
||||||
SetOneMethodProp(oneMethodInfo,
|
|
||||||
NCoderPropID::kNumFastBytes, _defaultFastBytes);
|
UInt32 algorithm =
|
||||||
SetOneMethodProp(oneMethodInfo,
|
(level >= 5 ? kLzmaAlgorithmX5 :
|
||||||
NCoderPropID::kMatchFinder, (const wchar_t *)_defaultMatchFinder);
|
kLzmaAlgorithmX1);
|
||||||
if (multiThread)
|
|
||||||
SetOneMethodProp(oneMethodInfo,
|
UInt32 fastBytes =
|
||||||
NCoderPropID::kMultiThread, true);
|
(level >= 7 ? kLzmaFastBytesX7 :
|
||||||
}
|
kLzmaFastBytesX1);
|
||||||
|
|
||||||
|
const wchar_t *matchFinder =
|
||||||
|
(level >= 5 ? kLzmaMatchFinderX5 :
|
||||||
|
kLzmaMatchFinderX1);
|
||||||
|
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algorithm);
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (IsDeflateMethod(oneMethodInfo.MethodName))
|
||||||
|
{
|
||||||
|
UInt32 fastBytes =
|
||||||
|
(level >= 9 ? kDeflateFastBytesX9 :
|
||||||
|
(level >= 7 ? kDeflateFastBytesX7 :
|
||||||
|
kDeflateFastBytesX1));
|
||||||
|
|
||||||
|
UInt32 numPasses =
|
||||||
|
(level >= 9 ? kDeflatePassesX9 :
|
||||||
|
(level >= 7 ? kDeflatePassesX7 :
|
||||||
|
kDeflatePassesX1));
|
||||||
|
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
||||||
}
|
}
|
||||||
else if (IsBZip2Method(oneMethodInfo.MethodName))
|
else if (IsBZip2Method(oneMethodInfo.MethodName))
|
||||||
{
|
{
|
||||||
SetOneMethodProp(oneMethodInfo,
|
UInt32 numPasses =
|
||||||
NCoderPropID::kNumPasses, _defaultBZip2Passes);
|
(level >= 9 ? kBZip2NumPassesX9 :
|
||||||
|
(level >= 7 ? kBZip2NumPassesX7 :
|
||||||
|
kBZip2NumPassesX1));
|
||||||
|
|
||||||
|
UInt32 dicSize =
|
||||||
|
(level >= 5 ? kBZip2DicSizeX5 :
|
||||||
|
(level >= 3 ? kBZip2DicSizeX3 :
|
||||||
|
kBZip2DicSizeX1));
|
||||||
|
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (IsPpmdMethod(oneMethodInfo.MethodName))
|
||||||
|
{
|
||||||
|
UInt32 useMemSize =
|
||||||
|
(level >= 9 ? kPpmdMemSizeX9 :
|
||||||
|
(level >= 7 ? kPpmdMemSizeX7 :
|
||||||
|
(level >= 5 ? kPpmdMemSizeX5 :
|
||||||
|
kPpmdMemSizeX1)));
|
||||||
|
|
||||||
|
UInt32 order =
|
||||||
|
(level >= 9 ? kPpmdOrderX9 :
|
||||||
|
(level >= 7 ? kPpmdOrderX7 :
|
||||||
|
(level >= 5 ? kPpmdOrderX5 :
|
||||||
|
kPpmdOrderX1)));
|
||||||
|
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
|
||||||
|
SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -383,6 +504,30 @@ HRESULT CHandler::SetCompressionMethod(
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
methodMode.Methods.Add(methodFull);
|
methodMode.Methods.Add(methodFull);
|
||||||
|
|
||||||
|
if (!_numSolidBytesDefined)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < methodFull.CoderProperties.Size(); j++)
|
||||||
|
{
|
||||||
|
const CProperty &prop = methodFull.CoderProperties[j];
|
||||||
|
if ((prop.PropID == NCoderPropID::kDictionarySize ||
|
||||||
|
prop.PropID == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
|
||||||
|
{
|
||||||
|
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
|
||||||
|
const UInt64 kMinSize = (1 << 24);
|
||||||
|
if (_numSolidBytes < kMinSize)
|
||||||
|
_numSolidBytes = kMinSize;
|
||||||
|
_numSolidBytesDefined = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needSolid && !_numSolidBytesDefined)
|
||||||
|
{
|
||||||
|
_numSolidBytesDefined = true;
|
||||||
|
_numSolidBytes = 0;
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -414,7 +559,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
// CMyComPtr<IUpdateCallback2> updateCallback2;
|
// CMyComPtr<IUpdateCallback2> updateCallback2;
|
||||||
// updateCallback->QueryInterface(&updateCallback2);
|
// updateCallback->QueryInterface(&updateCallback2);
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for(UInt32 i = 0; i < numItems; i++)
|
for(UInt32 i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
Int32 newData;
|
Int32 newData;
|
||||||
@@ -546,35 +690,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
if (updateItem.Size != 0 && updateItem.IsAnti)
|
if (updateItem.Size != 0 && updateItem.IsAnti)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
else
|
|
||||||
thereIsCopyData = true;
|
|
||||||
*/
|
|
||||||
|
|
||||||
updateItems.Add(updateItem);
|
updateItems.Add(updateItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (thereIsCopyData)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < _database.NumUnPackStreamsVector.Size(); i++)
|
|
||||||
if (_database.NumUnPackStreamsVector[i] != 1)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
if (!_solidIsSpecified)
|
|
||||||
_solid = false;
|
|
||||||
if (_solid)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
CCompressionMethodMode methodMode, headerMethod;
|
CCompressionMethodMode methodMode, headerMethod;
|
||||||
RINOK(SetCompressionMethod(methodMode, headerMethod));
|
RINOK(SetCompressionMethod(methodMode, headerMethod));
|
||||||
methodMode.MultiThread = _multiThread;
|
#ifdef COMPRESS_MT
|
||||||
// methodMode.MultiThreadMult = _multiThreadMult;
|
methodMode.NumThreads = _numThreads;
|
||||||
|
headerMethod.NumThreads = 1;
|
||||||
headerMethod.MultiThread = false;
|
#endif
|
||||||
// headerMethod.MultiThreadMult = _multiThreadMult;
|
|
||||||
|
|
||||||
RINOK(SetPassword(methodMode, updateCallback));
|
RINOK(SetPassword(methodMode, updateCallback));
|
||||||
|
|
||||||
@@ -623,124 +747,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ParseStringToUInt32(const UString &srcString, UInt32 &number)
|
|
||||||
{
|
|
||||||
const wchar_t *start = srcString;
|
|
||||||
const wchar_t *end;
|
|
||||||
UInt64 number64 = ConvertStringToUInt64(start, &end);
|
|
||||||
if (number64 > 0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
number = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
number = (UInt32)number64;
|
|
||||||
return end - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int kLogarithmicSizeLimit = 32;
|
|
||||||
static const char kByteSymbol = 'B';
|
|
||||||
static const char kKiloByteSymbol = 'K';
|
|
||||||
static const char kMegaByteSymbol = 'M';
|
|
||||||
|
|
||||||
HRESULT ParseDictionaryValues(const UString &srcStringSpec, UInt32 &dicSize)
|
|
||||||
{
|
|
||||||
UString srcString = srcStringSpec;
|
|
||||||
srcString.MakeUpper();
|
|
||||||
|
|
||||||
const wchar_t *start = srcString;
|
|
||||||
const wchar_t *end;
|
|
||||||
UInt64 number = ConvertStringToUInt64(start, &end);
|
|
||||||
int numDigits = end - start;
|
|
||||||
if (numDigits == 0 || srcString.Length() > numDigits + 1)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
if (srcString.Length() == numDigits)
|
|
||||||
{
|
|
||||||
if (number >= kLogarithmicSizeLimit)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = (UInt32)1 << (int)number;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
switch (srcString[numDigits])
|
|
||||||
{
|
|
||||||
case kByteSymbol:
|
|
||||||
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = (UInt32)number;
|
|
||||||
break;
|
|
||||||
case kKiloByteSymbol:
|
|
||||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = UInt32(number << 10);
|
|
||||||
break;
|
|
||||||
case kMegaByteSymbol:
|
|
||||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = UInt32(number << 20);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline UINT GetCurrentFileCodePage()
|
|
||||||
{
|
|
||||||
return AreFileApisANSI() ? CP_ACP : CP_OEMCP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
|
|
||||||
{
|
|
||||||
switch(value.vt)
|
|
||||||
{
|
|
||||||
case VT_EMPTY:
|
|
||||||
dest = true;
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
case VT_UI4:
|
|
||||||
dest = (value.ulVal != 0);
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
case VT_BSTR:
|
|
||||||
{
|
|
||||||
UString valueString = value.bstrVal;
|
|
||||||
valueString.MakeUpper();
|
|
||||||
if (valueString.Compare(L"ON") == 0)
|
|
||||||
dest = true;
|
|
||||||
else if (valueString.Compare(L"OFF") == 0)
|
|
||||||
dest = false;
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static HRESULT SetComplexProperty(bool &boolStatus, UInt32 &number,
|
|
||||||
const PROPVARIANT &value)
|
|
||||||
{
|
|
||||||
switch(value.vt)
|
|
||||||
{
|
|
||||||
case VT_EMPTY:
|
|
||||||
case VT_BSTR:
|
|
||||||
{
|
|
||||||
RINOK(SetBoolProperty(boolStatus, value));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case VT_UI4:
|
|
||||||
boolStatus = true;
|
|
||||||
number = (value.ulVal);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
|
static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
|
||||||
{
|
{
|
||||||
stream = 0;
|
stream = 0;
|
||||||
@@ -820,7 +826,7 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
|
|||||||
if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
|
if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
|
||||||
{
|
{
|
||||||
UInt32 dicSize;
|
UInt32 dicSize;
|
||||||
RINOK(ParseDictionaryValues(value, dicSize));
|
RINOK(ParsePropDictionaryValue(value, dicSize));
|
||||||
if (name.CompareNoCase(L"D") == 0)
|
if (name.CompareNoCase(L"D") == 0)
|
||||||
property.PropID = NCoderPropID::kDictionarySize;
|
property.PropID = NCoderPropID::kDictionarySize;
|
||||||
else
|
else
|
||||||
@@ -901,7 +907,7 @@ HRESULT CHandler::SetSolidSettings(const UString &s)
|
|||||||
_solidExtension = true;
|
_solidExtension = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
i += end - start;
|
i += (int)(end - start);
|
||||||
if (i == s2.Length())
|
if (i == s2.Length())
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
wchar_t c = s2[i++];
|
wchar_t c = s2[i++];
|
||||||
@@ -951,11 +957,17 @@ HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value)
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||||
{
|
{
|
||||||
UINT codePage = GetCurrentFileCodePage();
|
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
_methods.Clear();
|
_methods.Clear();
|
||||||
_binds.Clear();
|
_binds.Clear();
|
||||||
Init();
|
Init();
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UInt32 mainDicSize = 0xFFFFFFFF;
|
||||||
|
UInt32 mainDicMethodIndex = 0xFFFFFFFF;
|
||||||
|
|
||||||
UInt32 minNumber = 0;
|
UInt32 minNumber = 0;
|
||||||
|
|
||||||
for (int i = 0; i < numProperties; i++)
|
for (int i = 0; i < numProperties; i++)
|
||||||
@@ -971,55 +983,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
{
|
{
|
||||||
name.Delete(0);
|
name.Delete(0);
|
||||||
_level = 9;
|
_level = 9;
|
||||||
if (value.vt == VT_UI4)
|
RINOK(ParsePropValue(name, value, _level));
|
||||||
{
|
|
||||||
if (!name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
_level = value.ulVal;
|
|
||||||
}
|
|
||||||
else if (value.vt == VT_EMPTY)
|
|
||||||
{
|
|
||||||
if(!name.IsEmpty())
|
|
||||||
{
|
|
||||||
int index = ParseStringToUInt32(name, _level);
|
|
||||||
if (index != name.Length())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
if (_level == 0)
|
|
||||||
{
|
|
||||||
_copyMode = true;
|
|
||||||
_defaultBZip2Passes = 1;
|
|
||||||
}
|
|
||||||
else if (_level < 5)
|
|
||||||
{
|
|
||||||
_defaultAlgorithm = kAlgorithmForFast;
|
|
||||||
_defaultDicSize = kDicSizeForFast;
|
|
||||||
_defaultMatchFinder = kMatchFinderForFast;
|
|
||||||
_defaultBZip2Passes = 1;
|
|
||||||
}
|
|
||||||
else if (_level < 7)
|
|
||||||
{
|
|
||||||
_defaultBZip2Passes = 1;
|
|
||||||
// normal;
|
|
||||||
}
|
|
||||||
else if(_level < 9)
|
|
||||||
{
|
|
||||||
_defaultAlgorithm = kAlgorithmForX7;
|
|
||||||
_defaultDicSize = kDicSizeForX7;
|
|
||||||
_defaultFastBytes = kFastBytesForX7;
|
|
||||||
_defaultBZip2Passes = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_defaultAlgorithm = kAlgorithmForX9;
|
|
||||||
_defaultDicSize = kDicSizeForX9;
|
|
||||||
_defaultFastBytes = kFastBytesForX9;
|
|
||||||
_defaultMatchFinder = kMatchFinderForX9;
|
|
||||||
_defaultBZip2Passes = 7;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1052,7 +1016,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
UString realName = name.Mid(index);
|
UString realName = name.Mid(index);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
{
|
{
|
||||||
if (name.CompareNoCase(L"RSFX") == 0)
|
if(name.Left(2).CompareNoCase(L"MT") == 0)
|
||||||
|
{
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (name.CompareNoCase(L"RSFX") == 0)
|
||||||
{
|
{
|
||||||
RINOK(SetBoolProperty(_removeSfxBlock, value));
|
RINOK(SetBoolProperty(_removeSfxBlock, value));
|
||||||
continue;
|
continue;
|
||||||
@@ -1077,13 +1048,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
RINOK(SetBoolProperty(_encryptHeaders, value));
|
RINOK(SetBoolProperty(_encryptHeaders, value));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (name.CompareNoCase(L"MT") == 0)
|
|
||||||
{
|
|
||||||
// _multiThreadMult = 200;
|
|
||||||
RINOK(SetBoolProperty(_multiThread, value));
|
|
||||||
// RINOK(SetComplexProperty(MultiThread, _multiThreadMult, value));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (name.CompareNoCase(L"V") == 0)
|
else if (name.CompareNoCase(L"V") == 0)
|
||||||
{
|
{
|
||||||
RINOK(SetBoolProperty(_volumeMode, value));
|
RINOK(SetBoolProperty(_volumeMode, value));
|
||||||
@@ -1115,28 +1079,25 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CProperty property;
|
CProperty property;
|
||||||
if (realName.CompareNoCase(L"D") == 0 || realName.CompareNoCase(L"MEM") == 0)
|
if (realName.Left(1).CompareNoCase(L"D") == 0)
|
||||||
{
|
{
|
||||||
UInt32 dicSize;
|
UInt32 dicSize;
|
||||||
if (value.vt == VT_UI4)
|
RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
|
||||||
{
|
property.PropID = NCoderPropID::kDictionarySize;
|
||||||
UInt32 logDicSize = value.ulVal;
|
|
||||||
if (logDicSize >= 32)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = (UInt32)1 << logDicSize;
|
|
||||||
}
|
|
||||||
else if (value.vt == VT_BSTR)
|
|
||||||
{
|
|
||||||
RINOK(ParseDictionaryValues(value.bstrVal, dicSize));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_FAIL;
|
|
||||||
if (realName.CompareNoCase(L"D") == 0)
|
|
||||||
property.PropID = NCoderPropID::kDictionarySize;
|
|
||||||
else
|
|
||||||
property.PropID = NCoderPropID::kUsedMemorySize;
|
|
||||||
property.Value = dicSize;
|
property.Value = dicSize;
|
||||||
oneMethodInfo.CoderProperties.Add(property);
|
oneMethodInfo.CoderProperties.Add(property);
|
||||||
|
if (number <= mainDicMethodIndex)
|
||||||
|
mainDicSize = dicSize;
|
||||||
|
}
|
||||||
|
else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
|
||||||
|
{
|
||||||
|
UInt32 dicSize;
|
||||||
|
RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
|
||||||
|
property.PropID = NCoderPropID::kUsedMemorySize;
|
||||||
|
property.Value = dicSize;
|
||||||
|
oneMethodInfo.CoderProperties.Add(property);
|
||||||
|
if (number <= mainDicMethodIndex)
|
||||||
|
mainDicSize = dicSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1154,7 +1115,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CheckAndSetSolidBytesLimit();
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "7zMethods.h"
|
#include "7zMethods.h"
|
||||||
#include "7zDecode.h"
|
#include "7zDecode.h"
|
||||||
#include "../../Common/StreamObjects.h"
|
#include "../../Common/StreamObjects.h"
|
||||||
|
#include "../../Common/StreamUtils.h"
|
||||||
#include "../../../Common/CRC.h"
|
#include "../../../Common/CRC.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
@@ -69,7 +70,7 @@ HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size,
|
|||||||
UInt32 *processedSize)
|
UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
UInt32 realProcessedSize;
|
UInt32 realProcessedSize;
|
||||||
HRESULT result = stream->Read(data, size, &realProcessedSize);
|
HRESULT result = ReadStream(stream, data, size, &realProcessedSize);
|
||||||
if(processedSize != NULL)
|
if(processedSize != NULL)
|
||||||
*processedSize = realProcessedSize;
|
*processedSize = realProcessedSize;
|
||||||
_position += realProcessedSize;
|
_position += realProcessedSize;
|
||||||
@@ -850,7 +851,13 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
|
|||||||
// database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
|
// database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
|
||||||
|
|
||||||
CNum packIndex = 0;
|
CNum packIndex = 0;
|
||||||
CDecoder decoder(false);
|
CDecoder decoder(
|
||||||
|
#ifdef _ST_MODE
|
||||||
|
false
|
||||||
|
#else
|
||||||
|
true
|
||||||
|
#endif
|
||||||
|
);
|
||||||
UInt64 dataStartPos = baseOffset + dataOffset;
|
UInt64 dataStartPos = baseOffset + dataOffset;
|
||||||
for(int i = 0; i < folders.Size(); i++)
|
for(int i = 0; i < folders.Size(); i++)
|
||||||
{
|
{
|
||||||
@@ -873,6 +880,9 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
|
|||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
, false, 1
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
|
|
||||||
@@ -969,7 +979,7 @@ HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database
|
|||||||
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
|
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
|
||||||
|
|
||||||
CBoolVector emptyStreamVector;
|
CBoolVector emptyStreamVector;
|
||||||
emptyStreamVector.Reserve((size_t)numFiles);
|
emptyStreamVector.Reserve((int)numFiles);
|
||||||
for(i = 0; i < numFiles; i++)
|
for(i = 0; i < numFiles; i++)
|
||||||
emptyStreamVector.Add(false);
|
emptyStreamVector.Add(false);
|
||||||
CBoolVector emptyFileVector;
|
CBoolVector emptyFileVector;
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
|||||||
CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
|
CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
|
||||||
if (folderIndex >= 0)
|
if (folderIndex >= 0)
|
||||||
{
|
{
|
||||||
const CFolder &folderInfo = Folders[folderIndex];
|
|
||||||
if (FolderStartFileIndex[folderIndex] == fileIndex)
|
if (FolderStartFileIndex[folderIndex] == fileIndex)
|
||||||
return GetFolderFullPackSize(folderIndex);
|
return GetFolderFullPackSize(folderIndex);
|
||||||
}
|
}
|
||||||
@@ -244,7 +243,7 @@ private:
|
|||||||
CRecordVector<bool> &digestsDefined,
|
CRecordVector<bool> &digestsDefined,
|
||||||
CRecordVector<UInt32> &digests);
|
CRecordVector<UInt32> &digests);
|
||||||
|
|
||||||
HRESULT CInArchive::ReadStreamsInfo(
|
HRESULT ReadStreamsInfo(
|
||||||
const CObjectVector<CByteBuffer> *dataVector,
|
const CObjectVector<CByteBuffer> *dataVector,
|
||||||
UInt64 &dataOffset,
|
UInt64 &dataOffset,
|
||||||
CRecordVector<UInt64> &packSizes,
|
CRecordVector<UInt64> &packSizes,
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
|
|||||||
for(int i = 0; i < g_Methods.Size(); i++)
|
for(int i = 0; i < g_Methods.Size(); i++)
|
||||||
{
|
{
|
||||||
const CMethodInfo2 &method = g_Methods[i];
|
const CMethodInfo2 &method = g_Methods[i];
|
||||||
if (method.Name.CollateNoCase(name) == 0)
|
if (method.Name.CompareNoCase(name) == 0)
|
||||||
{
|
{
|
||||||
methodInfo = method;
|
methodInfo = method;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t
|
|||||||
{
|
{
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
UInt32 curSize = (UInt32)(MyMin(size, (size_t)0xFFFFFFFF));
|
UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);
|
||||||
UInt32 processedSize;
|
UInt32 processedSize;
|
||||||
RINOK(stream->WritePart(data, curSize, &processedSize));
|
RINOK(stream->Write(data, curSize, &processedSize));
|
||||||
if(processedSize == 0 || processedSize > curSize)
|
if(processedSize == 0)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
data = (const void *)((const Byte *)data + processedSize);
|
data = (const void *)((const Byte *)data + processedSize);
|
||||||
size -= processedSize;
|
size -= processedSize;
|
||||||
@@ -111,7 +111,10 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
|
|||||||
{
|
{
|
||||||
SeqStream.QueryInterface(IID_IOutStream, &Stream);
|
SeqStream.QueryInterface(IID_IOutStream, &Stream);
|
||||||
if (!Stream)
|
if (!Stream)
|
||||||
endMarker = true;
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
// endMarker = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
if (endMarker)
|
if (endMarker)
|
||||||
@@ -573,8 +576,8 @@ HRESULT COutArchive::EncodeStream(CEncoder &encoder, const Byte *data, size_t da
|
|||||||
CFolder folderItem;
|
CFolder folderItem;
|
||||||
folderItem.UnPackCRCDefined = true;
|
folderItem.UnPackCRCDefined = true;
|
||||||
folderItem.UnPackCRC = CCRC::CalculateDigest(data, dataSize);
|
folderItem.UnPackCRC = CCRC::CalculateDigest(data, dataSize);
|
||||||
RINOK(encoder.Encode(stream, NULL, folderItem, SeqStream,
|
UInt64 dataSize64 = dataSize;
|
||||||
packSizes, NULL));
|
RINOK(encoder.Encode(stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL));
|
||||||
folders.Add(folderItem);
|
folders.Add(folderItem);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,16 +14,6 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
|
|
||||||
_size += realProcessedSize;
|
|
||||||
if (processedSize != 0)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
|
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
|
||||||
UInt64 subStream, UInt64 *value)
|
UInt64 subStream, UInt64 *value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ public:
|
|||||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||||
|
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
|
|
||||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -73,11 +73,19 @@ static HRESULT WriteRange(IInStream *inStream,
|
|||||||
size, progress, currentComplexity);
|
size, progress, currentComplexity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int GetReverseSlashPos(const UString &name)
|
||||||
|
{
|
||||||
|
int slashPos = name.ReverseFind(L'/');
|
||||||
|
#ifdef _WIN32
|
||||||
|
int slash1Pos = name.ReverseFind(L'\\');
|
||||||
|
slashPos = MyMax(slashPos, slash1Pos);
|
||||||
|
#endif
|
||||||
|
return slashPos;
|
||||||
|
}
|
||||||
|
|
||||||
int CUpdateItem::GetExtensionPos() const
|
int CUpdateItem::GetExtensionPos() const
|
||||||
{
|
{
|
||||||
int slash1Pos = Name.ReverseFind(L'\\');
|
int slashPos = GetReverseSlashPos(Name);
|
||||||
int slash2Pos = Name.ReverseFind(L'/');
|
|
||||||
int slashPos = MyMax(slash1Pos, slash2Pos);
|
|
||||||
int dotPos = Name.ReverseFind(L'.');
|
int dotPos = Name.ReverseFind(L'.');
|
||||||
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
|
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
|
||||||
return Name.Length();
|
return Name.Length();
|
||||||
@@ -89,11 +97,13 @@ UString CUpdateItem::GetExtension() const
|
|||||||
return Name.Mid(GetExtensionPos());
|
return Name.Mid(GetExtensionPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
struct CFolderRef
|
struct CFolderRef
|
||||||
{
|
{
|
||||||
const CArchiveDatabaseEx *Database;
|
const CArchiveDatabaseEx *Database;
|
||||||
int FolderIndex;
|
int FolderIndex;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
||||||
|
|
||||||
@@ -106,10 +116,10 @@ static int CompareMethodIDs(const CMethodID &a1, const CMethodID &a2)
|
|||||||
|
|
||||||
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
|
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
|
||||||
{
|
{
|
||||||
int c1 = a1.GetCapacity();
|
size_t c1 = a1.GetCapacity();
|
||||||
int c2 = a2.GetCapacity();
|
size_t c2 = a2.GetCapacity();
|
||||||
RINOZ(MyCompare(c1, c2));
|
RINOZ(MyCompare(c1, c2));
|
||||||
for (int i = 0; i < c1; i++)
|
for (size_t i = 0; i < c1; i++)
|
||||||
RINOZ(MyCompare(a1[i], a2[i]));
|
RINOZ(MyCompare(a1[i], a2[i]));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -156,34 +166,34 @@ static int CompareFolders(const CFolder &f1, const CFolder &f2)
|
|||||||
|
|
||||||
static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
|
static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
|
||||||
{
|
{
|
||||||
return MyStringCollateNoCase(f1.Name, f2.Name);
|
return MyStringCompareNoCase(f1.Name, f2.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __cdecl CompareFolderRefs(const void *p1, const void *p2)
|
static int CompareFolderRefs(const int *p1, const int *p2, void *param)
|
||||||
{
|
{
|
||||||
const CFolderRef &a1 = *((const CFolderRef *)p1);
|
int i1 = *p1;
|
||||||
const CFolderRef &a2 = *((const CFolderRef *)p2);
|
int i2 = *p2;
|
||||||
const CArchiveDatabaseEx &d1 = *a1.Database;
|
const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
|
||||||
const CArchiveDatabaseEx &d2 = *a2.Database;
|
|
||||||
RINOZ(CompareFolders(
|
RINOZ(CompareFolders(
|
||||||
d1.Folders[a1.FolderIndex],
|
db.Folders[i1],
|
||||||
d2.Folders[a2.FolderIndex]));
|
db.Folders[i2]));
|
||||||
RINOZ(MyCompare(
|
RINOZ(MyCompare(
|
||||||
d1.NumUnPackStreamsVector[a1.FolderIndex],
|
db.NumUnPackStreamsVector[i1],
|
||||||
d2.NumUnPackStreamsVector[a2.FolderIndex]));
|
db.NumUnPackStreamsVector[i2]));
|
||||||
if (d1.NumUnPackStreamsVector[a1.FolderIndex] == 0)
|
if (db.NumUnPackStreamsVector[i1] == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return CompareFiles(
|
return CompareFiles(
|
||||||
d1.Files[(size_t)d1.FolderStartFileIndex[a1.FolderIndex]],
|
db.Files[db.FolderStartFileIndex[i1]],
|
||||||
d2.Files[(size_t)d2.FolderStartFileIndex[a2.FolderIndex]]);
|
db.Files[db.FolderStartFileIndex[i2]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int __cdecl CompareEmptyItems(const void *p1, const void *p2)
|
static int CompareEmptyItems(const int *p1, const int *p2, void *param)
|
||||||
{
|
{
|
||||||
const CUpdateItem &u1 = **((CUpdateItem **)p1);
|
const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
|
||||||
const CUpdateItem &u2 = **((CUpdateItem **)p2);
|
const CUpdateItem &u1 = updateItems[*p1];
|
||||||
|
const CUpdateItem &u2 = updateItems[*p2];
|
||||||
if (u1.IsDirectory != u2.IsDirectory)
|
if (u1.IsDirectory != u2.IsDirectory)
|
||||||
{
|
{
|
||||||
if (u1.IsDirectory)
|
if (u1.IsDirectory)
|
||||||
@@ -194,12 +204,12 @@ static int __cdecl CompareEmptyItems(const void *p1, const void *p2)
|
|||||||
{
|
{
|
||||||
if (u1.IsAnti != u2.IsAnti)
|
if (u1.IsAnti != u2.IsAnti)
|
||||||
return (u1.IsAnti ? 1 : -1);
|
return (u1.IsAnti ? 1 : -1);
|
||||||
int n = MyStringCollateNoCase(u1.Name, u2.Name);
|
int n = MyStringCompareNoCase(u1.Name, u2.Name);
|
||||||
return (u1.IsAnti ? (-n) : n);
|
return (u1.IsAnti ? (-n) : n);
|
||||||
}
|
}
|
||||||
if (u1.IsAnti != u2.IsAnti)
|
if (u1.IsAnti != u2.IsAnti)
|
||||||
return (u1.IsAnti ? 1 : -1);
|
return (u1.IsAnti ? 1 : -1);
|
||||||
return MyStringCollateNoCase(u1.Name, u2.Name);
|
return MyStringCompareNoCase(u1.Name, u2.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CRefItem
|
struct CRefItem
|
||||||
@@ -218,9 +228,7 @@ struct CRefItem
|
|||||||
{
|
{
|
||||||
if (sortByType)
|
if (sortByType)
|
||||||
{
|
{
|
||||||
int slash1Pos = updateItem.Name.ReverseFind(L'\\');
|
int slashPos = GetReverseSlashPos(updateItem.Name);
|
||||||
int slash2Pos = updateItem.Name.ReverseFind(L'/');
|
|
||||||
int slashPos = MyMax(slash1Pos, slash2Pos);
|
|
||||||
if (slashPos >= 0)
|
if (slashPos >= 0)
|
||||||
NamePos = slashPos + 1;
|
NamePos = slashPos + 1;
|
||||||
else
|
else
|
||||||
@@ -234,10 +242,10 @@ struct CRefItem
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __cdecl CompareUpdateItems(const void *p1, const void *p2)
|
static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
|
||||||
{
|
{
|
||||||
const CRefItem &a1 = *((CRefItem *)p1);
|
const CRefItem &a1 = *p1;
|
||||||
const CRefItem &a2 = *((CRefItem *)p2);
|
const CRefItem &a2 = *p2;
|
||||||
const CUpdateItem &u1 = *a1.UpdateItem;
|
const CUpdateItem &u1 = *a1.UpdateItem;
|
||||||
const CUpdateItem &u2 = *a2.UpdateItem;
|
const CUpdateItem &u2 = *a2.UpdateItem;
|
||||||
int n;
|
int n;
|
||||||
@@ -251,18 +259,18 @@ static int __cdecl CompareUpdateItems(const void *p1, const void *p2)
|
|||||||
{
|
{
|
||||||
if (u1.IsAnti != u2.IsAnti)
|
if (u1.IsAnti != u2.IsAnti)
|
||||||
return (u1.IsAnti ? 1 : -1);
|
return (u1.IsAnti ? 1 : -1);
|
||||||
n = MyStringCollateNoCase(u1.Name, u2.Name);
|
n = MyStringCompareNoCase(u1.Name, u2.Name);
|
||||||
return (u1.IsAnti ? (-n) : n);
|
return (u1.IsAnti ? (-n) : n);
|
||||||
}
|
}
|
||||||
if (a1.SortByType)
|
if (a1.SortByType)
|
||||||
{
|
{
|
||||||
RINOZ(MyStringCollateNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
|
RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
|
||||||
RINOZ(MyStringCollateNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
|
RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
|
||||||
if (u1.LastWriteTimeIsDefined && u2.LastWriteTimeIsDefined)
|
if (u1.LastWriteTimeIsDefined && u2.LastWriteTimeIsDefined)
|
||||||
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
|
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
|
||||||
RINOZ(MyCompare(u1.Size, u2.Size))
|
RINOZ(MyCompare(u1.Size, u2.Size))
|
||||||
}
|
}
|
||||||
return MyStringCollateNoCase(u1.Name, u2.Name);
|
return MyStringCompareNoCase(u1.Name, u2.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CSolidGroup
|
struct CSolidGroup
|
||||||
@@ -455,7 +463,7 @@ static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
|
|||||||
static HRESULT Update2(
|
static HRESULT Update2(
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
const CArchiveDatabaseEx *database,
|
const CArchiveDatabaseEx *database,
|
||||||
CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
ISequentialOutStream *seqOutStream,
|
ISequentialOutStream *seqOutStream,
|
||||||
IArchiveUpdateCallback *updateCallback,
|
IArchiveUpdateCallback *updateCallback,
|
||||||
const CUpdateOptions &options)
|
const CUpdateOptions &options)
|
||||||
@@ -496,38 +504,32 @@ static HRESULT Update2(
|
|||||||
fileIndexToUpdateIndexMap[index] = i;
|
fileIndexToUpdateIndexMap[index] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
CRecordVector<CFolderRef> folderRefs;
|
CRecordVector<int> folderRefs;
|
||||||
if (database != 0)
|
if (database != 0)
|
||||||
{
|
{
|
||||||
for(i = 0; i < database->Folders.Size(); i++)
|
for(i = 0; i < database->Folders.Size(); i++)
|
||||||
{
|
|
||||||
CNum indexInFolder = 0;
|
|
||||||
CNum numCopyItems = 0;
|
|
||||||
CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
|
|
||||||
for (CNum fileIndex = database->FolderStartFileIndex[i];
|
|
||||||
indexInFolder < numUnPackStreams; fileIndex++)
|
|
||||||
{
|
{
|
||||||
if (database->Files[fileIndex].HasStream)
|
CNum indexInFolder = 0;
|
||||||
|
CNum numCopyItems = 0;
|
||||||
|
CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
|
||||||
|
for (CNum fileIndex = database->FolderStartFileIndex[i];
|
||||||
|
indexInFolder < numUnPackStreams; fileIndex++)
|
||||||
{
|
{
|
||||||
indexInFolder++;
|
if (database->Files[fileIndex].HasStream)
|
||||||
int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
|
{
|
||||||
if (updateIndex >= 0)
|
indexInFolder++;
|
||||||
if (!updateItems[updateIndex].NewData)
|
int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
|
||||||
numCopyItems++;
|
if (updateIndex >= 0)
|
||||||
|
if (!updateItems[updateIndex].NewData)
|
||||||
|
numCopyItems++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (numCopyItems != numUnPackStreams && numCopyItems != 0)
|
||||||
|
return E_NOTIMPL; // It needs repacking !!!
|
||||||
|
if (numCopyItems > 0)
|
||||||
|
folderRefs.Add(i);
|
||||||
}
|
}
|
||||||
if (numCopyItems != numUnPackStreams && numCopyItems != 0)
|
folderRefs.Sort(CompareFolderRefs, (void *)database);
|
||||||
return E_NOTIMPL; // It needs repacking !!!
|
|
||||||
if (numCopyItems > 0)
|
|
||||||
{
|
|
||||||
CFolderRef folderRef;
|
|
||||||
folderRef.Database = database;
|
|
||||||
folderRef.FolderIndex = i;
|
|
||||||
folderRefs.Add(folderRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qsort(&folderRefs.Front(), folderRefs.Size(), sizeof(folderRefs[0]),
|
|
||||||
CompareFolderRefs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CArchiveDatabase newDatabase;
|
CArchiveDatabase newDatabase;
|
||||||
@@ -535,7 +537,7 @@ static HRESULT Update2(
|
|||||||
/////////////////////////////////////////
|
/////////////////////////////////////////
|
||||||
// Write Empty Files & Folders
|
// Write Empty Files & Folders
|
||||||
|
|
||||||
CRecordVector<const CUpdateItem *> emptyRefs;
|
CRecordVector<int> emptyRefs;
|
||||||
for(i = 0; i < updateItems.Size(); i++)
|
for(i = 0; i < updateItems.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[i];
|
const CUpdateItem &updateItem = updateItems[i];
|
||||||
@@ -548,13 +550,12 @@ static HRESULT Update2(
|
|||||||
if (updateItem.IndexInArchive != -1)
|
if (updateItem.IndexInArchive != -1)
|
||||||
if (database->Files[updateItem.IndexInArchive].HasStream)
|
if (database->Files[updateItem.IndexInArchive].HasStream)
|
||||||
continue;
|
continue;
|
||||||
emptyRefs.Add(&updateItem);
|
emptyRefs.Add(i);
|
||||||
}
|
}
|
||||||
qsort(&emptyRefs.Front(), emptyRefs.Size(), sizeof(emptyRefs[0]),
|
emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
|
||||||
CompareEmptyItems);
|
|
||||||
for(i = 0; i < emptyRefs.Size(); i++)
|
for(i = 0; i < emptyRefs.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = *emptyRefs[i];
|
const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
|
||||||
CFileItem file;
|
CFileItem file;
|
||||||
if (updateItem.NewProperties)
|
if (updateItem.NewProperties)
|
||||||
FromUpdateItemToFileItem(updateItem, file);
|
FromUpdateItemToFileItem(updateItem, file);
|
||||||
@@ -566,16 +567,26 @@ static HRESULT Update2(
|
|||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
|
||||||
COutArchive archive;
|
COutArchive archive;
|
||||||
archive.Create(seqOutStream, false);
|
RINOK(archive.Create(seqOutStream, false));
|
||||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
RINOK(archive.SkeepPrefixArchiveHeader());
|
||||||
UInt64 complexity = 0;
|
UInt64 complexity = 0;
|
||||||
for(i = 0; i < folderRefs.Size(); i++)
|
for(i = 0; i < folderRefs.Size(); i++)
|
||||||
complexity += database->GetFolderFullPackSize(folderRefs[i].FolderIndex);
|
complexity += database->GetFolderFullPackSize(folderRefs[i]);
|
||||||
|
UInt64 inSizeForReduce = 0;
|
||||||
for(i = 0; i < updateItems.Size(); i++)
|
for(i = 0; i < updateItems.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[i];
|
const CUpdateItem &updateItem = updateItems[i];
|
||||||
if (updateItem.NewData)
|
if (updateItem.NewData)
|
||||||
|
{
|
||||||
complexity += updateItem.Size;
|
complexity += updateItem.Size;
|
||||||
|
if (numSolidFiles == 1)
|
||||||
|
{
|
||||||
|
if (updateItem.Size > inSizeForReduce)
|
||||||
|
inSizeForReduce = updateItem.Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inSizeForReduce += updateItem.Size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RINOK(updateCallback->SetTotal(complexity));
|
RINOK(updateCallback->SetTotal(complexity));
|
||||||
complexity = 0;
|
complexity = 0;
|
||||||
@@ -586,7 +597,7 @@ static HRESULT Update2(
|
|||||||
|
|
||||||
for(i = 0; i < folderRefs.Size(); i++)
|
for(i = 0; i < folderRefs.Size(); i++)
|
||||||
{
|
{
|
||||||
int folderIndex = folderRefs[i].FolderIndex;
|
int folderIndex = folderRefs[i];
|
||||||
|
|
||||||
RINOK(WriteRange(inStream, archive.SeqStream,
|
RINOK(WriteRange(inStream, archive.SeqStream,
|
||||||
database->GetFolderStreamPos(folderIndex, 0),
|
database->GetFolderStreamPos(folderIndex, 0),
|
||||||
@@ -641,6 +652,10 @@ static HRESULT Update2(
|
|||||||
SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
|
SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
|
||||||
updateItems, groups);
|
updateItems, groups);
|
||||||
|
|
||||||
|
const UInt32 kMinReduceSize = (1 << 16);
|
||||||
|
if (inSizeForReduce < kMinReduceSize)
|
||||||
|
inSizeForReduce = kMinReduceSize;
|
||||||
|
|
||||||
for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++)
|
for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++)
|
||||||
{
|
{
|
||||||
const CSolidGroup &group = groups[groupIndex];
|
const CSolidGroup &group = groups[groupIndex];
|
||||||
@@ -652,7 +667,7 @@ static HRESULT Update2(
|
|||||||
for (i = 0; i < numFiles; i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
refItems.Add(CRefItem(group.Indices[i],
|
refItems.Add(CRefItem(group.Indices[i],
|
||||||
updateItems[group.Indices[i]], numSolidFiles > 1));
|
updateItems[group.Indices[i]], numSolidFiles > 1));
|
||||||
qsort(&refItems.Front(), refItems.Size(), sizeof(refItems[0]), CompareUpdateItems);
|
refItems.Sort(CompareUpdateItems, 0);
|
||||||
|
|
||||||
CRecordVector<UInt32> indices;
|
CRecordVector<UInt32> indices;
|
||||||
indices.Reserve(numFiles);
|
indices.Reserve(numFiles);
|
||||||
@@ -694,7 +709,7 @@ static HRESULT Update2(
|
|||||||
if (numSubFiles == 0)
|
if (numSubFiles == 0)
|
||||||
prevExtension = ext;
|
prevExtension = ext;
|
||||||
else
|
else
|
||||||
if (ext.CollateNoCase(prevExtension) != 0)
|
if (ext.CompareNoCase(prevExtension) != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -713,7 +728,7 @@ static HRESULT Update2(
|
|||||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||||
|
|
||||||
RINOK(encoder.Encode(solidInStream, NULL, folderItem,
|
RINOK(encoder.Encode(solidInStream, NULL, &inSizeForReduce, folderItem,
|
||||||
archive.SeqStream, newDatabase.PackSizes, compressProgress));
|
archive.SeqStream, newDatabase.PackSizes, compressProgress));
|
||||||
// for()
|
// for()
|
||||||
// newDatabase.PackCRCsDefined.Add(false);
|
// newDatabase.PackCRCsDefined.Add(false);
|
||||||
@@ -862,7 +877,7 @@ HRESULT UpdateVolume(
|
|||||||
RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
|
RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
|
||||||
|
|
||||||
COutArchive archive;
|
COutArchive archive;
|
||||||
archive.Create(volumeStream, true);
|
RINOK(archive.Create(volumeStream, true));
|
||||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
RINOK(archive.SkeepPrefixArchiveHeader());
|
||||||
|
|
||||||
CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
|
CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
|
||||||
@@ -914,7 +929,6 @@ public:
|
|||||||
|
|
||||||
HRESULT Flush();
|
HRESULT Flush();
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT COutVolumeStream::Flush()
|
HRESULT COutVolumeStream::Flush()
|
||||||
@@ -943,7 +957,7 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc
|
|||||||
RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
|
RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
|
||||||
_volIndex++;
|
_volIndex++;
|
||||||
_curPos = 0;
|
_curPos = 0;
|
||||||
_archive.Create(_volumeStream, true);
|
RINOK(_archive.Create(_volumeStream, true));
|
||||||
RINOK(_archive.SkeepPrefixArchiveHeader());
|
RINOK(_archive.SkeepPrefixArchiveHeader());
|
||||||
_crc.Init();
|
_crc.Init();
|
||||||
continue;
|
continue;
|
||||||
@@ -959,7 +973,7 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc
|
|||||||
if(processedSize != NULL)
|
if(processedSize != NULL)
|
||||||
*processedSize += realProcessed;
|
*processedSize += realProcessed;
|
||||||
_curPos += realProcessed;
|
_curPos += realProcessed;
|
||||||
if (realProcessed != curSize)
|
if (realProcessed != curSize && realProcessed == 0)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
if (_curPos == pureSize)
|
if (_curPos == pureSize)
|
||||||
{
|
{
|
||||||
@@ -969,16 +983,12 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP COutVolumeStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
return Write(data, size, processedSize);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HRESULT Update(
|
HRESULT Update(
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
const CArchiveDatabaseEx *database,
|
const CArchiveDatabaseEx *database,
|
||||||
CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
ISequentialOutStream *seqOutStream,
|
ISequentialOutStream *seqOutStream,
|
||||||
IArchiveUpdateCallback *updateCallback,
|
IArchiveUpdateCallback *updateCallback,
|
||||||
const CUpdateOptions &options)
|
const CUpdateOptions &options)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ struct CUpdateOptions
|
|||||||
HRESULT Update(
|
HRESULT Update(
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
const CArchiveDatabaseEx *database,
|
const CArchiveDatabaseEx *database,
|
||||||
CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
ISequentialOutStream *seqOutStream,
|
ISequentialOutStream *seqOutStream,
|
||||||
IArchiveUpdateCallback *updateCallback,
|
IArchiveUpdateCallback *updateCallback,
|
||||||
const CUpdateOptions &options);
|
const CUpdateOptions &options);
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
#include "../../../Common/MyInitGuid.h"
|
#include "../../../Common/MyInitGuid.h"
|
||||||
#include "../../../Common/ComTry.h"
|
#include "../../../Common/ComTry.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "../../../Common/Alloc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
#include "../../ICoder.h"
|
||||||
|
|
||||||
@@ -18,12 +21,32 @@ DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
HINSTANCE g_hInstance;
|
HINSTANCE g_hInstance;
|
||||||
|
#ifndef _UNICODE
|
||||||
|
bool g_IsNT = false;
|
||||||
|
static bool IsItWindowsNT()
|
||||||
|
{
|
||||||
|
OSVERSIONINFO versionInfo;
|
||||||
|
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
||||||
|
if (!::GetVersionEx(&versionInfo))
|
||||||
|
return false;
|
||||||
|
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||||
{
|
{
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
if (dwReason == DLL_PROCESS_ATTACH)
|
||||||
|
{
|
||||||
g_hInstance = hInstance;
|
g_hInstance = hInstance;
|
||||||
|
#ifndef _UNICODE
|
||||||
|
g_IsNT = IsItWindowsNT();
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
SetLargePageSize();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
#define __STDAFX_H
|
#define __STDAFX_H
|
||||||
|
|
||||||
#include "../../../Common/MyWindows.h"
|
#include "../../../Common/MyWindows.h"
|
||||||
|
#include "../../../Common/NewHandler.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
89
7zip/Archive/7z/makefile
Executable file
89
7zip/Archive/7z/makefile
Executable file
@@ -0,0 +1,89 @@
|
|||||||
|
PROG = 7z.dll
|
||||||
|
DEF_FILE = ../Archive.def
|
||||||
|
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
|
||||||
|
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||||
|
|
||||||
|
7Z_OBJS = \
|
||||||
|
$O\7zCompressionMode.obj \
|
||||||
|
$O\7zDecode.obj \
|
||||||
|
$O\7zEncode.obj \
|
||||||
|
$O\7zExtract.obj \
|
||||||
|
$O\7zFolderInStream.obj \
|
||||||
|
$O\7zFolderOutStream.obj \
|
||||||
|
$O\7zHandler.obj \
|
||||||
|
$O\7zHandlerOut.obj \
|
||||||
|
$O\7zHeader.obj \
|
||||||
|
$O\7zIn.obj \
|
||||||
|
$O\7zMethodID.obj \
|
||||||
|
$O\7zMethods.obj \
|
||||||
|
$O\7zOut.obj \
|
||||||
|
$O\7zProperties.obj \
|
||||||
|
$O\7zSpecStream.obj \
|
||||||
|
$O\7zUpdate.obj \
|
||||||
|
$O\DllExports.obj \
|
||||||
|
|
||||||
|
COMMON_OBJS = \
|
||||||
|
$O\Alloc.obj \
|
||||||
|
$O\CRC.obj \
|
||||||
|
$O\IntToString.obj \
|
||||||
|
$O\NewHandler.obj \
|
||||||
|
$O\String.obj \
|
||||||
|
$O\StringConvert.obj \
|
||||||
|
$O\StringToInt.obj \
|
||||||
|
$O\Vector.obj \
|
||||||
|
|
||||||
|
WIN_OBJS = \
|
||||||
|
$O\DLL.obj \
|
||||||
|
$O\FileDir.obj \
|
||||||
|
$O\FileFind.obj \
|
||||||
|
$O\FileIO.obj \
|
||||||
|
$O\PropVariant.obj \
|
||||||
|
$O\Synchronization.obj
|
||||||
|
|
||||||
|
7ZIP_COMMON_OBJS = \
|
||||||
|
$O\InOutTempBuffer.obj \
|
||||||
|
$O\LimitedStreams.obj \
|
||||||
|
$O\LockedStream.obj \
|
||||||
|
$O\OutBuffer.obj \
|
||||||
|
$O\ProgressUtils.obj \
|
||||||
|
$O\StreamBinder.obj \
|
||||||
|
$O\StreamObjects.obj \
|
||||||
|
$O\StreamUtils.obj \
|
||||||
|
|
||||||
|
AR_COMMON_OBJS = \
|
||||||
|
$O\CodecsPath.obj \
|
||||||
|
$O\CoderLoader.obj \
|
||||||
|
$O\CoderMixer2.obj \
|
||||||
|
$O\CoderMixer2MT.obj \
|
||||||
|
$O\CrossThreadProgress.obj \
|
||||||
|
$O\FilterCoder.obj \
|
||||||
|
$O\InStreamWithCRC.obj \
|
||||||
|
$O\ItemNameUtils.obj \
|
||||||
|
$O\MultiStream.obj \
|
||||||
|
$O\OutStreamWithCRC.obj \
|
||||||
|
$O\ParseProperties.obj \
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
$O\StdAfx.obj \
|
||||||
|
$(7Z_OBJS) \
|
||||||
|
$(COMMON_OBJS) \
|
||||||
|
$(WIN_OBJS) \
|
||||||
|
$(7ZIP_COMMON_OBJS) \
|
||||||
|
$(AR_COMMON_OBJS) \
|
||||||
|
$O\CopyCoder.obj \
|
||||||
|
$O\resource.res
|
||||||
|
|
||||||
|
!include "../../../Build.mak"
|
||||||
|
|
||||||
|
$(7Z_OBJS): $(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Developer Studio generated include file.
|
|
||||||
// Used by resource.rc
|
|
||||||
//
|
|
||||||
#define IDI_ICON1 101
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,130 +1,5 @@
|
|||||||
//Microsoft Developer Studio generated resource script.
|
#include "../../MyVersionInfo.rc"
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
MY_VERSION_INFO_DLL("7z Plugin", "7z")
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Russian resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
|
||||||
#pragma code_page(1251)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Russian resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "7z.ico"
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 4,23,0,0
|
|
||||||
PRODUCTVERSION 4,23,0,0
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS 0x1L
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS 0x40004L
|
|
||||||
FILETYPE 0x2L
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Comments", "\0"
|
|
||||||
VALUE "CompanyName", "Igor Pavlov\0"
|
|
||||||
VALUE "FileDescription", "7z Plugin for 7-Zip\0"
|
|
||||||
VALUE "FileVersion", "4, 23, 0, 0\0"
|
|
||||||
VALUE "InternalName", "7z\0"
|
|
||||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
|
||||||
VALUE "LegalTrademarks", "\0"
|
|
||||||
VALUE "OriginalFilename", "7z.dll\0"
|
|
||||||
VALUE "PrivateBuild", "\0"
|
|
||||||
VALUE "ProductName", "7-Zip\0"
|
|
||||||
VALUE "ProductVersion", "4, 23, 0, 0\0"
|
|
||||||
VALUE "SpecialBuild", "\0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // !_MAC
|
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
101 ICON "7z.ico"
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||||
|
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int g_allocCount = 0;
|
int g_allocCount = 0;
|
||||||
int g_allocCountTemp = 0;
|
int g_allocCountTemp = 0;
|
||||||
@@ -14,6 +18,8 @@ int g_allocCountTemp = 0;
|
|||||||
|
|
||||||
void *SzAlloc(size_t size)
|
void *SzAlloc(size_t size)
|
||||||
{
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
||||||
g_allocCount++;
|
g_allocCount++;
|
||||||
@@ -35,9 +41,14 @@ void SzFree(void *address)
|
|||||||
|
|
||||||
void *SzAllocTemp(size_t size)
|
void *SzAllocTemp(size_t size)
|
||||||
{
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
||||||
g_allocCountTemp++;
|
g_allocCountTemp++;
|
||||||
|
#ifdef _WIN32
|
||||||
|
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
@@ -50,6 +61,10 @@ void SzFreeTemp(void *address)
|
|||||||
g_allocCountTemp--;
|
g_allocCountTemp--;
|
||||||
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
||||||
}
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
HeapFree(GetProcessHeap(), 0, address);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
free(address);
|
free(address);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ void SzByteBufferInit(CSzByteBuffer *buffer)
|
|||||||
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
|
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
|
||||||
{
|
{
|
||||||
buffer->Capacity = newCapacity;
|
buffer->Capacity = newCapacity;
|
||||||
|
if (newCapacity == 0)
|
||||||
|
{
|
||||||
|
buffer->Items = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
buffer->Items = (Byte *)allocFunc(newCapacity);
|
buffer->Items = (Byte *)allocFunc(newCapacity);
|
||||||
return (buffer->Items != 0);
|
return (buffer->Items != 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,11 +114,16 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
return SZE_OUTOFMEMORY;
|
return SZE_OUTOFMEMORY;
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
#ifdef _LZMA_OUT_READ
|
||||||
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
|
if (state.Properties.DictionarySize == 0)
|
||||||
if (state.Dictionary == 0)
|
state.Dictionary = 0;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
allocMain->Free(state.Probs);
|
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
|
||||||
return SZE_OUTOFMEMORY;
|
if (state.Dictionary == 0)
|
||||||
|
{
|
||||||
|
allocMain->Free(state.Probs);
|
||||||
|
return SZE_OUTOFMEMORY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LzmaDecoderInit(&state);
|
LzmaDecoderInit(&state);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -45,18 +45,26 @@ SZ_RESULT SzExtract(
|
|||||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
#ifndef _LZMA_IN_CB
|
||||||
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
if (packSize != 0)
|
||||||
if (inBuffer == 0)
|
{
|
||||||
return SZE_OUTOFMEMORY;
|
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
||||||
|
if (inBuffer == 0)
|
||||||
|
return SZE_OUTOFMEMORY;
|
||||||
|
}
|
||||||
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
|
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
|
||||||
if (res == SZ_OK && processedSize != (size_t)packSize)
|
if (res == SZ_OK && processedSize != (size_t)packSize)
|
||||||
res = SZE_FAIL;
|
res = SZE_FAIL;
|
||||||
#endif
|
#endif
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
|
|
||||||
*outBufferSize = (size_t)unPackSize;
|
*outBufferSize = (size_t)unPackSize;
|
||||||
if (*outBuffer != 0)
|
if (unPackSize != 0)
|
||||||
|
{
|
||||||
|
*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
|
||||||
|
if (*outBuffer == 0)
|
||||||
|
res = SZE_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
size_t outRealSize;
|
size_t outRealSize;
|
||||||
res = SzDecode(db->Database.PackSizes +
|
res = SzDecode(db->Database.PackSizes +
|
||||||
@@ -81,8 +89,6 @@ SZ_RESULT SzExtract(
|
|||||||
res = SZE_FAIL;
|
res = SZE_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
res = SZE_OUTOFMEMORY;
|
|
||||||
}
|
}
|
||||||
#ifndef _LZMA_IN_CB
|
#ifndef _LZMA_IN_CB
|
||||||
allocTemp->Free(inBuffer);
|
allocTemp->Free(inBuffer);
|
||||||
|
|||||||
@@ -5,6 +5,26 @@
|
|||||||
|
|
||||||
#include "7zIn.h"
|
#include "7zIn.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
SzExtract extracts file from archive
|
||||||
|
|
||||||
|
*outBuffer must be 0 before first call for each new archive.
|
||||||
|
|
||||||
|
Extracting cache:
|
||||||
|
If you need to decompress more than one file, you can send
|
||||||
|
these values from previous call:
|
||||||
|
*blockIndex,
|
||||||
|
*outBuffer,
|
||||||
|
*outBufferSize
|
||||||
|
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||||
|
it will increase decompression speed.
|
||||||
|
|
||||||
|
If you use external function, you can declare these 3 cache variables
|
||||||
|
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||||
|
|
||||||
|
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||||
|
*/
|
||||||
|
|
||||||
SZ_RESULT SzExtract(
|
SZ_RESULT SzExtract(
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
CArchiveDatabaseEx *db,
|
CArchiveDatabaseEx *db,
|
||||||
|
|||||||
@@ -45,6 +45,18 @@ CFileSize GetFilePackSize(int fileIndex) const
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
SZ_RESULT MySzInAlloc(void **p, size_t size, void * (*allocFunc)(size_t size))
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
*p = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p = allocFunc(size);
|
||||||
|
RINOM(*p);
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
|
SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
|
||||||
{
|
{
|
||||||
UInt32 startPos = 0;
|
UInt32 startPos = 0;
|
||||||
@@ -52,16 +64,14 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
|
|||||||
UInt32 i;
|
UInt32 i;
|
||||||
UInt32 folderIndex = 0;
|
UInt32 folderIndex = 0;
|
||||||
UInt32 indexInFolder = 0;
|
UInt32 indexInFolder = 0;
|
||||||
db->FolderStartPackStreamIndex = (UInt32 *)allocFunc(db->Database.NumFolders * sizeof(UInt32));
|
RINOK(MySzInAlloc((void **)&db->FolderStartPackStreamIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
|
||||||
RINOM(db->FolderStartPackStreamIndex);
|
|
||||||
for(i = 0; i < db->Database.NumFolders; i++)
|
for(i = 0; i < db->Database.NumFolders; i++)
|
||||||
{
|
{
|
||||||
db->FolderStartPackStreamIndex[i] = startPos;
|
db->FolderStartPackStreamIndex[i] = startPos;
|
||||||
startPos += db->Database.Folders[i].NumPackStreams;
|
startPos += db->Database.Folders[i].NumPackStreams;
|
||||||
}
|
}
|
||||||
|
|
||||||
db->PackStreamStartPositions = (CFileSize *)allocFunc(db->Database.NumPackStreams * sizeof(CFileSize));
|
RINOK(MySzInAlloc((void **)&db->PackStreamStartPositions, db->Database.NumPackStreams * sizeof(CFileSize), allocFunc));
|
||||||
RINOM(db->PackStreamStartPositions);
|
|
||||||
|
|
||||||
for(i = 0; i < db->Database.NumPackStreams; i++)
|
for(i = 0; i < db->Database.NumPackStreams; i++)
|
||||||
{
|
{
|
||||||
@@ -69,11 +79,8 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
|
|||||||
startPosSize += db->Database.PackSizes[i];
|
startPosSize += db->Database.PackSizes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
db->FolderStartFileIndex = (UInt32 *)allocFunc(db->Database.NumFolders * sizeof(UInt32));
|
RINOK(MySzInAlloc((void **)&db->FolderStartFileIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
|
||||||
RINOM(db->FolderStartFileIndex);
|
RINOK(MySzInAlloc((void **)&db->FileIndexToFolderIndexMap, db->Database.NumFiles * sizeof(UInt32), allocFunc));
|
||||||
|
|
||||||
db->FileIndexToFolderIndexMap = (UInt32 *)allocFunc(db->Database.NumFiles * sizeof(UInt32));
|
|
||||||
RINOM(db->FileIndexToFolderIndexMap);
|
|
||||||
|
|
||||||
for (i = 0; i < db->Database.NumFiles; i++)
|
for (i = 0; i < db->Database.NumFiles; i++)
|
||||||
{
|
{
|
||||||
@@ -185,7 +192,7 @@ SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
|
|||||||
{
|
{
|
||||||
Byte *inBuffer;
|
Byte *inBuffer;
|
||||||
size_t processedSize;
|
size_t processedSize;
|
||||||
RINOK(inStream->Read(inStream, &inBuffer, size, &processedSize));
|
RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize));
|
||||||
if (processedSize == 0 || processedSize > size)
|
if (processedSize == 0 || processedSize > size)
|
||||||
return SZE_FAIL;
|
return SZE_FAIL;
|
||||||
size -= processedSize;
|
size -= processedSize;
|
||||||
@@ -373,13 +380,12 @@ SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, int **v, void * (*allocFunc)(size_t size))
|
SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
|
||||||
{
|
{
|
||||||
Byte b = 0;
|
Byte b = 0;
|
||||||
Byte mask = 0;
|
Byte mask = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
*v = (int *)allocFunc(numItems * sizeof(int));
|
RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), allocFunc));
|
||||||
RINOM(*v);
|
|
||||||
for(i = 0; i < numItems; i++)
|
for(i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
if (mask == 0)
|
if (mask == 0)
|
||||||
@@ -387,21 +393,20 @@ SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, int **v, void * (*alloc
|
|||||||
RINOK(SzReadByte(sd, &b));
|
RINOK(SzReadByte(sd, &b));
|
||||||
mask = 0x80;
|
mask = 0x80;
|
||||||
}
|
}
|
||||||
(*v)[i] = ((b & mask) != 0);
|
(*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
|
||||||
mask >>= 1;
|
mask >>= 1;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, int **v, void * (*allocFunc)(size_t size))
|
SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
|
||||||
{
|
{
|
||||||
Byte allAreDefined;
|
Byte allAreDefined;
|
||||||
size_t i;
|
size_t i;
|
||||||
RINOK(SzReadByte(sd, &allAreDefined));
|
RINOK(SzReadByte(sd, &allAreDefined));
|
||||||
if (allAreDefined == 0)
|
if (allAreDefined == 0)
|
||||||
return SzReadBoolVector(sd, numItems, v, allocFunc);
|
return SzReadBoolVector(sd, numItems, v, allocFunc);
|
||||||
*v = (int *)allocFunc(numItems * sizeof(int));
|
RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), allocFunc));
|
||||||
RINOM(*v);
|
|
||||||
for(i = 0; i < numItems; i++)
|
for(i = 0; i < numItems; i++)
|
||||||
(*v)[i] = 1;
|
(*v)[i] = 1;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
@@ -410,14 +415,13 @@ SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, int **v, void * (*allo
|
|||||||
SZ_RESULT SzReadHashDigests(
|
SZ_RESULT SzReadHashDigests(
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
size_t numItems,
|
size_t numItems,
|
||||||
int **digestsDefined,
|
Byte **digestsDefined,
|
||||||
UInt32 **digests,
|
UInt32 **digests,
|
||||||
void * (*allocFunc)(size_t size))
|
void * (*allocFunc)(size_t size))
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
|
RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
|
||||||
*digests = (UInt32 *)allocFunc(numItems * sizeof(UInt32));
|
RINOK(MySzInAlloc((void **)digests, numItems * sizeof(UInt32), allocFunc));
|
||||||
RINOM(*digests);
|
|
||||||
for(i = 0; i < numItems; i++)
|
for(i = 0; i < numItems; i++)
|
||||||
if ((*digestsDefined)[i])
|
if ((*digestsDefined)[i])
|
||||||
{
|
{
|
||||||
@@ -431,7 +435,7 @@ SZ_RESULT SzReadPackInfo(
|
|||||||
CFileSize *dataOffset,
|
CFileSize *dataOffset,
|
||||||
UInt32 *numPackStreams,
|
UInt32 *numPackStreams,
|
||||||
CFileSize **packSizes,
|
CFileSize **packSizes,
|
||||||
int **packCRCsDefined,
|
Byte **packCRCsDefined,
|
||||||
UInt32 **packCRCs,
|
UInt32 **packCRCs,
|
||||||
void * (*allocFunc)(size_t size))
|
void * (*allocFunc)(size_t size))
|
||||||
{
|
{
|
||||||
@@ -440,8 +444,8 @@ SZ_RESULT SzReadPackInfo(
|
|||||||
RINOK(SzReadNumber32(sd, numPackStreams));
|
RINOK(SzReadNumber32(sd, numPackStreams));
|
||||||
|
|
||||||
RINOK(SzWaitAttribute(sd, k7zIdSize));
|
RINOK(SzWaitAttribute(sd, k7zIdSize));
|
||||||
*packSizes = (CFileSize *)allocFunc((size_t)*numPackStreams * sizeof(CFileSize));
|
|
||||||
RINOM(*packSizes);
|
RINOK(MySzInAlloc((void **)packSizes, (size_t)*numPackStreams * sizeof(CFileSize), allocFunc));
|
||||||
|
|
||||||
for(i = 0; i < *numPackStreams; i++)
|
for(i = 0; i < *numPackStreams; i++)
|
||||||
{
|
{
|
||||||
@@ -463,10 +467,8 @@ SZ_RESULT SzReadPackInfo(
|
|||||||
}
|
}
|
||||||
if (*packCRCsDefined == 0)
|
if (*packCRCsDefined == 0)
|
||||||
{
|
{
|
||||||
*packCRCsDefined = (int *)allocFunc((size_t)*numPackStreams * sizeof(int));
|
RINOK(MySzInAlloc((void **)packCRCsDefined, (size_t)*numPackStreams * sizeof(Byte), allocFunc));
|
||||||
RINOM(*packCRCsDefined);
|
RINOK(MySzInAlloc((void **)packCRCs, (size_t)*numPackStreams * sizeof(UInt32), allocFunc));
|
||||||
*packCRCs = (UInt32 *)allocFunc((size_t)*numPackStreams * sizeof(UInt32));
|
|
||||||
RINOM(*packCRCs);
|
|
||||||
for(i = 0; i < *numPackStreams; i++)
|
for(i = 0; i < *numPackStreams; i++)
|
||||||
{
|
{
|
||||||
(*packCRCsDefined)[i] = 0;
|
(*packCRCsDefined)[i] = 0;
|
||||||
@@ -494,8 +496,8 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
|
|||||||
RINOK(SzReadNumber32(sd, &numCoders));
|
RINOK(SzReadNumber32(sd, &numCoders));
|
||||||
folder->NumCoders = numCoders;
|
folder->NumCoders = numCoders;
|
||||||
|
|
||||||
folder->Coders = (CCoderInfo *)allocFunc((size_t)numCoders * sizeof(CCoderInfo));
|
RINOK(MySzInAlloc((void **)&folder->Coders, (size_t)numCoders * sizeof(CCoderInfo), allocFunc));
|
||||||
RINOM(folder->Coders);
|
|
||||||
for (i = 0; i < numCoders; i++)
|
for (i = 0; i < numCoders; i++)
|
||||||
SzCoderInfoInit(folder->Coders + i);
|
SzCoderInfoInit(folder->Coders + i);
|
||||||
|
|
||||||
@@ -550,9 +552,9 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
|
|||||||
numBindPairs = numOutStreams - 1;
|
numBindPairs = numOutStreams - 1;
|
||||||
folder->NumBindPairs = numBindPairs;
|
folder->NumBindPairs = numBindPairs;
|
||||||
|
|
||||||
folder->BindPairs = (CBindPair *)allocFunc((size_t)numBindPairs * sizeof(CBindPair));
|
|
||||||
RINOM(folder->BindPairs);
|
RINOK(MySzInAlloc((void **)&folder->BindPairs, (size_t)numBindPairs * sizeof(CBindPair), allocFunc));
|
||||||
|
|
||||||
for (i = 0; i < numBindPairs; i++)
|
for (i = 0; i < numBindPairs; i++)
|
||||||
{
|
{
|
||||||
CBindPair *bindPair = folder->BindPairs + i;;
|
CBindPair *bindPair = folder->BindPairs + i;;
|
||||||
@@ -563,8 +565,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
|
|||||||
numPackedStreams = numInStreams - (UInt32)numBindPairs;
|
numPackedStreams = numInStreams - (UInt32)numBindPairs;
|
||||||
|
|
||||||
folder->NumPackStreams = numPackedStreams;
|
folder->NumPackStreams = numPackedStreams;
|
||||||
folder->PackStreams = (UInt32 *)allocFunc((size_t)numPackedStreams * sizeof(UInt32));
|
RINOK(MySzInAlloc((void **)&folder->PackStreams, (size_t)numPackedStreams * sizeof(UInt32), allocFunc));
|
||||||
RINOM(folder->PackStreams);
|
|
||||||
|
|
||||||
if (numPackedStreams == 1)
|
if (numPackedStreams == 1)
|
||||||
{
|
{
|
||||||
@@ -588,7 +589,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
|
|||||||
SZ_RESULT SzReadUnPackInfo(
|
SZ_RESULT SzReadUnPackInfo(
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
UInt32 *numFolders,
|
UInt32 *numFolders,
|
||||||
CFolder **folders,
|
CFolder **folders, /* for allocFunc */
|
||||||
void * (*allocFunc)(size_t size),
|
void * (*allocFunc)(size_t size),
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
@@ -598,8 +599,9 @@ SZ_RESULT SzReadUnPackInfo(
|
|||||||
{
|
{
|
||||||
RINOK(SzReadSwitch(sd));
|
RINOK(SzReadSwitch(sd));
|
||||||
|
|
||||||
*folders = (CFolder *)allocFunc((size_t)*numFolders * sizeof(CFolder));
|
|
||||||
RINOM(*folders);
|
RINOK(MySzInAlloc((void **)folders, (size_t)*numFolders * sizeof(CFolder), allocFunc));
|
||||||
|
|
||||||
for(i = 0; i < *numFolders; i++)
|
for(i = 0; i < *numFolders; i++)
|
||||||
SzFolderInit((*folders) + i);
|
SzFolderInit((*folders) + i);
|
||||||
|
|
||||||
@@ -617,8 +619,7 @@ SZ_RESULT SzReadUnPackInfo(
|
|||||||
CFolder *folder = (*folders) + i;
|
CFolder *folder = (*folders) + i;
|
||||||
UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
|
UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
|
||||||
|
|
||||||
folder->UnPackSizes = (CFileSize *)allocFunc((size_t)numOutStreams * sizeof(CFileSize));
|
RINOK(MySzInAlloc((void **)&folder->UnPackSizes, (size_t)numOutStreams * sizeof(CFileSize), allocFunc));
|
||||||
RINOM(folder->UnPackSizes);
|
|
||||||
|
|
||||||
for(j = 0; j < numOutStreams; j++)
|
for(j = 0; j < numOutStreams; j++)
|
||||||
{
|
{
|
||||||
@@ -635,7 +636,7 @@ SZ_RESULT SzReadUnPackInfo(
|
|||||||
if (type == k7zIdCRC)
|
if (type == k7zIdCRC)
|
||||||
{
|
{
|
||||||
SZ_RESULT res;
|
SZ_RESULT res;
|
||||||
int *crcsDefined = 0;
|
Byte *crcsDefined = 0;
|
||||||
UInt32 *crcs = 0;
|
UInt32 *crcs = 0;
|
||||||
res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
|
res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
@@ -662,9 +663,8 @@ SZ_RESULT SzReadSubStreamsInfo(
|
|||||||
CFolder *folders,
|
CFolder *folders,
|
||||||
UInt32 *numUnPackStreams,
|
UInt32 *numUnPackStreams,
|
||||||
CFileSize **unPackSizes,
|
CFileSize **unPackSizes,
|
||||||
int **digestsDefined,
|
Byte **digestsDefined,
|
||||||
UInt32 **digests,
|
UInt32 **digests,
|
||||||
void * (*allocFunc)(size_t size),
|
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
UInt64 type = 0;
|
UInt64 type = 0;
|
||||||
@@ -698,14 +698,21 @@ SZ_RESULT SzReadSubStreamsInfo(
|
|||||||
RINOK(SzSkeepData(sd));
|
RINOK(SzSkeepData(sd));
|
||||||
}
|
}
|
||||||
|
|
||||||
*unPackSizes = (CFileSize *)allocFunc((size_t)*numUnPackStreams * sizeof(CFileSize));
|
if (*numUnPackStreams == 0)
|
||||||
RINOM(*unPackSizes);
|
{
|
||||||
|
*unPackSizes = 0;
|
||||||
*digestsDefined = (int *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(int));
|
*digestsDefined = 0;
|
||||||
RINOM(*digestsDefined);
|
*digests = 0;
|
||||||
|
}
|
||||||
*digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32));
|
else
|
||||||
RINOM(*digests);
|
{
|
||||||
|
*unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize));
|
||||||
|
RINOM(*unPackSizes);
|
||||||
|
*digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte));
|
||||||
|
RINOM(*digestsDefined);
|
||||||
|
*digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32));
|
||||||
|
RINOM(*digests);
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0; i < numFolders; i++)
|
for(i = 0; i < numFolders; i++)
|
||||||
{
|
{
|
||||||
@@ -754,7 +761,7 @@ SZ_RESULT SzReadSubStreamsInfo(
|
|||||||
if (type == k7zIdCRC)
|
if (type == k7zIdCRC)
|
||||||
{
|
{
|
||||||
int digestIndex = 0;
|
int digestIndex = 0;
|
||||||
int *digestsDefined2 = 0;
|
Byte *digestsDefined2 = 0;
|
||||||
UInt32 *digests2 = 0;
|
UInt32 *digests2 = 0;
|
||||||
SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
|
SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
@@ -801,9 +808,9 @@ SZ_RESULT SzReadStreamsInfo(
|
|||||||
CFileSize *dataOffset,
|
CFileSize *dataOffset,
|
||||||
CArchiveDatabase *db,
|
CArchiveDatabase *db,
|
||||||
UInt32 *numUnPackStreams,
|
UInt32 *numUnPackStreams,
|
||||||
CFileSize **unPackSizes,
|
CFileSize **unPackSizes, /* allocTemp */
|
||||||
int **digestsDefined,
|
Byte **digestsDefined, /* allocTemp */
|
||||||
UInt32 **digests,
|
UInt32 **digests, /* allocTemp */
|
||||||
void * (*allocFunc)(size_t size),
|
void * (*allocFunc)(size_t size),
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
@@ -831,7 +838,7 @@ SZ_RESULT SzReadStreamsInfo(
|
|||||||
case k7zIdSubStreamsInfo:
|
case k7zIdSubStreamsInfo:
|
||||||
{
|
{
|
||||||
RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
|
RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
|
||||||
numUnPackStreams, unPackSizes, digestsDefined, digests, allocFunc, allocTemp));
|
numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -880,8 +887,7 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
|
|||||||
len += numAdds;
|
len += numAdds;
|
||||||
}
|
}
|
||||||
|
|
||||||
file->Name = (char *)allocFunc((size_t)len * sizeof(char));
|
RINOK(MySzInAlloc((void **)&file->Name, (size_t)len * sizeof(char), allocFunc));
|
||||||
RINOM(file->Name);
|
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
while(2 <= sd->Size)
|
while(2 <= sd->Size)
|
||||||
@@ -921,10 +927,12 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
|
|||||||
|
|
||||||
SZ_RESULT SzReadHeader2(
|
SZ_RESULT SzReadHeader2(
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
CArchiveDatabaseEx *db,
|
CArchiveDatabaseEx *db, /* allocMain */
|
||||||
CFileSize **unPackSizes,
|
CFileSize **unPackSizes, /* allocTemp */
|
||||||
int **digestsDefined,
|
Byte **digestsDefined, /* allocTemp */
|
||||||
UInt32 **digests,
|
UInt32 **digests, /* allocTemp */
|
||||||
|
Byte **emptyStreamVector, /* allocTemp */
|
||||||
|
Byte **emptyFileVector, /* allocTemp */
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
@@ -932,6 +940,7 @@ SZ_RESULT SzReadHeader2(
|
|||||||
UInt32 numUnPackStreams = 0;
|
UInt32 numUnPackStreams = 0;
|
||||||
UInt32 numFiles = 0;
|
UInt32 numFiles = 0;
|
||||||
CFileItem *files = 0;
|
CFileItem *files = 0;
|
||||||
|
UInt32 numEmptyStreams = 0;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
|
|
||||||
RINOK(SzReadID(sd, &type));
|
RINOK(SzReadID(sd, &type));
|
||||||
@@ -955,10 +964,6 @@ SZ_RESULT SzReadHeader2(
|
|||||||
db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
|
db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
|
||||||
RINOK(SzReadID(sd, &type));
|
RINOK(SzReadID(sd, &type));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == k7zIdEnd)
|
if (type == k7zIdEnd)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
@@ -968,21 +973,12 @@ SZ_RESULT SzReadHeader2(
|
|||||||
RINOK(SzReadNumber32(sd, &numFiles));
|
RINOK(SzReadNumber32(sd, &numFiles));
|
||||||
db->Database.NumFiles = numFiles;
|
db->Database.NumFiles = numFiles;
|
||||||
|
|
||||||
files = (CFileItem *)allocTemp->Alloc((size_t)numFiles * sizeof(CFileItem));
|
RINOK(MySzInAlloc((void **)&files, (size_t)numFiles * sizeof(CFileItem), allocMain->Alloc));
|
||||||
RINOM(files);
|
|
||||||
db->Database.Files = files;
|
db->Database.Files = files;
|
||||||
for(i = 0; i < numFiles; i++)
|
for(i = 0; i < numFiles; i++)
|
||||||
SzFileInit(files + i);
|
SzFileInit(files + i);
|
||||||
|
|
||||||
/*
|
|
||||||
CBoolVector emptyStreamVector;
|
|
||||||
emptyStreamVector.Reserve((size_t)numFiles);
|
|
||||||
for(i = 0; i < numFiles; i++)
|
|
||||||
emptyStreamVector.Add(false);
|
|
||||||
CBoolVector emptyFileVector;
|
|
||||||
UInt32 numEmptyStreams = 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
UInt64 type;
|
UInt64 type;
|
||||||
@@ -1007,30 +1003,17 @@ SZ_RESULT SzReadHeader2(
|
|||||||
}
|
}
|
||||||
case k7zIdEmptyStream:
|
case k7zIdEmptyStream:
|
||||||
{
|
{
|
||||||
/*
|
RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
|
||||||
RINOK(ReadBoolVector((UInt32)numFiles, emptyStreamVector))
|
numEmptyStreams = 0;
|
||||||
UInt32 i;
|
for (i = 0; i < numFiles; i++)
|
||||||
for (i = 0; i < (UInt32)emptyStreamVector.Size(); i++)
|
if ((*emptyStreamVector)[i])
|
||||||
if (emptyStreamVector[i])
|
|
||||||
numEmptyStreams++;
|
numEmptyStreams++;
|
||||||
emptyFileVector.Reserve(numEmptyStreams);
|
|
||||||
antiFileVector.Reserve(numEmptyStreams);
|
|
||||||
for (i = 0; i < numEmptyStreams; i++)
|
|
||||||
{
|
|
||||||
emptyFileVector.Add(false);
|
|
||||||
antiFileVector.Add(false);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
}
|
}
|
||||||
case k7zIdEmptyFile:
|
case k7zIdEmptyFile:
|
||||||
{
|
{
|
||||||
/*
|
RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
|
||||||
RINOK(ReadBoolVector(numEmptyStreams, emptyFileVector))
|
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@@ -1039,38 +1022,36 @@ SZ_RESULT SzReadHeader2(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
UInt32 emptyFileIndex = 0;
|
|
||||||
UInt32 sizeIndex = 0;
|
|
||||||
for(i = 0; i < numFiles; i++)
|
|
||||||
{
|
{
|
||||||
CFileItem *file = files + i;
|
UInt32 emptyFileIndex = 0;
|
||||||
file.HasStream = !emptyStreamVector[(UInt32)i];
|
UInt32 sizeIndex = 0;
|
||||||
if(file.HasStream)
|
for(i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
file.IsDirectory = false;
|
CFileItem *file = files + i;
|
||||||
file.IsAnti = false;
|
file->IsAnti = 0;
|
||||||
file.UnPackSize = unPackSizes[sizeIndex];
|
if (*emptyStreamVector == 0)
|
||||||
file.FileCRC = digests[sizeIndex];
|
file->HasStream = 1;
|
||||||
file.IsFileCRCDefined = digestsDefined[sizeIndex];
|
else
|
||||||
sizeIndex++;
|
file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
|
||||||
|
if(file->HasStream)
|
||||||
|
{
|
||||||
|
file->IsDirectory = 0;
|
||||||
|
file->Size = (*unPackSizes)[sizeIndex];
|
||||||
|
file->FileCRC = (*digests)[sizeIndex];
|
||||||
|
file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
|
||||||
|
sizeIndex++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*emptyFileVector == 0)
|
||||||
|
file->IsDirectory = 1;
|
||||||
|
else
|
||||||
|
file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
|
||||||
|
emptyFileIndex++;
|
||||||
|
file->Size = 0;
|
||||||
|
file->IsFileCRCDefined = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
file.IsDirectory = !emptyFileVector[emptyFileIndex];
|
|
||||||
file.IsAnti = antiFileVector[emptyFileIndex];
|
|
||||||
emptyFileIndex++;
|
|
||||||
file.UnPackSize = 0;
|
|
||||||
file.IsFileCRCDefined = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
for(i = 0; i < numFiles; i++)
|
|
||||||
{
|
|
||||||
CFileItem *file = files + i;
|
|
||||||
file->Size = (*unPackSizes)[i];
|
|
||||||
file->FileCRC = (*digests)[i];
|
|
||||||
file->IsFileCRCDefined = (Byte)(*digestsDefined)[i];
|
|
||||||
}
|
}
|
||||||
return SzArDbExFill(db, allocMain->Alloc);
|
return SzArDbExFill(db, allocMain->Alloc);
|
||||||
}
|
}
|
||||||
@@ -1082,14 +1063,19 @@ SZ_RESULT SzReadHeader(
|
|||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
CFileSize *unPackSizes = 0;
|
CFileSize *unPackSizes = 0;
|
||||||
int *digestsDefined = 0;
|
Byte *digestsDefined = 0;
|
||||||
UInt32 *digests = 0;
|
UInt32 *digests = 0;
|
||||||
|
Byte *emptyStreamVector = 0;
|
||||||
|
Byte *emptyFileVector = 0;
|
||||||
SZ_RESULT res = SzReadHeader2(sd, db,
|
SZ_RESULT res = SzReadHeader2(sd, db,
|
||||||
&unPackSizes, &digestsDefined, &digests,
|
&unPackSizes, &digestsDefined, &digests,
|
||||||
|
&emptyStreamVector, &emptyFileVector,
|
||||||
allocMain, allocTemp);
|
allocMain, allocTemp);
|
||||||
allocTemp->Free(unPackSizes);
|
allocTemp->Free(unPackSizes);
|
||||||
allocTemp->Free(digestsDefined);
|
allocTemp->Free(digestsDefined);
|
||||||
allocTemp->Free(digests);
|
allocTemp->Free(digests);
|
||||||
|
allocTemp->Free(emptyStreamVector);
|
||||||
|
allocTemp->Free(emptyFileVector);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1100,7 +1086,7 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
|
|||||||
CFileSize baseOffset,
|
CFileSize baseOffset,
|
||||||
CArchiveDatabase *db,
|
CArchiveDatabase *db,
|
||||||
CFileSize **unPackSizes,
|
CFileSize **unPackSizes,
|
||||||
int **digestsDefined,
|
Byte **digestsDefined,
|
||||||
UInt32 **digests,
|
UInt32 **digests,
|
||||||
#ifndef _LZMA_IN_CB
|
#ifndef _LZMA_IN_CB
|
||||||
Byte **inBuffer,
|
Byte **inBuffer,
|
||||||
@@ -1136,9 +1122,8 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
|
|||||||
for (i = 0; i < db->NumPackStreams; i++)
|
for (i = 0; i < db->NumPackStreams; i++)
|
||||||
packSize += db->PackSizes[i];
|
packSize += db->PackSizes[i];
|
||||||
|
|
||||||
*inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
RINOK(MySzInAlloc((void **)inBuffer, (size_t)packSize, allocTemp->Alloc));
|
||||||
RINOM(*inBuffer);
|
|
||||||
|
|
||||||
RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
|
RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1171,7 +1156,7 @@ SZ_RESULT SzReadAndDecodePackedStreams(
|
|||||||
{
|
{
|
||||||
CArchiveDatabase db;
|
CArchiveDatabase db;
|
||||||
CFileSize *unPackSizes = 0;
|
CFileSize *unPackSizes = 0;
|
||||||
int *digestsDefined = 0;
|
Byte *digestsDefined = 0;
|
||||||
UInt32 *digests = 0;
|
UInt32 *digests = 0;
|
||||||
#ifndef _LZMA_IN_CB
|
#ifndef _LZMA_IN_CB
|
||||||
Byte *inBuffer = 0;
|
Byte *inBuffer = 0;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ typedef struct _CArchiveDatabase
|
|||||||
{
|
{
|
||||||
UInt32 NumPackStreams;
|
UInt32 NumPackStreams;
|
||||||
CFileSize *PackSizes;
|
CFileSize *PackSizes;
|
||||||
int *PackCRCsDefined;
|
Byte *PackCRCsDefined;
|
||||||
UInt32 *PackCRCs;
|
UInt32 *PackCRCs;
|
||||||
UInt32 NumFolders;
|
UInt32 NumFolders;
|
||||||
CFolder *Folders;
|
CFolder *Folders;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
7zMain.c
|
7zMain.c
|
||||||
Test application for 7z Decoder
|
Test application for 7z Decoder
|
||||||
LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-09-24)
|
LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -71,7 +71,7 @@ int main(int numargs, char *args[])
|
|||||||
ISzAlloc allocImp;
|
ISzAlloc allocImp;
|
||||||
ISzAlloc allocTempImp;
|
ISzAlloc allocTempImp;
|
||||||
|
|
||||||
printf("\n7z ANSI-C Decoder 4.16 Copyright (c) 1999-2005 Igor Pavlov 2005-03-29\n");
|
printf("\n7z ANSI-C Decoder 4.30 Copyright (c) 1999-2005 Igor Pavlov 2005-11-20\n");
|
||||||
if (numargs == 1)
|
if (numargs == 1)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
@@ -132,19 +132,31 @@ int main(int numargs, char *args[])
|
|||||||
else if (testCommand || extractCommand)
|
else if (testCommand || extractCommand)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
UInt32 blockIndex;
|
|
||||||
Byte *outBuffer = 0;
|
// if you need cache, use these 3 variables.
|
||||||
size_t outBufferSize;
|
// if you use external function, you can make these variable as static.
|
||||||
|
UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0)
|
||||||
|
Byte *outBuffer = 0; // it must be 0 before first call for each new archive.
|
||||||
|
size_t outBufferSize = 0; // it can have any value before first call (if outBuffer = 0)
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
for (i = 0; i < db.Database.NumFiles; i++)
|
for (i = 0; i < db.Database.NumFiles; i++)
|
||||||
{
|
{
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t outSizeProcessed;
|
size_t outSizeProcessed;
|
||||||
CFileItem *f = db.Database.Files + i;
|
CFileItem *f = db.Database.Files + i;
|
||||||
printf(testCommand ?
|
if (f->IsDirectory)
|
||||||
"Tesing ":
|
printf("Directory ");
|
||||||
|
else
|
||||||
|
printf(testCommand ?
|
||||||
|
"Testing ":
|
||||||
"Extracting");
|
"Extracting");
|
||||||
printf(" %s", f->Name);
|
printf(" %s", f->Name);
|
||||||
|
if (f->IsDirectory)
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
res = SzExtract(&archiveStream.InStream, &db, i,
|
res = SzExtract(&archiveStream.InStream, &db, i,
|
||||||
&blockIndex, &outBuffer, &outBufferSize,
|
&blockIndex, &outBuffer, &outBufferSize,
|
||||||
&offset, &outSizeProcessed,
|
&offset, &outSizeProcessed,
|
||||||
|
|||||||
@@ -1,50 +1,55 @@
|
|||||||
PROG = 7zDec
|
PROG = 7zDec.exe
|
||||||
CXX = g++ -O2 -Wall
|
|
||||||
LIB =
|
|
||||||
RM = rm -f
|
|
||||||
CFLAGS = -c
|
|
||||||
|
|
||||||
OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o
|
!IFNDEF O
|
||||||
|
!IFDEF CPU
|
||||||
|
O=$(CPU)
|
||||||
|
!ELSE
|
||||||
|
O=O
|
||||||
|
!ENDIF
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
all: $(PROG)
|
CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS-
|
||||||
|
CFLAGS_O1 = $(CFLAGS) -O1
|
||||||
|
CFLAGS_O2 = $(CFLAGS) -O2
|
||||||
|
|
||||||
$(PROG): $(OBJS)
|
LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98
|
||||||
$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
7zAlloc.o: 7zAlloc.c
|
PROGPATH = $O\$(PROG)
|
||||||
$(CXX) $(CFLAGS) 7zAlloc.c
|
|
||||||
|
|
||||||
7zBuffer.o: 7zBuffer.c
|
COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
|
||||||
$(CXX) $(CFLAGS) 7zBuffer.c
|
COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
|
||||||
|
COMPL = $(CPP) $(CFLAGS_O1) $**
|
||||||
|
|
||||||
7zCrc.o: 7zCrc.c
|
|
||||||
$(CXX) $(CFLAGS) 7zCrc.c
|
|
||||||
|
|
||||||
7zDecode.o: 7zDecode.c
|
7Z_OBJS = \
|
||||||
$(CXX) $(CFLAGS) 7zDecode.c
|
$O\7zAlloc.obj \
|
||||||
|
$O\7zBuffer.obj \
|
||||||
|
$O\7zCrc.obj \
|
||||||
|
$O\7zDecode.obj \
|
||||||
|
$O\7zExtract.obj \
|
||||||
|
$O\7zHeader.obj \
|
||||||
|
$O\7zIn.obj \
|
||||||
|
$O\7zItem.obj \
|
||||||
|
$O\7zMain.obj \
|
||||||
|
$O\7zMethodID.obj \
|
||||||
|
|
||||||
7zExtract.o: 7zExtract.c
|
OBJS = \
|
||||||
$(CXX) $(CFLAGS) 7zExtract.c
|
$(7Z_OBJS) \
|
||||||
|
$O\LzmaDecode.obj \
|
||||||
7zHeader.o: 7zHeader.c
|
|
||||||
$(CXX) $(CFLAGS) 7zHeader.c
|
|
||||||
|
|
||||||
7zIn.o: 7zIn.c
|
|
||||||
$(CXX) $(CFLAGS) 7zIn.c
|
|
||||||
|
|
||||||
7zItem.o: 7zItem.c
|
|
||||||
$(CXX) $(CFLAGS) 7zItem.c
|
|
||||||
|
|
||||||
7zMain.o: 7zMain.c
|
|
||||||
$(CXX) $(CFLAGS) 7zMain.c
|
|
||||||
|
|
||||||
7zMethodID.o: 7zMethodID.c
|
|
||||||
$(CXX) $(CFLAGS) 7zMethodID.c
|
|
||||||
|
|
||||||
LzmaDecode.o: ../../Compress/LZMA_C/LzmaDecode.c
|
|
||||||
$(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c
|
|
||||||
|
|
||||||
|
all: $(PROGPATH)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-$(RM) $(PROG) $(OBJS)
|
-del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
|
||||||
|
|
||||||
|
$O:
|
||||||
|
if not exist "$O" mkdir "$O"
|
||||||
|
|
||||||
|
$(PROGPATH): $O $(OBJS)
|
||||||
|
link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
|
$(7Z_OBJS): $(*B).c
|
||||||
|
$(COMPL)
|
||||||
|
$O\LzmaDecode.obj: ../../Compress/LZMA_C/$(*B).c
|
||||||
|
$(COMPL_O2)
|
||||||
|
|||||||
50
7zip/Archive/7z_C/makefile.gcc
Executable file
50
7zip/Archive/7z_C/makefile.gcc
Executable file
@@ -0,0 +1,50 @@
|
|||||||
|
PROG = 7zDec
|
||||||
|
CXX = g++
|
||||||
|
LIB =
|
||||||
|
RM = rm -f
|
||||||
|
CFLAGS = -c -O2 -Wall
|
||||||
|
|
||||||
|
OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
|
||||||
|
$(PROG): $(OBJS)
|
||||||
|
$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
|
||||||
|
|
||||||
|
7zAlloc.o: 7zAlloc.c
|
||||||
|
$(CXX) $(CFLAGS) 7zAlloc.c
|
||||||
|
|
||||||
|
7zBuffer.o: 7zBuffer.c
|
||||||
|
$(CXX) $(CFLAGS) 7zBuffer.c
|
||||||
|
|
||||||
|
7zCrc.o: 7zCrc.c
|
||||||
|
$(CXX) $(CFLAGS) 7zCrc.c
|
||||||
|
|
||||||
|
7zDecode.o: 7zDecode.c
|
||||||
|
$(CXX) $(CFLAGS) 7zDecode.c
|
||||||
|
|
||||||
|
7zExtract.o: 7zExtract.c
|
||||||
|
$(CXX) $(CFLAGS) 7zExtract.c
|
||||||
|
|
||||||
|
7zHeader.o: 7zHeader.c
|
||||||
|
$(CXX) $(CFLAGS) 7zHeader.c
|
||||||
|
|
||||||
|
7zIn.o: 7zIn.c
|
||||||
|
$(CXX) $(CFLAGS) 7zIn.c
|
||||||
|
|
||||||
|
7zItem.o: 7zItem.c
|
||||||
|
$(CXX) $(CFLAGS) 7zItem.c
|
||||||
|
|
||||||
|
7zMain.o: 7zMain.c
|
||||||
|
$(CXX) $(CFLAGS) 7zMain.c
|
||||||
|
|
||||||
|
7zMethodID.o: 7zMethodID.c
|
||||||
|
$(CXX) $(CFLAGS) 7zMethodID.c
|
||||||
|
|
||||||
|
LzmaDecode.o: ../../Compress/LZMA_C/LzmaDecode.c
|
||||||
|
$(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) $(PROG) $(OBJS)
|
||||||
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
EXPORTS
|
EXPORTS
|
||||||
CreateObject PRIVATE
|
CreateObject PRIVATE
|
||||||
GetHandlerProperty PRIVATE
|
GetHandlerProperty PRIVATE
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ LINK32=link.exe
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\arj.def
|
SOURCE=..\Archive.def
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -101,10 +101,6 @@ SOURCE=.\DllExports.cpp
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\resource.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.rc
|
SOURCE=.\resource.rc
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -217,19 +213,19 @@ SOURCE=.\ArjItem.h
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Arj\Decoder1.cpp
|
SOURCE=..\..\Compress\Arj\ArjDecoder1.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Arj\Decoder1.h
|
SOURCE=..\..\Compress\Arj\ArjDecoder1.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Arj\Decoder2.cpp
|
SOURCE=..\..\Compress\Arj\ArjDecoder2.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Arj\Decoder2.h
|
SOURCE=..\..\Compress\Arj\ArjDecoder2.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "LZ"
|
# Begin Group "LZ"
|
||||||
@@ -282,12 +278,28 @@ SOURCE=..\..\Common\MSBFDecoder.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin 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
|
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.h
|
SOURCE=..\..\Common\ProgressUtils.h
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.h
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Archive Common"
|
# Begin Group "Archive Common"
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
#include "../../Common/LimitedStreams.h"
|
#include "../../Common/LimitedStreams.h"
|
||||||
|
|
||||||
#include "../../Compress/Copy/CopyCoder.h"
|
#include "../../Compress/Copy/CopyCoder.h"
|
||||||
#include "../../Compress/Arj/Decoder1.h"
|
#include "../../Compress/Arj/ArjDecoder1.h"
|
||||||
#include "../../Compress/Arj/Decoder2.h"
|
#include "../../Compress/Arj/ArjDecoder2.h"
|
||||||
|
|
||||||
#include "../Common/ItemNameUtils.h"
|
#include "../Common/ItemNameUtils.h"
|
||||||
#include "../Common/OutStreamWithCRC.h"
|
#include "../Common/OutStreamWithCRC.h"
|
||||||
@@ -256,6 +256,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::Close()
|
STDMETHODIMP CHandler::Close()
|
||||||
{
|
{
|
||||||
|
_items.Clear();
|
||||||
_stream.Release();
|
_stream.Release();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "Common/Buffer.h"
|
#include "Common/Buffer.h"
|
||||||
#include "Common/CRC.h"
|
#include "Common/CRC.h"
|
||||||
|
|
||||||
|
#include "../../Common/StreamUtils.h"
|
||||||
|
|
||||||
#include "ArjIn.h"
|
#include "ArjIn.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
@@ -14,7 +16,7 @@ namespace NArj {
|
|||||||
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
|
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
UInt32 realProcessedSize;
|
UInt32 realProcessedSize;
|
||||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
HRESULT result = ReadStream(_stream, data, size, &realProcessedSize);
|
||||||
if(processedSize != NULL)
|
if(processedSize != NULL)
|
||||||
*processedSize = realProcessedSize;
|
*processedSize = realProcessedSize;
|
||||||
IncreasePositionValue(realProcessedSize);
|
IncreasePositionValue(realProcessedSize);
|
||||||
@@ -162,7 +164,7 @@ bool CInArchive::ReadBlock()
|
|||||||
{
|
{
|
||||||
_blockPos = 0;
|
_blockPos = 0;
|
||||||
_blockSize = SafeReadUInt16();
|
_blockSize = SafeReadUInt16();
|
||||||
if (_blockSize == 0)
|
if (_blockSize == 0 || _blockSize > kMaxBlockSize)
|
||||||
return false;
|
return false;
|
||||||
SafeReadBytes(_block, _blockSize);
|
SafeReadBytes(_block, _blockSize);
|
||||||
UInt32 crcFromFile = SafeReadUInt32();
|
UInt32 crcFromFile = SafeReadUInt32();
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
#include "../../ICoder.h"
|
#include "../../ICoder.h"
|
||||||
#include "ArjHandler.h"
|
#include "ArjHandler.h"
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-0001100A0000}
|
// {23170F69-40C1-278A-1000-000110040000}
|
||||||
DEFINE_GUID(CLSID_CArjHandler,
|
DEFINE_GUID(CLSID_CArjHandler,
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0A, 0x00, 0x00);
|
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00);
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||||
|
|||||||
66
7zip/Archive/Arj/makefile
Executable file
66
7zip/Archive/Arj/makefile
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
PROG = arj.dll
|
||||||
|
DEF_FILE = ../Archive.def
|
||||||
|
CFLAGS = $(CFLAGS) -I ../../../
|
||||||
|
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||||
|
|
||||||
|
ARJ_OBJS = \
|
||||||
|
$O\DllExports.obj \
|
||||||
|
$O\ArjHandler.obj \
|
||||||
|
$O\ArjIn.obj \
|
||||||
|
|
||||||
|
COMMON_OBJS = \
|
||||||
|
$O\Alloc.obj \
|
||||||
|
$O\CRC.obj \
|
||||||
|
$O\NewHandler.obj \
|
||||||
|
$O\String.obj \
|
||||||
|
$O\StringConvert.obj \
|
||||||
|
$O\Vector.obj \
|
||||||
|
|
||||||
|
WIN_OBJS = \
|
||||||
|
$O\PropVariant.obj \
|
||||||
|
|
||||||
|
7ZIP_COMMON_OBJS = \
|
||||||
|
$O\InBuffer.obj \
|
||||||
|
$O\LimitedStreams.obj \
|
||||||
|
$O\OutBuffer.obj \
|
||||||
|
$O\ProgressUtils.obj \
|
||||||
|
$O\StreamUtils.obj \
|
||||||
|
|
||||||
|
AR_COMMON_OBJS = \
|
||||||
|
$O\ItemNameUtils.obj \
|
||||||
|
$O\OutStreamWithCRC.obj \
|
||||||
|
|
||||||
|
COMPRESS_ARJ_OBJS = \
|
||||||
|
$O\ArjDecoder1.obj \
|
||||||
|
$O\ArjDecoder2.obj \
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
$O\StdAfx.obj \
|
||||||
|
$(ARJ_OBJS) \
|
||||||
|
$(COMMON_OBJS) \
|
||||||
|
$(WIN_OBJS) \
|
||||||
|
$(7ZIP_COMMON_OBJS) \
|
||||||
|
$(AR_COMMON_OBJS) \
|
||||||
|
$(COMPRESS_ARJ_OBJS) \
|
||||||
|
$O\CopyCoder.obj \
|
||||||
|
$O\LZOutWindow.obj \
|
||||||
|
$O\resource.res
|
||||||
|
|
||||||
|
!include "../../../Build.mak"
|
||||||
|
|
||||||
|
$(ARJ_OBJS): $(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMPRESS_ARJ_OBJS): ../../Compress/Arj/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Developer Studio generated include file.
|
|
||||||
// Used by resource.rc
|
|
||||||
//
|
|
||||||
#define IDI_ICON1 101
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,130 +1,5 @@
|
|||||||
//Microsoft Developer Studio generated resource script.
|
#include "../../MyVersionInfo.rc"
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
MY_VERSION_INFO_DLL("Arj Plugin", "arj")
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Russian resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
|
||||||
#pragma code_page(1251)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Russian resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "arj.ico"
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 4,23,0,0
|
|
||||||
PRODUCTVERSION 4,23,0,0
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS 0x1L
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS 0x40004L
|
|
||||||
FILETYPE 0x2L
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Comments", "\0"
|
|
||||||
VALUE "CompanyName", "Igor Pavlov\0"
|
|
||||||
VALUE "FileDescription", "Arj Plugin for 7-Zip\0"
|
|
||||||
VALUE "FileVersion", "4, 23, 0, 0\0"
|
|
||||||
VALUE "InternalName", "arj\0"
|
|
||||||
VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0"
|
|
||||||
VALUE "LegalTrademarks", "\0"
|
|
||||||
VALUE "OriginalFilename", "arj.dll\0"
|
|
||||||
VALUE "PrivateBuild", "\0"
|
|
||||||
VALUE "ProductName", "7-Zip\0"
|
|
||||||
VALUE "ProductVersion", "4, 23, 0, 0\0"
|
|
||||||
VALUE "SpecialBuild", "\0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // !_MAC
|
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
101 ICON "arj.ico"
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
; BZip2.def
|
|
||||||
|
|
||||||
LIBRARY bz2.dll
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
CreateObject PRIVATE
|
|
||||||
GetHandlerProperty PRIVATE
|
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
|||||||
# PROP Ignore_Export_Lib 1
|
# PROP Ignore_Export_Lib 1
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c
|
||||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /c
|
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
|||||||
# PROP Ignore_Export_Lib 1
|
# PROP Ignore_Export_Lib 1
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||||
@@ -93,7 +93,7 @@ LINK32=link.exe
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\BZip2.def
|
SOURCE=..\Archive.def
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -105,10 +105,6 @@ SOURCE=.\DllExports.cpp
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\resource.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.rc
|
SOURCE=.\resource.rc
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -220,6 +216,14 @@ SOURCE=..\Common\DummyOutStream.cpp
|
|||||||
|
|
||||||
SOURCE=..\Common\DummyOutStream.h
|
SOURCE=..\Common\DummyOutStream.h
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ParseProperties.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ParseProperties.h
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Engine"
|
# Begin Group "Engine"
|
||||||
|
|
||||||
@@ -260,6 +264,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
|
|||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.h
|
SOURCE=..\..\Common\ProgressUtils.h
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.h
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "Common/Defs.h"
|
#include "Common/Defs.h"
|
||||||
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
#include "../../Common/ProgressUtils.h"
|
||||||
// #include "Interface/EnumStatProp.h"
|
#include "../../Common/StreamUtils.h"
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
#include "Windows/Defs.h"
|
#include "Windows/Defs.h"
|
||||||
@@ -111,7 +111,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
|||||||
const int kSignatureSize = 3;
|
const int kSignatureSize = 3;
|
||||||
Byte buffer[kSignatureSize];
|
Byte buffer[kSignatureSize];
|
||||||
UInt32 processedSize;
|
UInt32 processedSize;
|
||||||
RINOK(stream->Read(buffer, kSignatureSize, &processedSize));
|
RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize));
|
||||||
if (processedSize != kSignatureSize)
|
if (processedSize != kSignatureSize)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
|
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
|
||||||
@@ -191,6 +191,16 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
{
|
||||||
|
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||||
|
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||||
|
if (setCoderMt)
|
||||||
|
{
|
||||||
|
RINOK(setCoderMt->SetNumberOfThreads(_numThreads));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||||
@@ -221,7 +231,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
const int kSignatureSize = 3;
|
const int kSignatureSize = 3;
|
||||||
Byte buffer[kSignatureSize];
|
Byte buffer[kSignatureSize];
|
||||||
UInt32 processedSize;
|
UInt32 processedSize;
|
||||||
RINOK(_stream->Read(buffer, kSignatureSize, &processedSize));
|
RINOK(ReadStream(_stream, buffer, kSignatureSize, &processedSize));
|
||||||
if (processedSize < kSignatureSize)
|
if (processedSize < kSignatureSize)
|
||||||
{
|
{
|
||||||
if (firstItem)
|
if (firstItem)
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
#include "../IArchive.h"
|
#include "../IArchive.h"
|
||||||
#include "BZip2Item.h"
|
#include "BZip2Item.h"
|
||||||
|
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
#include "../../../Windows/System.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NBZip2 {
|
namespace NBZip2 {
|
||||||
|
|
||||||
@@ -20,8 +24,21 @@ class CHandler:
|
|||||||
NArchive::NBZip2::CItem _item;
|
NArchive::NBZip2::CItem _item;
|
||||||
UInt64 _streamStartPosition;
|
UInt64 _streamStartPosition;
|
||||||
|
|
||||||
|
UInt32 _level;
|
||||||
|
UInt32 _dicSize;
|
||||||
UInt32 _numPasses;
|
UInt32 _numPasses;
|
||||||
void InitMethodProperties() { _numPasses = 1; }
|
#ifdef COMPRESS_MT
|
||||||
|
UInt32 _numThreads;
|
||||||
|
#endif
|
||||||
|
void InitMethodProperties()
|
||||||
|
{
|
||||||
|
_level = 5;
|
||||||
|
_dicSize =
|
||||||
|
_numPasses = 0xFFFFFFFF;
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP3(
|
MY_UNKNOWN_IMP3(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// BZip2/OutHandler.cpp
|
// BZip2HandlerOut.cpp
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
@@ -7,13 +7,23 @@
|
|||||||
|
|
||||||
#include "Common/Defs.h"
|
#include "Common/Defs.h"
|
||||||
#include "Common/String.h"
|
#include "Common/String.h"
|
||||||
#include "Common/StringToInt.h"
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
|
|
||||||
#include "../../Compress/Copy/CopyCoder.h"
|
#include "../../Compress/Copy/CopyCoder.h"
|
||||||
|
|
||||||
|
#include "../Common/ParseProperties.h"
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
|
static const UInt32 kNumPassesX1 = 1;
|
||||||
|
static const UInt32 kNumPassesX7 = 2;
|
||||||
|
static const UInt32 kNumPassesX9 = 7;
|
||||||
|
|
||||||
|
static const UInt32 kDicSizeX1 = 100000;
|
||||||
|
static const UInt32 kDicSizeX3 = 500000;
|
||||||
|
static const UInt32 kDicSizeX5 = 900000;
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NBZip2 {
|
namespace NBZip2 {
|
||||||
|
|
||||||
@@ -69,7 +79,24 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
size = propVariant.uhVal.QuadPart;
|
size = propVariant.uhVal.QuadPart;
|
||||||
}
|
}
|
||||||
return UpdateArchive(size, outStream, 0, _numPasses, updateCallback);
|
|
||||||
|
UInt32 dicSize = _dicSize;
|
||||||
|
if (dicSize == 0xFFFFFFFF)
|
||||||
|
dicSize = (_level >= 5 ? kDicSizeX5 :
|
||||||
|
(_level >= 3 ? kDicSizeX3 :
|
||||||
|
kDicSizeX1));
|
||||||
|
|
||||||
|
UInt32 numPasses = _numPasses;
|
||||||
|
if (numPasses == 0xFFFFFFFF)
|
||||||
|
numPasses = (_level >= 9 ? kNumPassesX9 :
|
||||||
|
(_level >= 7 ? kNumPassesX7 :
|
||||||
|
kNumPassesX1));
|
||||||
|
|
||||||
|
return UpdateArchive(size, outStream, 0, dicSize, numPasses,
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
_numThreads,
|
||||||
|
#endif
|
||||||
|
updateCallback);
|
||||||
}
|
}
|
||||||
if (indexInArchive != 0)
|
if (indexInArchive != 0)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
@@ -80,6 +107,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||||
{
|
{
|
||||||
InitMethodProperties();
|
InitMethodProperties();
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||||
|
_numThreads = numProcessors;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < numProperties; i++)
|
for (int i = 0; i < numProperties; i++)
|
||||||
{
|
{
|
||||||
UString name = UString(names[i]);
|
UString name = UString(names[i]);
|
||||||
@@ -87,68 +119,34 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
if (name.IsEmpty())
|
if (name.IsEmpty())
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
const PROPVARIANT &value = values[i];
|
const PROPVARIANT &prop = values[i];
|
||||||
|
|
||||||
if (name[0] == 'X')
|
if (name[0] == 'X')
|
||||||
{
|
{
|
||||||
name.Delete(0);
|
|
||||||
UInt32 level = 9;
|
UInt32 level = 9;
|
||||||
if (value.vt == VT_UI4)
|
RINOK(ParsePropValue(name.Mid(1), prop, level));
|
||||||
{
|
_level = level;
|
||||||
if (!name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
level = value.ulVal;
|
|
||||||
}
|
|
||||||
else if (value.vt == VT_EMPTY)
|
|
||||||
{
|
|
||||||
if(!name.IsEmpty())
|
|
||||||
{
|
|
||||||
const wchar_t *start = name;
|
|
||||||
const wchar_t *end;
|
|
||||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
|
||||||
if (end - start != name.Length())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
level = (UInt32)v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
if (level < 7)
|
|
||||||
_numPasses = 1;
|
|
||||||
else if (level < 9)
|
|
||||||
_numPasses = 2;
|
|
||||||
else
|
|
||||||
_numPasses = 7;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (name.Left(4) == L"PASS")
|
if (name[0] == 'D')
|
||||||
{
|
{
|
||||||
name.Delete(0, 4);
|
UInt32 dicSize = kDicSizeX5;
|
||||||
UInt32 numPasses = 1;
|
RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
|
||||||
if (value.vt == VT_UI4)
|
_dicSize = dicSize;
|
||||||
{
|
continue;
|
||||||
if (!name.IsEmpty())
|
}
|
||||||
return E_INVALIDARG;
|
if (name.Left(4) == L"PASS")
|
||||||
numPasses = value.ulVal;
|
{
|
||||||
}
|
UInt32 num = kNumPassesX9;
|
||||||
else if (value.vt == VT_EMPTY)
|
RINOK(ParsePropValue(name.Mid(4), prop, num));
|
||||||
{
|
_numPasses = num;
|
||||||
if(!name.IsEmpty())
|
continue;
|
||||||
{
|
}
|
||||||
const wchar_t *start = name;
|
if (name.Left(2) == L"MT")
|
||||||
const wchar_t *end;
|
{
|
||||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
#ifdef COMPRESS_MT
|
||||||
if (end - start != name.Length())
|
RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
|
||||||
return E_INVALIDARG;
|
#endif
|
||||||
numPasses = (UInt32)v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
if (numPasses < 1 || numPasses > 10)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
_numPasses = numPasses;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ namespace NBZip2 {
|
|||||||
HRESULT UpdateArchive(UInt64 unpackSize,
|
HRESULT UpdateArchive(UInt64 unpackSize,
|
||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
int indexInClient,
|
int indexInClient,
|
||||||
|
UInt32 dictionary,
|
||||||
UInt32 numPasses,
|
UInt32 numPasses,
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
UInt32 numThreads,
|
||||||
|
#endif
|
||||||
IArchiveUpdateCallback *updateCallback)
|
IArchiveUpdateCallback *updateCallback)
|
||||||
{
|
{
|
||||||
RINOK(updateCallback->SetTotal(unpackSize));
|
RINOK(updateCallback->SetTotal(unpackSize));
|
||||||
@@ -53,21 +57,23 @@ HRESULT UpdateArchive(UInt64 unpackSize,
|
|||||||
encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
||||||
if (setCoderProperties)
|
if (setCoderProperties)
|
||||||
{
|
{
|
||||||
/*
|
NWindows::NCOM::CPropVariant properties[] =
|
||||||
NWindows::NCOM::CPropVariant properties[2] =
|
|
||||||
{
|
{
|
||||||
dictionary, numPasses
|
dictionary,
|
||||||
|
numPasses
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
, numThreads
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
PROPID propIDs[2] =
|
PROPID propIDs[] =
|
||||||
{
|
{
|
||||||
NCoderPropID::kDictionarySize,
|
NCoderPropID::kDictionarySize,
|
||||||
NCoderPropID::kNumPasses,
|
NCoderPropID::kNumPasses
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
, NCoderPropID::kNumThreads
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2));
|
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
|
||||||
*/
|
|
||||||
NWindows::NCOM::CPropVariant property = numPasses;
|
|
||||||
PROPID propID = NCoderPropID::kNumPasses;
|
|
||||||
RINOK(setCoderProperties->SetCoderProperties(&propID, &property, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
|
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ HRESULT UpdateArchive(
|
|||||||
UInt64 unpackSize,
|
UInt64 unpackSize,
|
||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
int indexInClient,
|
int indexInClient,
|
||||||
|
UInt32 dictionary,
|
||||||
UInt32 numPasses,
|
UInt32 numPasses,
|
||||||
|
#ifdef COMPRESS_MT
|
||||||
|
UInt32 numThreads,
|
||||||
|
#endif
|
||||||
IArchiveUpdateCallback *updateCallback);
|
IArchiveUpdateCallback *updateCallback);
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -16,11 +16,22 @@ DEFINE_GUID(CLSID_CCompressBZip2Encoder,
|
|||||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
||||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-000110070000}
|
// {23170F69-40C1-278A-1000-000110020000}
|
||||||
DEFINE_GUID(CLSID_CBZip2Handler,
|
DEFINE_GUID(CLSID_CBZip2Handler,
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
|
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
|
||||||
|
|
||||||
HINSTANCE g_hInstance;
|
HINSTANCE g_hInstance;
|
||||||
|
#ifndef _UNICODE
|
||||||
|
bool g_IsNT = false;
|
||||||
|
static bool IsItWindowsNT()
|
||||||
|
{
|
||||||
|
OSVERSIONINFO versionInfo;
|
||||||
|
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
||||||
|
if (!::GetVersionEx(&versionInfo))
|
||||||
|
return false;
|
||||||
|
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef COMPRESS_BZIP2
|
#ifndef COMPRESS_BZIP2
|
||||||
#include "../Common/CodecsPath.h"
|
#include "../Common/CodecsPath.h"
|
||||||
@@ -34,7 +45,12 @@ extern "C"
|
|||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||||
{
|
{
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
if (dwReason == DLL_PROCESS_ATTACH)
|
||||||
|
{
|
||||||
g_hInstance = hInstance;
|
g_hInstance = hInstance;
|
||||||
|
#ifndef _UNICODE
|
||||||
|
g_IsNT = IsItWindowsNT();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,10 +102,10 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
case NArchive::kExtension:
|
case NArchive::kExtension:
|
||||||
propVariant = L"bz2 tbz2";
|
propVariant = L"bz2 bzip2 tbz2 tbz";
|
||||||
break;
|
break;
|
||||||
case NArchive::kAddExtension:
|
case NArchive::kAddExtension:
|
||||||
propVariant = L"* .tar";
|
propVariant = L"* * .tar .tar";
|
||||||
break;
|
break;
|
||||||
case NArchive::kUpdate:
|
case NArchive::kUpdate:
|
||||||
propVariant = true;
|
propVariant = true;
|
||||||
|
|||||||
55
7zip/Archive/BZip2/makefile
Executable file
55
7zip/Archive/BZip2/makefile
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
PROG = bz2.dll
|
||||||
|
DEF_FILE = ../Archive.def
|
||||||
|
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
|
||||||
|
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||||
|
|
||||||
|
BZ2_OBJS = \
|
||||||
|
$O\BZip2Handler.obj \
|
||||||
|
$O\BZip2HandlerOut.obj \
|
||||||
|
$O\BZip2Update.obj \
|
||||||
|
$O\DllExports.obj \
|
||||||
|
|
||||||
|
COMMON_OBJS = \
|
||||||
|
$O\Alloc.obj \
|
||||||
|
$O\NewHandler.obj \
|
||||||
|
$O\String.obj \
|
||||||
|
$O\StringConvert.obj \
|
||||||
|
$O\StringToInt.obj \
|
||||||
|
|
||||||
|
WIN_OBJS = \
|
||||||
|
$O\DLL.obj \
|
||||||
|
$O\PropVariant.obj \
|
||||||
|
|
||||||
|
7ZIP_COMMON_OBJS = \
|
||||||
|
$O\ProgressUtils.obj \
|
||||||
|
$O\StreamUtils.obj \
|
||||||
|
|
||||||
|
AR_COMMON_OBJS = \
|
||||||
|
$O\CodecsPath.obj \
|
||||||
|
$O\DummyOutStream.obj \
|
||||||
|
$O\ParseProperties.obj \
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
$O\StdAfx.obj \
|
||||||
|
$(BZ2_OBJS) \
|
||||||
|
$(COMMON_OBJS) \
|
||||||
|
$(WIN_OBJS) \
|
||||||
|
$(7ZIP_COMMON_OBJS) \
|
||||||
|
$(AR_COMMON_OBJS) \
|
||||||
|
$O\CopyCoder.obj \
|
||||||
|
$O\resource.res
|
||||||
|
|
||||||
|
!include "../../../Build.mak"
|
||||||
|
|
||||||
|
$(BZ2_OBJS): $(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Developer Studio generated include file.
|
|
||||||
// Used by resource.rc
|
|
||||||
//
|
|
||||||
#define IDI_ICON1 101
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,130 +1,5 @@
|
|||||||
//Microsoft Developer Studio generated resource script.
|
#include "../../MyVersionInfo.rc"
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
MY_VERSION_INFO_DLL("BZip2 Plugin", "bz2")
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Russian resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
|
||||||
#pragma code_page(1251)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Russian resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "bz2.ico"
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 4,19,0,0
|
|
||||||
PRODUCTVERSION 4,19,0,0
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS 0x1L
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS 0x40004L
|
|
||||||
FILETYPE 0x2L
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Comments", "\0"
|
|
||||||
VALUE "CompanyName", "Igor Pavlov\0"
|
|
||||||
VALUE "FileDescription", "BZip2 Plugin for 7-Zip\0"
|
|
||||||
VALUE "FileVersion", "4, 19, 0, 0\0"
|
|
||||||
VALUE "InternalName", "bz2\0"
|
|
||||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
|
||||||
VALUE "LegalTrademarks", "\0"
|
|
||||||
VALUE "OriginalFilename", "bz2.dll\0"
|
|
||||||
VALUE "PrivateBuild", "\0"
|
|
||||||
VALUE "ProductName", "7-Zip\0"
|
|
||||||
VALUE "ProductVersion", "4, 19, 0, 0\0"
|
|
||||||
VALUE "SpecialBuild", "\0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // !_MAC
|
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
101 ICON "bz2.ico"
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
; Cab.def
|
|
||||||
|
|
||||||
LIBRARY cab.dll
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
CreateObject PRIVATE
|
|
||||||
GetHandlerProperty PRIVATE
|
|
||||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
|||||||
# PROP Ignore_Export_Lib 1
|
# PROP Ignore_Export_Lib 1
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /c
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /c
|
||||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /c
|
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAs /Yu"StdAfx.h" /FD /c
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
|||||||
# PROP Ignore_Export_Lib 1
|
# PROP Ignore_Export_Lib 1
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAcs /Yu"StdAfx.h" /FD /GZ /c
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||||
@@ -93,7 +93,7 @@ LINK32=link.exe
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\Cab.def
|
SOURCE=..\Archive.def
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -101,10 +101,6 @@ SOURCE=.\DllExports.cpp
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\resource.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.rc
|
SOURCE=.\resource.rc
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -194,11 +190,11 @@ SOURCE=..\..\..\Windows\PropVariant.h
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\CabCopyDecoder.cpp
|
SOURCE=.\CabBlockInStream.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\CabCopyDecoder.h
|
SOURCE=.\CabBlockInStream.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -226,60 +222,8 @@ SOURCE=.\CabIn.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\CabInBuffer.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabInBuffer.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabItem.h
|
SOURCE=.\CabItem.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXBitDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXConst.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXDecoder.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXExtConst.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXi86Converter.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXi86Converter.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\MSZipConst.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\MSZipDecoder.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\MSZipDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\MSZipExtConst.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "7zip Common"
|
# Begin Group "7zip Common"
|
||||||
|
|
||||||
@@ -302,6 +246,10 @@ SOURCE=..\..\Common\LSBFDecoder.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\MSBFDecoder.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Common\OutBuffer.cpp
|
SOURCE=..\..\Common\OutBuffer.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -310,11 +258,11 @@ SOURCE=..\..\Common\OutBuffer.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
SOURCE=..\..\Common\StreamUtils.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.h
|
SOURCE=..\..\Common\StreamUtils.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Compress"
|
# Begin Group "Compress"
|
||||||
@@ -332,13 +280,115 @@ SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
|
|||||||
SOURCE=..\..\Compress\LZ\LZOutWindow.h
|
SOURCE=..\..\Compress\LZ\LZOutWindow.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# End Group
|
# Begin Group "Lzx"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\bitmap1.bmp
|
SOURCE=..\..\Compress\Lzx\Lzx.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "Cab - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\Lzx86Converter.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "Cab - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\LzxDecoder.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Deflate"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Deflate\DeflateConst.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "Cab - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Deflate\DeflateDecoder.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Deflate\DeflateExtConst.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Copy"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Quantum"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Quantum\QuantumDecoder.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Quantum\QuantumDecoder.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Huffman"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# End Group
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\cab.ico
|
SOURCE=.\cab.ico
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Target
|
# End Target
|
||||||
|
|||||||
194
7zip/Archive/Cab/CabBlockInStream.cpp
Executable file
194
7zip/Archive/Cab/CabBlockInStream.cpp
Executable file
@@ -0,0 +1,194 @@
|
|||||||
|
// CabBlockInStream.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Common/Alloc.h"
|
||||||
|
#include "Common/Defs.h"
|
||||||
|
|
||||||
|
#include "../../Common/StreamUtils.h"
|
||||||
|
|
||||||
|
#include "CabBlockInStream.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NCab {
|
||||||
|
|
||||||
|
static const UInt32 kBlockSize = (1 << 16);
|
||||||
|
|
||||||
|
bool CCabBlockInStream::Create()
|
||||||
|
{
|
||||||
|
if (!_buffer)
|
||||||
|
_buffer = (Byte *)::MyAlloc(kBlockSize);
|
||||||
|
return (_buffer != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCabBlockInStream::~CCabBlockInStream()
|
||||||
|
{
|
||||||
|
MyFree(_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CCheckSum2
|
||||||
|
{
|
||||||
|
UInt32 m_Value;
|
||||||
|
int m_Pos;
|
||||||
|
Byte m_Hist[4];
|
||||||
|
public:
|
||||||
|
CCheckSum2(): m_Value(0){};
|
||||||
|
void Init() { m_Value = 0; m_Pos = 0; }
|
||||||
|
void Update(const void *data, UInt32 size);
|
||||||
|
void FinishDataUpdate()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_Pos; i++)
|
||||||
|
m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1));
|
||||||
|
}
|
||||||
|
void UpdateUInt32(UInt32 v) { m_Value ^= v; }
|
||||||
|
UInt32 GetResult() const { return m_Value; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void CCheckSum2::Update(const void *data, UInt32 size)
|
||||||
|
{
|
||||||
|
UInt32 checkSum = m_Value;
|
||||||
|
const Byte *dataPointer = (const Byte *)data;
|
||||||
|
|
||||||
|
while (size != 0 && m_Pos != 0)
|
||||||
|
{
|
||||||
|
m_Hist[m_Pos] = *dataPointer++;
|
||||||
|
m_Pos = (m_Pos + 1) & 3;
|
||||||
|
size--;
|
||||||
|
if (m_Pos == 0)
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
checkSum ^= ((UInt32)m_Hist[i]) << (8 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int numWords = size / 4;
|
||||||
|
|
||||||
|
while (numWords-- != 0)
|
||||||
|
{
|
||||||
|
UInt32 temp = *dataPointer++;
|
||||||
|
temp |= ((UInt32)(*dataPointer++)) << 8;
|
||||||
|
temp |= ((UInt32)(*dataPointer++)) << 16;
|
||||||
|
temp |= ((UInt32)(*dataPointer++)) << 24;
|
||||||
|
checkSum ^= temp;
|
||||||
|
}
|
||||||
|
m_Value = checkSum;
|
||||||
|
|
||||||
|
size &= 3;
|
||||||
|
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
m_Hist[m_Pos] = *dataPointer++;
|
||||||
|
m_Pos = (m_Pos + 1) & 3;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const UInt32 kDataBlockHeaderSize = 8;
|
||||||
|
|
||||||
|
class CTempCabInBuffer2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Byte Buffer[kDataBlockHeaderSize];
|
||||||
|
UInt32 Pos;
|
||||||
|
Byte ReadByte()
|
||||||
|
{
|
||||||
|
return Buffer[Pos++];
|
||||||
|
}
|
||||||
|
UInt32 ReadUInt32()
|
||||||
|
{
|
||||||
|
UInt32 value = 0;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
value |= (((UInt32)ReadByte()) << (8 * i));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
UInt16 ReadUInt16()
|
||||||
|
{
|
||||||
|
UInt16 value = 0;
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
value |= (((UInt16)ReadByte()) << (8 * i));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize)
|
||||||
|
{
|
||||||
|
CTempCabInBuffer2 inBuffer;
|
||||||
|
inBuffer.Pos = 0;
|
||||||
|
UInt32 processedSizeLoc;
|
||||||
|
RINOK(ReadStream(_stream, inBuffer.Buffer, kDataBlockHeaderSize, &processedSizeLoc))
|
||||||
|
if (processedSizeLoc != kDataBlockHeaderSize)
|
||||||
|
return S_FALSE; // bad block
|
||||||
|
|
||||||
|
UInt32 checkSum = inBuffer.ReadUInt32();
|
||||||
|
packSize = inBuffer.ReadUInt16();
|
||||||
|
unpackSize = inBuffer.ReadUInt16();
|
||||||
|
if (ReservedSize != 0)
|
||||||
|
{
|
||||||
|
RINOK(ReadStream(_stream, _buffer, ReservedSize, &processedSizeLoc));
|
||||||
|
if(ReservedSize != processedSizeLoc)
|
||||||
|
return S_FALSE; // bad block;
|
||||||
|
}
|
||||||
|
_pos = 0;
|
||||||
|
CCheckSum2 checkSumCalc;
|
||||||
|
checkSumCalc.Init();
|
||||||
|
UInt32 packSize2 = packSize;
|
||||||
|
if (MsZip && _size == 0)
|
||||||
|
{
|
||||||
|
if (packSize < 2)
|
||||||
|
return S_FALSE; // bad block;
|
||||||
|
Byte sig[2];
|
||||||
|
RINOK(ReadStream(_stream, sig, 2, &processedSizeLoc));
|
||||||
|
if(processedSizeLoc != 2)
|
||||||
|
return S_FALSE;
|
||||||
|
if (sig[0] != 0x43 || sig[1] != 0x4B)
|
||||||
|
return S_FALSE;
|
||||||
|
packSize2 -= 2;
|
||||||
|
checkSumCalc.Update(sig, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kBlockSize - _size < packSize2)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
UInt32 curSize = packSize2;
|
||||||
|
if (curSize != 0)
|
||||||
|
{
|
||||||
|
RINOK(ReadStream(_stream, _buffer + _size, curSize, &processedSizeLoc));
|
||||||
|
checkSumCalc.Update(_buffer + _size, processedSizeLoc);
|
||||||
|
_size += processedSizeLoc;
|
||||||
|
if (processedSizeLoc != curSize)
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
TotalPackSize = _size;
|
||||||
|
|
||||||
|
checkSumCalc.FinishDataUpdate();
|
||||||
|
|
||||||
|
bool dataError;
|
||||||
|
if (checkSum == 0)
|
||||||
|
dataError = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checkSumCalc.UpdateUInt32(packSize | (((UInt32)unpackSize) << 16));
|
||||||
|
dataError = (checkSumCalc.GetResult() != checkSum);
|
||||||
|
}
|
||||||
|
DataError |= dataError;
|
||||||
|
return dataError ? S_FALSE : S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
|
{
|
||||||
|
if (processedSize != 0)
|
||||||
|
*processedSize = 0;
|
||||||
|
if (size == 0)
|
||||||
|
return S_OK;
|
||||||
|
if (_size != 0)
|
||||||
|
{
|
||||||
|
size = MyMin(_size, size);
|
||||||
|
memmove(data, _buffer + _pos, size);
|
||||||
|
_pos += size;
|
||||||
|
_size -= size;
|
||||||
|
if (processedSize != 0)
|
||||||
|
*processedSize = size;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
return S_OK; // no blocks data
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
56
7zip/Archive/Cab/CabBlockInStream.h
Executable file
56
7zip/Archive/Cab/CabBlockInStream.h
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
// CabBlockInStream.cpp
|
||||||
|
|
||||||
|
#ifndef __CABBLOCKINSTREAM_H
|
||||||
|
#define __CABBLOCKINSTREAM_H
|
||||||
|
|
||||||
|
#include "Common/MyCom.h"
|
||||||
|
#include "../../IStream.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NCab {
|
||||||
|
|
||||||
|
class CCabBlockInStream:
|
||||||
|
public ISequentialInStream,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
CMyComPtr<ISequentialInStream> _stream;
|
||||||
|
Byte *_buffer;
|
||||||
|
UInt32 _pos;
|
||||||
|
UInt32 _size;
|
||||||
|
int _align;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UInt32 TotalPackSize;
|
||||||
|
UInt32 ReservedSize;
|
||||||
|
bool DataError;
|
||||||
|
bool MsZip;
|
||||||
|
|
||||||
|
CCabBlockInStream(): _buffer(0), ReservedSize(0), MsZip(false), DataError(false), _align(0), TotalPackSize(0) {}
|
||||||
|
~CCabBlockInStream();
|
||||||
|
bool Create();
|
||||||
|
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
||||||
|
|
||||||
|
void InitForNewFolder()
|
||||||
|
{
|
||||||
|
_align = 0;
|
||||||
|
TotalPackSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitForNewBlock()
|
||||||
|
{
|
||||||
|
_size = 0;
|
||||||
|
_align = (_align + (int)TotalPackSize) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetAlign() const { return _align; }
|
||||||
|
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
|
||||||
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
|
||||||
|
HRESULT PreRead(UInt32 &packSize, UInt32 &unpackSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
// CabCopyDecoder.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "CabCopyDecoder.h"
|
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Windows/Defs.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
|
|
||||||
static const UInt32 kBufferSize = 1 << 17;
|
|
||||||
|
|
||||||
void CCopyDecoder::ReleaseStreams()
|
|
||||||
{
|
|
||||||
m_InStream.ReleaseStream();
|
|
||||||
m_OutStream.ReleaseStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
class CCopyDecoderFlusher
|
|
||||||
{
|
|
||||||
CCopyDecoder *m_Decoder;
|
|
||||||
public:
|
|
||||||
CCopyDecoderFlusher(CCopyDecoder *decoder): m_Decoder(decoder) {}
|
|
||||||
~CCopyDecoderFlusher()
|
|
||||||
{
|
|
||||||
m_Decoder->Flush();
|
|
||||||
m_Decoder->ReleaseStreams();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
STDMETHODIMP CCopyDecoder::Code(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
const UInt64 *inSize, const UInt64 *outSize,
|
|
||||||
ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
if (outSize == NULL)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
UInt64 size = *outSize;
|
|
||||||
|
|
||||||
if (!m_OutStream.Create(1 << 20))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
if (!m_InStream.Create(1 << 20))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
m_InStream.SetStream(inStream);
|
|
||||||
m_InStream.Init(m_ReservedSize, m_NumInDataBlocks);
|
|
||||||
m_OutStream.SetStream(outStream);
|
|
||||||
m_OutStream.Init();
|
|
||||||
CCopyDecoderFlusher decoderFlusher(this);
|
|
||||||
|
|
||||||
UInt64 nowPos64 = 0;
|
|
||||||
while(nowPos64 < size)
|
|
||||||
{
|
|
||||||
UInt32 blockSize;
|
|
||||||
bool dataAreCorrect;
|
|
||||||
RINOK(m_InStream.ReadBlock(blockSize, dataAreCorrect));
|
|
||||||
if (!dataAreCorrect)
|
|
||||||
{
|
|
||||||
throw 123456;
|
|
||||||
}
|
|
||||||
for (UInt32 i = 0; i < blockSize; i++)
|
|
||||||
m_OutStream.WriteByte(m_InStream.ReadByte());
|
|
||||||
nowPos64 += blockSize;
|
|
||||||
if (progress != NULL)
|
|
||||||
{
|
|
||||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
// CabCopyDecoder.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_COPY_DECODER_H
|
|
||||||
#define __ARCHIVE_CAB_COPY_DECODER_H
|
|
||||||
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
#include "../../Common/OutBuffer.h"
|
|
||||||
#include "CabInBuffer.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
|
|
||||||
class CCopyDecoder:
|
|
||||||
public ICompressCoder,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
CInBuffer m_InStream;
|
|
||||||
COutBuffer m_OutStream;
|
|
||||||
Byte m_ReservedSize;
|
|
||||||
UInt32 m_NumInDataBlocks;
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
const UInt64 *inSize, const UInt64 *outSize,
|
|
||||||
ICompressProgressInfo *progress);
|
|
||||||
|
|
||||||
void ReleaseStreams();
|
|
||||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
|
||||||
void SetParams(Byte reservedSize, UInt32 numInDataBlocks)
|
|
||||||
{
|
|
||||||
m_ReservedSize = reservedSize;
|
|
||||||
m_NumInDataBlocks = numInDataBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -37,12 +37,9 @@ public:
|
|||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CObjectVector<NHeader::CFolder> m_Folders;
|
CMvDatabaseEx m_Database;
|
||||||
CObjectVector<CItem> m_Files;
|
|
||||||
CInArchiveInfo m_ArchiveInfo;
|
|
||||||
CMyComPtr<IInStream> m_Stream;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ static class CSignatureInitializer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|||||||
@@ -9,53 +9,15 @@ namespace NArchive {
|
|||||||
namespace NCab {
|
namespace NCab {
|
||||||
namespace NHeader{
|
namespace NHeader{
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive
|
||||||
|
{
|
||||||
extern UInt32 kSignature;
|
extern UInt32 kSignature;
|
||||||
|
|
||||||
namespace NFlags
|
namespace NFlags
|
||||||
{
|
{
|
||||||
const int kPrevCabinet = 0x0001;
|
const int kPrevCabinet = 0x0001;
|
||||||
const int kNextCabinet = 0x0002;
|
const int kNextCabinet = 0x0002;
|
||||||
const int kReservePresent = 0x0004;
|
const int kReservePresent = 0x0004;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UInt32 kArchiveHeaderSize = 36;
|
|
||||||
/*
|
|
||||||
struct CBlock
|
|
||||||
{
|
|
||||||
UInt32 Signature; // cabinet file signature
|
|
||||||
UInt32 Reserved1; // reserved
|
|
||||||
UInt32 Size; // size of this cabinet file in bytes
|
|
||||||
UInt32 Reserved2; // reserved
|
|
||||||
UInt32 FileOffset; // offset of the first CFFILE entry
|
|
||||||
UInt32 Reserved3; // reserved
|
|
||||||
Byte VersionMinor; // cabinet file format version, minor
|
|
||||||
Byte VersionMajor; // cabinet file format version, major
|
|
||||||
UInt16 NumFolders; // number of CFFOLDER entries in this cabinet
|
|
||||||
UInt16 NumFiles; // number of CFFILE entries in this cabinet
|
|
||||||
UInt16 Flags; // cabinet file option indicators
|
|
||||||
UInt16 SetID; // must be the same for all cabinets in a set
|
|
||||||
UInt16 CabinetNumber; // number of this cabinet file in a set
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
const UInt32 kPerDataSizesHeaderSize = 4;
|
|
||||||
|
|
||||||
struct CPerDataSizes
|
|
||||||
{
|
|
||||||
UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area
|
|
||||||
Byte PerFolderAreaSize; // (optional) size of per-folder reserved area
|
|
||||||
Byte PerDatablockAreaSize; // (optional) size of per-datablock reserved area
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Byte abReserve[]; // (optional) per-cabinet reserved area
|
|
||||||
Byte szCabinetPrev[]; // (optional) name of previous cabinet file
|
|
||||||
Byte szDiskPrev[]; // (optional) name of previous disk
|
|
||||||
Byte szCabinetNext[]; // (optional) name of next cabinet file
|
|
||||||
Byte szDiskNext[]; // (optional) name of next disk
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NCompressionMethodMajor
|
namespace NCompressionMethodMajor
|
||||||
@@ -66,17 +28,6 @@ namespace NCompressionMethodMajor
|
|||||||
const Byte kLZX = 3;
|
const Byte kLZX = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UInt32 kFolderHeaderSize = 8;
|
|
||||||
struct CFolder
|
|
||||||
{
|
|
||||||
UInt32 DataStart; // offset of the first CFDATA block in this folder
|
|
||||||
UInt16 NumDataBlocks; // number of CFDATA blocks in this folder
|
|
||||||
Byte CompressionTypeMajor;
|
|
||||||
Byte CompressionTypeMinor;
|
|
||||||
// Byte abReserve[]; // (optional) per-folder reserved area
|
|
||||||
Byte GetCompressionMethod() const { return CompressionTypeMajor & 0xF; }
|
|
||||||
};
|
|
||||||
|
|
||||||
const int kFileNameIsUTFAttributeMask = 0x80;
|
const int kFileNameIsUTFAttributeMask = 0x80;
|
||||||
|
|
||||||
namespace NFolderIndex
|
namespace NFolderIndex
|
||||||
@@ -84,34 +35,8 @@ namespace NFolderIndex
|
|||||||
const int kContinuedFromPrev = 0xFFFD;
|
const int kContinuedFromPrev = 0xFFFD;
|
||||||
const int kContinuedToNext = 0xFFFE;
|
const int kContinuedToNext = 0xFFFE;
|
||||||
const int kContinuedPrevAndNext = 0xFFFF;
|
const int kContinuedPrevAndNext = 0xFFFF;
|
||||||
inline UInt16 GetRealFolderIndex(UInt16 aNumFolders, UInt16 aFolderIndex)
|
|
||||||
{
|
|
||||||
switch(aFolderIndex)
|
|
||||||
{
|
|
||||||
case kContinuedFromPrev:
|
|
||||||
return 0;
|
|
||||||
case kContinuedToNext:
|
|
||||||
case kContinuedPrevAndNext:
|
|
||||||
return aNumFolders - 1;
|
|
||||||
default:
|
|
||||||
return aFolderIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const UInt32 kFileHeaderSize = 16;
|
|
||||||
/*
|
|
||||||
struct CFile
|
|
||||||
{
|
|
||||||
UInt32 UnPackSize; // uncompressed size of this file in bytes
|
|
||||||
UInt32 UnPackOffset; // uncompressed offset of this file in the folder
|
|
||||||
UInt16 FolderIndex; // index into the CFFOLDER area
|
|
||||||
UInt16 PureDate;
|
|
||||||
UInt16 PureTime; // Time
|
|
||||||
UInt16 Attributes; // attribute flags for this file
|
|
||||||
Byte szName[]; // name of this file
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
#include "Common/MyCom.h"
|
#include "Common/MyCom.h"
|
||||||
#include "CabIn.h"
|
#include "CabIn.h"
|
||||||
#include "Windows/Defs.h"
|
#include "Windows/Defs.h"
|
||||||
#include "../../Common/InBuffer.h"
|
|
||||||
|
#include "../../Common/StreamUtils.h"
|
||||||
|
|
||||||
namespace NArchive{
|
namespace NArchive{
|
||||||
namespace NCab{
|
namespace NCab{
|
||||||
@@ -14,7 +15,7 @@ namespace NCab{
|
|||||||
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
|
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
|
||||||
{
|
{
|
||||||
UInt32 realProcessedSize;
|
UInt32 realProcessedSize;
|
||||||
RINOK(inStream->Read(data, size, &realProcessedSize));
|
RINOK(ReadStream(inStream, data, size, &realProcessedSize));
|
||||||
if(realProcessedSize != size)
|
if(realProcessedSize != size)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -23,7 +24,7 @@ static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
|
|||||||
static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size)
|
static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size)
|
||||||
{
|
{
|
||||||
UInt32 realProcessedSize;
|
UInt32 realProcessedSize;
|
||||||
RINOK(inStream->Read(data, size, &realProcessedSize));
|
RINOK(ReadStream(inStream, data, size, &realProcessedSize));
|
||||||
if(realProcessedSize != size)
|
if(realProcessedSize != size)
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -37,25 +38,12 @@ static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size)
|
|||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SafeReadName(::CInBuffer &inBuffer, AString &name)
|
|
||||||
{
|
|
||||||
name.Empty();
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
Byte b;
|
|
||||||
if (!inBuffer.ReadByte(b))
|
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
|
||||||
if (b == 0)
|
|
||||||
return;
|
|
||||||
name += char(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte CInArchive::ReadByte()
|
Byte CInArchive::ReadByte()
|
||||||
{
|
{
|
||||||
if (_blockPos >= _blockSize)
|
Byte b;
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
if (!inBuffer.ReadByte(b))
|
||||||
return _block[_blockPos++];
|
throw CInArchiveException(CInArchiveException::kUnsupported);
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt16 CInArchive::ReadUInt16()
|
UInt16 CInArchive::ReadUInt16()
|
||||||
@@ -80,20 +68,38 @@ UInt32 CInArchive::ReadUInt32()
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CInArchive::Open(IInStream *inStream,
|
AString CInArchive::SafeReadName()
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
|
||||||
CInArchiveInfo &inArchiveInfo,
|
|
||||||
CObjectVector<NHeader::CFolder> &folders,
|
|
||||||
CObjectVector<CItem> &files,
|
|
||||||
CProgressVirt *progressVirt)
|
|
||||||
{
|
{
|
||||||
UInt64 startPosition;
|
AString name;
|
||||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition));
|
while(true)
|
||||||
|
{
|
||||||
|
Byte b = ReadByte();
|
||||||
|
if (b == 0)
|
||||||
|
return name;
|
||||||
|
name += (char)b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NHeader::NArchive::CBlock archiveHeader;
|
void CInArchive::ReadOtherArchive(COtherArchive &oa)
|
||||||
|
{
|
||||||
|
oa.FileName = SafeReadName();
|
||||||
|
oa.DiskName = SafeReadName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInArchive::Skeep(size_t size)
|
||||||
|
{
|
||||||
|
while (size-- != 0)
|
||||||
|
ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::Open2(IInStream *inStream,
|
||||||
|
const UInt64 *searchHeaderSizeLimit,
|
||||||
|
CDatabase &database)
|
||||||
|
{
|
||||||
|
database.Clear();
|
||||||
|
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition));
|
||||||
|
|
||||||
{
|
{
|
||||||
::CInBuffer inBuffer;
|
|
||||||
if (!inBuffer.Create(1 << 17))
|
if (!inBuffer.Create(1 << 17))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
inBuffer.SetStream(inStream);
|
inBuffer.SetStream(inStream);
|
||||||
@@ -117,139 +123,219 @@ HRESULT CInArchive::Open(IInStream *inStream,
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startPosition += inBuffer.GetProcessedSize() - kSignatureSize;
|
database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize;
|
||||||
}
|
}
|
||||||
RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL));
|
|
||||||
|
|
||||||
RINOK(ReadBytes(inStream, _block, NHeader::NArchive::kArchiveHeaderSize));
|
CInArchiveInfo &archiveInfo = database.ArchiveInfo;
|
||||||
_blockSize = NHeader::NArchive::kArchiveHeaderSize;
|
|
||||||
_blockPos = 0;
|
|
||||||
|
|
||||||
ReadUInt32(); // Signature; // cabinet file signature
|
archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes
|
||||||
// if (archiveHeader.Signature != NHeader::NArchive::kSignature)
|
if (ReadUInt32() != 0)
|
||||||
// return S_FALSE;
|
return S_FALSE;
|
||||||
|
archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry
|
||||||
|
if (ReadUInt32() != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
UInt32 reserved1 = ReadUInt32();
|
archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor
|
||||||
UInt32 size = ReadUInt32(); // size of this cabinet file in bytes
|
archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
|
||||||
UInt32 reserved2 = ReadUInt32();
|
archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
|
||||||
UInt32 fileOffset = ReadUInt32(); // offset of the first CFFILE entry
|
archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
|
||||||
UInt32 reserved3 = ReadUInt32();
|
archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet
|
||||||
|
archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
|
||||||
|
archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
|
||||||
|
|
||||||
inArchiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor
|
if (archiveInfo.ReserveBlockPresent())
|
||||||
inArchiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
|
|
||||||
inArchiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
|
|
||||||
inArchiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
|
|
||||||
inArchiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet
|
|
||||||
UInt16 setID = ReadUInt16(); // must be the same for all cabinets in a set
|
|
||||||
UInt16 cabinetNumber = ReadUInt16(); // number of this cabinet file in a set
|
|
||||||
|
|
||||||
if (reserved1 != 0 || reserved2 != 0 || reserved3 != 0)
|
|
||||||
throw CInArchiveException(CInArchiveException::kUnsupported);
|
|
||||||
|
|
||||||
if (inArchiveInfo.ReserveBlockPresent())
|
|
||||||
{
|
{
|
||||||
RINOK(SafeRead(inStream, _block, NHeader::NArchive::kPerDataSizesHeaderSize));
|
archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area
|
||||||
_blockSize = NHeader::NArchive::kPerDataSizesHeaderSize;
|
archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area
|
||||||
_blockPos = 0;
|
archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area
|
||||||
|
|
||||||
inArchiveInfo.PerDataSizes.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area
|
Skeep(archiveInfo.PerCabinetAreaSize);
|
||||||
inArchiveInfo.PerDataSizes.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area
|
|
||||||
inArchiveInfo.PerDataSizes.PerDatablockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area
|
|
||||||
RINOK(inStream->Seek(inArchiveInfo.PerDataSizes.PerCabinetAreaSize,
|
|
||||||
STREAM_SEEK_CUR, NULL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt64 foldersStartPosition;
|
if (archiveInfo.IsTherePrev())
|
||||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition));
|
ReadOtherArchive(archiveInfo.PreviousArchive);
|
||||||
::CInBuffer inBuffer;
|
if (archiveInfo.IsThereNext())
|
||||||
if (!inBuffer.Create(1 << 17))
|
ReadOtherArchive(archiveInfo.NextArchive);
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
inBuffer.SetStream(inStream);
|
|
||||||
inBuffer.Init();
|
|
||||||
if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0)
|
|
||||||
{
|
|
||||||
SafeReadName(inBuffer, inArchiveInfo.PreviousCabinetName);
|
|
||||||
SafeReadName(inBuffer, inArchiveInfo.PreviousDiskName);
|
|
||||||
}
|
|
||||||
if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0)
|
|
||||||
{
|
|
||||||
SafeReadName(inBuffer, inArchiveInfo.NextCabinetName);
|
|
||||||
SafeReadName(inBuffer, inArchiveInfo.NextDiskName);
|
|
||||||
}
|
|
||||||
foldersStartPosition += inBuffer.GetProcessedSize();
|
|
||||||
RINOK(inStream->Seek(foldersStartPosition, STREAM_SEEK_SET, NULL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progressVirt != NULL)
|
|
||||||
{
|
|
||||||
UInt64 numFiles = inArchiveInfo.NumFiles;
|
|
||||||
RINOK(progressVirt->SetTotal(&numFiles));
|
|
||||||
}
|
|
||||||
folders.Clear();
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < inArchiveInfo.NumFolders; i++)
|
for(i = 0; i < archiveInfo.NumFolders; i++)
|
||||||
{
|
{
|
||||||
if (progressVirt != NULL)
|
CFolder folder;
|
||||||
{
|
|
||||||
UInt64 numFiles = 0;
|
|
||||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
|
||||||
}
|
|
||||||
NHeader::CFolder folder;
|
|
||||||
RINOK(SafeRead(inStream, _block, NHeader::kFolderHeaderSize));
|
|
||||||
_blockSize = NHeader::kFolderHeaderSize;
|
|
||||||
_blockPos = 0;
|
|
||||||
|
|
||||||
folder.DataStart = ReadUInt32();
|
folder.DataStart = ReadUInt32();
|
||||||
folder.NumDataBlocks = ReadUInt16();
|
folder.NumDataBlocks = ReadUInt16();
|
||||||
folder.CompressionTypeMajor = ReadByte();
|
folder.CompressionTypeMajor = ReadByte();
|
||||||
folder.CompressionTypeMinor = ReadByte();
|
folder.CompressionTypeMinor = ReadByte();
|
||||||
|
|
||||||
if (inArchiveInfo.ReserveBlockPresent())
|
Skeep(archiveInfo.PerFolderAreaSize);
|
||||||
{
|
database.Folders.Add(folder);
|
||||||
RINOK(inStream->Seek(
|
|
||||||
inArchiveInfo.PerDataSizes.PerFolderAreaSize, STREAM_SEEK_CUR, NULL));
|
|
||||||
}
|
|
||||||
folder.DataStart += (UInt32)startPosition;
|
|
||||||
folders.Add(folder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(inStream->Seek(startPosition + fileOffset,
|
RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
||||||
STREAM_SEEK_SET, NULL));
|
|
||||||
|
|
||||||
::CInBuffer inBuffer;
|
|
||||||
if (!inBuffer.Create(1 << 17))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
inBuffer.SetStream(inStream);
|
inBuffer.SetStream(inStream);
|
||||||
inBuffer.Init();
|
inBuffer.Init();
|
||||||
files.Clear();
|
for(i = 0; i < archiveInfo.NumFiles; i++)
|
||||||
if (progressVirt != NULL)
|
|
||||||
{
|
{
|
||||||
UInt64 numFiles = files.Size();
|
|
||||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
|
||||||
}
|
|
||||||
for(i = 0; i < inArchiveInfo.NumFiles; i++)
|
|
||||||
{
|
|
||||||
SafeInByteRead(inBuffer, _block, NHeader::kFileHeaderSize);
|
|
||||||
_blockSize = NHeader::kFileHeaderSize;
|
|
||||||
_blockPos = 0;
|
|
||||||
CItem item;
|
CItem item;
|
||||||
item.UnPackSize = ReadUInt32();
|
item.Size = ReadUInt32();
|
||||||
item.UnPackOffset = ReadUInt32();
|
item.Offset = ReadUInt32();
|
||||||
item.FolderIndex = ReadUInt16();
|
item.FolderIndex = ReadUInt16();
|
||||||
UInt16 pureDate = ReadUInt16();
|
UInt16 pureDate = ReadUInt16();
|
||||||
UInt16 pureTime = ReadUInt16();
|
UInt16 pureTime = ReadUInt16();
|
||||||
item.Time = ((UInt32(pureDate) << 16)) | pureTime;
|
item.Time = ((UInt32(pureDate) << 16)) | pureTime;
|
||||||
item.Attributes = ReadUInt16();
|
item.Attributes = ReadUInt16();
|
||||||
SafeReadName(inBuffer, item.Name);
|
item.Name = SafeReadName();
|
||||||
files.Add(item);
|
int folderIndex = item.GetFolderIndex(database.Folders.Size());
|
||||||
if (progressVirt != NULL)
|
if (folderIndex >= database.Folders.Size())
|
||||||
{
|
return S_FALSE;
|
||||||
UInt64 numFiles = files.Size();
|
database.Items.Add(item);
|
||||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
||||||
|
|
||||||
|
HRESULT CInArchive::Open(
|
||||||
|
const UInt64 *searchHeaderSizeLimit,
|
||||||
|
CDatabaseEx &database)
|
||||||
|
{
|
||||||
|
return Open2(database.Stream, searchHeaderSizeLimit, database);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int CompareMvItems2(const CMvItem *p1, const CMvItem *p2)
|
||||||
|
{
|
||||||
|
RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex));
|
||||||
|
return MyCompare(p1->ItemIndex, p2->ItemIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
||||||
|
{
|
||||||
|
const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param;
|
||||||
|
const CDatabaseEx &db1 = mvDb.Volumes[p1->VolumeIndex];
|
||||||
|
const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex];
|
||||||
|
const CItem &item1 = db1.Items[p1->ItemIndex];
|
||||||
|
const CItem &item2 = db2.Items[p2->ItemIndex];;
|
||||||
|
bool isDir1 = item1.IsDirectory();
|
||||||
|
bool isDir2 = item2.IsDirectory();
|
||||||
|
if (isDir1 && !isDir2)
|
||||||
|
return -1;
|
||||||
|
if (isDir2 && !isDir1)
|
||||||
|
return 1;
|
||||||
|
int f1 = mvDb.GetFolderIndex(p1);
|
||||||
|
int f2 = mvDb.GetFolderIndex(p2);
|
||||||
|
RINOZ(MyCompare(f1, f2));
|
||||||
|
RINOZ(MyCompare(item1.Offset, item2.Offset));
|
||||||
|
RINOZ(MyCompare(item1.Size, item2.Size));
|
||||||
|
return CompareMvItems2(p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMvDatabaseEx::AreItemsEqual(int i1, int i2)
|
||||||
|
{
|
||||||
|
const CMvItem *p1 = &Items[i1];
|
||||||
|
const CMvItem *p2 = &Items[i2];
|
||||||
|
const CDatabaseEx &db1 = Volumes[p1->VolumeIndex];
|
||||||
|
const CDatabaseEx &db2 = Volumes[p2->VolumeIndex];
|
||||||
|
const CItem &item1 = db1.Items[p1->ItemIndex];
|
||||||
|
const CItem &item2 = db2.Items[p2->ItemIndex];;
|
||||||
|
int f1 = GetFolderIndex(p1);
|
||||||
|
int f2 = GetFolderIndex(p2);
|
||||||
|
if (f1 != f2)
|
||||||
|
return false;
|
||||||
|
if (item1.Offset != item2.Offset)
|
||||||
|
return false;
|
||||||
|
if (item1.Size != item2.Size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMvDatabaseEx::FillSortAndShrink()
|
||||||
|
{
|
||||||
|
Items.Clear();
|
||||||
|
StartFolderOfVol.Clear();
|
||||||
|
FolderStartFileIndex.Clear();
|
||||||
|
int offset = 0;
|
||||||
|
for (int v = 0; v < Volumes.Size(); v++)
|
||||||
|
{
|
||||||
|
const CDatabaseEx &db = Volumes[v];
|
||||||
|
int curOffset = offset;
|
||||||
|
if (db.IsTherePrevFolder())
|
||||||
|
curOffset--;
|
||||||
|
StartFolderOfVol.Add(curOffset);
|
||||||
|
offset += db.GetNumberOfNewFolders();
|
||||||
|
|
||||||
|
CMvItem mvItem;
|
||||||
|
mvItem.VolumeIndex = v;
|
||||||
|
for (int i = 0 ; i < db.Items.Size(); i++)
|
||||||
|
{
|
||||||
|
mvItem.ItemIndex = i;
|
||||||
|
Items.Add(mvItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Items.Sort(CompareMvItems, (void *)this);
|
||||||
|
int j = 1;
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < Items.Size(); i++)
|
||||||
|
if (!AreItemsEqual(i, i -1))
|
||||||
|
Items[j++] = Items[i];
|
||||||
|
Items.DeleteFrom(j);
|
||||||
|
|
||||||
|
for (i = 0; i < Items.Size(); i++)
|
||||||
|
{
|
||||||
|
const CMvItem &mvItem = Items[i];
|
||||||
|
int folderIndex = GetFolderIndex(&mvItem);
|
||||||
|
if (folderIndex >= FolderStartFileIndex.Size())
|
||||||
|
FolderStartFileIndex.Add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMvDatabaseEx::Check()
|
||||||
|
{
|
||||||
|
for (int v = 1; v < Volumes.Size(); v++)
|
||||||
|
{
|
||||||
|
const CDatabaseEx &db1 = Volumes[v];
|
||||||
|
if (db1.IsTherePrevFolder())
|
||||||
|
{
|
||||||
|
const CDatabaseEx &db0 = Volumes[v - 1];
|
||||||
|
if (db0.Folders.IsEmpty() || db1.Folders.IsEmpty())
|
||||||
|
return false;
|
||||||
|
const CFolder &f0 = db0.Folders.Back();
|
||||||
|
const CFolder &f1 = db1.Folders.Front();
|
||||||
|
if (f0.CompressionTypeMajor != f1.CompressionTypeMajor ||
|
||||||
|
f0.CompressionTypeMinor != f1.CompressionTypeMinor)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UInt64 maxPos = 0;
|
||||||
|
int prevFolder = -2;
|
||||||
|
for(int i = 0; i < Items.Size(); i++)
|
||||||
|
{
|
||||||
|
const CMvItem &mvItem = Items[i];
|
||||||
|
int fIndex = GetFolderIndex(&mvItem);
|
||||||
|
if (fIndex >= FolderStartFileIndex.Size())
|
||||||
|
return false;
|
||||||
|
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||||
|
if (item.IsDirectory())
|
||||||
|
continue;
|
||||||
|
int folderIndex = GetFolderIndex(&mvItem);
|
||||||
|
if (folderIndex != prevFolder)
|
||||||
|
{
|
||||||
|
prevFolder = folderIndex;
|
||||||
|
maxPos = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (item.Offset < maxPos)
|
||||||
|
return false;
|
||||||
|
maxPos = item.GetEndOffset();
|
||||||
|
if (maxPos < item.Offset)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define __ARCHIVE_CAB_IN_H
|
#define __ARCHIVE_CAB_IN_H
|
||||||
|
|
||||||
#include "../../IStream.h"
|
#include "../../IStream.h"
|
||||||
|
#include "../../Common/InBuffer.h"
|
||||||
#include "CabHeader.h"
|
#include "CabHeader.h"
|
||||||
#include "CabItem.h"
|
#include "CabItem.h"
|
||||||
|
|
||||||
@@ -22,10 +23,14 @@ public:
|
|||||||
CInArchiveException(CCauseType cause) : Cause(cause) {}
|
CInArchiveException(CCauseType cause) : Cause(cause) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CInArchiveInfo
|
struct COtherArchive
|
||||||
|
{
|
||||||
|
AString FileName;
|
||||||
|
AString DiskName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CArchiveInfo
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
UInt32 Size; /* size of this cabinet file in bytes */
|
|
||||||
Byte VersionMinor; /* cabinet file format version, minor */
|
Byte VersionMinor; /* cabinet file format version, minor */
|
||||||
Byte VersionMajor; /* cabinet file format version, major */
|
Byte VersionMajor; /* cabinet file format version, major */
|
||||||
UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */
|
UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */
|
||||||
@@ -35,39 +40,125 @@ public:
|
|||||||
UInt16 CabinetNumber; /* number of this cabinet file in a set */
|
UInt16 CabinetNumber; /* number of this cabinet file in a set */
|
||||||
|
|
||||||
bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }
|
bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }
|
||||||
NHeader::NArchive::CPerDataSizes PerDataSizes;
|
|
||||||
|
|
||||||
AString PreviousCabinetName;
|
bool IsTherePrev() const { return (Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0; }
|
||||||
AString PreviousDiskName;
|
bool IsThereNext() const { return (Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0; }
|
||||||
AString NextCabinetName;
|
|
||||||
AString NextDiskName;
|
UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area
|
||||||
|
Byte PerFolderAreaSize; // (optional) size of per-folder reserved area
|
||||||
|
Byte PerDataBlockAreaSize; // (optional) size of per-datablock reserved area
|
||||||
|
|
||||||
|
Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); }
|
||||||
|
|
||||||
|
COtherArchive PreviousArchive;
|
||||||
|
COtherArchive NextArchive;
|
||||||
|
|
||||||
|
CArchiveInfo()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
PerCabinetAreaSize = 0;
|
||||||
|
PerFolderAreaSize = 0;
|
||||||
|
PerDataBlockAreaSize = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CProgressVirt
|
struct CInArchiveInfo: public CArchiveInfo
|
||||||
|
{
|
||||||
|
UInt32 Size; /* size of this cabinet file in bytes */
|
||||||
|
UInt32 FileHeadersOffset; //offset of the first CFFILE entry
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CDatabase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE;
|
UInt64 StartPosition;
|
||||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
CInArchiveInfo ArchiveInfo;
|
||||||
|
CObjectVector<CFolder> Folders;
|
||||||
|
CObjectVector<CItem> Items;
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
ArchiveInfo.Clear();
|
||||||
|
Folders.Clear();
|
||||||
|
Items.Clear();
|
||||||
|
}
|
||||||
|
bool IsTherePrevFolder() const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Items.Size(); i++)
|
||||||
|
if (Items[i].ContinuedFromPrev())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int GetNumberOfNewFolders() const
|
||||||
|
{
|
||||||
|
int res = Folders.Size();
|
||||||
|
if (IsTherePrevFolder())
|
||||||
|
res--;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
UInt32 GetFileOffset(int index) const { return Items[index].Offset; }
|
||||||
|
UInt32 GetFileSize(int index) const { return Items[index].Size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
const UInt32 kMaxBlockSize = NHeader::NArchive::kArchiveHeaderSize;
|
class CDatabaseEx: public CDatabase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMyComPtr<IInStream> Stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMvItem
|
||||||
|
{
|
||||||
|
int VolumeIndex;
|
||||||
|
int ItemIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CMvDatabaseEx
|
||||||
|
{
|
||||||
|
bool AreItemsEqual(int i1, int i2);
|
||||||
|
public:
|
||||||
|
CObjectVector<CDatabaseEx> Volumes;
|
||||||
|
CRecordVector<CMvItem> Items;
|
||||||
|
CRecordVector<int> StartFolderOfVol;
|
||||||
|
CRecordVector<int> FolderStartFileIndex;
|
||||||
|
int GetFolderIndex(const CMvItem *mvi) const
|
||||||
|
{
|
||||||
|
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
|
||||||
|
return StartFolderOfVol[mvi->VolumeIndex] +
|
||||||
|
db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
|
||||||
|
}
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
Volumes.Clear();
|
||||||
|
Items.Clear();
|
||||||
|
StartFolderOfVol.Clear();
|
||||||
|
FolderStartFileIndex.Clear();
|
||||||
|
}
|
||||||
|
void FillSortAndShrink();
|
||||||
|
bool Check();
|
||||||
|
};
|
||||||
|
|
||||||
class CInArchive
|
class CInArchive
|
||||||
{
|
{
|
||||||
UInt16 _blockSize;
|
CInBuffer inBuffer;
|
||||||
Byte _block[kMaxBlockSize];
|
|
||||||
UInt32 _blockPos;
|
|
||||||
|
|
||||||
Byte ReadByte();
|
Byte ReadByte();
|
||||||
UInt16 ReadUInt16();
|
UInt16 ReadUInt16();
|
||||||
UInt32 ReadUInt32();
|
UInt32 ReadUInt32();
|
||||||
public:
|
AString SafeReadName();
|
||||||
HRESULT Open(IInStream *inStream,
|
void Skeep(size_t size);
|
||||||
|
void ReadOtherArchive(COtherArchive &oa);
|
||||||
|
|
||||||
|
HRESULT Open2(IInStream *inStream,
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
const UInt64 *searchHeaderSizeLimit,
|
||||||
CInArchiveInfo &inArchiveInfo,
|
CDatabase &database);
|
||||||
CObjectVector<NHeader::CFolder> &folders,
|
public:
|
||||||
CObjectVector<CItem> &files,
|
HRESULT Open(
|
||||||
CProgressVirt *progressVirt);
|
const UInt64 *searchHeaderSizeLimit,
|
||||||
|
CDatabaseEx &database);
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,175 +0,0 @@
|
|||||||
// Archive/CabInBuffer.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "../../../Common/Alloc.h"
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
#include "../../../Windows/Defs.h"
|
|
||||||
#include "CabInBuffer.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
|
|
||||||
static const UInt32 kDataBlockHeaderSize = 8;
|
|
||||||
/*
|
|
||||||
struct CDataBlockHeader
|
|
||||||
{
|
|
||||||
UInt32 CheckSum; // checksum of this CFDATA entry
|
|
||||||
UInt16 PackSize; // number of compressed bytes in this block
|
|
||||||
UInt16 UnPackSize; // number of uncompressed bytes in this block
|
|
||||||
// Byte abReserve[]; // (optional) per-datablock reserved area
|
|
||||||
// Byte ab[cbData]; // compressed data bytes
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
class CTempCabInBuffer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Byte *Buffer;
|
|
||||||
UInt32 Size;
|
|
||||||
UInt32 Pos;
|
|
||||||
Byte ReadByte()
|
|
||||||
{
|
|
||||||
if (Pos >= Size)
|
|
||||||
throw "overflow";
|
|
||||||
return Buffer[Pos++];
|
|
||||||
}
|
|
||||||
UInt32 ReadUInt32()
|
|
||||||
{
|
|
||||||
UInt32 value = 0;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
value |= (((UInt32)ReadByte()) << (8 * i));
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
UInt16 ReadUInt16()
|
|
||||||
{
|
|
||||||
UInt16 value = 0;
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
value |= (((UInt16)ReadByte()) << (8 * i));
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool CInBuffer::Create(UInt32 bufferSize)
|
|
||||||
{
|
|
||||||
const UInt32 kMinBlockSize = 1;
|
|
||||||
if (bufferSize < kMinBlockSize)
|
|
||||||
bufferSize = kMinBlockSize;
|
|
||||||
if (m_Buffer != 0 && m_BufferSize == bufferSize)
|
|
||||||
return true;
|
|
||||||
Free();
|
|
||||||
m_BufferSize = bufferSize;
|
|
||||||
m_Buffer = (Byte *)::BigAlloc(bufferSize);
|
|
||||||
return (m_Buffer != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInBuffer::Free()
|
|
||||||
{
|
|
||||||
BigFree(m_Buffer);
|
|
||||||
m_Buffer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInBuffer::Init(Byte reservedSize, UInt32 numBlocks)
|
|
||||||
{
|
|
||||||
m_ReservedSize = reservedSize;
|
|
||||||
m_NumBlocks = numBlocks;
|
|
||||||
m_CurrentBlockIndex = 0;
|
|
||||||
m_ProcessedSize = 0;
|
|
||||||
m_Pos = 0;
|
|
||||||
m_NumReadBytesInBuffer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
class CCheckSum
|
|
||||||
{
|
|
||||||
UInt32 m_Value;
|
|
||||||
public:
|
|
||||||
CCheckSum(): m_Value(0){};
|
|
||||||
void Init() { m_Value = 0; }
|
|
||||||
void Update(const void *data, UInt32 size);
|
|
||||||
void UpdateUInt32(UInt32 v) { m_Value ^= v; }
|
|
||||||
UInt32 GetResult() const { return m_Value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
void CCheckSum::Update(const void *data, UInt32 size)
|
|
||||||
{
|
|
||||||
UInt32 checkSum = m_Value;
|
|
||||||
const Byte *dataPointer = (const Byte *)data;
|
|
||||||
int numUINT32Words = size / 4; // Number of ULONGs
|
|
||||||
|
|
||||||
UInt32 temp;
|
|
||||||
while (numUINT32Words-- > 0)
|
|
||||||
{
|
|
||||||
temp = *dataPointer++;
|
|
||||||
temp |= (((UInt32)(*dataPointer++)) << 8);
|
|
||||||
temp |= (((UInt32)(*dataPointer++)) << 16);
|
|
||||||
temp |= (((UInt32)(*dataPointer++)) << 24);
|
|
||||||
checkSum ^= temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = 0;
|
|
||||||
int rem = (size & 3);
|
|
||||||
if (rem >= 3)
|
|
||||||
temp |= (((UInt32)(*dataPointer++)) << 16);
|
|
||||||
if (rem >= 2)
|
|
||||||
temp |= (((UInt32)(*dataPointer++)) << 8);
|
|
||||||
if (rem >= 1)
|
|
||||||
temp |= *dataPointer++;
|
|
||||||
checkSum ^= temp;
|
|
||||||
m_Value = checkSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CInBuffer::ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
|
|
||||||
{
|
|
||||||
if (m_CurrentBlockIndex >= m_NumBlocks)
|
|
||||||
throw "there is no more data blocks";
|
|
||||||
|
|
||||||
m_ProcessedSize += m_NumReadBytesInBuffer;
|
|
||||||
|
|
||||||
Byte buffer[kDataBlockHeaderSize];
|
|
||||||
UInt32 numProcessedBytes;
|
|
||||||
RINOK(m_Stream->Read(buffer, kDataBlockHeaderSize, &numProcessedBytes));
|
|
||||||
if (numProcessedBytes != kDataBlockHeaderSize)
|
|
||||||
throw "bad block";
|
|
||||||
|
|
||||||
CTempCabInBuffer inBuffer;
|
|
||||||
inBuffer.Size = kDataBlockHeaderSize;
|
|
||||||
inBuffer.Buffer = (Byte *)buffer;
|
|
||||||
inBuffer.Pos = 0;
|
|
||||||
|
|
||||||
UInt32 checkSum = inBuffer.ReadUInt32(); // checksum of this CFDATA entry
|
|
||||||
UInt16 packSize = inBuffer.ReadUInt16(); // number of compressed bytes in this block
|
|
||||||
UInt16 unPackSize = inBuffer.ReadUInt16(); // number of uncompressed bytes in this block
|
|
||||||
|
|
||||||
if (m_ReservedSize != 0)
|
|
||||||
{
|
|
||||||
Byte reservedArea[256];
|
|
||||||
RINOK(m_Stream->Read(reservedArea, m_ReservedSize, &numProcessedBytes));
|
|
||||||
if (numProcessedBytes != m_ReservedSize)
|
|
||||||
throw "bad block";
|
|
||||||
}
|
|
||||||
|
|
||||||
RINOK(m_Stream->Read(m_Buffer, packSize, &m_NumReadBytesInBuffer));
|
|
||||||
if (m_NumReadBytesInBuffer != packSize)
|
|
||||||
throw "bad block";
|
|
||||||
|
|
||||||
// Now I don't remember why (checkSum == 0) check is disbaled
|
|
||||||
// Cab specification:
|
|
||||||
// checkSum: May be set to zero if the checksum is not supplied.
|
|
||||||
// but seems it's stupid rule.
|
|
||||||
if (checkSum == 0)
|
|
||||||
dataAreCorrect = true;
|
|
||||||
{
|
|
||||||
CCheckSum checkSumCalc;
|
|
||||||
checkSumCalc.Update(m_Buffer, packSize);
|
|
||||||
checkSumCalc.UpdateUInt32(packSize | (((UInt32)unPackSize) << 16));
|
|
||||||
dataAreCorrect = (checkSumCalc.GetResult() == checkSum);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Pos = 0;
|
|
||||||
uncompressedSize = unPackSize;
|
|
||||||
|
|
||||||
m_CurrentBlockIndex++;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
// Archive/CabInBuffer.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_INBUFFER_H
|
|
||||||
#define __ARCHIVE_CAB_INBUFFER_H
|
|
||||||
|
|
||||||
#include "../../IStream.h"
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
|
|
||||||
class CInBuffer
|
|
||||||
{
|
|
||||||
UInt64 m_ProcessedSize;
|
|
||||||
UInt32 m_Pos;
|
|
||||||
UInt32 m_NumReadBytesInBuffer;
|
|
||||||
Byte *m_Buffer;
|
|
||||||
CMyComPtr<ISequentialInStream> m_Stream;
|
|
||||||
UInt32 m_BufferSize;
|
|
||||||
|
|
||||||
UInt32 m_NumBlocks;
|
|
||||||
UInt32 m_CurrentBlockIndex;
|
|
||||||
UInt32 m_ReservedSize;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CInBuffer(): m_Buffer(0) {}
|
|
||||||
~CInBuffer() { Free(); }
|
|
||||||
bool Create(UInt32 bufferSize);
|
|
||||||
void Free();
|
|
||||||
|
|
||||||
void SetStream(ISequentialInStream *inStream) { m_Stream = inStream; }
|
|
||||||
void ReleaseStream() { m_Stream.Release(); }
|
|
||||||
|
|
||||||
void Init(Byte reservedSize, UInt32 numBlocks);
|
|
||||||
void Init() {}
|
|
||||||
|
|
||||||
bool ReadByte(Byte &b)
|
|
||||||
{
|
|
||||||
if(m_Pos >= m_NumReadBytesInBuffer)
|
|
||||||
return false;
|
|
||||||
b = m_Buffer[m_Pos++];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Byte ReadByte()
|
|
||||||
{
|
|
||||||
if(m_Pos >= m_NumReadBytesInBuffer)
|
|
||||||
return 0;
|
|
||||||
return m_Buffer[m_Pos++];
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
void ReadBytes(void *data, UInt32 size, UInt32 &aProcessedSize)
|
|
||||||
{
|
|
||||||
Byte *aDataPointer = (Byte *)data;
|
|
||||||
for(int i = 0; i < size; i++)
|
|
||||||
if (!ReadByte(aDataPointer[i]))
|
|
||||||
break;
|
|
||||||
aProcessedSize = i;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect);
|
|
||||||
UInt64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Archive/Cab/ItemInfo.h
|
// Archive/CabItem.h
|
||||||
|
|
||||||
#ifndef __ARCHIVE_RAR_ITEMINFO_H
|
#ifndef __ARCHIVE_CAB_ITEM_H
|
||||||
#define __ARCHIVE_RAR_ITEMINFO_H
|
#define __ARCHIVE_CAB_ITEM_H
|
||||||
|
|
||||||
#include "Common/Types.h"
|
#include "Common/Types.h"
|
||||||
#include "Common/String.h"
|
#include "Common/String.h"
|
||||||
@@ -10,23 +10,53 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NCab {
|
namespace NCab {
|
||||||
|
|
||||||
|
struct CFolder
|
||||||
|
{
|
||||||
|
UInt32 DataStart; // offset of the first CFDATA block in this folder
|
||||||
|
UInt16 NumDataBlocks; // number of CFDATA blocks in this folder
|
||||||
|
Byte CompressionTypeMajor;
|
||||||
|
Byte CompressionTypeMinor;
|
||||||
|
Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); }
|
||||||
|
};
|
||||||
|
|
||||||
class CItem
|
class CItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UInt16 Flags;
|
AString Name;
|
||||||
UInt64 UnPackSize;
|
UInt32 Offset;
|
||||||
UInt32 UnPackOffset;
|
UInt32 Size;
|
||||||
UInt16 FolderIndex;
|
|
||||||
UInt32 Time;
|
UInt32 Time;
|
||||||
UInt16 Attributes;
|
UInt16 FolderIndex;
|
||||||
UInt32 GetWinAttributes() const { return Attributes & (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
|
UInt16 Flags;
|
||||||
|
UInt16 Attributes;
|
||||||
|
UInt64 GetEndOffset() const { return (UInt64)Offset + Size; }
|
||||||
|
UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
|
||||||
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
|
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
|
||||||
bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
|
bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
|
||||||
AString Name;
|
|
||||||
|
bool ContinuedFromPrev() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) ||
|
||||||
|
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
|
||||||
|
}
|
||||||
|
bool ContinuedToNext() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(FolderIndex == NHeader::NFolderIndex::kContinuedToNext) ||
|
||||||
|
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetFolderIndex(int numFolders) const
|
||||||
|
{
|
||||||
|
if (ContinuedFromPrev())
|
||||||
|
return 0;
|
||||||
|
if (ContinuedToNext())
|
||||||
|
return (numFolders - 1);
|
||||||
|
return FolderIndex;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
#include "CabHandler.h"
|
#include "CabHandler.h"
|
||||||
#include "../../ICoder.h"
|
#include "../../ICoder.h"
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-000110060000}
|
// {23170F69-40C1-278A-1000-000110080000}
|
||||||
DEFINE_GUID(CLSID_CCabHandler,
|
DEFINE_GUID(CLSID_CCabHandler,
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00);
|
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0x00);
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
// Archive/Cab/LZXBitDecoder.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_LZXBITDECODER_H
|
|
||||||
#define __ARCHIVE_CAB_LZXBITDECODER_H
|
|
||||||
|
|
||||||
#include "CabInBuffer.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NLZX {
|
|
||||||
namespace NBitStream {
|
|
||||||
|
|
||||||
const int kNumBigValueBits = 8 * 4;
|
|
||||||
|
|
||||||
const int kNumValueBits = 17;
|
|
||||||
const int kBitDecoderValueMask = (1 << kNumValueBits) - 1;
|
|
||||||
|
|
||||||
class CDecoder
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
CInBuffer m_Stream;
|
|
||||||
UInt32 m_BitPos;
|
|
||||||
UInt32 m_Value;
|
|
||||||
public:
|
|
||||||
bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
|
|
||||||
void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); }
|
|
||||||
void ReleaseStream() { m_Stream.ReleaseStream(); }
|
|
||||||
void Init(Byte reservedSize, UInt32 numBlocks)
|
|
||||||
{
|
|
||||||
m_Stream.Init(reservedSize, numBlocks);
|
|
||||||
}
|
|
||||||
UInt64 GetProcessedSize() const
|
|
||||||
{ return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
|
|
||||||
UInt32 GetBitPosition() const
|
|
||||||
{ return UInt32(m_Stream.GetProcessedSize() * 8 - (kNumBigValueBits - m_BitPos)); }
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
m_BitPos = kNumBigValueBits;
|
|
||||||
Normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Normalize()
|
|
||||||
{
|
|
||||||
for (;m_BitPos >= 16; m_BitPos -= 16)
|
|
||||||
{
|
|
||||||
Byte b0 = m_Stream.ReadByte();
|
|
||||||
Byte b1 = m_Stream.ReadByte();
|
|
||||||
m_Value = (m_Value << 8) | b1;
|
|
||||||
m_Value = (m_Value << 8) | b0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 GetValue(UInt32 numBits)
|
|
||||||
{
|
|
||||||
return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >>
|
|
||||||
(kNumValueBits - numBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MovePos(UInt32 numBits)
|
|
||||||
{
|
|
||||||
m_BitPos += numBits;
|
|
||||||
Normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 ReadBits(UInt32 numBits)
|
|
||||||
{
|
|
||||||
UInt32 res = GetValue(numBits);
|
|
||||||
MovePos(numBits);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
UInt32 ReadBitsBig(UInt32 numBits)
|
|
||||||
{
|
|
||||||
UInt32 numBits0 = numBits / 2;
|
|
||||||
UInt32 numBits1 = numBits - numBits0;
|
|
||||||
UInt32 res = ReadBits(numBits0) << numBits1;
|
|
||||||
return res + ReadBits(numBits1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte DirectReadByte()
|
|
||||||
{
|
|
||||||
if (m_BitPos == kNumBigValueBits)
|
|
||||||
return m_Stream.ReadByte();
|
|
||||||
Byte res;
|
|
||||||
switch(m_BitPos)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
res = Byte(m_Value >> 16);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
res = Byte(m_Value >> 24);
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
res = Byte(m_Value);
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
res = Byte(m_Value >> 8);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
m_BitPos += 8;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
|
|
||||||
{ return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}}}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
// Archive/Cab/LZXConst.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_LZXCONST_H
|
|
||||||
#define __ARCHIVE_CAB_LZXCONST_H
|
|
||||||
|
|
||||||
#include "LZXExtConst.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NLZX {
|
|
||||||
|
|
||||||
namespace NBlockType
|
|
||||||
{
|
|
||||||
const int kNumBits = 3;
|
|
||||||
enum EEnum
|
|
||||||
{
|
|
||||||
kVerbatim = 1,
|
|
||||||
kAligned = 2,
|
|
||||||
kUncompressed = 3
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const int kUncompressedBlockSizeNumBits = 24;
|
|
||||||
|
|
||||||
const UInt32 kLevelTableSize = 20;
|
|
||||||
|
|
||||||
const UInt32 kNumBitsForPreTreeLevel = 4;
|
|
||||||
|
|
||||||
const int kLevelSymbolZeros = 17;
|
|
||||||
const int kLevelSymbolZerosBig = 18;
|
|
||||||
const int kLevelSymbolSame = 19;
|
|
||||||
|
|
||||||
const int kLevelSymbolZerosStartValue = 4;
|
|
||||||
const int kLevelSymbolZerosNumBits = 4;
|
|
||||||
|
|
||||||
const int kLevelSymbolZerosBigStartValue = kLevelSymbolZerosStartValue +
|
|
||||||
(1 << kLevelSymbolZerosNumBits);
|
|
||||||
const int kLevelSymbolZerosBigNumBits = 5;
|
|
||||||
|
|
||||||
const int kNumBitsForAlignLevel = 3;
|
|
||||||
|
|
||||||
const int kLevelSymbolSameNumBits = 1;
|
|
||||||
const int kLevelSymbolSameStartValue = 4;
|
|
||||||
|
|
||||||
// const UInt32 kMainTableSize = 256 + kNumPosLenSlots + 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
const UInt32 kLenTableSize = 28;
|
|
||||||
|
|
||||||
const UInt32 kLenTableStart = kMainTableSize;
|
|
||||||
const UInt32 kAlignTableStart = kLenTableStart + kLenTableSize;
|
|
||||||
|
|
||||||
const UInt32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize;
|
|
||||||
|
|
||||||
|
|
||||||
const UInt32 kMaxTableSize = kHeapTablesSizesSum;
|
|
||||||
|
|
||||||
const UInt32 kTableDirectLevels = 16;
|
|
||||||
const UInt32 kTableLevelRepNumber = kTableDirectLevels;
|
|
||||||
const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
|
||||||
const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
|
||||||
|
|
||||||
const UInt32 kLevelMask = 0xF;
|
|
||||||
|
|
||||||
const UInt32 kPosLenNumber = 256;
|
|
||||||
const UInt32 kReadTableNumber = 256 + kNumPosLenSlots;
|
|
||||||
|
|
||||||
//const UInt32 kMatchNumber = kReadTableNumber + 1;
|
|
||||||
|
|
||||||
const Byte kLenStart[kLenTableSize] =
|
|
||||||
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
|
|
||||||
const Byte kLenDirectBits[kLenTableSize] =
|
|
||||||
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
|
|
||||||
*/
|
|
||||||
|
|
||||||
const UInt32 kDistStart[] =
|
|
||||||
{ 0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,
|
|
||||||
1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152,65536,98304,131072,196608,
|
|
||||||
0x40000,
|
|
||||||
0x60000,
|
|
||||||
0x80000,
|
|
||||||
0xA0000,
|
|
||||||
0xC0000,
|
|
||||||
0xE0000,
|
|
||||||
|
|
||||||
0x100000,
|
|
||||||
0x120000,
|
|
||||||
0x140000,
|
|
||||||
0x160000,
|
|
||||||
0x180000,
|
|
||||||
0x1A0000,
|
|
||||||
0x1C0000,
|
|
||||||
0x1E0000
|
|
||||||
};
|
|
||||||
const Byte kDistDirectBits[] =
|
|
||||||
{
|
|
||||||
0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,
|
|
||||||
17, 17, 17, 17, 17, 17,
|
|
||||||
17, 17,17, 17, 17, 17, 17, 17
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
|
|
||||||
|
|
||||||
const UInt32 kDistLimit2 = 0x101 - 1;
|
|
||||||
*/
|
|
||||||
|
|
||||||
}}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,310 +0,0 @@
|
|||||||
// Archive/Cab/LZXDecoder.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "LZXDecoder.h"
|
|
||||||
|
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Windows/Defs.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NLZX {
|
|
||||||
|
|
||||||
static const UInt32 kHistorySize = (1 << 21);
|
|
||||||
|
|
||||||
CDecoder::CDecoder()
|
|
||||||
{
|
|
||||||
m_i86TranslationOutStreamSpec = new Ci86TranslationOutStream;
|
|
||||||
m_i86TranslationOutStream = m_i86TranslationOutStreamSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDecoder::ReleaseStreams()
|
|
||||||
{
|
|
||||||
m_OutWindowStream.ReleaseStream();
|
|
||||||
m_InBitStream.ReleaseStream();
|
|
||||||
m_i86TranslationOutStreamSpec->ReleaseStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CDecoder::Flush()
|
|
||||||
{
|
|
||||||
RINOK(m_OutWindowStream.Flush());
|
|
||||||
return m_i86TranslationOutStreamSpec->Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols)
|
|
||||||
{
|
|
||||||
Byte levelLevels[kLevelTableSize];
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < kLevelTableSize; i++)
|
|
||||||
levelLevels[i] = Byte(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel));
|
|
||||||
m_LevelDecoder.SetCodeLengths(levelLevels);
|
|
||||||
for (i = 0; i < numSymbols;)
|
|
||||||
{
|
|
||||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
|
||||||
if (number <= kNumHuffmanBits)
|
|
||||||
newLevels[i++] = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
|
|
||||||
else if (number == kLevelSymbolZeros || number == kLevelSymbolZerosBig)
|
|
||||||
{
|
|
||||||
int num;
|
|
||||||
if (number == kLevelSymbolZeros)
|
|
||||||
num = kLevelSymbolZerosStartValue +
|
|
||||||
m_InBitStream.ReadBits(kLevelSymbolZerosNumBits);
|
|
||||||
else
|
|
||||||
num = kLevelSymbolZerosBigStartValue +
|
|
||||||
m_InBitStream.ReadBits(kLevelSymbolZerosBigNumBits);
|
|
||||||
for (;num > 0 && i < numSymbols; num--, i++)
|
|
||||||
newLevels[i] = 0;
|
|
||||||
}
|
|
||||||
else if (number == kLevelSymbolSame)
|
|
||||||
{
|
|
||||||
int num = kLevelSymbolSameStartValue + m_InBitStream.ReadBits(kLevelSymbolSameNumBits);
|
|
||||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
|
||||||
if (number > kNumHuffmanBits)
|
|
||||||
throw "bad data";
|
|
||||||
Byte symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
|
|
||||||
for (; num > 0 && i < numSymbols; num--, i++)
|
|
||||||
newLevels[i] = symbol;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw "bad data";
|
|
||||||
}
|
|
||||||
|
|
||||||
memmove(lastLevels, newLevels, numSymbols);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDecoder::ReadTables(void)
|
|
||||||
{
|
|
||||||
int blockType = m_InBitStream.ReadBits(NBlockType::kNumBits);
|
|
||||||
|
|
||||||
if (blockType != NBlockType::kVerbatim && blockType != NBlockType::kAligned &&
|
|
||||||
blockType != NBlockType::kUncompressed)
|
|
||||||
throw "bad data";
|
|
||||||
|
|
||||||
m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits);
|
|
||||||
|
|
||||||
if (blockType == NBlockType::kUncompressed)
|
|
||||||
{
|
|
||||||
m_UncompressedBlock = true;
|
|
||||||
UInt32 bitPos = m_InBitStream.GetBitPosition() % 16;
|
|
||||||
m_InBitStream.ReadBits(16 - bitPos);
|
|
||||||
for (int i = 0; i < kNumRepDistances; i++)
|
|
||||||
{
|
|
||||||
m_RepDistances[i] = 0;
|
|
||||||
for (int j = 0; j < 4; j++)
|
|
||||||
m_RepDistances[i] |= (m_InBitStream.DirectReadByte()) << (8 * j);
|
|
||||||
m_RepDistances[i]--;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_UncompressedBlock = false;
|
|
||||||
|
|
||||||
m_AlignIsUsed = (blockType == NBlockType::kAligned);
|
|
||||||
|
|
||||||
Byte newLevels[kMaxTableSize];
|
|
||||||
|
|
||||||
if (m_AlignIsUsed)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < kAlignTableSize; i++)
|
|
||||||
newLevels[i] = m_InBitStream.ReadBits(kNumBitsForAlignLevel);
|
|
||||||
m_AlignDecoder.SetCodeLengths(newLevels);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadTable(m_LastByteLevels, newLevels, 256);
|
|
||||||
ReadTable(m_LastPosLenLevels, newLevels + 256, m_NumPosLenSlots);
|
|
||||||
for (int i = m_NumPosLenSlots; i < kNumPosSlotLenSlotSymbols; i++)
|
|
||||||
newLevels[256 + i] = 0;
|
|
||||||
m_MainDecoder.SetCodeLengths(newLevels);
|
|
||||||
|
|
||||||
ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols);
|
|
||||||
m_LenDecoder.SetCodeLengths(newLevels);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class CDecoderFlusher
|
|
||||||
{
|
|
||||||
CDecoder *m_Decoder;
|
|
||||||
public:
|
|
||||||
CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder) {}
|
|
||||||
~CDecoderFlusher()
|
|
||||||
{
|
|
||||||
m_Decoder->Flush();
|
|
||||||
m_Decoder->ReleaseStreams();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void CDecoder::ClearPrevLeveles()
|
|
||||||
{
|
|
||||||
memset(m_LastByteLevels, 0, 256);
|
|
||||||
memset(m_LastPosLenLevels, 0, kNumPosSlotLenSlotSymbols);
|
|
||||||
memset(m_LastLenLevels, 0, kNumLenSymbols);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
const UInt64 *inSize, const UInt64 *outSize,
|
|
||||||
ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
if (outSize == NULL)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
UInt64 size = *outSize;
|
|
||||||
|
|
||||||
if (!m_OutWindowStream.Create(kHistorySize))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
if (!m_InBitStream.Create(1 << 20))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
m_OutWindowStream.SetStream(m_i86TranslationOutStream);
|
|
||||||
m_OutWindowStream.Init();
|
|
||||||
|
|
||||||
m_InBitStream.SetStream(inStream);
|
|
||||||
m_InBitStream.Init(m_ReservedSize, m_NumInDataBlocks);
|
|
||||||
|
|
||||||
CDecoderFlusher flusher(this);
|
|
||||||
|
|
||||||
UInt32 uncompressedCFDataBlockSize;
|
|
||||||
bool dataAreCorrect;
|
|
||||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
|
||||||
if (!dataAreCorrect)
|
|
||||||
{
|
|
||||||
throw "Data Error";
|
|
||||||
}
|
|
||||||
UInt32 uncompressedCFDataCurrentValue = 0;
|
|
||||||
m_InBitStream.Init();
|
|
||||||
|
|
||||||
ClearPrevLeveles();
|
|
||||||
|
|
||||||
if (m_InBitStream.ReadBits(1) == 0)
|
|
||||||
m_i86TranslationOutStreamSpec->Init(outStream, false, 0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UInt32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16;
|
|
||||||
i86TranslationSize |= m_InBitStream.ReadBits(16);
|
|
||||||
m_i86TranslationOutStreamSpec->Init(outStream, true , i86TranslationSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0 ; i < kNumRepDistances; i++)
|
|
||||||
m_RepDistances[i] = 0;
|
|
||||||
|
|
||||||
UInt64 nowPos64 = 0;
|
|
||||||
while(nowPos64 < size)
|
|
||||||
{
|
|
||||||
if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
|
|
||||||
{
|
|
||||||
bool dataAreCorrect;
|
|
||||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
|
||||||
if (!dataAreCorrect)
|
|
||||||
{
|
|
||||||
throw "Data Error";
|
|
||||||
}
|
|
||||||
m_InBitStream.Init();
|
|
||||||
uncompressedCFDataCurrentValue = 0;
|
|
||||||
}
|
|
||||||
ReadTables();
|
|
||||||
UInt32 nowPos = 0;
|
|
||||||
UInt32 next = (UInt32)MyMin((UInt64)m_UnCompressedBlockSize, size - nowPos64);
|
|
||||||
if (m_UncompressedBlock)
|
|
||||||
{
|
|
||||||
while(nowPos < next)
|
|
||||||
{
|
|
||||||
m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte());
|
|
||||||
nowPos++;
|
|
||||||
uncompressedCFDataCurrentValue++;
|
|
||||||
if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
|
|
||||||
{
|
|
||||||
bool dataAreCorrect;
|
|
||||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
|
||||||
if (!dataAreCorrect)
|
|
||||||
{
|
|
||||||
throw "Data Error";
|
|
||||||
}
|
|
||||||
// m_InBitStream.Init();
|
|
||||||
uncompressedCFDataCurrentValue = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int bitPos = m_InBitStream.GetBitPosition() % 16;
|
|
||||||
if (bitPos == 8)
|
|
||||||
m_InBitStream.DirectReadByte();
|
|
||||||
m_InBitStream.Normalize();
|
|
||||||
}
|
|
||||||
else for (;nowPos < next;)
|
|
||||||
{
|
|
||||||
if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
|
|
||||||
{
|
|
||||||
bool dataAreCorrect;
|
|
||||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
|
||||||
if (!dataAreCorrect)
|
|
||||||
{
|
|
||||||
throw "Data Error";
|
|
||||||
}
|
|
||||||
m_InBitStream.Init();
|
|
||||||
uncompressedCFDataCurrentValue = 0;
|
|
||||||
}
|
|
||||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
|
||||||
if (number < 256)
|
|
||||||
{
|
|
||||||
m_OutWindowStream.PutByte(Byte(number));
|
|
||||||
nowPos++;
|
|
||||||
uncompressedCFDataCurrentValue++;
|
|
||||||
// continue;
|
|
||||||
}
|
|
||||||
else if (number < 256 + m_NumPosLenSlots)
|
|
||||||
{
|
|
||||||
UInt32 posLenSlot = number - 256;
|
|
||||||
UInt32 posSlot = posLenSlot / kNumLenSlots;
|
|
||||||
UInt32 lenSlot = posLenSlot % kNumLenSlots;
|
|
||||||
UInt32 length = 2 + lenSlot;
|
|
||||||
if (lenSlot == kNumLenSlots - 1)
|
|
||||||
length += m_LenDecoder.DecodeSymbol(&m_InBitStream);
|
|
||||||
|
|
||||||
if (posSlot < kNumRepDistances)
|
|
||||||
{
|
|
||||||
UInt32 distance = m_RepDistances[posSlot];
|
|
||||||
m_OutWindowStream.CopyBlock(distance, length);
|
|
||||||
if (posSlot != 0)
|
|
||||||
{
|
|
||||||
m_RepDistances[posSlot] = m_RepDistances[0];
|
|
||||||
m_RepDistances[0] = distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UInt32 pos = kDistStart[posSlot];
|
|
||||||
UInt32 posDirectBits = kDistDirectBits[posSlot];
|
|
||||||
if (m_AlignIsUsed && posDirectBits >= kNumAlignBits)
|
|
||||||
{
|
|
||||||
pos += (m_InBitStream.ReadBits(posDirectBits - kNumAlignBits) << kNumAlignBits);
|
|
||||||
pos += m_AlignDecoder.DecodeSymbol(&m_InBitStream);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pos += m_InBitStream.ReadBits(posDirectBits);
|
|
||||||
UInt32 distance = pos - kNumRepDistances;
|
|
||||||
if (distance >= nowPos64 + nowPos)
|
|
||||||
throw 777123;
|
|
||||||
m_OutWindowStream.CopyBlock(distance, length);
|
|
||||||
m_RepDistances[2] = m_RepDistances[1];
|
|
||||||
m_RepDistances[1] = m_RepDistances[0];
|
|
||||||
m_RepDistances[0] = distance;
|
|
||||||
}
|
|
||||||
nowPos += length;
|
|
||||||
uncompressedCFDataCurrentValue += length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw 98112823;
|
|
||||||
}
|
|
||||||
if (progress != NULL)
|
|
||||||
{
|
|
||||||
UInt64 inSize = m_InBitStream.GetProcessedSize();
|
|
||||||
UInt64 outSize = nowPos64 + nowPos;
|
|
||||||
RINOK(progress->SetRatioInfo(&inSize, &outSize));
|
|
||||||
}
|
|
||||||
nowPos64 += nowPos;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
// Archive/Cab/LZXDecoder.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_LZXDECODER_H
|
|
||||||
#define __ARCHIVE_CAB_LZXDECODER_H
|
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
#include "../../Compress/Huffman/HuffmanDecoder.h"
|
|
||||||
#include "../../Compress/LZ/LZOutWindow.h"
|
|
||||||
|
|
||||||
#include "LZXExtConst.h"
|
|
||||||
#include "LZXBitDecoder.h"
|
|
||||||
|
|
||||||
#include "LZXi86Converter.h"
|
|
||||||
#include "LZXConst.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NLZX {
|
|
||||||
|
|
||||||
const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols;
|
|
||||||
|
|
||||||
class CDecoder :
|
|
||||||
public ICompressCoder,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
CLZOutWindow m_OutWindowStream;
|
|
||||||
NBitStream::CDecoder m_InBitStream;
|
|
||||||
|
|
||||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
|
|
||||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kNumLenSymbols> m_LenDecoder;
|
|
||||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;
|
|
||||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
|
|
||||||
|
|
||||||
UInt32 m_RepDistances[kNumRepDistances];
|
|
||||||
|
|
||||||
Byte m_LastByteLevels[256];
|
|
||||||
Byte m_LastPosLenLevels[kNumPosSlotLenSlotSymbols];
|
|
||||||
Byte m_LastLenLevels[kNumLenSymbols];
|
|
||||||
|
|
||||||
UInt32 m_DictionarySizePowerOf2;
|
|
||||||
UInt32 m_NumPosSlots;
|
|
||||||
UInt32 m_NumPosLenSlots;
|
|
||||||
|
|
||||||
// bool m_i86PreprocessingUsed;
|
|
||||||
// UInt32 m_i86TranslationSize;
|
|
||||||
|
|
||||||
bool m_UncompressedBlock;
|
|
||||||
bool m_AlignIsUsed;
|
|
||||||
|
|
||||||
UInt32 m_UnCompressedBlockSize;
|
|
||||||
|
|
||||||
Ci86TranslationOutStream *m_i86TranslationOutStreamSpec;
|
|
||||||
CMyComPtr<ISequentialOutStream> m_i86TranslationOutStream;
|
|
||||||
|
|
||||||
Byte m_ReservedSize;
|
|
||||||
UInt32 m_NumInDataBlocks;
|
|
||||||
|
|
||||||
void ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols);
|
|
||||||
void ReadTables();
|
|
||||||
void ClearPrevLeveles();
|
|
||||||
|
|
||||||
public:
|
|
||||||
CDecoder();
|
|
||||||
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
void ReleaseStreams();
|
|
||||||
STDMETHOD(Flush)();
|
|
||||||
|
|
||||||
// ICompressCoder interface
|
|
||||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
const UInt64 *inSize, const UInt64 *outSize,
|
|
||||||
ICompressProgressInfo *progress);
|
|
||||||
|
|
||||||
void SetParams(Byte reservedSize, UInt32 numInDataBlocks,
|
|
||||||
UInt32 dictionarySizePowerOf2)
|
|
||||||
{
|
|
||||||
m_ReservedSize = reservedSize;
|
|
||||||
m_NumInDataBlocks = numInDataBlocks;
|
|
||||||
m_DictionarySizePowerOf2 = dictionarySizePowerOf2;
|
|
||||||
if (dictionarySizePowerOf2 < 20)
|
|
||||||
m_NumPosSlots = 30 + (dictionarySizePowerOf2 - 15) * 2;
|
|
||||||
else if (dictionarySizePowerOf2 == 20)
|
|
||||||
m_NumPosSlots = 42;
|
|
||||||
else
|
|
||||||
m_NumPosSlots = 50;
|
|
||||||
m_NumPosLenSlots = m_NumPosSlots * kNumLenSlots;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
// Archive/Cab/LZXExtConst.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_LZXEXTCONST_H
|
|
||||||
#define __ARCHIVE_CAB_LZXEXTCONST_H
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NLZX {
|
|
||||||
|
|
||||||
const UInt32 kNumRepDistances = 3;
|
|
||||||
|
|
||||||
const UInt32 kNumLenSlots = 8;
|
|
||||||
const UInt32 kMatchMinLen = 2;
|
|
||||||
const UInt32 kNumLenSymbols = 249;
|
|
||||||
const UInt32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1;
|
|
||||||
|
|
||||||
const Byte kNumAlignBits = 3;
|
|
||||||
const UInt32 kAlignTableSize = 1 << kNumAlignBits;
|
|
||||||
|
|
||||||
const UInt32 kNumHuffmanBits = 16;
|
|
||||||
|
|
||||||
const int kNumPosSlotSymbols = 50;
|
|
||||||
const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots;
|
|
||||||
|
|
||||||
const int kMaxTableSize = 256 + kNumPosSlotLenSlotSymbols;
|
|
||||||
|
|
||||||
|
|
||||||
}}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
// MSZipConst.h
|
|
||||||
|
|
||||||
#ifndef __MSZIP_CONST_H
|
|
||||||
#define __MSZIP_CONST_H
|
|
||||||
|
|
||||||
#include "MSZipExtConst.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NMSZip {
|
|
||||||
|
|
||||||
const UInt32 kLenTableSize = 29;
|
|
||||||
|
|
||||||
const UInt32 kStaticDistTableSize = 32;
|
|
||||||
const UInt32 kStaticLenTableSize = 31;
|
|
||||||
|
|
||||||
const UInt32 kReadTableNumber = 0x100;
|
|
||||||
const UInt32 kMatchNumber = kReadTableNumber + 1;
|
|
||||||
|
|
||||||
const UInt32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
|
|
||||||
const UInt32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
|
|
||||||
|
|
||||||
const UInt32 kDistTableStart = kMainTableSize;
|
|
||||||
|
|
||||||
const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize;
|
|
||||||
|
|
||||||
const UInt32 kLevelTableSize = 19;
|
|
||||||
|
|
||||||
const UInt32 kMaxTableSize = kHeapTablesSizesSum; // test it
|
|
||||||
const UInt32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
|
|
||||||
|
|
||||||
const UInt32 kTableDirectLevels = 16;
|
|
||||||
const UInt32 kTableLevelRepNumber = kTableDirectLevels;
|
|
||||||
const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
|
||||||
const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
|
||||||
|
|
||||||
const UInt32 kLevelMask = 0xF;
|
|
||||||
|
|
||||||
const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255};
|
|
||||||
const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
|
|
||||||
|
|
||||||
|
|
||||||
const UInt32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576};
|
|
||||||
const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
|
|
||||||
|
|
||||||
const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
|
|
||||||
|
|
||||||
const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
|
||||||
|
|
||||||
const UInt32 kMatchMinLen = 3;
|
|
||||||
const UInt32 kMatchMaxLen = kNumLenCombinations + kMatchMinLen - 1; //255 + 2; test it
|
|
||||||
|
|
||||||
const int kFinalBlockFieldSize = 1;
|
|
||||||
|
|
||||||
namespace NFinalBlockField
|
|
||||||
{
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
kNotFinalBlock = 0,
|
|
||||||
kFinalBlock = 1
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const int kBlockTypeFieldSize = 2;
|
|
||||||
|
|
||||||
namespace NBlockType
|
|
||||||
{
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
kStored = 0,
|
|
||||||
kFixedHuffman = 1,
|
|
||||||
kDynamicHuffman = 2,
|
|
||||||
kReserved = 3
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const UInt32 kDeflateNumberOfLengthCodesFieldSize = 5;
|
|
||||||
const UInt32 kDeflateNumberOfDistanceCodesFieldSize = 5;
|
|
||||||
const UInt32 kDeflateNumberOfLevelCodesFieldSize = 4;
|
|
||||||
|
|
||||||
const UInt32 kDeflateNumberOfLitLenCodesMin = 257;
|
|
||||||
|
|
||||||
const UInt32 kDeflateNumberOfDistanceCodesMin = 1;
|
|
||||||
const UInt32 kDeflateNumberOfLevelCodesMin = 4;
|
|
||||||
|
|
||||||
const UInt32 kDeflateLevelCodeFieldSize = 3;
|
|
||||||
|
|
||||||
const UInt32 kDeflateStoredBlockLengthFieldSizeSize = 16;
|
|
||||||
|
|
||||||
}}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,268 +0,0 @@
|
|||||||
// Archive/Cab/MSZipDecoder.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "MSZipDecoder.h"
|
|
||||||
|
|
||||||
#include "Windows/Defs.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NMSZip {
|
|
||||||
|
|
||||||
CDecoder::CDecoder(){}
|
|
||||||
|
|
||||||
HRESULT CDecoder::Flush()
|
|
||||||
{
|
|
||||||
return m_OutWindowStream.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDecoder::ReleaseStreams()
|
|
||||||
{
|
|
||||||
m_OutWindowStream.ReleaseStream();
|
|
||||||
m_InBitStream.ReleaseStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDecoder::DeCodeLevelTable(Byte *newLevels, int numLevels)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
while (i < numLevels)
|
|
||||||
{
|
|
||||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
|
||||||
if (number < kTableDirectLevels)
|
|
||||||
newLevels[i++] = Byte(number);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (number == kTableLevelRepNumber)
|
|
||||||
{
|
|
||||||
int t = m_InBitStream.ReadBits(2) + 3;
|
|
||||||
for (int reps = t; reps > 0 && i < numLevels ; reps--, i++)
|
|
||||||
newLevels[i] = newLevels[i - 1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int num;
|
|
||||||
if (number == kTableLevel0Number)
|
|
||||||
num = m_InBitStream.ReadBits(3) + 3;
|
|
||||||
else
|
|
||||||
num = m_InBitStream.ReadBits(7) + 11;
|
|
||||||
for (;num > 0 && i < numLevels; num--)
|
|
||||||
newLevels[i++] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDecoder::ReadTables(void)
|
|
||||||
{
|
|
||||||
if(m_FinalBlock) // test it
|
|
||||||
throw CDecoderException(CDecoderException::kData);
|
|
||||||
|
|
||||||
m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
|
|
||||||
|
|
||||||
int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize);
|
|
||||||
|
|
||||||
switch(blockType)
|
|
||||||
{
|
|
||||||
case NBlockType::kStored:
|
|
||||||
{
|
|
||||||
m_StoredMode = true;
|
|
||||||
UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
|
|
||||||
UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
|
|
||||||
if (numBitsForAlign > 0)
|
|
||||||
m_InBitStream.ReadBits(numBitsForAlign);
|
|
||||||
m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
|
|
||||||
WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
|
|
||||||
if (m_StoredBlockSize != onesComplementReverse)
|
|
||||||
throw CDecoderException(CDecoderException::kData);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NBlockType::kFixedHuffman:
|
|
||||||
case NBlockType::kDynamicHuffman:
|
|
||||||
{
|
|
||||||
m_StoredMode = false;
|
|
||||||
Byte litLenLevels[kStaticMainTableSize];
|
|
||||||
Byte distLevels[kStaticDistTableSize];
|
|
||||||
if (blockType == NBlockType::kFixedHuffman)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Leteral / length levels
|
|
||||||
for (i = 0; i < 144; i++)
|
|
||||||
litLenLevels[i] = 8;
|
|
||||||
for (; i < 256; i++)
|
|
||||||
litLenLevels[i] = 9;
|
|
||||||
for (; i < 280; i++)
|
|
||||||
litLenLevels[i] = 7;
|
|
||||||
for (; i < 288; i++) /* make a complete, but wrong code set */
|
|
||||||
litLenLevels[i] = 8;
|
|
||||||
|
|
||||||
// Distance levels
|
|
||||||
for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize
|
|
||||||
distLevels[i] = 5;
|
|
||||||
}
|
|
||||||
else // in case when (blockType == kDeflateBlockTypeFixedHuffman)
|
|
||||||
{
|
|
||||||
int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
|
|
||||||
kDeflateNumberOfLitLenCodesMin;
|
|
||||||
int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
|
|
||||||
kDeflateNumberOfDistanceCodesMin;
|
|
||||||
int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
|
|
||||||
kDeflateNumberOfLevelCodesMin;
|
|
||||||
|
|
||||||
int numLevels;
|
|
||||||
numLevels = kHeapTablesSizesSum;
|
|
||||||
|
|
||||||
Byte levelLevels[kLevelTableSize];
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < kLevelTableSize; i++)
|
|
||||||
{
|
|
||||||
int position = kCodeLengthAlphabetOrder[i];
|
|
||||||
if(i < numLevelCodes)
|
|
||||||
levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
|
|
||||||
else
|
|
||||||
levelLevels[position] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_LevelDecoder.SetCodeLengths(levelLevels);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
throw CDecoderException(CDecoderException::kData);
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte tmpLevels[kStaticMaxTableSize];
|
|
||||||
DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
|
|
||||||
|
|
||||||
memmove(litLenLevels, tmpLevels, numLitLenLevels);
|
|
||||||
memset(litLenLevels + numLitLenLevels, 0,
|
|
||||||
kStaticMainTableSize - numLitLenLevels);
|
|
||||||
|
|
||||||
memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels);
|
|
||||||
memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels);
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_MainDecoder.SetCodeLengths(litLenLevels);
|
|
||||||
m_DistDecoder.SetCodeLengths(distLevels);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
throw CDecoderException(CDecoderException::kData);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw CDecoderException(CDecoderException::kData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CCoderReleaser
|
|
||||||
{
|
|
||||||
CDecoder *m_Coder;
|
|
||||||
public:
|
|
||||||
CCoderReleaser(CDecoder *aCoder): m_Coder(aCoder) {}
|
|
||||||
~CCoderReleaser()
|
|
||||||
{
|
|
||||||
m_Coder->Flush();
|
|
||||||
m_Coder->ReleaseStreams();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
|
||||||
ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
if (outSize == NULL)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
UInt64 size = *outSize;
|
|
||||||
|
|
||||||
if (!m_OutWindowStream.Create(kHistorySize))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
if (!m_InBitStream.Create(1 << 20))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
m_OutWindowStream.SetStream(outStream);
|
|
||||||
m_OutWindowStream.Init(false);
|
|
||||||
|
|
||||||
m_InBitStream.SetStream(inStream);
|
|
||||||
m_InBitStream.InitMain(m_ReservedSize, m_NumInDataBlocks);
|
|
||||||
CCoderReleaser coderReleaser(this);
|
|
||||||
|
|
||||||
UInt64 nowPos = 0;
|
|
||||||
while(nowPos < size)
|
|
||||||
{
|
|
||||||
if (progress != NULL)
|
|
||||||
{
|
|
||||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
|
||||||
RINOK(progress->SetRatioInfo(&packSize, &nowPos));
|
|
||||||
}
|
|
||||||
UInt32 uncompressedCFDataBlockSize;
|
|
||||||
bool dataAreCorrect;
|
|
||||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
|
||||||
if (!dataAreCorrect)
|
|
||||||
{
|
|
||||||
throw "Data Error";
|
|
||||||
}
|
|
||||||
m_InBitStream.Init();
|
|
||||||
if (m_InBitStream.ReadBits(8) != 0x43)
|
|
||||||
throw CDecoderException(CDecoderException::kData);
|
|
||||||
if (m_InBitStream.ReadBits(8) != 0x4B)
|
|
||||||
throw CDecoderException(CDecoderException::kData);
|
|
||||||
UInt32 uncompressedCFDataCurrentValue = 0;
|
|
||||||
m_FinalBlock = false;
|
|
||||||
while (uncompressedCFDataCurrentValue < uncompressedCFDataBlockSize)
|
|
||||||
{
|
|
||||||
ReadTables();
|
|
||||||
if(m_StoredMode)
|
|
||||||
{
|
|
||||||
for (UInt32 i = 0; i < m_StoredBlockSize; i++)
|
|
||||||
m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8)));
|
|
||||||
nowPos += m_StoredBlockSize;
|
|
||||||
uncompressedCFDataCurrentValue += m_StoredBlockSize;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
|
||||||
|
|
||||||
if (number < 256)
|
|
||||||
{
|
|
||||||
m_OutWindowStream.PutByte(Byte(number));
|
|
||||||
nowPos++;
|
|
||||||
uncompressedCFDataCurrentValue++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (number >= kMatchNumber)
|
|
||||||
{
|
|
||||||
number -= kMatchNumber;
|
|
||||||
UInt32 length = UInt32(kLenStart[number]) + kMatchMinLen;
|
|
||||||
UInt32 numBits;
|
|
||||||
if ((numBits = kLenDirectBits[number]) > 0)
|
|
||||||
length += m_InBitStream.ReadBits(numBits);
|
|
||||||
|
|
||||||
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
|
|
||||||
UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
|
|
||||||
/*
|
|
||||||
if (distance >= nowPos)
|
|
||||||
throw "data error";
|
|
||||||
*/
|
|
||||||
m_OutWindowStream.CopyBlock(distance, length);
|
|
||||||
nowPos += length;
|
|
||||||
uncompressedCFDataCurrentValue += length;
|
|
||||||
}
|
|
||||||
else if (number == kReadTableNumber)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw CDecoderException(CDecoderException::kData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
// Archive/Cab/MSZipDecoder.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_DECODER_H
|
|
||||||
#define __ARCHIVE_CAB_DECODER_H
|
|
||||||
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
#include "../../Common/LSBFDecoder.h"
|
|
||||||
#include "../../Compress/Huffman/HuffmanDecoder.h"
|
|
||||||
#include "../../Compress/LZ/LZOutWindow.h"
|
|
||||||
|
|
||||||
#include "CabInBuffer.h"
|
|
||||||
#include "MSZipExtConst.h"
|
|
||||||
#include "MSZipConst.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NMSZip {
|
|
||||||
|
|
||||||
class CDecoderException
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum ECauseType
|
|
||||||
{
|
|
||||||
kData
|
|
||||||
} m_Cause;
|
|
||||||
CDecoderException(ECauseType aCause): m_Cause(aCause) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CMSZipBitDecoder: public NStream::NLSBF::CDecoder<NCab::CInBuffer>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void InitMain(Byte reservedSize, UInt32 aNumBlocks)
|
|
||||||
{
|
|
||||||
m_Stream.Init(reservedSize, aNumBlocks);
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
|
|
||||||
{
|
|
||||||
return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CDecoder :
|
|
||||||
public ICompressCoder,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
CLZOutWindow m_OutWindowStream;
|
|
||||||
CMSZipBitDecoder m_InBitStream;
|
|
||||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticMainTableSize> m_MainDecoder;
|
|
||||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder;
|
|
||||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
|
|
||||||
|
|
||||||
bool m_FinalBlock;
|
|
||||||
bool m_StoredMode;
|
|
||||||
UInt32 m_StoredBlockSize;
|
|
||||||
|
|
||||||
Byte m_ReservedSize;
|
|
||||||
UInt32 m_NumInDataBlocks;
|
|
||||||
|
|
||||||
void DeCodeLevelTable(Byte *newLevels, int numLevels);
|
|
||||||
void ReadTables();
|
|
||||||
public:
|
|
||||||
CDecoder();
|
|
||||||
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
HRESULT Flush();
|
|
||||||
void ReleaseStreams();
|
|
||||||
|
|
||||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
|
||||||
ICompressProgressInfo *progress);
|
|
||||||
|
|
||||||
void SetParams(Byte reservedSize, UInt32 numInDataBlocks)
|
|
||||||
{
|
|
||||||
m_ReservedSize = reservedSize;
|
|
||||||
m_NumInDataBlocks = numInDataBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
// DeflateExtConst.h
|
|
||||||
|
|
||||||
#ifndef __DEFLATEEXTCONST_H
|
|
||||||
#define __DEFLATEEXTCONST_H
|
|
||||||
|
|
||||||
#include "Common/Types.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NMSZip {
|
|
||||||
|
|
||||||
const UInt32 kDistTableSize = 30;
|
|
||||||
const UInt32 kHistorySize = 0x8000;
|
|
||||||
const UInt32 kNumLenCombinations = 256;
|
|
||||||
|
|
||||||
const UInt32 kNumHuffmanBits = 15;
|
|
||||||
|
|
||||||
}}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
70
7zip/Archive/Cab/makefile
Executable file
70
7zip/Archive/Cab/makefile
Executable file
@@ -0,0 +1,70 @@
|
|||||||
|
PROG = cab.dll
|
||||||
|
DEF_FILE = ../Archive.def
|
||||||
|
CFLAGS = $(CFLAGS) -I ../../../
|
||||||
|
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||||
|
|
||||||
|
CAB_OBJS = \
|
||||||
|
$O\DllExports.obj \
|
||||||
|
$O\CabBlockInStream.obj \
|
||||||
|
$O\CabHandler.obj \
|
||||||
|
$O\CabHeader.obj \
|
||||||
|
$O\CabIn.obj \
|
||||||
|
|
||||||
|
COMMON_OBJS = \
|
||||||
|
$O\Alloc.obj \
|
||||||
|
$O\IntToString.obj \
|
||||||
|
$O\NewHandler.obj \
|
||||||
|
$O\String.obj \
|
||||||
|
$O\StringConvert.obj \
|
||||||
|
$O\StringToInt.obj \
|
||||||
|
$O\UTFConvert.obj \
|
||||||
|
$O\Vector.obj \
|
||||||
|
|
||||||
|
WIN_OBJS = \
|
||||||
|
$O\PropVariant.obj \
|
||||||
|
|
||||||
|
7ZIP_COMMON_OBJS = \
|
||||||
|
$O\InBuffer.obj \
|
||||||
|
$O\LSBFDecoder.obj \
|
||||||
|
$O\OutBuffer.obj \
|
||||||
|
$O\ProgressUtils.obj \
|
||||||
|
$O\StreamUtils.obj \
|
||||||
|
|
||||||
|
COMPRESS_LZX_OBJS = \
|
||||||
|
$O\LzxDecoder.obj \
|
||||||
|
$O\Lzx86Converter.obj \
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
$O\StdAfx.obj \
|
||||||
|
$(CAB_OBJS) \
|
||||||
|
$(COMMON_OBJS) \
|
||||||
|
$(WIN_OBJS) \
|
||||||
|
$(7ZIP_COMMON_OBJS) \
|
||||||
|
$(COMPRESS_LZX_OBJS) \
|
||||||
|
$O\DeflateDecoder.obj \
|
||||||
|
$O\QuantumDecoder.obj \
|
||||||
|
$O\LZOutWindow.obj \
|
||||||
|
$O\CopyCoder.obj \
|
||||||
|
$O\resource.res
|
||||||
|
|
||||||
|
!include "../../../Build.mak"
|
||||||
|
|
||||||
|
$(CAB_OBJS): $(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMPRESS_LZX_OBJS): ../../Compress/Lzx/$(*B).cpp
|
||||||
|
$(COMPL_O2)
|
||||||
|
$O\DeflateDecoder.obj: ../../Compress/Deflate/$(*B).cpp
|
||||||
|
$(COMPL_O2)
|
||||||
|
$O\QuantumDecoder.obj: ../../Compress/Quantum/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Developer Studio generated include file.
|
|
||||||
// Used by resource.rc
|
|
||||||
//
|
|
||||||
#define IDI_ICON1 101
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,130 +1,5 @@
|
|||||||
//Microsoft Developer Studio generated resource script.
|
#include "../../MyVersionInfo.rc"
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
MY_VERSION_INFO_DLL("Cab Plugin", "cab")
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Russian resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
|
||||||
#pragma code_page(1251)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Russian resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 4,23,0,0
|
|
||||||
PRODUCTVERSION 4,23,0,0
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS 0x1L
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS 0x40004L
|
|
||||||
FILETYPE 0x2L
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Comments", "\0"
|
|
||||||
VALUE "CompanyName", "Igor Pavlov \0"
|
|
||||||
VALUE "FileDescription", "Cab Plugin for 7-Zip\0"
|
|
||||||
VALUE "FileVersion", "4, 23, 0, 0\0"
|
|
||||||
VALUE "InternalName", "cab\0"
|
|
||||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
|
||||||
VALUE "LegalTrademarks", "\0"
|
|
||||||
VALUE "OriginalFilename", "cab.dll\0"
|
|
||||||
VALUE "PrivateBuild", "\0"
|
|
||||||
VALUE "ProductName", "7-Zip\0"
|
|
||||||
VALUE "ProductVersion", "4, 23, 0, 0\0"
|
|
||||||
VALUE "SpecialBuild", "\0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // !_MAC
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "cab.ico"
|
|
||||||
#endif // English (U.S.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
101 ICON "cab.ico"
|
||||||
|
|||||||
337
7zip/Archive/Chm/Chm.dsp
Executable file
337
7zip/Archive/Chm/Chm.dsp
Executable file
@@ -0,0 +1,337 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="Chm" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||||
|
|
||||||
|
CFG=Chm - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "Chm.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "Chm.mak" CFG="Chm - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "Chm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "Chm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
MTL=midl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "Chm - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||||
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\chm.dll" /opt:NOWIN98
|
||||||
|
# SUBTRACT LINK32 /pdb:none
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "Chm - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||||
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\chm.dll" /pdbtype:sept
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "Chm - Win32 Release"
|
||||||
|
# Name "Chm - Win32 Debug"
|
||||||
|
# Begin Group "Spec"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Archive.def
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\DllExports.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\resource.rc
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\StdAfx.cpp
|
||||||
|
# ADD CPP /Yc"StdAfx.h"
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\StdAfx.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Engine"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ChmHandler.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ChmHandler.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ChmHeader.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ChmHeader.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ChmIn.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\ChmIn.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "7zip Common"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\InBuffer.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\InBuffer.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\LimitedStreams.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\LimitedStreams.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\OutBuffer.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\OutBuffer.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\ProgressUtils.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Common"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Alloc.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Alloc.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Buffer.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\IntToString.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\IntToString.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\String.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\String.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\StringConvert.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\UTFConvert.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\UTFConvert.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Vector.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Vector.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Windows"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\PropVariant.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\PropVariant.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Archive Common"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ItemNameUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ItemNameUtils.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Compress"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Group "LZ"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\LZ\LZOutWindow.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Lzx"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\Lzx.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "Chm - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "Chm - Win32 Debug"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\Lzx86Converter.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "Chm - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "Chm - Win32 Debug"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Lzx\LzxDecoder.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
||||||
@@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
|
|||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
Project: "BZip2"=.\BZip2.dsp - Package Owner=<4>
|
Project: "Chm"=.\Chm.dsp - Package Owner=<4>
|
||||||
|
|
||||||
Package=<5>
|
Package=<5>
|
||||||
{{{
|
{{{
|
||||||
730
7zip/Archive/Chm/ChmHandler.cpp
Executable file
730
7zip/Archive/Chm/ChmHandler.cpp
Executable file
@@ -0,0 +1,730 @@
|
|||||||
|
// Chm/Handler.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Common/StringConvert.h"
|
||||||
|
#include "Common/Defs.h"
|
||||||
|
#include "Common/UTFConvert.h"
|
||||||
|
#include "Common/ComTry.h"
|
||||||
|
|
||||||
|
#include "Windows/PropVariant.h"
|
||||||
|
#include "Windows/Time.h"
|
||||||
|
|
||||||
|
#include "../../Common/LimitedStreams.h"
|
||||||
|
#include "../../Common/StreamUtils.h"
|
||||||
|
#include "../../Common/ProgressUtils.h"
|
||||||
|
|
||||||
|
#include "../../Compress/Copy/CopyCoder.h"
|
||||||
|
#include "../../Compress/Lzx/LzxDecoder.h"
|
||||||
|
|
||||||
|
#include "../Common/ItemNameUtils.h"
|
||||||
|
|
||||||
|
#include "ChmHandler.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace NWindows;
|
||||||
|
using namespace NTime;
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NChm {
|
||||||
|
|
||||||
|
// #define _CHM_DETAILS
|
||||||
|
|
||||||
|
#ifdef _CHM_DETAILS
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kpidSection = kpidUserDefined,
|
||||||
|
kpidOffset
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STATPROPSTG kProperties[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
|
// { NULL, kpidIsFolder, VT_BOOL},
|
||||||
|
{ NULL, kpidSize, VT_UI8},
|
||||||
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
|
{ NULL, kpidBlock, VT_UI4}
|
||||||
|
|
||||||
|
#ifdef _CHM_DETAILS
|
||||||
|
,
|
||||||
|
{ L"Section", kpidSection, VT_UI4},
|
||||||
|
{ L"Offset", kpidOffset, VT_UI4}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
value->vt = VT_EMPTY;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||||
|
{
|
||||||
|
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||||
|
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||||
|
{
|
||||||
|
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
const STATPROPSTG &srcItem = kProperties[index];
|
||||||
|
*propID = srcItem.propid;
|
||||||
|
*varType = srcItem.vt;
|
||||||
|
if (srcItem.lpwstrName == 0)
|
||||||
|
*name = 0;
|
||||||
|
else
|
||||||
|
*name = ::SysAllocString(srcItem.lpwstrName);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||||
|
{
|
||||||
|
*numProperties = 0;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||||
|
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||||
|
{
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
NWindows::NCOM::CPropVariant propVariant;
|
||||||
|
if (m_Database.NewFormat)
|
||||||
|
{
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidSize:
|
||||||
|
propVariant = (UInt64)m_Database.NewFormatString.Length();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
propVariant.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
int entryIndex;
|
||||||
|
if (m_Database.LowLevel)
|
||||||
|
entryIndex = index;
|
||||||
|
else
|
||||||
|
entryIndex = m_Database.Indices[index];
|
||||||
|
const CItem &item = m_Database.Items[entryIndex];
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidPath:
|
||||||
|
{
|
||||||
|
UString us;
|
||||||
|
if (ConvertUTF8ToUnicode(item.Name, us))
|
||||||
|
{
|
||||||
|
if (!m_Database.LowLevel)
|
||||||
|
{
|
||||||
|
if (us.Length() > 1)
|
||||||
|
if (us[0] == L'/')
|
||||||
|
us.Delete(0);
|
||||||
|
}
|
||||||
|
propVariant = NItemName::GetOSName2(us);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kpidIsFolder:
|
||||||
|
propVariant = item.IsDirectory();
|
||||||
|
break;
|
||||||
|
case kpidSize:
|
||||||
|
propVariant = item.Size;
|
||||||
|
break;
|
||||||
|
case kpidMethod:
|
||||||
|
{
|
||||||
|
if (!item.IsDirectory())
|
||||||
|
if (item.Section == 0)
|
||||||
|
propVariant = L"Copy";
|
||||||
|
else if (item.Section < m_Database.Sections.Size())
|
||||||
|
propVariant = m_Database.Sections[(size_t)item.Section].GetMethodName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kpidBlock:
|
||||||
|
if (m_Database.LowLevel)
|
||||||
|
propVariant = item.Section;
|
||||||
|
else if (item.Section != 0)
|
||||||
|
propVariant = m_Database.GetFolder(index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef _CHM_DETAILS
|
||||||
|
|
||||||
|
case kpidSection:
|
||||||
|
propVariant = (UInt32)item.Section;
|
||||||
|
break;
|
||||||
|
case kpidOffset:
|
||||||
|
propVariant = (UInt32)item.Offset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
propVariant.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
class CPropgressImp: public CProgressVirt
|
||||||
|
{
|
||||||
|
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
||||||
|
public:
|
||||||
|
STDMETHOD(SetTotal)(const UInt64 *numFiles);
|
||||||
|
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
||||||
|
void Init(IArchiveOpenCallback *openArchiveCallback)
|
||||||
|
{ m_OpenArchiveCallback = openArchiveCallback; }
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
|
||||||
|
{
|
||||||
|
if (m_OpenArchiveCallback)
|
||||||
|
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
||||||
|
{
|
||||||
|
if (m_OpenArchiveCallback)
|
||||||
|
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||||
|
const UInt64 *maxCheckStartPosition,
|
||||||
|
IArchiveOpenCallback *openArchiveCallback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
m_Stream.Release();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CInArchive archive;
|
||||||
|
CPropgressImp progressImp;
|
||||||
|
progressImp.Init(openArchiveCallback);
|
||||||
|
RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database));
|
||||||
|
/*
|
||||||
|
if (m_Database.LowLevel)
|
||||||
|
return S_FALSE;
|
||||||
|
*/
|
||||||
|
m_Stream = inStream;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Close()
|
||||||
|
{
|
||||||
|
m_Database.Clear();
|
||||||
|
m_Stream.Release();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CChmFolderOutStream:
|
||||||
|
public ISequentialOutStream,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
|
||||||
|
HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
|
||||||
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
|
||||||
|
UInt64 m_FolderSize;
|
||||||
|
UInt64 m_PosInFolder;
|
||||||
|
UInt64 m_PosInSection;
|
||||||
|
const CRecordVector<bool> *m_ExtractStatuses;
|
||||||
|
int m_StartIndex;
|
||||||
|
int m_CurrentIndex;
|
||||||
|
int m_NumFiles;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const CFilesDatabase *m_Database;
|
||||||
|
CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
|
||||||
|
bool m_TestMode;
|
||||||
|
|
||||||
|
bool m_IsOk;
|
||||||
|
bool m_FileIsOpen;
|
||||||
|
UInt64 m_RemainFileSize;
|
||||||
|
CMyComPtr<ISequentialOutStream> m_RealOutStream;
|
||||||
|
|
||||||
|
HRESULT OpenFile();
|
||||||
|
HRESULT WriteEmptyFiles();
|
||||||
|
public:
|
||||||
|
void Init(
|
||||||
|
const CFilesDatabase *database,
|
||||||
|
IArchiveExtractCallback *extractCallback,
|
||||||
|
bool testMode);
|
||||||
|
HRESULT FlushCorrupted();
|
||||||
|
};
|
||||||
|
|
||||||
|
void CChmFolderOutStream::Init(
|
||||||
|
const CFilesDatabase *database,
|
||||||
|
IArchiveExtractCallback *extractCallback,
|
||||||
|
bool testMode)
|
||||||
|
{
|
||||||
|
m_Database = database;
|
||||||
|
m_ExtractCallback = extractCallback;
|
||||||
|
m_TestMode = testMode;
|
||||||
|
|
||||||
|
m_CurrentIndex = 0;
|
||||||
|
m_FileIsOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CChmFolderOutStream::OpenFile()
|
||||||
|
{
|
||||||
|
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||||
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract) :
|
||||||
|
NExtract::NAskMode::kSkip;
|
||||||
|
m_RealOutStream.Release();
|
||||||
|
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
|
||||||
|
if (!m_RealOutStream && !m_TestMode)
|
||||||
|
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||||
|
return m_ExtractCallback->PrepareOperation(askMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CChmFolderOutStream::WriteEmptyFiles()
|
||||||
|
{
|
||||||
|
if (m_FileIsOpen)
|
||||||
|
return S_OK;
|
||||||
|
for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
|
||||||
|
{
|
||||||
|
UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex);
|
||||||
|
if (fileSize != 0)
|
||||||
|
return S_OK;
|
||||||
|
HRESULT result = OpenFile();
|
||||||
|
m_RealOutStream.Release();
|
||||||
|
RINOK(result);
|
||||||
|
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is WritePart function
|
||||||
|
HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
|
||||||
|
{
|
||||||
|
UInt32 realProcessed = 0;
|
||||||
|
if (processedSize != NULL)
|
||||||
|
*processedSize = 0;
|
||||||
|
while(size != 0)
|
||||||
|
{
|
||||||
|
if (m_FileIsOpen)
|
||||||
|
{
|
||||||
|
UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size));
|
||||||
|
HRESULT res = S_OK;
|
||||||
|
if (numBytesToWrite > 0)
|
||||||
|
{
|
||||||
|
if (!isOK)
|
||||||
|
m_IsOk = false;
|
||||||
|
if (m_RealOutStream)
|
||||||
|
{
|
||||||
|
UInt32 processedSizeLocal = 0;
|
||||||
|
res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
|
||||||
|
numBytesToWrite = processedSizeLocal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
realProcessed += numBytesToWrite;
|
||||||
|
if (processedSize != NULL)
|
||||||
|
*processedSize = realProcessed;
|
||||||
|
data = (const void *)((const Byte *)data + numBytesToWrite);
|
||||||
|
size -= numBytesToWrite;
|
||||||
|
m_RemainFileSize -= numBytesToWrite;
|
||||||
|
m_PosInSection += numBytesToWrite;
|
||||||
|
m_PosInFolder += numBytesToWrite;
|
||||||
|
if (res != S_OK)
|
||||||
|
return res;
|
||||||
|
if (m_RemainFileSize == 0)
|
||||||
|
{
|
||||||
|
m_RealOutStream.Release();
|
||||||
|
RINOK(m_ExtractCallback->SetOperationResult(
|
||||||
|
m_IsOk ?
|
||||||
|
NArchive::NExtract::NOperationResult::kOK:
|
||||||
|
NArchive::NExtract::NOperationResult::kDataError));
|
||||||
|
m_FileIsOpen = false;
|
||||||
|
}
|
||||||
|
if (realProcessed > 0)
|
||||||
|
break; // with this break this function works as write part
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_CurrentIndex >= m_NumFiles)
|
||||||
|
return E_FAIL;
|
||||||
|
int fullIndex = m_StartIndex + m_CurrentIndex;
|
||||||
|
m_RemainFileSize = m_Database->GetFileSize(fullIndex);
|
||||||
|
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
|
||||||
|
if (fileOffset < m_PosInSection)
|
||||||
|
return E_FAIL;
|
||||||
|
if (fileOffset > m_PosInSection)
|
||||||
|
{
|
||||||
|
UInt32 numBytesToWrite = (UInt32)MyMin(fileOffset - m_PosInSection, UInt64(size));
|
||||||
|
realProcessed += numBytesToWrite;
|
||||||
|
if (processedSize != NULL)
|
||||||
|
*processedSize = realProcessed;
|
||||||
|
data = (const void *)((const Byte *)data + numBytesToWrite);
|
||||||
|
size -= numBytesToWrite;
|
||||||
|
m_PosInSection += numBytesToWrite;
|
||||||
|
m_PosInFolder += numBytesToWrite;
|
||||||
|
}
|
||||||
|
if (fileOffset == m_PosInSection)
|
||||||
|
{
|
||||||
|
RINOK(OpenFile());
|
||||||
|
m_FileIsOpen = true;
|
||||||
|
m_CurrentIndex++;
|
||||||
|
m_IsOk = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return WriteEmptyFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CChmFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||||
|
{
|
||||||
|
return Write2(data, size, processedSize, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CChmFolderOutStream::FlushCorrupted()
|
||||||
|
{
|
||||||
|
const UInt32 kBufferSize = (1 << 10);
|
||||||
|
Byte buffer[kBufferSize];
|
||||||
|
for (int i = 0; i < kBufferSize; i++)
|
||||||
|
buffer[i] = 0;
|
||||||
|
while(m_PosInFolder < m_FolderSize)
|
||||||
|
{
|
||||||
|
UInt32 size = (UInt32)MyMin(m_FolderSize - m_PosInFolder, (UInt64)kBufferSize);
|
||||||
|
UInt32 processedSizeLocal = 0;
|
||||||
|
RINOK(Write2(buffer, size, &processedSizeLocal, false));
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||||
|
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
bool allFilesMode = (numItems == UInt32(-1));
|
||||||
|
|
||||||
|
if (allFilesMode)
|
||||||
|
numItems = m_Database.NewFormat ? 1:
|
||||||
|
(m_Database.LowLevel ?
|
||||||
|
m_Database.Items.Size():
|
||||||
|
m_Database.Indices.Size());
|
||||||
|
if(numItems == 0)
|
||||||
|
return S_OK;
|
||||||
|
bool testMode = (_aTestMode != 0);
|
||||||
|
|
||||||
|
UInt64 currentTotalSize = 0;
|
||||||
|
|
||||||
|
CMyComPtr<ICompressCoder> copyCoder;
|
||||||
|
UInt32 i;
|
||||||
|
|
||||||
|
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||||
|
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||||
|
|
||||||
|
if (m_Database.LowLevel)
|
||||||
|
{
|
||||||
|
UInt64 currentItemSize = 0;
|
||||||
|
UInt64 totalSize = 0;
|
||||||
|
if (m_Database.NewFormat)
|
||||||
|
totalSize = m_Database.NewFormatString.Length();
|
||||||
|
else
|
||||||
|
for(i = 0; i < numItems; i++)
|
||||||
|
totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size;
|
||||||
|
extractCallback->SetTotal(totalSize);
|
||||||
|
|
||||||
|
for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||||
|
{
|
||||||
|
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||||
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
Int32 askMode;
|
||||||
|
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||||
|
NArchive::NExtract::NAskMode::kExtract;
|
||||||
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
|
||||||
|
if (m_Database.NewFormat)
|
||||||
|
{
|
||||||
|
if (index != 0)
|
||||||
|
return E_FAIL;
|
||||||
|
if(!testMode && (!realOutStream))
|
||||||
|
continue;
|
||||||
|
if (!testMode)
|
||||||
|
{
|
||||||
|
UInt32 size = m_Database.NewFormatString.Length();
|
||||||
|
RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size, 0));
|
||||||
|
}
|
||||||
|
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const CItem &item = m_Database.Items[index];
|
||||||
|
|
||||||
|
currentItemSize = item.Size;
|
||||||
|
|
||||||
|
if(!testMode && (!realOutStream))
|
||||||
|
continue;
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
if (item.Section != 0)
|
||||||
|
{
|
||||||
|
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (testMode)
|
||||||
|
{
|
||||||
|
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
|
||||||
|
streamSpec->Init(m_Stream, item.Size);
|
||||||
|
|
||||||
|
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||||
|
localProgressSpec->Init(extractCallback, false);
|
||||||
|
|
||||||
|
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||||
|
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||||
|
localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize);
|
||||||
|
|
||||||
|
if(!copyCoder)
|
||||||
|
copyCoder = new NCompress::CCopyCoder;
|
||||||
|
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
|
||||||
|
realOutStream.Release();
|
||||||
|
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 lastFolderIndex = ((UInt64)0 - 1);
|
||||||
|
for(i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
|
int entryIndex = m_Database.Indices[index];
|
||||||
|
const CItem &item = m_Database.Items[entryIndex];
|
||||||
|
UInt64 sectionIndex = item.Section;
|
||||||
|
if (item.IsDirectory() || item.Size == 0)
|
||||||
|
continue;
|
||||||
|
if (sectionIndex == 0)
|
||||||
|
{
|
||||||
|
currentTotalSize += item.Size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const CSectionInfo §ion = m_Database.Sections[(size_t)item.Section];
|
||||||
|
if (section.IsLzx())
|
||||||
|
{
|
||||||
|
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
|
||||||
|
UInt64 folderIndex = m_Database.GetFolder(index);
|
||||||
|
if (lastFolderIndex == folderIndex)
|
||||||
|
folderIndex++;
|
||||||
|
lastFolderIndex = m_Database.GetLastFolder(index);
|
||||||
|
for (; folderIndex <= lastFolderIndex; folderIndex++)
|
||||||
|
currentTotalSize += lzxInfo.GetFolderSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RINOK(extractCallback->SetTotal(currentTotalSize));
|
||||||
|
|
||||||
|
NCompress::NLzx::CDecoder *lzxDecoderSpec = 0;
|
||||||
|
CMyComPtr<ICompressCoder> lzxDecoder;
|
||||||
|
CChmFolderOutStream *chmFolderOutStream = 0;
|
||||||
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
|
|
||||||
|
currentTotalSize = 0;
|
||||||
|
|
||||||
|
CRecordVector<bool> extractStatuses;
|
||||||
|
for(i = 0; i < numItems;)
|
||||||
|
{
|
||||||
|
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||||
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
|
i++;
|
||||||
|
int entryIndex = m_Database.Indices[index];
|
||||||
|
const CItem &item = m_Database.Items[entryIndex];
|
||||||
|
UInt64 sectionIndex = item.Section;
|
||||||
|
Int32 askMode= testMode ?
|
||||||
|
NArchive::NExtract::NAskMode::kTest :
|
||||||
|
NArchive::NExtract::NAskMode::kExtract;
|
||||||
|
if (item.IsDirectory())
|
||||||
|
{
|
||||||
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
realOutStream.Release();
|
||||||
|
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||||
|
localProgressSpec->Init(extractCallback, false);
|
||||||
|
|
||||||
|
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||||
|
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||||
|
localCompressProgressSpec->Init(progress, NULL, ¤tTotalSize);
|
||||||
|
|
||||||
|
if (item.Size == 0 || sectionIndex == 0)
|
||||||
|
{
|
||||||
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
if(!testMode && (!realOutStream))
|
||||||
|
continue;
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
if (!testMode && item.Size != 0)
|
||||||
|
{
|
||||||
|
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
|
||||||
|
streamSpec->Init(m_Stream, item.Size);
|
||||||
|
if(!copyCoder)
|
||||||
|
copyCoder = new NCompress::CCopyCoder;
|
||||||
|
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
|
||||||
|
}
|
||||||
|
realOutStream.Release();
|
||||||
|
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||||
|
currentTotalSize += item.Size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CSectionInfo §ion = m_Database.Sections[(size_t)sectionIndex];
|
||||||
|
|
||||||
|
if (!section.IsLzx())
|
||||||
|
{
|
||||||
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
if(!testMode && (!realOutStream))
|
||||||
|
continue;
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
|
||||||
|
|
||||||
|
if (chmFolderOutStream == 0)
|
||||||
|
{
|
||||||
|
chmFolderOutStream = new CChmFolderOutStream;
|
||||||
|
outStream = chmFolderOutStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
chmFolderOutStream->Init(&m_Database, extractCallback, testMode);
|
||||||
|
|
||||||
|
if(lzxDecoderSpec == NULL)
|
||||||
|
{
|
||||||
|
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
||||||
|
lzxDecoder = lzxDecoderSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 folderIndex = m_Database.GetFolder(index);
|
||||||
|
|
||||||
|
UInt64 compressedPos = m_Database.ContentOffset + section.Offset;
|
||||||
|
UInt32 numDictBits = lzxInfo.GetNumDictBits();
|
||||||
|
RINOK(lzxDecoderSpec->SetParams(numDictBits));
|
||||||
|
|
||||||
|
const CItem *lastItem = &item;
|
||||||
|
extractStatuses.Clear();
|
||||||
|
extractStatuses.Add(true);
|
||||||
|
|
||||||
|
for (;true; folderIndex++)
|
||||||
|
{
|
||||||
|
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||||
|
|
||||||
|
UInt64 startPos = lzxInfo.GetFolderPos(folderIndex);
|
||||||
|
UInt64 finishPos = lastItem->Offset + lastItem->Size;
|
||||||
|
UInt64 limitFolderIndex = lzxInfo.GetFolder(finishPos);
|
||||||
|
|
||||||
|
lastFolderIndex = m_Database.GetLastFolder(index);
|
||||||
|
UInt64 folderSize = lzxInfo.GetFolderSize();
|
||||||
|
UInt64 unPackSize = folderSize;
|
||||||
|
if (extractStatuses.IsEmpty())
|
||||||
|
chmFolderOutStream->m_StartIndex = index + 1;
|
||||||
|
else
|
||||||
|
chmFolderOutStream->m_StartIndex = index;
|
||||||
|
if (limitFolderIndex == folderIndex)
|
||||||
|
{
|
||||||
|
for(; i < numItems; i++)
|
||||||
|
{
|
||||||
|
UInt32 nextIndex = allFilesMode ? i : indices[i];
|
||||||
|
int entryIndex = m_Database.Indices[nextIndex];
|
||||||
|
const CItem &nextItem = m_Database.Items[entryIndex];
|
||||||
|
if (nextItem.Section != sectionIndex)
|
||||||
|
break;
|
||||||
|
UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex);
|
||||||
|
if (nextFolderIndex != folderIndex)
|
||||||
|
break;
|
||||||
|
for (index++; index < nextIndex; index++)
|
||||||
|
extractStatuses.Add(false);
|
||||||
|
extractStatuses.Add(true);
|
||||||
|
index = nextIndex;
|
||||||
|
lastItem = &nextItem;
|
||||||
|
if (nextItem.Size != 0)
|
||||||
|
finishPos = nextItem.Offset + nextItem.Size;
|
||||||
|
lastFolderIndex = m_Database.GetLastFolder(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unPackSize = MyMin(finishPos - startPos, unPackSize);
|
||||||
|
|
||||||
|
chmFolderOutStream->m_FolderSize = folderSize;
|
||||||
|
chmFolderOutStream->m_PosInFolder = 0;
|
||||||
|
chmFolderOutStream->m_PosInSection = startPos;
|
||||||
|
chmFolderOutStream->m_ExtractStatuses = &extractStatuses;
|
||||||
|
chmFolderOutStream->m_NumFiles = extractStatuses.Size();
|
||||||
|
chmFolderOutStream->m_CurrentIndex = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex);
|
||||||
|
const CResetTable &rt = lzxInfo.ResetTable;
|
||||||
|
UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize);
|
||||||
|
for (UInt32 b = 0; b < numBlocks; b++)
|
||||||
|
{
|
||||||
|
UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos;
|
||||||
|
RINOK(extractCallback->SetCompleted(&completedSize));
|
||||||
|
UInt64 bCur = startBlock + b;
|
||||||
|
if (bCur >= rt.ResetOffsets.Size())
|
||||||
|
return E_FAIL;
|
||||||
|
UInt64 startOffset = rt.ResetOffsets[(int)startBlock];
|
||||||
|
UInt64 offset = rt.ResetOffsets[(int)bCur];
|
||||||
|
UInt64 compressedSize;
|
||||||
|
rt.GetCompressedSizeOfBlock(bCur, compressedSize);
|
||||||
|
UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection;
|
||||||
|
if (rem > rt.BlockSize)
|
||||||
|
rem = rt.BlockSize;
|
||||||
|
const UInt64 *offsets = (const UInt64 *)&rt.ResetOffsets.Front();
|
||||||
|
RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL));
|
||||||
|
streamSpec->Init(m_Stream, compressedSize);
|
||||||
|
lzxDecoderSpec->SetKeepHistory(b > 0, (int)((offset - startOffset) & 1));
|
||||||
|
RINOK(lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
RINOK(chmFolderOutStream->FlushCorrupted());
|
||||||
|
}
|
||||||
|
currentTotalSize += folderSize;
|
||||||
|
if (folderIndex == lastFolderIndex)
|
||||||
|
break;
|
||||||
|
extractStatuses.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
*numItems = m_Database.NewFormat ? 1:
|
||||||
|
(m_Database.LowLevel ?
|
||||||
|
m_Database.Items.Size():
|
||||||
|
m_Database.Indices.Size());
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
46
7zip/Archive/Chm/ChmHandler.h
Executable file
46
7zip/Archive/Chm/ChmHandler.h
Executable file
@@ -0,0 +1,46 @@
|
|||||||
|
// ChmHandler.h
|
||||||
|
|
||||||
|
#ifndef __ARCHIVE_CHM_HANDLER_H
|
||||||
|
#define __ARCHIVE_CHM_HANDLER_H
|
||||||
|
|
||||||
|
#include "Common/MyCom.h"
|
||||||
|
#include "../IArchive.h"
|
||||||
|
#include "ChmIn.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NChm {
|
||||||
|
|
||||||
|
class CHandler:
|
||||||
|
public IInArchive,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
|
||||||
|
STDMETHOD(Open)(IInStream *stream,
|
||||||
|
const UInt64 *maxCheckStartPosition,
|
||||||
|
IArchiveOpenCallback *openArchiveCallback);
|
||||||
|
STDMETHOD(Close)();
|
||||||
|
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
|
||||||
|
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
||||||
|
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
|
||||||
|
Int32 testMode, IArchiveExtractCallback *extractCallback);
|
||||||
|
|
||||||
|
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
||||||
|
|
||||||
|
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
||||||
|
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||||
|
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||||
|
|
||||||
|
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
||||||
|
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
||||||
|
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CFilesDatabase m_Database;
|
||||||
|
CMyComPtr<IInStream> m_Stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif
|
||||||
24
7zip/Archive/Chm/ChmHeader.cpp
Executable file
24
7zip/Archive/Chm/ChmHeader.cpp
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
// Archive/Chm/Header.h
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "ChmHeader.h"
|
||||||
|
|
||||||
|
namespace NArchive{
|
||||||
|
namespace NChm{
|
||||||
|
namespace NHeader{
|
||||||
|
|
||||||
|
UInt32 kItsfSignature = 0x46535449 + 1;
|
||||||
|
UInt32 kItolSignature = 0x4C4F5449 + 1;
|
||||||
|
static class CSignatureInitializer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CSignatureInitializer()
|
||||||
|
{
|
||||||
|
kItsfSignature--;
|
||||||
|
kItolSignature--;
|
||||||
|
}
|
||||||
|
}g_SignatureInitializer;
|
||||||
|
|
||||||
|
|
||||||
|
}}}
|
||||||
28
7zip/Archive/Chm/ChmHeader.h
Executable file
28
7zip/Archive/Chm/ChmHeader.h
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
// Archive/Chm/Header.h
|
||||||
|
|
||||||
|
#ifndef __ARCHIVE_CHM_HEADER_H
|
||||||
|
#define __ARCHIVE_CHM_HEADER_H
|
||||||
|
|
||||||
|
#include "Common/Types.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NChm {
|
||||||
|
namespace NHeader{
|
||||||
|
|
||||||
|
const UInt32 kItspSignature = 0x50535449;
|
||||||
|
const UInt32 kPmglSignature = 0x4C474D50;
|
||||||
|
const UInt32 kLzxcSignature = 0x43585A4C;
|
||||||
|
|
||||||
|
const UInt32 kIfcmSignature = 0x4D434649;
|
||||||
|
const UInt32 kAollSignature = 0x4C4C4F41;
|
||||||
|
const UInt32 kCaolSignature = 0x4C4F4143;
|
||||||
|
|
||||||
|
extern UInt32 kItsfSignature;
|
||||||
|
|
||||||
|
extern UInt32 kItolSignature;
|
||||||
|
const UInt32 kItlsSignature = 0x534C5449;
|
||||||
|
UInt64 inline GetHxsSignature() { return ((UInt64)kItlsSignature << 32) | kItolSignature; }
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#endif
|
||||||
924
7zip/Archive/Chm/ChmIn.cpp
Executable file
924
7zip/Archive/Chm/ChmIn.cpp
Executable file
@@ -0,0 +1,924 @@
|
|||||||
|
// Archive/ChmIn.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Common/StringConvert.h"
|
||||||
|
#include "Common/MyCom.h"
|
||||||
|
#include "Common/UTFConvert.h"
|
||||||
|
#include "Common/IntToString.h"
|
||||||
|
#include "Windows/Defs.h"
|
||||||
|
|
||||||
|
#include "../../Common/LimitedStreams.h"
|
||||||
|
#include "ChmIn.h"
|
||||||
|
|
||||||
|
namespace NArchive{
|
||||||
|
namespace NChm{
|
||||||
|
|
||||||
|
// define CHM_LOW, if you want to see low level items
|
||||||
|
// #define CHM_LOW
|
||||||
|
|
||||||
|
static const GUID kChmLzxGuid =
|
||||||
|
{ 0x7FC28940, 0x9D31, 0x11D0, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C };
|
||||||
|
static const GUID kHelp2LzxGuid =
|
||||||
|
{ 0x0A9007C6, 0x4076, 0x11D3, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 };
|
||||||
|
static const GUID kDesGuid =
|
||||||
|
{ 0x67F6E4A2, 0x60BF, 0x11D3, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF };
|
||||||
|
|
||||||
|
static bool AreGuidsEqual(REFGUID g1, REFGUID g2)
|
||||||
|
{
|
||||||
|
if (g1.Data1 != g2.Data1 ||
|
||||||
|
g1.Data2 != g2.Data2 ||
|
||||||
|
g1.Data3 != g2.Data3)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
if (g1.Data4[i] != g2.Data4[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char GetHex(Byte value)
|
||||||
|
{
|
||||||
|
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintByte(Byte b, AString &s)
|
||||||
|
{
|
||||||
|
s += GetHex(b >> 4);
|
||||||
|
s += GetHex(b & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintUInt16(UInt16 v, AString &s)
|
||||||
|
{
|
||||||
|
PrintByte((Byte)(v >> 8), s);
|
||||||
|
PrintByte((Byte)v, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintUInt32(UInt32 v, AString &s)
|
||||||
|
{
|
||||||
|
PrintUInt16((UInt16)(v >> 16), s);
|
||||||
|
PrintUInt16((UInt16)v, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
AString CMethodInfo::GetGuidString() const
|
||||||
|
{
|
||||||
|
AString s;
|
||||||
|
s += '{';
|
||||||
|
PrintUInt32(Guid.Data1, s);
|
||||||
|
s += '-';
|
||||||
|
PrintUInt16(Guid.Data2, s);
|
||||||
|
s += '-';
|
||||||
|
PrintUInt16(Guid.Data3, s);
|
||||||
|
s += '-';
|
||||||
|
PrintByte(Guid.Data4[0], s);
|
||||||
|
PrintByte(Guid.Data4[1], s);
|
||||||
|
s += '-';
|
||||||
|
for (int i = 2; i < 8; i++)
|
||||||
|
PrintByte(Guid.Data4[i], s);
|
||||||
|
s += '}';
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMethodInfo::IsLzx() const
|
||||||
|
{
|
||||||
|
if (AreGuidsEqual(Guid, kChmLzxGuid))
|
||||||
|
return true;
|
||||||
|
return AreGuidsEqual(Guid, kHelp2LzxGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMethodInfo::IsDes() const
|
||||||
|
{
|
||||||
|
return AreGuidsEqual(Guid, kDesGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
UString CMethodInfo::GetName() const
|
||||||
|
{
|
||||||
|
UString s;
|
||||||
|
if (IsLzx())
|
||||||
|
{
|
||||||
|
s = L"LZX:";
|
||||||
|
UInt32 numDictBits = LzxInfo.GetNumDictBits();
|
||||||
|
wchar_t temp[32];
|
||||||
|
ConvertUInt64ToString(numDictBits, temp);
|
||||||
|
s += temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AString s2;
|
||||||
|
if (IsDes())
|
||||||
|
s2 = "DES";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s2 = GetGuidString();
|
||||||
|
if (ControlData.GetCapacity() > 0)
|
||||||
|
{
|
||||||
|
s2 += ":";
|
||||||
|
for (size_t i = 0; i < ControlData.GetCapacity(); i++)
|
||||||
|
PrintByte(ControlData[i], s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ConvertUTF8ToUnicode(s2, s);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSectionInfo::IsLzx() const
|
||||||
|
{
|
||||||
|
if (Methods.Size() != 1)
|
||||||
|
return false;
|
||||||
|
return Methods[0].IsLzx();
|
||||||
|
}
|
||||||
|
|
||||||
|
UString CSectionInfo::GetMethodName() const
|
||||||
|
{
|
||||||
|
UString s;
|
||||||
|
if (!IsLzx())
|
||||||
|
{
|
||||||
|
UString temp;
|
||||||
|
if (ConvertUTF8ToUnicode(Name, temp))
|
||||||
|
s += temp;
|
||||||
|
s += L": ";
|
||||||
|
}
|
||||||
|
for (int i = 0; i < Methods.Size(); i++)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
s += L" ";
|
||||||
|
s += Methods[i].GetName();
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte CInArchive::ReadByte()
|
||||||
|
{
|
||||||
|
Byte b;
|
||||||
|
if (!_inBuffer.ReadByte(b))
|
||||||
|
throw 1;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInArchive::Skeep(size_t size)
|
||||||
|
{
|
||||||
|
while (size-- != 0)
|
||||||
|
ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInArchive::ReadBytes(Byte *data, UInt32 size)
|
||||||
|
{
|
||||||
|
for (UInt32 i = 0; i < size; i++)
|
||||||
|
data[i] = ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt16 CInArchive::ReadUInt16()
|
||||||
|
{
|
||||||
|
UInt16 value = 0;
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
value |= ((UInt16)(ReadByte()) << (8 * i));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 CInArchive::ReadUInt32()
|
||||||
|
{
|
||||||
|
UInt32 value = 0;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
value |= ((UInt32)(ReadByte()) << (8 * i));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 CInArchive::ReadUInt64()
|
||||||
|
{
|
||||||
|
UInt64 value = 0;
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
value |= ((UInt64)(ReadByte()) << (8 * i));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 CInArchive::ReadEncInt()
|
||||||
|
{
|
||||||
|
UInt64 val = 0;;
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
Byte b = ReadByte();
|
||||||
|
val |= (b & 0x7F);
|
||||||
|
if (b < 0x80)
|
||||||
|
return val;
|
||||||
|
val <<= 7;
|
||||||
|
}
|
||||||
|
throw 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInArchive::ReadGUID(GUID &g)
|
||||||
|
{
|
||||||
|
g.Data1 = ReadUInt32();
|
||||||
|
g.Data2 = ReadUInt16();
|
||||||
|
g.Data3 = ReadUInt16();
|
||||||
|
ReadBytes(g.Data4, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInArchive::ReadString(int size, AString &s)
|
||||||
|
{
|
||||||
|
s.Empty();
|
||||||
|
while(size-- != 0)
|
||||||
|
{
|
||||||
|
char c = (char)ReadByte();
|
||||||
|
if (c == 0)
|
||||||
|
{
|
||||||
|
Skeep(size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInArchive::ReadUString(int size, UString &s)
|
||||||
|
{
|
||||||
|
s.Empty();
|
||||||
|
while(size-- != 0)
|
||||||
|
{
|
||||||
|
wchar_t c = ReadUInt16();
|
||||||
|
if (c == 0)
|
||||||
|
{
|
||||||
|
Skeep(2 * size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size)
|
||||||
|
{
|
||||||
|
RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL));
|
||||||
|
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||||
|
CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
|
||||||
|
streamSpec->Init(inStream, size);
|
||||||
|
_inBuffer.SetStream(limitedStream);
|
||||||
|
_inBuffer.Init();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::ReadDirEntry(CDatabase &database)
|
||||||
|
{
|
||||||
|
CItem item;
|
||||||
|
UInt64 nameLength = ReadEncInt();
|
||||||
|
if (nameLength == 0 || nameLength >= 0x10000000)
|
||||||
|
return S_FALSE;
|
||||||
|
ReadString((int)nameLength, item.Name);
|
||||||
|
item.Section = ReadEncInt();
|
||||||
|
item.Offset = ReadEncInt();
|
||||||
|
item.Size = ReadEncInt();
|
||||||
|
database.Items.Add(item);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
|
||||||
|
{
|
||||||
|
UInt32 headerSize = ReadUInt32();
|
||||||
|
if (headerSize != 0x60)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 unknown1 = ReadUInt32();
|
||||||
|
if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 timeStamp = ReadUInt32();
|
||||||
|
// Considered as a big-endian DWORD, it appears to contain seconds (MSB) and
|
||||||
|
// fractional seconds (second byte).
|
||||||
|
// The third and fourth bytes may contain even more fractional bits.
|
||||||
|
// The 4 least significant bits in the last byte are constant.
|
||||||
|
UInt32 lang = ReadUInt32();
|
||||||
|
GUID g;
|
||||||
|
ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC}
|
||||||
|
ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC}
|
||||||
|
const int kNumSections = 2;
|
||||||
|
UInt64 sectionOffsets[kNumSections];
|
||||||
|
UInt64 sectionSizes[kNumSections];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < kNumSections; i++)
|
||||||
|
{
|
||||||
|
sectionOffsets[i] = ReadUInt64();
|
||||||
|
sectionSizes[i] = ReadUInt64();
|
||||||
|
}
|
||||||
|
// if (chmVersion == 3)
|
||||||
|
database.ContentOffset = ReadUInt64();
|
||||||
|
/*
|
||||||
|
else
|
||||||
|
database.ContentOffset = _startPosition + 0x58
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Section 0
|
||||||
|
ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]);
|
||||||
|
if (sectionSizes[0] != 0x18)
|
||||||
|
return S_FALSE;
|
||||||
|
ReadUInt32(); // unknown: 01FE
|
||||||
|
ReadUInt32(); // unknown: 0
|
||||||
|
UInt64 fileSize = ReadUInt64();
|
||||||
|
ReadUInt32(); // unknown: 0
|
||||||
|
ReadUInt32(); // unknown: 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Section 1: The Directory Listing
|
||||||
|
ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]);
|
||||||
|
if (ReadUInt32() != NHeader::kItspSignature)
|
||||||
|
return S_FALSE;
|
||||||
|
if (ReadUInt32() != 1) // version
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 dirHeaderSize = ReadUInt32();
|
||||||
|
ReadUInt32(); // 0x0A (unknown)
|
||||||
|
UInt32 dirChunkSize = ReadUInt32(); // $1000
|
||||||
|
if (dirChunkSize < 32)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 density = ReadUInt32(); // "Density" of quickref section, usually 2.
|
||||||
|
UInt32 depth = ReadUInt32(); // Depth of the index tree: 1 there is no index,
|
||||||
|
// 2 if there is one level of PMGI chunks.
|
||||||
|
|
||||||
|
UInt32 chunkNumber = ReadUInt32(); // Chunk number of root index chunk, -1 if there is none
|
||||||
|
// (though at least one file has 0 despite there being no
|
||||||
|
// index chunk, probably a bug.)
|
||||||
|
UInt32 firstPmglChunkNumber = ReadUInt32(); // Chunk number of first PMGL (listing) chunk
|
||||||
|
UInt32 lastPmglChunkNumber = ReadUInt32(); // Chunk number of last PMGL (listing) chunk
|
||||||
|
ReadUInt32(); // -1 (unknown)
|
||||||
|
UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total)
|
||||||
|
UInt32 windowsLangId = ReadUInt32();
|
||||||
|
ReadGUID(g); // {5D02926A-212E-11D0-9DF9-00A0C922E6EC}
|
||||||
|
ReadUInt32(); // 0x54 (This is the length again)
|
||||||
|
ReadUInt32(); // -1 (unknown)
|
||||||
|
ReadUInt32(); // -1 (unknown)
|
||||||
|
ReadUInt32(); // -1 (unknown)
|
||||||
|
|
||||||
|
for (UInt32 ci = 0; ci < numDirChunks; ci++)
|
||||||
|
{
|
||||||
|
UInt64 chunkPos = _inBuffer.GetProcessedSize();
|
||||||
|
if (ReadUInt32() == NHeader::kPmglSignature)
|
||||||
|
{
|
||||||
|
// The quickref area is written backwards from the end of the chunk.
|
||||||
|
// One quickref entry exists for every n entries in the file, where n
|
||||||
|
// is calculated as 1 + (1 << quickref density). So for density = 2, n = 5.
|
||||||
|
|
||||||
|
UInt32 quickrefLength = ReadUInt32(); // Length of free space and/or quickref area at end of directory chunk
|
||||||
|
if (quickrefLength > dirChunkSize || quickrefLength < 2)
|
||||||
|
return S_FALSE;
|
||||||
|
ReadUInt32(); // Always 0
|
||||||
|
ReadUInt32(); // Chunk number of previous listing chunk when reading
|
||||||
|
// directory in sequence (-1 if this is the first listing chunk)
|
||||||
|
ReadUInt32(); // Chunk number of next listing chunk when reading
|
||||||
|
// directory in sequence (-1 if this is the last listing chunk)
|
||||||
|
int numItems = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
|
||||||
|
UInt32 offsetLimit = dirChunkSize - quickrefLength;
|
||||||
|
if (offset > offsetLimit)
|
||||||
|
return S_FALSE;
|
||||||
|
if (offset == offsetLimit)
|
||||||
|
break;
|
||||||
|
RINOK(ReadDirEntry(database));
|
||||||
|
numItems++;
|
||||||
|
}
|
||||||
|
Skeep(quickrefLength - 2);
|
||||||
|
if (ReadUInt16() != numItems)
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Skeep(dirChunkSize - 4);
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
|
||||||
|
{
|
||||||
|
if (ReadUInt32() != 1) // version
|
||||||
|
return S_FALSE;
|
||||||
|
if (ReadUInt32() != 0x28) // Location of header section table
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 numHeaderSections = ReadUInt32();
|
||||||
|
const int kNumHeaderSectionsMax = 5;
|
||||||
|
if (numHeaderSections != kNumHeaderSectionsMax)
|
||||||
|
return S_FALSE;
|
||||||
|
ReadUInt32(); // Length of post-header table
|
||||||
|
GUID g;
|
||||||
|
ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754}
|
||||||
|
|
||||||
|
// header section table
|
||||||
|
UInt64 sectionOffsets[kNumHeaderSectionsMax];
|
||||||
|
UInt64 sectionSizes[kNumHeaderSectionsMax];
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < numHeaderSections; i++)
|
||||||
|
{
|
||||||
|
sectionOffsets[i] = ReadUInt64();
|
||||||
|
sectionSizes[i] = ReadUInt64();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post-Header
|
||||||
|
ReadUInt32(); // 2
|
||||||
|
ReadUInt32(); // 0x98: offset to CAOL from beginning of post-header)
|
||||||
|
// ----- Directory information
|
||||||
|
ReadUInt64(); // Chunk number of top-level AOLI chunk in directory, or -1
|
||||||
|
ReadUInt64(); // Chunk number of first AOLL chunk in directory
|
||||||
|
ReadUInt64(); // Chunk number of last AOLL chunk in directory
|
||||||
|
ReadUInt64(); // 0 (unknown)
|
||||||
|
ReadUInt32(); // $2000 (Directory chunk size of directory)
|
||||||
|
ReadUInt32(); // Quickref density for main directory, usually 2
|
||||||
|
ReadUInt32(); // 0 (unknown)
|
||||||
|
ReadUInt32(); // Depth of main directory index tree
|
||||||
|
// 1 there is no index, 2 if there is one level of AOLI chunks.
|
||||||
|
ReadUInt64(); // 0 (unknown)
|
||||||
|
UInt64 numDirEntries = ReadUInt64(); // Number of directory entries
|
||||||
|
// ----- Directory Index Information
|
||||||
|
ReadUInt64(); // -1 (unknown, probably chunk number of top-level AOLI in directory index)
|
||||||
|
ReadUInt64(); // Chunk number of first AOLL chunk in directory index
|
||||||
|
ReadUInt64(); // Chunk number of last AOLL chunk in directory index
|
||||||
|
ReadUInt64(); // 0 (unknown)
|
||||||
|
ReadUInt32(); // $200 (Directory chunk size of directory index)
|
||||||
|
ReadUInt32(); // Quickref density for directory index, usually 2
|
||||||
|
ReadUInt32(); // 0 (unknown)
|
||||||
|
ReadUInt32(); // Depth of directory index index tree.
|
||||||
|
ReadUInt64(); // Possibly flags -- sometimes 1, sometimes 0.
|
||||||
|
ReadUInt64(); // Number of directory index entries (same as number of AOLL
|
||||||
|
// chunks in main directory)
|
||||||
|
|
||||||
|
// (The obvious guess for the following two fields, which recur in a number
|
||||||
|
// of places, is they are maximum sizes for the directory and directory index.
|
||||||
|
// However, I have seen no direct evidence that this is the case.)
|
||||||
|
|
||||||
|
ReadUInt32(); // $100000 (Same as field following chunk size in directory)
|
||||||
|
ReadUInt32(); // $20000 (Same as field following chunk size in directory index)
|
||||||
|
|
||||||
|
ReadUInt64(); // 0 (unknown)
|
||||||
|
if (ReadUInt32() != NHeader::kCaolSignature)
|
||||||
|
return S_FALSE;
|
||||||
|
if (ReadUInt32() != 2) // (Most likely a version number)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 caolLength = ReadUInt32(); // $50 (Length of the CAOL section, which includes the ITSF section)
|
||||||
|
if (caolLength >= 0x2C)
|
||||||
|
{
|
||||||
|
UInt32 c7 = ReadUInt16(); // Unknown. Remains the same when identical files are built.
|
||||||
|
// Does not appear to be a checksum. Many files have
|
||||||
|
// 'HH' (HTML Help?) here, indicating this may be a compiler ID
|
||||||
|
// field. But at least one ITOL/ITLS compiler does not set this
|
||||||
|
// field to a constant value.
|
||||||
|
ReadUInt16(); // 0 (Unknown. Possibly part of 00A4 field)
|
||||||
|
ReadUInt32(); // Unknown. Two values have been seen -- $43ED, and 0.
|
||||||
|
ReadUInt32(); // $2000 (Directory chunk size of directory)
|
||||||
|
ReadUInt32(); // $200 (Directory chunk size of directory index)
|
||||||
|
ReadUInt32(); // $100000 (Same as field following chunk size in directory)
|
||||||
|
ReadUInt32(); // $20000 (Same as field following chunk size in directory index)
|
||||||
|
ReadUInt32(); // 0 (unknown)
|
||||||
|
ReadUInt32(); // 0 (Unknown)
|
||||||
|
if (caolLength == 0x2C)
|
||||||
|
{
|
||||||
|
database.ContentOffset = 0;
|
||||||
|
database.NewFormat = true;
|
||||||
|
}
|
||||||
|
else if (caolLength == 0x50)
|
||||||
|
{
|
||||||
|
ReadUInt32(); // 0 (Unknown)
|
||||||
|
if (ReadUInt32() != NHeader::kItsfSignature)
|
||||||
|
return S_FALSE;
|
||||||
|
if (ReadUInt32() != 4) // $4 (Version number -- CHM uses 3)
|
||||||
|
return S_FALSE;
|
||||||
|
if (ReadUInt32() != 0x20) // $20 (length of ITSF)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 unknown = ReadUInt32();
|
||||||
|
if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases;
|
||||||
|
return S_FALSE;
|
||||||
|
database.ContentOffset = _startPosition + ReadUInt64();
|
||||||
|
UInt32 timeStamp = ReadUInt32();
|
||||||
|
// A timestamp of some sort.
|
||||||
|
// Considered as a big-endian DWORD, it appears to contain
|
||||||
|
// seconds (MSB) and fractional seconds (second byte).
|
||||||
|
// The third and fourth bytes may contain even more fractional
|
||||||
|
// bits. The 4 least significant bits in the last byte are constant.
|
||||||
|
UInt32 lang = ReadUInt32(); // BE?
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Section 0
|
||||||
|
ReadChunk(inStream, _startPosition + sectionOffsets[0], sectionSizes[0]);
|
||||||
|
if (sectionSizes[0] != 0x18)
|
||||||
|
return S_FALSE;
|
||||||
|
ReadUInt32(); // unknown: 01FE
|
||||||
|
ReadUInt32(); // unknown: 0
|
||||||
|
UInt64 fileSize = ReadUInt64();
|
||||||
|
ReadUInt32(); // unknown: 0
|
||||||
|
ReadUInt32(); // unknown: 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Section 1: The Directory Listing
|
||||||
|
ReadChunk(inStream, _startPosition + sectionOffsets[1], sectionSizes[1]);
|
||||||
|
if (ReadUInt32() != NHeader::kIfcmSignature)
|
||||||
|
return S_FALSE;
|
||||||
|
if (ReadUInt32() != 1) // (probably a version number)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 dirChunkSize = ReadUInt32(); // $2000
|
||||||
|
if (dirChunkSize < 64)
|
||||||
|
return S_FALSE;
|
||||||
|
ReadUInt32(); // $100000 (unknown)
|
||||||
|
ReadUInt32(); // -1 (unknown)
|
||||||
|
ReadUInt32(); // -1 (unknown)
|
||||||
|
UInt32 numDirChunks = ReadUInt32();
|
||||||
|
ReadUInt32(); // 0 (unknown, probably high word of above)
|
||||||
|
|
||||||
|
for (UInt32 ci = 0; ci < numDirChunks; ci++)
|
||||||
|
{
|
||||||
|
UInt64 chunkPos = _inBuffer.GetProcessedSize();
|
||||||
|
if (ReadUInt32() == NHeader::kAollSignature)
|
||||||
|
{
|
||||||
|
UInt32 quickrefLength = ReadUInt32(); // Length of quickref area at end of directory chunk
|
||||||
|
if (quickrefLength > dirChunkSize || quickrefLength < 2)
|
||||||
|
return S_FALSE;
|
||||||
|
ReadUInt64(); // Directory chunk number
|
||||||
|
// This must match physical position in file, that is
|
||||||
|
// the chunk size times the chunk number must be the
|
||||||
|
// offset from the end of the directory header.
|
||||||
|
ReadUInt64(); // Chunk number of previous listing chunk when reading
|
||||||
|
// directory in sequence (-1 if first listing chunk)
|
||||||
|
ReadUInt64(); // Chunk number of next listing chunk when reading
|
||||||
|
// directory in sequence (-1 if last listing chunk)
|
||||||
|
ReadUInt64(); // Number of first listing entry in this chunk
|
||||||
|
ReadUInt32(); // 1 (unknown -- other values have also been seen here)
|
||||||
|
ReadUInt32(); // 0 (unknown)
|
||||||
|
|
||||||
|
int numItems = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
|
||||||
|
UInt32 offsetLimit = dirChunkSize - quickrefLength;
|
||||||
|
if (offset > offsetLimit)
|
||||||
|
return S_FALSE;
|
||||||
|
if (offset == offsetLimit)
|
||||||
|
break;
|
||||||
|
if (database.NewFormat)
|
||||||
|
{
|
||||||
|
UInt16 nameLength = ReadUInt16();
|
||||||
|
if (nameLength == 0)
|
||||||
|
return S_FALSE;
|
||||||
|
UString name;
|
||||||
|
ReadUString((int)nameLength, name);
|
||||||
|
AString s;
|
||||||
|
ConvertUnicodeToUTF8(name, s);
|
||||||
|
Byte b = ReadByte();
|
||||||
|
s += ' ';
|
||||||
|
PrintByte(b, s);
|
||||||
|
s += ' ';
|
||||||
|
UInt64 len = ReadEncInt();
|
||||||
|
// then number of items ?
|
||||||
|
// then length ?
|
||||||
|
// then some data (binary encoding?)
|
||||||
|
while (len-- != 0)
|
||||||
|
{
|
||||||
|
b = ReadByte();
|
||||||
|
PrintByte(b, s);
|
||||||
|
}
|
||||||
|
database.NewFormatString += s;
|
||||||
|
database.NewFormatString += "\r\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RINOK(ReadDirEntry(database));
|
||||||
|
}
|
||||||
|
numItems++;
|
||||||
|
}
|
||||||
|
Skeep(quickrefLength - 2);
|
||||||
|
if (ReadUInt16() != numItems)
|
||||||
|
return S_FALSE;
|
||||||
|
if (numItems > numDirEntries)
|
||||||
|
return S_FALSE;
|
||||||
|
numDirEntries -= numItems;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Skeep(dirChunkSize - 4);
|
||||||
|
}
|
||||||
|
return numDirEntries == 0 ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name)
|
||||||
|
{
|
||||||
|
int index = database.FindItem(name);
|
||||||
|
if (index < 0)
|
||||||
|
return S_FALSE;
|
||||||
|
const CItem &item = database.Items[index];
|
||||||
|
_chunkSize = item.Size;
|
||||||
|
return ReadChunk(inStream, database.ContentOffset + item.Offset, item.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define DATA_SPACE "::DataSpace/"
|
||||||
|
static const char *kNameList = DATA_SPACE "NameList";
|
||||||
|
static const char *kStorage = DATA_SPACE "Storage/";
|
||||||
|
static const char *kContent = "Content";
|
||||||
|
static const char *kControlData = "ControlData";
|
||||||
|
static const char *kSpanInfo = "SpanInfo";
|
||||||
|
static const char *kTransform = "Transform/";
|
||||||
|
static const char *kResetTable = "/InstanceData/ResetTable";
|
||||||
|
static const char *kTransformList = "List";
|
||||||
|
|
||||||
|
static AString GetSectionPrefix(const AString &name)
|
||||||
|
{
|
||||||
|
return AString(kStorage) + name + AString("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
||||||
|
|
||||||
|
static int CompareFiles(const int *p1, const int *p2, void *param)
|
||||||
|
{
|
||||||
|
const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param;
|
||||||
|
const CItem &item1 = items[*p1];
|
||||||
|
const CItem &item2 = items[*p2];
|
||||||
|
bool isDir1 = item1.IsDirectory();
|
||||||
|
bool isDir2 = item2.IsDirectory();
|
||||||
|
if (isDir1 && !isDir2)
|
||||||
|
return -1;
|
||||||
|
if (isDir2)
|
||||||
|
{
|
||||||
|
if (isDir1)
|
||||||
|
return MyCompare(*p1, *p2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
RINOZ(MyCompare(item1.Section, item2.Section));
|
||||||
|
RINOZ(MyCompare(item1.Offset, item2.Offset));
|
||||||
|
RINOZ(MyCompare(item1.Size, item2.Size));
|
||||||
|
return MyCompare(*p1, *p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFilesDatabase::SetIndices()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Items.Size(); i++)
|
||||||
|
{
|
||||||
|
const CItem &item = Items[i];
|
||||||
|
if (item.IsUserItem() && item.Name.Length() != 1)
|
||||||
|
Indices.Add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFilesDatabase::Sort()
|
||||||
|
{
|
||||||
|
Indices.Sort(CompareFiles, (void *)&Items);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFilesDatabase::Check()
|
||||||
|
{
|
||||||
|
UInt64 maxPos = 0;
|
||||||
|
UInt64 prevSection = 0;
|
||||||
|
for(int i = 0; i < Indices.Size(); i++)
|
||||||
|
{
|
||||||
|
const CItem &item = Items[Indices[i]];
|
||||||
|
if (item.Section == 0 || item.IsDirectory())
|
||||||
|
continue;
|
||||||
|
if (item.Section != prevSection)
|
||||||
|
{
|
||||||
|
prevSection = item.Section;
|
||||||
|
maxPos = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (item.Offset < maxPos)
|
||||||
|
return false;
|
||||||
|
maxPos = item.Offset + item.Size;
|
||||||
|
if (maxPos < item.Offset)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// The NameList file
|
||||||
|
RINOK(DecompressStream(inStream, database, kNameList));
|
||||||
|
UInt16 length = ReadUInt16();
|
||||||
|
UInt16 numSections = ReadUInt16();
|
||||||
|
for (int i = 0; i < numSections; i++)
|
||||||
|
{
|
||||||
|
CSectionInfo section;
|
||||||
|
UInt16 nameLength = ReadUInt16();
|
||||||
|
UString name;
|
||||||
|
ReadUString(nameLength, name);
|
||||||
|
if (ReadUInt16() != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
if (!ConvertUnicodeToUTF8(name, section.Name))
|
||||||
|
return S_FALSE;
|
||||||
|
database.Sections.Add(section);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < database.Sections.Size(); i++)
|
||||||
|
{
|
||||||
|
CSectionInfo §ion = database.Sections[i];
|
||||||
|
AString sectionPrefix = GetSectionPrefix(section.Name);
|
||||||
|
{
|
||||||
|
// Content
|
||||||
|
int index = database.FindItem(sectionPrefix + kContent);
|
||||||
|
if (index < 0)
|
||||||
|
return S_FALSE;
|
||||||
|
const CItem &item = database.Items[index];
|
||||||
|
section.Offset = item.Offset;
|
||||||
|
section.CompressedSize = item.Size;
|
||||||
|
}
|
||||||
|
AString transformPrefix = sectionPrefix + kTransform;
|
||||||
|
if (database.Help2Format)
|
||||||
|
{
|
||||||
|
// Transform List
|
||||||
|
RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList));
|
||||||
|
if ((_chunkSize & 0xF) != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
int numGuids = (int)(_chunkSize / 0x10);
|
||||||
|
if (numGuids < 1)
|
||||||
|
return S_FALSE;
|
||||||
|
for (int i = 0; i < numGuids; i++)
|
||||||
|
{
|
||||||
|
CMethodInfo method;
|
||||||
|
ReadGUID(method.Guid);
|
||||||
|
section.Methods.Add(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CMethodInfo method;
|
||||||
|
method.Guid = kChmLzxGuid;
|
||||||
|
section.Methods.Add(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Control Data
|
||||||
|
RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData));
|
||||||
|
for (int mi = 0; mi < section.Methods.Size(); mi++)
|
||||||
|
{
|
||||||
|
CMethodInfo &method = section.Methods[mi];
|
||||||
|
UInt32 numDWORDS = ReadUInt32();
|
||||||
|
if (method.IsLzx())
|
||||||
|
{
|
||||||
|
if (numDWORDS < 5)
|
||||||
|
return S_FALSE;
|
||||||
|
if (ReadUInt32() != NHeader::kLzxcSignature)
|
||||||
|
return S_FALSE;
|
||||||
|
CLzxInfo &li = method.LzxInfo;
|
||||||
|
li.Version = ReadUInt32();
|
||||||
|
if (li.Version != 2 && li.Version != 3)
|
||||||
|
return S_FALSE;
|
||||||
|
li.ResetInterval = ReadUInt32();
|
||||||
|
li.WindowSize = ReadUInt32();
|
||||||
|
li.CacheSize = ReadUInt32();
|
||||||
|
if (li.ResetInterval != 2 && li.ResetInterval != 4)
|
||||||
|
return S_FALSE;
|
||||||
|
if (li.WindowSize != 2 && li.WindowSize != 4)
|
||||||
|
return S_FALSE;
|
||||||
|
numDWORDS -= 5;
|
||||||
|
while (numDWORDS-- != 0)
|
||||||
|
ReadUInt32();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt32 numBytes = numDWORDS * 4;
|
||||||
|
method.ControlData.SetCapacity(numBytes);
|
||||||
|
ReadBytes(method.ControlData, numBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// SpanInfo
|
||||||
|
RINOK(DecompressStream(inStream, database, sectionPrefix + kSpanInfo));
|
||||||
|
section.UncompressedSize = ReadUInt64();
|
||||||
|
}
|
||||||
|
|
||||||
|
// read ResetTable for LZX
|
||||||
|
for (int mi = 0; mi < section.Methods.Size(); mi++)
|
||||||
|
{
|
||||||
|
CMethodInfo &method = section.Methods[mi];
|
||||||
|
if (method.IsLzx())
|
||||||
|
{
|
||||||
|
// ResetTable;
|
||||||
|
RINOK(DecompressStream(inStream, database, transformPrefix +
|
||||||
|
method.GetGuidString() + kResetTable));
|
||||||
|
CResetTable &rt = method.LzxInfo.ResetTable;
|
||||||
|
if (_chunkSize < 4)
|
||||||
|
{
|
||||||
|
if (_chunkSize != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
// ResetTable is empty in .chw files
|
||||||
|
if (section.UncompressedSize != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
rt.UncompressedSize = 0;
|
||||||
|
rt.CompressedSize = 0;
|
||||||
|
rt.BlockSize = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt32 ver = ReadUInt32(); // 2 unknown (possibly a version number)
|
||||||
|
if (ver != 2 && ver != 3)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 numEntries = ReadUInt32();
|
||||||
|
if (ReadUInt32() != 8) // Size of table entry (bytes)
|
||||||
|
return S_FALSE;
|
||||||
|
if (ReadUInt32() != 0x28) // Length of table header
|
||||||
|
return S_FALSE;
|
||||||
|
rt.UncompressedSize = ReadUInt64();
|
||||||
|
rt.CompressedSize = ReadUInt64();
|
||||||
|
rt.BlockSize = ReadUInt64(); // 0x8000 block size for locations below
|
||||||
|
if (rt.BlockSize != 0x8000)
|
||||||
|
return S_FALSE;
|
||||||
|
rt.ResetOffsets.Reserve(numEntries);
|
||||||
|
for (UInt32 i = 0; i < numEntries; i++)
|
||||||
|
rt.ResetOffsets.Add(ReadUInt64());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
database.SetIndices();
|
||||||
|
database.Sort();
|
||||||
|
return database.Check() ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::Open2(IInStream *inStream,
|
||||||
|
const UInt64 *searchHeaderSizeLimit,
|
||||||
|
CFilesDatabase &database)
|
||||||
|
{
|
||||||
|
database.Clear();
|
||||||
|
|
||||||
|
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &_startPosition));
|
||||||
|
|
||||||
|
database.Help2Format = false;
|
||||||
|
const UInt32 chmVersion = 3;
|
||||||
|
{
|
||||||
|
if (!_inBuffer.Create(1 << 14))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
_inBuffer.SetStream(inStream);
|
||||||
|
_inBuffer.Init();
|
||||||
|
UInt64 value = 0;
|
||||||
|
const int kSignatureSize = 8;
|
||||||
|
UInt64 hxsSignature = NHeader::GetHxsSignature();
|
||||||
|
UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
Byte b;
|
||||||
|
if (!_inBuffer.ReadByte(b))
|
||||||
|
return S_FALSE;
|
||||||
|
value >>= 8;
|
||||||
|
value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
|
||||||
|
if (_inBuffer.GetProcessedSize() >= kSignatureSize)
|
||||||
|
{
|
||||||
|
if (value == chmSignature)
|
||||||
|
break;
|
||||||
|
if (value == hxsSignature)
|
||||||
|
{
|
||||||
|
database.Help2Format = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (searchHeaderSizeLimit != NULL)
|
||||||
|
if (_inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_startPosition += _inBuffer.GetProcessedSize() - kSignatureSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (database.Help2Format)
|
||||||
|
{
|
||||||
|
RINOK(OpenHelp2(inStream, database));
|
||||||
|
if (database.NewFormat)
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RINOK(OpenChm(inStream, database));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CHM_LOW
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HRESULT res = OpenHighLevel(inStream, database);
|
||||||
|
if (res == S_FALSE)
|
||||||
|
{
|
||||||
|
database.HighLevelClear();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
RINOK(res);
|
||||||
|
database.LowLevel = false;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::Open(IInStream *inStream,
|
||||||
|
const UInt64 *searchHeaderSizeLimit,
|
||||||
|
CFilesDatabase &database)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HRESULT res = Open2(inStream, searchHeaderSizeLimit, database);
|
||||||
|
_inBuffer.ReleaseStream();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
_inBuffer.ReleaseStream();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
242
7zip/Archive/Chm/ChmIn.h
Executable file
242
7zip/Archive/Chm/ChmIn.h
Executable file
@@ -0,0 +1,242 @@
|
|||||||
|
// Archive/ChmIn.h
|
||||||
|
|
||||||
|
#ifndef __ARCHIVE_CHM_IN_H
|
||||||
|
#define __ARCHIVE_CHM_IN_H
|
||||||
|
|
||||||
|
#include "Common/String.h"
|
||||||
|
#include "Common/Buffer.h"
|
||||||
|
#include "../../IStream.h"
|
||||||
|
#include "../../Common/InBuffer.h"
|
||||||
|
#include "ChmHeader.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NChm {
|
||||||
|
|
||||||
|
struct CItem
|
||||||
|
{
|
||||||
|
UInt64 Section;
|
||||||
|
UInt64 Offset;
|
||||||
|
UInt64 Size;
|
||||||
|
AString Name;
|
||||||
|
|
||||||
|
bool IsFormatRelatedItem() const
|
||||||
|
{
|
||||||
|
if (Name.Length() < 2)
|
||||||
|
return false;
|
||||||
|
return Name[0] == ':' && Name[1] == ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsUserItem() const
|
||||||
|
{
|
||||||
|
if (Name.Length() < 2)
|
||||||
|
return false;
|
||||||
|
return Name[0] == '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDirectory() const
|
||||||
|
{
|
||||||
|
if (Name.Length() == 0)
|
||||||
|
return false;
|
||||||
|
return (Name[Name.Length() - 1] == '/');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CDatabase
|
||||||
|
{
|
||||||
|
UInt64 ContentOffset;
|
||||||
|
CObjectVector<CItem> Items;
|
||||||
|
AString NewFormatString;
|
||||||
|
bool Help2Format;
|
||||||
|
bool NewFormat;
|
||||||
|
|
||||||
|
int FindItem(const AString &name) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Items.Size(); i++)
|
||||||
|
if (Items[i].Name == name)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
NewFormat = false;
|
||||||
|
NewFormatString.Empty();
|
||||||
|
Help2Format = false;
|
||||||
|
Items.Clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CResetTable
|
||||||
|
{
|
||||||
|
UInt64 UncompressedSize;
|
||||||
|
UInt64 CompressedSize;
|
||||||
|
UInt64 BlockSize;
|
||||||
|
CRecordVector<UInt64> ResetOffsets;
|
||||||
|
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
|
||||||
|
{
|
||||||
|
if (blockIndex >= ResetOffsets.Size())
|
||||||
|
return false;
|
||||||
|
UInt64 startPos = ResetOffsets[(size_t)blockIndex];
|
||||||
|
if (blockIndex + numBlocks >= ResetOffsets.Size())
|
||||||
|
size = CompressedSize - startPos;
|
||||||
|
else
|
||||||
|
size = ResetOffsets[(size_t)blockIndex + numBlocks] - startPos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
|
||||||
|
{
|
||||||
|
return GetCompressedSizeOfBlocks(blockIndex, 1, size);
|
||||||
|
}
|
||||||
|
UInt64 GetNumBlocks(UInt64 size) const
|
||||||
|
{
|
||||||
|
return (size + BlockSize - 1) / BlockSize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CLzxInfo
|
||||||
|
{
|
||||||
|
UInt32 Version;
|
||||||
|
UInt32 ResetInterval;
|
||||||
|
UInt32 WindowSize;
|
||||||
|
UInt32 CacheSize;
|
||||||
|
CResetTable ResetTable;
|
||||||
|
|
||||||
|
UInt32 GetNumDictBits() const
|
||||||
|
{
|
||||||
|
if (Version == 2 || Version == 3)
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= 31; i++)
|
||||||
|
if (((UInt32)1 << i) >= WindowSize)
|
||||||
|
return 15 + i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 GetFolderSize() const { return ResetTable.BlockSize * ResetInterval; };
|
||||||
|
UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); };
|
||||||
|
UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); };
|
||||||
|
UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; };
|
||||||
|
bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
|
||||||
|
{
|
||||||
|
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
||||||
|
if (blockIndex >= ResetTable.ResetOffsets.Size())
|
||||||
|
return false;
|
||||||
|
offset = ResetTable.ResetOffsets[(size_t)blockIndex];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
|
||||||
|
{
|
||||||
|
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
||||||
|
return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMethodInfo
|
||||||
|
{
|
||||||
|
GUID Guid;
|
||||||
|
CByteBuffer ControlData;
|
||||||
|
CLzxInfo LzxInfo;
|
||||||
|
bool IsLzx() const;
|
||||||
|
bool IsDes() const;
|
||||||
|
AString GetGuidString() const;
|
||||||
|
UString GetName() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CSectionInfo
|
||||||
|
{
|
||||||
|
UInt64 Offset;
|
||||||
|
UInt64 CompressedSize;
|
||||||
|
UInt64 UncompressedSize;
|
||||||
|
|
||||||
|
AString Name;
|
||||||
|
CObjectVector<CMethodInfo> Methods;
|
||||||
|
|
||||||
|
bool IsLzx() const;
|
||||||
|
UString GetMethodName() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CFilesDatabase: public CDatabase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool LowLevel;
|
||||||
|
CRecordVector<int> Indices;
|
||||||
|
CObjectVector<CSectionInfo> Sections;
|
||||||
|
|
||||||
|
UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; }
|
||||||
|
UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; }
|
||||||
|
|
||||||
|
UInt64 GetFolder(int fileIndex) const
|
||||||
|
{
|
||||||
|
const CItem &item = Items[Indices[fileIndex]];
|
||||||
|
const CSectionInfo §ion = Sections[(size_t)item.Section];
|
||||||
|
if (section.IsLzx())
|
||||||
|
return section.Methods[0].LzxInfo.GetFolder(item.Offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 GetLastFolder(int fileIndex) const
|
||||||
|
{
|
||||||
|
const CItem &item = Items[Indices[fileIndex]];
|
||||||
|
const CSectionInfo §ion = Sections[(size_t)item.Section];
|
||||||
|
if (section.IsLzx())
|
||||||
|
return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HighLevelClear()
|
||||||
|
{
|
||||||
|
LowLevel = true;
|
||||||
|
Indices.Clear();
|
||||||
|
Sections.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
CDatabase::Clear();
|
||||||
|
HighLevelClear();
|
||||||
|
}
|
||||||
|
void SetIndices();
|
||||||
|
void Sort();
|
||||||
|
bool Check();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CProgressVirt
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE;
|
||||||
|
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CInArchive
|
||||||
|
{
|
||||||
|
UInt64 _startPosition;
|
||||||
|
::CInBuffer _inBuffer;
|
||||||
|
UInt64 _chunkSize;
|
||||||
|
|
||||||
|
Byte ReadByte();
|
||||||
|
void ReadBytes(Byte *data, UInt32 size);
|
||||||
|
void Skeep(size_t size);
|
||||||
|
UInt16 ReadUInt16();
|
||||||
|
UInt32 ReadUInt32();
|
||||||
|
UInt64 ReadUInt64();
|
||||||
|
UInt64 ReadEncInt();
|
||||||
|
void ReadString(int size, AString &s);
|
||||||
|
void ReadUString(int size, UString &s);
|
||||||
|
void ReadGUID(GUID &g);
|
||||||
|
|
||||||
|
HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size);
|
||||||
|
|
||||||
|
HRESULT ReadDirEntry(CDatabase &database);
|
||||||
|
HRESULT DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name);
|
||||||
|
|
||||||
|
public:
|
||||||
|
HRESULT OpenChm(IInStream *inStream, CDatabase &database);
|
||||||
|
HRESULT OpenHelp2(IInStream *inStream, CDatabase &database);
|
||||||
|
HRESULT OpenHighLevel(IInStream *inStream, CFilesDatabase &database);
|
||||||
|
HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database);
|
||||||
|
HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database);
|
||||||
|
};
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif
|
||||||
77
7zip/Archive/Chm/DllExports.cpp
Executable file
77
7zip/Archive/Chm/DllExports.cpp
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
// DLLExports.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Common/MyInitGuid.h"
|
||||||
|
#include "Common/ComTry.h"
|
||||||
|
#include "Windows/PropVariant.h"
|
||||||
|
#include "ChmHandler.h"
|
||||||
|
#include "../../ICoder.h"
|
||||||
|
|
||||||
|
// {23170F69-40C1-278A-1000-000110E90000}
|
||||||
|
DEFINE_GUID(CLSID_CChmHandler,
|
||||||
|
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xE9, 0x00, 0x00);
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDAPI CreateObject(
|
||||||
|
const GUID *classID,
|
||||||
|
const GUID *interfaceID,
|
||||||
|
void **outObject)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
*outObject = 0;
|
||||||
|
if (*classID != CLSID_CChmHandler)
|
||||||
|
return CLASS_E_CLASSNOTAVAILABLE;
|
||||||
|
if (*interfaceID != IID_IInArchive)
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NChm::CHandler;
|
||||||
|
*outObject = inArchive.Detach();
|
||||||
|
COM_TRY_END
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
NWindows::NCOM::CPropVariant propVariant;
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case NArchive::kName:
|
||||||
|
propVariant = L"Chm";
|
||||||
|
break;
|
||||||
|
case NArchive::kClassID:
|
||||||
|
{
|
||||||
|
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||||
|
(const char *)&CLSID_CChmHandler, sizeof(GUID))) != 0)
|
||||||
|
value->vt = VT_BSTR;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
case NArchive::kExtension:
|
||||||
|
propVariant = L"chm chi chq chw hxs hxi hxr hxq hxw lit";
|
||||||
|
break;
|
||||||
|
case NArchive::kUpdate:
|
||||||
|
propVariant = false;
|
||||||
|
break;
|
||||||
|
case NArchive::kKeepName:
|
||||||
|
propVariant = false;
|
||||||
|
break;
|
||||||
|
case NArchive::kStartSignature:
|
||||||
|
{
|
||||||
|
const char sig[] = { 'I', 'T', 'S', 'F' };
|
||||||
|
if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0)
|
||||||
|
value->vt = VT_BSTR;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
case NArchive::kAssociate:
|
||||||
|
{
|
||||||
|
propVariant = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
propVariant.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
3
7zip/Archive/Chm/StdAfx.cpp
Executable file
3
7zip/Archive/Chm/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
// StdAfx.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
8
7zip/Archive/Chm/StdAfx.h
Executable file
8
7zip/Archive/Chm/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
// StdAfx.h
|
||||||
|
|
||||||
|
#ifndef __STDAFX_H
|
||||||
|
#define __STDAFX_H
|
||||||
|
|
||||||
|
#include "../../../Common/MyWindows.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
68
7zip/Archive/Chm/makefile
Executable file
68
7zip/Archive/Chm/makefile
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
PROG = chm.dll
|
||||||
|
DEF_FILE = ../Archive.def
|
||||||
|
CFLAGS = $(CFLAGS) -I ../../../
|
||||||
|
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||||
|
|
||||||
|
CHM_OBJS = \
|
||||||
|
$O\DllExports.obj \
|
||||||
|
$O\ChmHandler.obj \
|
||||||
|
$O\ChmHeader.obj \
|
||||||
|
$O\ChmIn.obj \
|
||||||
|
|
||||||
|
COMMON_OBJS = \
|
||||||
|
$O\Alloc.obj \
|
||||||
|
$O\IntToString.obj \
|
||||||
|
$O\NewHandler.obj \
|
||||||
|
$O\String.obj \
|
||||||
|
$O\StringConvert.obj \
|
||||||
|
$O\UTFConvert.obj \
|
||||||
|
$O\Vector.obj \
|
||||||
|
|
||||||
|
WIN_OBJS = \
|
||||||
|
$O\PropVariant.obj \
|
||||||
|
|
||||||
|
7ZIP_COMMON_OBJS = \
|
||||||
|
$O\InBuffer.obj \
|
||||||
|
$O\LimitedStreams.obj \
|
||||||
|
$O\OutBuffer.obj \
|
||||||
|
$O\ProgressUtils.obj \
|
||||||
|
$O\StreamUtils.obj \
|
||||||
|
|
||||||
|
AR_COMMON_OBJS = \
|
||||||
|
$O\ItemNameUtils.obj \
|
||||||
|
|
||||||
|
COMPRESS_LZX_OBJS = \
|
||||||
|
$O\LzxDecoder.obj \
|
||||||
|
$O\Lzx86Converter.obj \
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
$O\StdAfx.obj \
|
||||||
|
$(CHM_OBJS) \
|
||||||
|
$(COMMON_OBJS) \
|
||||||
|
$(WIN_OBJS) \
|
||||||
|
$(7ZIP_COMMON_OBJS) \
|
||||||
|
$(AR_COMMON_OBJS) \
|
||||||
|
$(COMPRESS_LZX_OBJS) \
|
||||||
|
$O\LZOutWindow.obj \
|
||||||
|
$O\CopyCoder.obj \
|
||||||
|
$O\resource.res
|
||||||
|
|
||||||
|
!include "../../../Build.mak"
|
||||||
|
|
||||||
|
$(CHM_OBJS): $(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMPRESS_LZX_OBJS): ../../Compress/Lzx/$(*B).cpp
|
||||||
|
$(COMPL_O2)
|
||||||
|
$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
|
||||||
3
7zip/Archive/Chm/resource.rc
Executable file
3
7zip/Archive/Chm/resource.rc
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#include "../../MyVersionInfo.rc"
|
||||||
|
|
||||||
|
MY_VERSION_INFO_DLL("Chm Plugin", "chm")
|
||||||
@@ -15,7 +15,7 @@ static CSysString GetLibraryPath()
|
|||||||
static CSysString GetLibraryFolderPrefix()
|
static CSysString GetLibraryFolderPrefix()
|
||||||
{
|
{
|
||||||
CSysString path = GetLibraryPath();
|
CSysString path = GetLibraryPath();
|
||||||
int pos = path.ReverseFind(TEXT('\\'));
|
int pos = path.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
|
||||||
return path.Left(pos + 1);
|
return path.Left(pos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,11 +24,11 @@ CSysString GetBaseFolderPrefix()
|
|||||||
CSysString libPrefix = GetLibraryFolderPrefix();
|
CSysString libPrefix = GetLibraryFolderPrefix();
|
||||||
CSysString temp = libPrefix;
|
CSysString temp = libPrefix;
|
||||||
temp.Delete(temp.Length() - 1);
|
temp.Delete(temp.Length() - 1);
|
||||||
int pos = temp.ReverseFind(TEXT('\\'));
|
int pos = temp.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
|
||||||
return temp.Left(pos + 1);
|
return temp.Left(pos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSysString GetCodecsFolderPrefix()
|
CSysString GetCodecsFolderPrefix()
|
||||||
{
|
{
|
||||||
return GetBaseFolderPrefix() + TEXT("Codecs\\");
|
return GetBaseFolderPrefix() + (CSysString)(TEXT("Codecs")) + (CSysString)(TEXT(STRING_PATH_SEPARATOR));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
int FindPath(LPCTSTR filePath)
|
int FindPath(LPCTSTR filePath)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Pairs.Size(); i++)
|
for (int i = 0; i < Pairs.Size(); i++)
|
||||||
if (Pairs[i].Path.CollateNoCase(filePath) == 0)
|
if (Pairs[i].Path.CompareNoCase(filePath) == 0)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,7 +229,6 @@ STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams,
|
|||||||
{
|
{
|
||||||
if (_coderInfoVector.Size() != _bindInfo.Coders.Size())
|
if (_coderInfoVector.Size() != _bindInfo.Coders.Size())
|
||||||
throw 0;
|
throw 0;
|
||||||
UInt32 numInStreams = 0, numOutStreams = 0;
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < _coderInfoVector.Size(); i++)
|
for(i = 0; i < _coderInfoVector.Size(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user