mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-17 14:11:53 -06:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
708873490e | ||
|
|
3dacb5eb8a | ||
|
|
76b173af78 | ||
|
|
993daef9cb | ||
|
|
db5eb6d638 | ||
|
|
1fbaf0aac5 | ||
|
|
2fed872194 | ||
|
|
c99f3ebdd6 | ||
|
|
829409452d | ||
|
|
8874e4fbc9 | ||
|
|
1dc92281fa | ||
|
|
3a524e5ba2 | ||
|
|
c1f1243a70 | ||
|
|
b717a4dbfe | ||
|
|
c10e6b16f6 | ||
|
|
173c07e166 | ||
|
|
3901bf0ab8 | ||
|
|
bd1fa36322 | ||
|
|
acd742622d | ||
|
|
b67ffe691b | ||
|
|
b82f80647d | ||
|
|
051769bbc5 | ||
|
|
33ccab7e72 | ||
|
|
d14d4dcdef | ||
|
|
980e181dcc | ||
|
|
7038848692 | ||
|
|
fd8b1d78b4 | ||
|
|
0b33f700a6 | ||
|
|
c574fc0f4b | ||
|
|
a145bfc7cf | ||
|
|
d9666cf046 | ||
|
|
804edc5756 | ||
|
|
0ec42ff829 | ||
|
|
631462beb2 | ||
|
|
bd9a40b0ed | ||
|
|
3415684502 | ||
|
|
83911c8529 | ||
|
|
cb9eea7264 | ||
|
|
8304895f29 | ||
|
|
191cf6781a | ||
|
|
0f60a4933b | ||
|
|
02516d3fce | ||
|
|
e8d0636d7a | ||
|
|
acac987575 | ||
|
|
e18587ba51 | ||
|
|
bcd1db2f5a | ||
|
|
32c73adef4 | ||
|
|
d66cf2fcf3 | ||
|
|
31e7b924e8 | ||
|
|
af1fe52701 | ||
|
|
47f4915611 | ||
|
|
ac2b563958 |
@@ -1,4 +0,0 @@
|
|||||||
EXPORTS
|
|
||||||
CreateObject PRIVATE
|
|
||||||
GetHandlerProperty PRIVATE
|
|
||||||
|
|
||||||
@@ -1,428 +0,0 @@
|
|||||||
// Decode.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "7zDecode.h"
|
|
||||||
|
|
||||||
#include "../../IPassword.h"
|
|
||||||
#include "../../Common/LockedStream.h"
|
|
||||||
#include "../../Common/StreamObjects.h"
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
|
||||||
#include "../../Common/LimitedStreams.h"
|
|
||||||
#include "../Common/FilterCoder.h"
|
|
||||||
|
|
||||||
#include "7zMethods.h"
|
|
||||||
|
|
||||||
#ifdef COMPRESS_LZMA
|
|
||||||
#include "../../Compress/LZMA/LZMADecoder.h"
|
|
||||||
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_PPMD
|
|
||||||
#include "../../Compress/PPMD/PPMDDecoder.h"
|
|
||||||
static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BCJ_X86
|
|
||||||
#include "../../Compress/Branch/x86.h"
|
|
||||||
static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BCJ2
|
|
||||||
#include "../../Compress/Branch/x86_2.h"
|
|
||||||
static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_DEFLATE
|
|
||||||
#ifndef COMPRESS_DEFLATE_DECODER
|
|
||||||
#define COMPRESS_DEFLATE_DECODER
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_DEFLATE_DECODER
|
|
||||||
#include "../../Compress/Deflate/DeflateDecoder.h"
|
|
||||||
static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BZIP2
|
|
||||||
#ifndef COMPRESS_BZIP2_DECODER
|
|
||||||
#define COMPRESS_BZIP2_DECODER
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BZIP2_DECODER
|
|
||||||
#include "../../Compress/BZip2/BZip2Decoder.h"
|
|
||||||
static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_COPY
|
|
||||||
#include "../../Compress/Copy/CopyCoder.h"
|
|
||||||
static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CRYPTO_7ZAES
|
|
||||||
#include "../../Crypto/7zAES/7zAES.h"
|
|
||||||
static NArchive::N7z::CMethodID k_7zAES = { { 0x6, 0xF1, 0x07, 0x01 }, 4 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
|
|
||||||
CBindInfoEx &bindInfo)
|
|
||||||
{
|
|
||||||
bindInfo.Clear();
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < folder.BindPairs.Size(); i++)
|
|
||||||
{
|
|
||||||
NCoderMixer2::CBindPair bindPair;
|
|
||||||
bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
|
|
||||||
bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
|
|
||||||
bindInfo.BindPairs.Add(bindPair);
|
|
||||||
}
|
|
||||||
UInt32 outStreamIndex = 0;
|
|
||||||
for (i = 0; i < folder.Coders.Size(); i++)
|
|
||||||
{
|
|
||||||
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
|
||||||
const CCoderInfo &coderInfo = folder.Coders[i];
|
|
||||||
coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
|
|
||||||
coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
|
|
||||||
bindInfo.Coders.Add(coderStreamsInfo);
|
|
||||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
|
||||||
bindInfo.CoderMethodIDs.Add(altCoderInfo.MethodID);
|
|
||||||
for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
|
|
||||||
if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
|
|
||||||
bindInfo.OutStreams.Add(outStreamIndex);
|
|
||||||
}
|
|
||||||
for (i = 0; i < folder.PackStreams.Size(); i++)
|
|
||||||
bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1,
|
|
||||||
const NCoderMixer2::CCoderStreamsInfo &a2)
|
|
||||||
{
|
|
||||||
return (a1.NumInStreams == a2.NumInStreams) &&
|
|
||||||
(a1.NumOutStreams == a2.NumOutStreams);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool AreBindPairsEqual(const NCoderMixer2::CBindPair &a1, const NCoderMixer2::CBindPair &a2)
|
|
||||||
{
|
|
||||||
return (a1.InIndex == a2.InIndex) &&
|
|
||||||
(a1.OutIndex == a2.OutIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
|
|
||||||
{
|
|
||||||
if (a1.Coders.Size() != a2.Coders.Size())
|
|
||||||
return false;
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < a1.Coders.Size(); i++)
|
|
||||||
if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
|
|
||||||
return false;
|
|
||||||
if (a1.BindPairs.Size() != a2.BindPairs.Size())
|
|
||||||
return false;
|
|
||||||
for (i = 0; i < a1.BindPairs.Size(); i++)
|
|
||||||
if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
|
|
||||||
return false;
|
|
||||||
for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
|
|
||||||
if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
|
|
||||||
return false;
|
|
||||||
if (a1.InStreams.Size() != a2.InStreams.Size())
|
|
||||||
return false;
|
|
||||||
if (a1.OutStreams.Size() != a2.OutStreams.Size())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CDecoder::CDecoder(bool multiThread)
|
|
||||||
{
|
|
||||||
_multiThread = true;
|
|
||||||
#ifdef _ST_MODE
|
|
||||||
_multiThread = multiThread;
|
|
||||||
#endif
|
|
||||||
_bindInfoExPrevIsDefinded = false;
|
|
||||||
#ifndef EXCLUDE_COM
|
|
||||||
LoadMethodMap();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CDecoder::Decode(IInStream *inStream,
|
|
||||||
UInt64 startPos,
|
|
||||||
const UInt64 *packSizes,
|
|
||||||
const CFolder &folderInfo,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
ICompressProgressInfo *compressProgress
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
|
||||||
|
|
||||||
CLockedInStream lockedInStream;
|
|
||||||
lockedInStream.Init(inStream);
|
|
||||||
|
|
||||||
for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
|
|
||||||
{
|
|
||||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
|
||||||
CLockedSequentialInStreamImp;
|
|
||||||
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
|
||||||
lockedStreamImpSpec->Init(&lockedInStream, startPos);
|
|
||||||
startPos += packSizes[j];
|
|
||||||
|
|
||||||
CLimitedSequentialInStream *streamSpec = new
|
|
||||||
CLimitedSequentialInStream;
|
|
||||||
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
|
||||||
streamSpec->Init(lockedStreamImp, packSizes[j]);
|
|
||||||
inStreams.Add(inStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
int numCoders = folderInfo.Coders.Size();
|
|
||||||
|
|
||||||
CBindInfoEx bindInfo;
|
|
||||||
ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
|
|
||||||
bool createNewCoders;
|
|
||||||
if (!_bindInfoExPrevIsDefinded)
|
|
||||||
createNewCoders = true;
|
|
||||||
else
|
|
||||||
createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
|
|
||||||
if (createNewCoders)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
_decoders.Clear();
|
|
||||||
// _decoders2.Clear();
|
|
||||||
|
|
||||||
_mixerCoder.Release();
|
|
||||||
|
|
||||||
if (_multiThread)
|
|
||||||
{
|
|
||||||
_mixerCoderMTSpec = new NCoderMixer2::CCoderMixer2MT;
|
|
||||||
_mixerCoder = _mixerCoderMTSpec;
|
|
||||||
_mixerCoderCommon = _mixerCoderMTSpec;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef _ST_MODE
|
|
||||||
_mixerCoderSTSpec = new NCoderMixer2::CCoderMixer2ST;
|
|
||||||
_mixerCoder = _mixerCoderSTSpec;
|
|
||||||
_mixerCoderCommon = _mixerCoderSTSpec;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
_mixerCoderCommon->SetBindInfo(bindInfo);
|
|
||||||
|
|
||||||
for (i = 0; i < numCoders; i++)
|
|
||||||
{
|
|
||||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
|
||||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
|
||||||
#ifndef EXCLUDE_COM
|
|
||||||
CMethodInfo methodInfo;
|
|
||||||
if (!GetMethodInfo(altCoderInfo.MethodID, methodInfo))
|
|
||||||
return E_NOTIMPL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (coderInfo.IsSimpleCoder())
|
|
||||||
{
|
|
||||||
CMyComPtr<ICompressCoder> decoder;
|
|
||||||
CMyComPtr<ICompressFilter> filter;
|
|
||||||
|
|
||||||
#ifdef COMPRESS_LZMA
|
|
||||||
if (altCoderInfo.MethodID == k_LZMA)
|
|
||||||
decoder = new NCompress::NLZMA::CDecoder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_PPMD
|
|
||||||
if (altCoderInfo.MethodID == k_PPMD)
|
|
||||||
decoder = new NCompress::NPPMD::CDecoder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BCJ_X86
|
|
||||||
if (altCoderInfo.MethodID == k_BCJ_X86)
|
|
||||||
filter = new CBCJ_x86_Decoder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_DEFLATE_DECODER
|
|
||||||
if (altCoderInfo.MethodID == k_Deflate)
|
|
||||||
decoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BZIP2_DECODER
|
|
||||||
if (altCoderInfo.MethodID == k_BZip2)
|
|
||||||
decoder = new NCompress::NBZip2::CDecoder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COMPRESS_COPY
|
|
||||||
if (altCoderInfo.MethodID == k_Copy)
|
|
||||||
decoder = new NCompress::CCopyCoder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CRYPTO_7ZAES
|
|
||||||
if (altCoderInfo.MethodID == k_7zAES)
|
|
||||||
filter = new NCrypto::NSevenZ::CDecoder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (filter)
|
|
||||||
{
|
|
||||||
CFilterCoder *coderSpec = new CFilterCoder;
|
|
||||||
decoder = coderSpec;
|
|
||||||
coderSpec->Filter = filter;
|
|
||||||
}
|
|
||||||
#ifndef EXCLUDE_COM
|
|
||||||
if (decoder == 0)
|
|
||||||
{
|
|
||||||
RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath,
|
|
||||||
methodInfo.Decoder, &decoder));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (decoder == 0)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
_decoders.Add((IUnknown *)decoder);
|
|
||||||
|
|
||||||
if (_multiThread)
|
|
||||||
_mixerCoderMTSpec->AddCoder(decoder);
|
|
||||||
#ifdef _ST_MODE
|
|
||||||
else
|
|
||||||
_mixerCoderSTSpec->AddCoder(decoder, false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CMyComPtr<ICompressCoder2> decoder;
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BCJ2
|
|
||||||
if (altCoderInfo.MethodID == k_BCJ2)
|
|
||||||
decoder = new CBCJ2_x86_Decoder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EXCLUDE_COM
|
|
||||||
if (decoder == 0)
|
|
||||||
{
|
|
||||||
RINOK(_libraries.CreateCoder2(methodInfo.FilePath,
|
|
||||||
methodInfo.Decoder, &decoder));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (decoder == 0)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
_decoders.Add((IUnknown *)decoder);
|
|
||||||
if (_multiThread)
|
|
||||||
_mixerCoderMTSpec->AddCoder2(decoder);
|
|
||||||
#ifdef _ST_MODE
|
|
||||||
else
|
|
||||||
_mixerCoderSTSpec->AddCoder2(decoder, false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_bindInfoExPrev = bindInfo;
|
|
||||||
_bindInfoExPrevIsDefinded = true;
|
|
||||||
}
|
|
||||||
int i;
|
|
||||||
_mixerCoderCommon->ReInit();
|
|
||||||
|
|
||||||
UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
|
|
||||||
UInt32 coderIndex = 0;
|
|
||||||
// UInt32 coder2Index = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < numCoders; i++)
|
|
||||||
{
|
|
||||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
|
||||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
|
||||||
CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
|
|
||||||
HRESULT result = _decoders[coderIndex].QueryInterface(
|
|
||||||
IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
|
|
||||||
|
|
||||||
if (result == S_OK)
|
|
||||||
{
|
|
||||||
const CByteBuffer &properties = altCoderInfo.Properties;
|
|
||||||
UInt32 size = properties.GetCapacity();
|
|
||||||
if (size > 0)
|
|
||||||
{
|
|
||||||
RINOK(compressSetDecoderProperties->SetDecoderProperties2((const Byte *)properties, size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (result != E_NOINTERFACE)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
|
||||||
result = _decoders[coderIndex].QueryInterface(
|
|
||||||
IID_ICryptoSetPassword, &cryptoSetPassword);
|
|
||||||
|
|
||||||
if (result == S_OK)
|
|
||||||
{
|
|
||||||
if (getTextPassword == 0)
|
|
||||||
return E_FAIL;
|
|
||||||
CMyComBSTR password;
|
|
||||||
RINOK(getTextPassword->CryptoGetTextPassword(&password));
|
|
||||||
CByteBuffer buffer;
|
|
||||||
UString unicodePassword(password);
|
|
||||||
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
|
|
||||||
buffer.SetCapacity(sizeInBytes);
|
|
||||||
for (int i = 0; i < unicodePassword.Length(); i++)
|
|
||||||
{
|
|
||||||
wchar_t c = unicodePassword[i];
|
|
||||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
|
||||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
|
||||||
}
|
|
||||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
|
||||||
(const Byte *)buffer, sizeInBytes));
|
|
||||||
}
|
|
||||||
else if (result != E_NOINTERFACE)
|
|
||||||
return result;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
coderIndex++;
|
|
||||||
|
|
||||||
UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
|
|
||||||
UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
|
|
||||||
CRecordVector<const UInt64 *> packSizesPointers;
|
|
||||||
CRecordVector<const UInt64 *> unPackSizesPointers;
|
|
||||||
packSizesPointers.Reserve(numInStreams);
|
|
||||||
unPackSizesPointers.Reserve(numOutStreams);
|
|
||||||
UInt32 j;
|
|
||||||
for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
|
|
||||||
unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
|
|
||||||
|
|
||||||
for (j = 0; j < numInStreams; j++, packStreamIndex++)
|
|
||||||
{
|
|
||||||
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
|
|
||||||
if (bindPairIndex >= 0)
|
|
||||||
packSizesPointers.Add(
|
|
||||||
&folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
|
|
||||||
if (index < 0)
|
|
||||||
return E_FAIL;
|
|
||||||
packSizesPointers.Add(&packSizes[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_mixerCoderCommon->SetCoderInfo(i,
|
|
||||||
&packSizesPointers.Front(),
|
|
||||||
&unPackSizesPointers.Front());
|
|
||||||
}
|
|
||||||
UInt32 mainCoder, temp;
|
|
||||||
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
|
|
||||||
|
|
||||||
if (_multiThread)
|
|
||||||
_mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
|
|
||||||
/*
|
|
||||||
else
|
|
||||||
_mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (numCoders == 0)
|
|
||||||
return 0;
|
|
||||||
CRecordVector<ISequentialInStream *> inStreamPointers;
|
|
||||||
inStreamPointers.Reserve(inStreams.Size());
|
|
||||||
for (i = 0; i < inStreams.Size(); i++)
|
|
||||||
inStreamPointers.Add(inStreams[i]);
|
|
||||||
ISequentialOutStream *outStreamPointer = outStream;
|
|
||||||
return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
|
|
||||||
inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
// 7zFolderOutStream.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "7zFolderOutStream.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
CFolderOutStream::CFolderOutStream()
|
|
||||||
{
|
|
||||||
_outStreamWithHashSpec = new COutStreamWithCRC;
|
|
||||||
_outStreamWithHash = _outStreamWithHashSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::Init(
|
|
||||||
const CArchiveDatabaseEx *archiveDatabase,
|
|
||||||
UInt32 ref2Offset,
|
|
||||||
UInt32 startIndex,
|
|
||||||
const CBoolVector *extractStatuses,
|
|
||||||
IArchiveExtractCallback *extractCallback,
|
|
||||||
bool testMode)
|
|
||||||
{
|
|
||||||
_archiveDatabase = archiveDatabase;
|
|
||||||
_ref2Offset = ref2Offset;
|
|
||||||
_startIndex = startIndex;
|
|
||||||
|
|
||||||
_extractStatuses = extractStatuses;
|
|
||||||
_extractCallback = extractCallback;
|
|
||||||
_testMode = testMode;
|
|
||||||
|
|
||||||
_currentIndex = 0;
|
|
||||||
_fileIsOpen = false;
|
|
||||||
return WriteEmptyFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::OpenFile()
|
|
||||||
{
|
|
||||||
Int32 askMode;
|
|
||||||
if((*_extractStatuses)[_currentIndex])
|
|
||||||
askMode = _testMode ?
|
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
|
||||||
else
|
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
|
||||||
|
|
||||||
UInt32 index = _startIndex + _currentIndex;
|
|
||||||
RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
|
|
||||||
|
|
||||||
_outStreamWithHashSpec->Init(realOutStream);
|
|
||||||
if (askMode == NArchive::NExtract::NAskMode::kExtract &&
|
|
||||||
(!realOutStream))
|
|
||||||
{
|
|
||||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
|
||||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
|
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
|
||||||
}
|
|
||||||
return _extractCallback->PrepareOperation(askMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::WriteEmptyFiles()
|
|
||||||
{
|
|
||||||
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
|
|
||||||
{
|
|
||||||
UInt32 index = _startIndex + _currentIndex;
|
|
||||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
|
||||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
|
|
||||||
return S_OK;
|
|
||||||
RINOK(OpenFile());
|
|
||||||
RINOK(_extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kOK));
|
|
||||||
_outStreamWithHashSpec->ReleaseStream();
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CFolderOutStream::Write(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize = 0;
|
|
||||||
while(_currentIndex < _extractStatuses->Size())
|
|
||||||
{
|
|
||||||
if (_fileIsOpen)
|
|
||||||
{
|
|
||||||
UInt32 index = _startIndex + _currentIndex;
|
|
||||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
|
||||||
UInt64 fileSize = fileInfo.UnPackSize;
|
|
||||||
|
|
||||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
|
|
||||||
UInt64(size - realProcessedSize));
|
|
||||||
|
|
||||||
UInt32 processedSizeLocal;
|
|
||||||
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal));
|
|
||||||
|
|
||||||
_filePos += processedSizeLocal;
|
|
||||||
realProcessedSize += processedSizeLocal;
|
|
||||||
if (_filePos == fileSize)
|
|
||||||
{
|
|
||||||
bool digestsAreEqual;
|
|
||||||
if (fileInfo.IsFileCRCDefined)
|
|
||||||
digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
|
|
||||||
else
|
|
||||||
digestsAreEqual = true;
|
|
||||||
|
|
||||||
RINOK(_extractCallback->SetOperationResult(
|
|
||||||
digestsAreEqual ?
|
|
||||||
NArchive::NExtract::NOperationResult::kOK :
|
|
||||||
NArchive::NExtract::NOperationResult::kCRCError));
|
|
||||||
_outStreamWithHashSpec->ReleaseStream();
|
|
||||||
_fileIsOpen = false;
|
|
||||||
_currentIndex++;
|
|
||||||
}
|
|
||||||
if (realProcessedSize == size)
|
|
||||||
{
|
|
||||||
if (processedSize != NULL)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return WriteEmptyFiles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RINOK(OpenFile());
|
|
||||||
_fileIsOpen = true;
|
|
||||||
_filePos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (processedSize != NULL)
|
|
||||||
*processedSize = size;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CFolderOutStream::WritePart(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
return Write(data, size, processedSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
|
||||||
{
|
|
||||||
while(_currentIndex < _extractStatuses->Size())
|
|
||||||
{
|
|
||||||
if (_fileIsOpen)
|
|
||||||
{
|
|
||||||
RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
|
|
||||||
_outStreamWithHashSpec->ReleaseStream();
|
|
||||||
_fileIsOpen = false;
|
|
||||||
_currentIndex++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RINOK(OpenFile());
|
|
||||||
_fileIsOpen = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::WasWritingFinished()
|
|
||||||
{
|
|
||||||
if (_currentIndex == _extractStatuses->Size())
|
|
||||||
return S_OK;
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
// 7zFolderOutStream.h
|
|
||||||
|
|
||||||
#ifndef __7Z_FOLDEROUTSTREAM_H
|
|
||||||
#define __7Z_FOLDEROUTSTREAM_H
|
|
||||||
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
#include "../../IStream.h"
|
|
||||||
#include "../IArchive.h"
|
|
||||||
#include "../Common/OutStreamWithCRC.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
class CFolderOutStream:
|
|
||||||
public ISequentialOutStream,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
CFolderOutStream();
|
|
||||||
|
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
private:
|
|
||||||
|
|
||||||
COutStreamWithCRC *_outStreamWithHashSpec;
|
|
||||||
CMyComPtr<ISequentialOutStream> _outStreamWithHash;
|
|
||||||
const CArchiveDatabaseEx *_archiveDatabase;
|
|
||||||
const CBoolVector *_extractStatuses;
|
|
||||||
UInt32 _startIndex;
|
|
||||||
UInt32 _ref2Offset;
|
|
||||||
int _currentIndex;
|
|
||||||
// UInt64 _currentDataPos;
|
|
||||||
CMyComPtr<IArchiveExtractCallback> _extractCallback;
|
|
||||||
bool _testMode;
|
|
||||||
|
|
||||||
bool _fileIsOpen;
|
|
||||||
UInt64 _filePos;
|
|
||||||
|
|
||||||
HRESULT OpenFile();
|
|
||||||
HRESULT WriteEmptyFiles();
|
|
||||||
public:
|
|
||||||
HRESULT Init(
|
|
||||||
const CArchiveDatabaseEx *archiveDatabase,
|
|
||||||
UInt32 ref2Offset,
|
|
||||||
UInt32 startIndex,
|
|
||||||
const CBoolVector *extractStatuses,
|
|
||||||
IArchiveExtractCallback *extractCallback,
|
|
||||||
bool testMode);
|
|
||||||
HRESULT FlushCorrupted(Int32 resultEOperationResult);
|
|
||||||
HRESULT WasWritingFinished();
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,711 +0,0 @@
|
|||||||
// 7zHandler.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "7zHandler.h"
|
|
||||||
#include "7zProperties.h"
|
|
||||||
|
|
||||||
#include "../../../Common/IntToString.h"
|
|
||||||
#include "../../../Common/ComTry.h"
|
|
||||||
#include "../../../Windows/Defs.h"
|
|
||||||
|
|
||||||
#include "../Common/ItemNameUtils.h"
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
#include "../Common/MultiStream.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace NWindows;
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
CHandler::CHandler()
|
|
||||||
{
|
|
||||||
#ifndef EXTRACT_ONLY
|
|
||||||
Init();
|
|
||||||
#endif
|
|
||||||
#ifndef EXCLUDE_COM
|
|
||||||
LoadMethodMap();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
*numItems =
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
_refs.Size();
|
|
||||||
#else
|
|
||||||
*numItems = _database.Files.Size();
|
|
||||||
#endif
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
value->vt = VT_EMPTY;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _SFX
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
|
||||||
{
|
|
||||||
*numProperties = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void MySetFileTime(bool timeDefined, FILETIME unixTime,
|
|
||||||
NWindows::NCOM::CPropVariant &propVariant)
|
|
||||||
{
|
|
||||||
if (timeDefined)
|
|
||||||
propVariant = unixTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
inline static wchar_t GetHex(Byte value)
|
|
||||||
{
|
|
||||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
static UString ConvertBytesToHexString(const Byte *data, UInt32 size)
|
|
||||||
{
|
|
||||||
UString result;
|
|
||||||
for (UInt32 i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
Byte b = data[i];
|
|
||||||
result += GetHex(b >> 4);
|
|
||||||
result += GetHex(b & 0xF);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _SFX
|
|
||||||
|
|
||||||
static UString ConvertUInt32ToString(UInt32 value)
|
|
||||||
{
|
|
||||||
wchar_t buffer[32];
|
|
||||||
ConvertUInt64ToString(value, buffer);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static UString GetStringForSizeValue(UInt32 value)
|
|
||||||
{
|
|
||||||
for (int i = 31; i >= 0; i--)
|
|
||||||
if ((UInt32(1) << i) == value)
|
|
||||||
return ConvertUInt32ToString(i);
|
|
||||||
UString result;
|
|
||||||
if (value % (1 << 20) == 0)
|
|
||||||
{
|
|
||||||
result += ConvertUInt32ToString(value >> 20);
|
|
||||||
result += L"m";
|
|
||||||
}
|
|
||||||
else if (value % (1 << 10) == 0)
|
|
||||||
{
|
|
||||||
result += ConvertUInt32ToString(value >> 10);
|
|
||||||
result += L"k";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result += ConvertUInt32ToString(value);
|
|
||||||
result += L"b";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CMethodID k_Copy = { { 0x0 }, 1 };
|
|
||||||
static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
|
||||||
static CMethodID k_BCJ = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
|
|
||||||
static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
|
||||||
static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
|
|
||||||
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
|
|
||||||
static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
|
||||||
|
|
||||||
static inline char GetHex(Byte value)
|
|
||||||
{
|
|
||||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
|
||||||
}
|
|
||||||
static inline UString GetHex2(Byte value)
|
|
||||||
{
|
|
||||||
UString result;
|
|
||||||
result += GetHex(value >> 4);
|
|
||||||
result += GetHex(value & 0xF);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
|
|
||||||
{
|
|
||||||
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
|
|
||||||
/*
|
|
||||||
const CRef2 &ref2 = _refs[index];
|
|
||||||
if (ref2.Refs.IsEmpty())
|
|
||||||
return E_FAIL;
|
|
||||||
const CRef &ref = ref2.Refs.Front();
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
const CRef &ref = _refs[index];
|
|
||||||
const CVolume &volume = _volumes[ref.VolumeIndex];
|
|
||||||
const CArchiveDatabaseEx &_database = volume.Database;
|
|
||||||
UInt32 index2 = ref.ItemIndex;
|
|
||||||
const CFileItem &item = _database.Files[index2];
|
|
||||||
#else
|
|
||||||
const CFileItem &item = _database.Files[index];
|
|
||||||
UInt32 index2 = index;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case kpidPath:
|
|
||||||
{
|
|
||||||
if (!item.Name.IsEmpty())
|
|
||||||
propVariant = NItemName::GetOSName(item.Name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kpidIsFolder:
|
|
||||||
propVariant = item.IsDirectory;
|
|
||||||
break;
|
|
||||||
case kpidSize:
|
|
||||||
{
|
|
||||||
propVariant = item.UnPackSize;
|
|
||||||
// propVariant = ref2.UnPackSize;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kpidPosition:
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (ref2.Refs.Size() > 1)
|
|
||||||
propVariant = ref2.StartPos;
|
|
||||||
else
|
|
||||||
*/
|
|
||||||
if (item.IsStartPosDefined)
|
|
||||||
propVariant = item.StartPos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kpidPackedSize:
|
|
||||||
{
|
|
||||||
// propVariant = ref2.PackSize;
|
|
||||||
{
|
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
|
||||||
if (folderIndex != kNumNoIndex)
|
|
||||||
{
|
|
||||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
|
||||||
propVariant = _database.GetFolderFullPackSize(folderIndex);
|
|
||||||
/*
|
|
||||||
else
|
|
||||||
propVariant = UInt64(0);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else
|
|
||||||
propVariant = UInt64(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kpidLastAccessTime:
|
|
||||||
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant);
|
|
||||||
break;
|
|
||||||
case kpidCreationTime:
|
|
||||||
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant);
|
|
||||||
break;
|
|
||||||
case kpidLastWriteTime:
|
|
||||||
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant);
|
|
||||||
break;
|
|
||||||
case kpidAttributes:
|
|
||||||
if (item.AreAttributesDefined)
|
|
||||||
propVariant = item.Attributes;
|
|
||||||
break;
|
|
||||||
case kpidCRC:
|
|
||||||
if (item.IsFileCRCDefined)
|
|
||||||
propVariant = item.FileCRC;
|
|
||||||
break;
|
|
||||||
#ifndef _SFX
|
|
||||||
case kpidMethod:
|
|
||||||
{
|
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
|
||||||
if (folderIndex != kNumNoIndex)
|
|
||||||
{
|
|
||||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
|
||||||
UString methodsString;
|
|
||||||
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
|
||||||
if (!methodsString.IsEmpty())
|
|
||||||
methodsString += L' ';
|
|
||||||
CMethodInfo methodInfo;
|
|
||||||
|
|
||||||
bool methodIsKnown;
|
|
||||||
|
|
||||||
for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
|
|
||||||
{
|
|
||||||
if (j > 0)
|
|
||||||
methodsString += L"|";
|
|
||||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j];
|
|
||||||
|
|
||||||
UString methodName;
|
|
||||||
#ifdef NO_REGISTRY
|
|
||||||
|
|
||||||
methodIsKnown = true;
|
|
||||||
if (altCoderInfo.MethodID == k_Copy)
|
|
||||||
methodName = L"Copy";
|
|
||||||
else if (altCoderInfo.MethodID == k_LZMA)
|
|
||||||
methodName = L"LZMA";
|
|
||||||
else if (altCoderInfo.MethodID == k_BCJ)
|
|
||||||
methodName = L"BCJ";
|
|
||||||
else if (altCoderInfo.MethodID == k_BCJ2)
|
|
||||||
methodName = L"BCJ2";
|
|
||||||
else if (altCoderInfo.MethodID == k_PPMD)
|
|
||||||
methodName = L"PPMD";
|
|
||||||
else if (altCoderInfo.MethodID == k_Deflate)
|
|
||||||
methodName = L"Deflate";
|
|
||||||
else if (altCoderInfo.MethodID == k_BZip2)
|
|
||||||
methodName = L"BZip2";
|
|
||||||
else
|
|
||||||
methodIsKnown = false;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
methodIsKnown = GetMethodInfo(
|
|
||||||
altCoderInfo.MethodID, methodInfo);
|
|
||||||
methodName = methodInfo.Name;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (methodIsKnown)
|
|
||||||
{
|
|
||||||
methodsString += methodName;
|
|
||||||
if (altCoderInfo.MethodID == k_LZMA)
|
|
||||||
{
|
|
||||||
if (altCoderInfo.Properties.GetCapacity() >= 5)
|
|
||||||
{
|
|
||||||
methodsString += L":";
|
|
||||||
UInt32 dicSize = GetUInt32FromMemLE(
|
|
||||||
((const Byte *)altCoderInfo.Properties + 1));
|
|
||||||
methodsString += GetStringForSizeValue(dicSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (altCoderInfo.MethodID == k_PPMD)
|
|
||||||
{
|
|
||||||
if (altCoderInfo.Properties.GetCapacity() >= 5)
|
|
||||||
{
|
|
||||||
Byte order = *(const Byte *)altCoderInfo.Properties;
|
|
||||||
methodsString += L":o";
|
|
||||||
methodsString += ConvertUInt32ToString(order);
|
|
||||||
methodsString += L":mem";
|
|
||||||
UInt32 dicSize = GetUInt32FromMemLE(
|
|
||||||
((const Byte *)altCoderInfo.Properties + 1));
|
|
||||||
methodsString += GetStringForSizeValue(dicSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (altCoderInfo.Properties.GetCapacity() > 0)
|
|
||||||
{
|
|
||||||
methodsString += L":[";
|
|
||||||
for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
|
|
||||||
{
|
|
||||||
if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())
|
|
||||||
{
|
|
||||||
methodsString += L"..";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
methodsString += GetHex2(altCoderInfo.Properties[bi]);
|
|
||||||
}
|
|
||||||
methodsString += L"]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
methodsString += altCoderInfo.MethodID.ConvertToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
propVariant = methodsString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case kpidBlock:
|
|
||||||
{
|
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
|
||||||
if (folderIndex != kNumNoIndex)
|
|
||||||
propVariant = (UInt32)folderIndex;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case kpidPackedSize0:
|
|
||||||
case kpidPackedSize1:
|
|
||||||
case kpidPackedSize2:
|
|
||||||
case kpidPackedSize3:
|
|
||||||
case kpidPackedSize4:
|
|
||||||
{
|
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
|
||||||
if (folderIndex != kNumNoIndex)
|
|
||||||
{
|
|
||||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
|
||||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
|
||||||
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
|
|
||||||
{
|
|
||||||
propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
propVariant = UInt64(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
propVariant = UInt64(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case kpidIsAnti:
|
|
||||||
propVariant = item.IsAnti;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
propVariant.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
static const wchar_t *kExt = L"7z";
|
|
||||||
static const wchar_t *kAfterPart = L".7z";
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
|
|
||||||
class CVolumeName
|
|
||||||
{
|
|
||||||
bool _first;
|
|
||||||
UString _unchangedPart;
|
|
||||||
UString _changedPart;
|
|
||||||
UString _afterPart;
|
|
||||||
public:
|
|
||||||
bool InitName(const UString &name)
|
|
||||||
{
|
|
||||||
_first = true;
|
|
||||||
int dotPos = name.ReverseFind('.');
|
|
||||||
UString basePart = name;
|
|
||||||
if (dotPos >= 0)
|
|
||||||
{
|
|
||||||
UString ext = name.Mid(dotPos + 1);
|
|
||||||
if (ext.CompareNoCase(kExt)==0 ||
|
|
||||||
ext.CompareNoCase(L"EXE") == 0)
|
|
||||||
{
|
|
||||||
_afterPart = kAfterPart;
|
|
||||||
basePart = name.Left(dotPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int numLetters = 1;
|
|
||||||
bool splitStyle = false;
|
|
||||||
if (basePart.Right(numLetters) == L"1")
|
|
||||||
{
|
|
||||||
while (numLetters < basePart.Length())
|
|
||||||
{
|
|
||||||
if (basePart[basePart.Length() - numLetters - 1] != '0')
|
|
||||||
break;
|
|
||||||
numLetters++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
_unchangedPart = basePart.Left(basePart.Length() - numLetters);
|
|
||||||
_changedPart = basePart.Right(numLetters);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UString GetNextName()
|
|
||||||
{
|
|
||||||
UString newName;
|
|
||||||
// if (_newStyle || !_first)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int numLetters = _changedPart.Length();
|
|
||||||
for (i = numLetters - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
wchar_t c = _changedPart[i];
|
|
||||||
if (c == L'9')
|
|
||||||
{
|
|
||||||
c = L'0';
|
|
||||||
newName = c + newName;
|
|
||||||
if (i == 0)
|
|
||||||
newName = UString(L'1') + newName;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
newName = UString(c) + newName;
|
|
||||||
i--;
|
|
||||||
for (; i >= 0; i--)
|
|
||||||
newName = _changedPart[i] + newName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_changedPart = newName;
|
|
||||||
}
|
|
||||||
_first = false;
|
|
||||||
return _unchangedPart + _changedPart + _afterPart;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
|
||||||
const UInt64 *maxCheckStartPosition,
|
|
||||||
IArchiveOpenCallback *openArchiveCallback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
Close();
|
|
||||||
#ifndef _SFX
|
|
||||||
_fileInfoPopIDs.Clear();
|
|
||||||
#endif
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
CVolumeName seqName;
|
|
||||||
|
|
||||||
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
|
||||||
if (openArchiveCallback)
|
|
||||||
{
|
|
||||||
openArchiveCallbackTemp.QueryInterface(
|
|
||||||
IID_ICryptoGetTextPassword, &getTextPassword);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
if (openArchiveCallback)
|
|
||||||
{
|
|
||||||
openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
|
|
||||||
}
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
CMyComPtr<IInStream> inStream;
|
|
||||||
if (!_volumes.IsEmpty())
|
|
||||||
{
|
|
||||||
if (!openVolumeCallback)
|
|
||||||
break;
|
|
||||||
if(_volumes.Size() == 1)
|
|
||||||
{
|
|
||||||
UString baseName;
|
|
||||||
{
|
|
||||||
NCOM::CPropVariant propVariant;
|
|
||||||
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
|
|
||||||
if (propVariant.vt != VT_BSTR)
|
|
||||||
break;
|
|
||||||
baseName = propVariant.bstrVal;
|
|
||||||
}
|
|
||||||
seqName.InitName(baseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
UString fullName = seqName.GetNextName();
|
|
||||||
HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
|
|
||||||
if (result == S_FALSE)
|
|
||||||
break;
|
|
||||||
if (result != S_OK)
|
|
||||||
return result;
|
|
||||||
if (!stream)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
inStream = stream;
|
|
||||||
|
|
||||||
CInArchive archive;
|
|
||||||
RINOK(archive.Open(inStream, maxCheckStartPosition));
|
|
||||||
|
|
||||||
_volumes.Add(CVolume());
|
|
||||||
CVolume &volume = _volumes.Back();
|
|
||||||
CArchiveDatabaseEx &database = volume.Database;
|
|
||||||
volume.Stream = inStream;
|
|
||||||
volume.StartRef2Index = _refs.Size();
|
|
||||||
|
|
||||||
HRESULT result = archive.ReadDatabase(database
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
, getTextPassword
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
if (result != S_OK)
|
|
||||||
{
|
|
||||||
_volumes.Clear();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
database.Fill();
|
|
||||||
for(int i = 0; i < database.Files.Size(); i++)
|
|
||||||
{
|
|
||||||
CRef refNew;
|
|
||||||
refNew.VolumeIndex = _volumes.Size() - 1;
|
|
||||||
refNew.ItemIndex = i;
|
|
||||||
_refs.Add(refNew);
|
|
||||||
/*
|
|
||||||
const CFileItem &file = database.Files[i];
|
|
||||||
int j;
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
for (j = _refs.Size() - 1; j >= 0; j--)
|
|
||||||
{
|
|
||||||
CRef2 &ref2 = _refs[j];
|
|
||||||
const CRef &ref = ref2.Refs.Back();
|
|
||||||
const CVolume &volume2 = _volumes[ref.VolumeIndex];
|
|
||||||
const CArchiveDatabaseEx &database2 = volume2.Database;
|
|
||||||
const CFileItem &file2 = database2.Files[ref.ItemIndex];
|
|
||||||
if (file2.Name.CompareNoCase(file.Name) == 0)
|
|
||||||
{
|
|
||||||
if (!file.IsStartPosDefined)
|
|
||||||
continue;
|
|
||||||
if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
|
|
||||||
continue;
|
|
||||||
ref2.Refs.Add(refNew);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
j = -1;
|
|
||||||
if (j < 0)
|
|
||||||
{
|
|
||||||
CRef2 ref2New;
|
|
||||||
ref2New.Refs.Add(refNew);
|
|
||||||
j = _refs.Add(ref2New);
|
|
||||||
}
|
|
||||||
CRef2 &ref2 = _refs[j];
|
|
||||||
ref2.UnPackSize += file.UnPackSize;
|
|
||||||
ref2.PackSize += database.GetFilePackSize(i);
|
|
||||||
if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
|
|
||||||
ref2.StartPos = file.StartPos;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
if (database.Files.Size() != 1)
|
|
||||||
break;
|
|
||||||
const CFileItem &file = database.Files.Front();
|
|
||||||
if (!file.IsStartPosDefined)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
CInArchive archive;
|
|
||||||
RINOK(archive.Open(stream, maxCheckStartPosition));
|
|
||||||
HRESULT result = archive.ReadDatabase(_database
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
, getTextPassword
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
RINOK(result);
|
|
||||||
_database.Fill();
|
|
||||||
_inStream = stream;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
// _inStream = stream;
|
|
||||||
#ifndef _SFX
|
|
||||||
FillPopIDs();
|
|
||||||
#endif
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Close()
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
_volumes.Clear();
|
|
||||||
_refs.Clear();
|
|
||||||
#else
|
|
||||||
_inStream.Release();
|
|
||||||
_database.Clear();
|
|
||||||
#endif
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
|
||||||
{
|
|
||||||
if (index != 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
*stream = 0;
|
|
||||||
CMultiStream *streamSpec = new CMultiStream;
|
|
||||||
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
|
|
||||||
|
|
||||||
UInt64 pos = 0;
|
|
||||||
const UString *fileName;
|
|
||||||
for (int i = 0; i < _refs.Size(); i++)
|
|
||||||
{
|
|
||||||
const CRef &ref = _refs[i];
|
|
||||||
const CVolume &volume = _volumes[ref.VolumeIndex];
|
|
||||||
const CArchiveDatabaseEx &database = volume.Database;
|
|
||||||
const CFileItem &file = database.Files[ref.ItemIndex];
|
|
||||||
if (i == 0)
|
|
||||||
fileName = &file.Name;
|
|
||||||
else
|
|
||||||
if (fileName->Compare(file.Name) != 0)
|
|
||||||
return S_FALSE;
|
|
||||||
if (!file.IsStartPosDefined)
|
|
||||||
return S_FALSE;
|
|
||||||
if (file.StartPos != pos)
|
|
||||||
return S_FALSE;
|
|
||||||
CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
|
|
||||||
if (folderIndex == kNumNoIndex)
|
|
||||||
{
|
|
||||||
if (file.UnPackSize != 0)
|
|
||||||
return E_FAIL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (database.NumUnPackStreamsVector[folderIndex] != 1)
|
|
||||||
return S_FALSE;
|
|
||||||
const CFolder &folder = database.Folders[folderIndex];
|
|
||||||
if (folder.Coders.Size() != 1)
|
|
||||||
return S_FALSE;
|
|
||||||
const CCoderInfo &coder = folder.Coders.Front();
|
|
||||||
if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
|
|
||||||
return S_FALSE;
|
|
||||||
const CAltCoderInfo &altCoder = coder.AltCoders.Front();
|
|
||||||
if (altCoder.MethodID.IDSize != 1 || altCoder.MethodID.ID[0] != 0)
|
|
||||||
return S_FALSE;
|
|
||||||
|
|
||||||
pos += file.UnPackSize;
|
|
||||||
CMultiStream::CSubStreamInfo subStreamInfo;
|
|
||||||
subStreamInfo.Stream = volume.Stream;
|
|
||||||
subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
|
|
||||||
subStreamInfo.Size = file.UnPackSize;
|
|
||||||
streamSpec->Streams.Add(subStreamInfo);
|
|
||||||
}
|
|
||||||
streamSpec->Init();
|
|
||||||
*stream = streamTemp.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
// 7z/Handler.h
|
|
||||||
|
|
||||||
#ifndef __7Z_HANDLER_H
|
|
||||||
#define __7Z_HANDLER_H
|
|
||||||
|
|
||||||
#include "../IArchive.h"
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
#include "7zCompressionMode.h"
|
|
||||||
|
|
||||||
#ifndef _SFX
|
|
||||||
#include "7zMethods.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
struct CRef
|
|
||||||
{
|
|
||||||
int VolumeIndex;
|
|
||||||
int ItemIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct CRef2
|
|
||||||
{
|
|
||||||
CRecordVector<CRef> Refs;
|
|
||||||
UInt64 UnPackSize;
|
|
||||||
UInt64 PackSize;
|
|
||||||
UInt64 StartPos;
|
|
||||||
CRef2(): UnPackSize(0), PackSize(0), StartPos(0) {}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct CVolume
|
|
||||||
{
|
|
||||||
int StartRef2Index;
|
|
||||||
CMyComPtr<IInStream> Stream;
|
|
||||||
CArchiveDatabaseEx Database;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
|
||||||
|
|
||||||
struct COneMethodInfo
|
|
||||||
{
|
|
||||||
CObjectVector<CProperty> CoderProperties;
|
|
||||||
UString MethodName;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-000110050000}
|
|
||||||
DEFINE_GUID(CLSID_CFormat7z,
|
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
|
|
||||||
|
|
||||||
class CHandler:
|
|
||||||
public IInArchive,
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
public IInArchiveGetStream,
|
|
||||||
#endif
|
|
||||||
#ifndef EXTRACT_ONLY
|
|
||||||
public IOutArchive,
|
|
||||||
public ISetProperties,
|
|
||||||
#endif
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MY_QUERYINTERFACE_BEGIN
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
|
||||||
#endif
|
|
||||||
#ifndef EXTRACT_ONLY
|
|
||||||
MY_QUERYINTERFACE_ENTRY(IOutArchive)
|
|
||||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
|
||||||
#endif
|
|
||||||
MY_QUERYINTERFACE_END
|
|
||||||
MY_ADDREF_RELEASE
|
|
||||||
|
|
||||||
STDMETHOD(Open)(IInStream *stream,
|
|
||||||
const UInt64 *maxCheckStartPosition,
|
|
||||||
IArchiveOpenCallback *openArchiveCallback);
|
|
||||||
STDMETHOD(Close)();
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
|
|
||||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
|
||||||
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 testMode, IArchiveExtractCallback *extractCallback);
|
|
||||||
|
|
||||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
|
||||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
|
||||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
|
||||||
// IOutArchiveHandler
|
|
||||||
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
|
|
||||||
IArchiveUpdateCallback *updateCallback);
|
|
||||||
|
|
||||||
STDMETHOD(GetFileTimeType)(UInt32 *type);
|
|
||||||
|
|
||||||
// ISetProperties
|
|
||||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
|
||||||
|
|
||||||
HRESULT SetSolidSettings(const UString &s);
|
|
||||||
HRESULT SetSolidSettings(const PROPVARIANT &value);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CHandler();
|
|
||||||
|
|
||||||
private:
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
CObjectVector<CVolume> _volumes;
|
|
||||||
CObjectVector<CRef> _refs;
|
|
||||||
#else
|
|
||||||
CMyComPtr<IInStream> _inStream;
|
|
||||||
NArchive::N7z::CArchiveDatabaseEx _database;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
|
||||||
CObjectVector<COneMethodInfo> _methods;
|
|
||||||
CRecordVector<CBind> _binds;
|
|
||||||
bool _removeSfxBlock;
|
|
||||||
UInt64 _numSolidFiles;
|
|
||||||
UInt64 _numSolidBytes;
|
|
||||||
bool _numSolidBytesDefined;
|
|
||||||
bool _solidExtension;
|
|
||||||
|
|
||||||
bool _compressHeaders;
|
|
||||||
bool _compressHeadersFull;
|
|
||||||
bool _encryptHeaders;
|
|
||||||
|
|
||||||
bool _copyMode;
|
|
||||||
UInt32 _defaultDicSize;
|
|
||||||
UInt32 _defaultAlgorithm;
|
|
||||||
UInt32 _defaultFastBytes;
|
|
||||||
UString _defaultMatchFinder;
|
|
||||||
UInt32 _defaultBZip2Passes;
|
|
||||||
bool _autoFilter;
|
|
||||||
bool _multiThread;
|
|
||||||
UInt32 _level;
|
|
||||||
|
|
||||||
bool _volumeMode;
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
|
|
||||||
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
|
|
||||||
|
|
||||||
HRESULT SetPassword(CCompressionMethodMode &methodMode,
|
|
||||||
IArchiveUpdateCallback *updateCallback);
|
|
||||||
|
|
||||||
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
|
|
||||||
CObjectVector<COneMethodInfo> &methodsInfo,
|
|
||||||
bool multiThread);
|
|
||||||
|
|
||||||
HRESULT SetCompressionMethod(
|
|
||||||
CCompressionMethodMode &method,
|
|
||||||
CCompressionMethodMode &headerMethod);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _SFX
|
|
||||||
|
|
||||||
CRecordVector<UInt64> _fileInfoPopIDs;
|
|
||||||
void FillPopIDs();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
|
||||||
|
|
||||||
void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); }
|
|
||||||
void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); }
|
|
||||||
void InitSolid()
|
|
||||||
{
|
|
||||||
InitSolidFiles();
|
|
||||||
InitSolidSize();
|
|
||||||
_solidExtension = false;
|
|
||||||
_numSolidBytesDefined = false;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
void InitSolidPart()
|
|
||||||
{
|
|
||||||
if (_numSolidFiles <= 1)
|
|
||||||
InitSolidFiles();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void SetSolidBytesLimit()
|
|
||||||
{
|
|
||||||
_numSolidBytes = ((UInt64)_defaultDicSize) << 7;
|
|
||||||
const UInt64 kMinSize = (1<<24);
|
|
||||||
if (_numSolidBytes < kMinSize)
|
|
||||||
_numSolidBytes = kMinSize;
|
|
||||||
}
|
|
||||||
void CheckAndSetSolidBytesLimit()
|
|
||||||
{
|
|
||||||
if (!_numSolidBytesDefined)
|
|
||||||
{
|
|
||||||
if (_copyMode)
|
|
||||||
_numSolidBytes = 0;
|
|
||||||
else
|
|
||||||
SetSolidBytesLimit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
_removeSfxBlock = false;
|
|
||||||
_compressHeaders = true;
|
|
||||||
_compressHeadersFull = true;
|
|
||||||
_encryptHeaders = false;
|
|
||||||
_multiThread = false;
|
|
||||||
_copyMode = false;
|
|
||||||
_defaultDicSize = (1 << 21);
|
|
||||||
_defaultBZip2Passes = 1;
|
|
||||||
_defaultAlgorithm = 1;
|
|
||||||
_defaultFastBytes = 32;
|
|
||||||
_defaultMatchFinder = L"BT4";
|
|
||||||
_level = 5;
|
|
||||||
_autoFilter = true;
|
|
||||||
_volumeMode = false;
|
|
||||||
InitSolid();
|
|
||||||
SetSolidBytesLimit();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
|||||||
// 7z/Header.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "7zHeader.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
||||||
Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
|
|
||||||
|
|
||||||
class SignatureInitializer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SignatureInitializer() { kSignature[0]--; kFinishSignature[0]--;};
|
|
||||||
} g_SignatureInitializer;
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,289 +0,0 @@
|
|||||||
// 7zIn.h
|
|
||||||
|
|
||||||
#ifndef __7Z_IN_H
|
|
||||||
#define __7Z_IN_H
|
|
||||||
|
|
||||||
#include "../../IStream.h"
|
|
||||||
#include "../../IPassword.h"
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
#include "../../Common/InBuffer.h"
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zItem.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
class CInArchiveException
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum CCauseType
|
|
||||||
{
|
|
||||||
kUnsupportedVersion = 0,
|
|
||||||
kUnexpectedEndOfArchive = 0,
|
|
||||||
kIncorrectHeader,
|
|
||||||
} Cause;
|
|
||||||
CInArchiveException(CCauseType cause);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CInArchiveInfo
|
|
||||||
{
|
|
||||||
CArchiveVersion Version;
|
|
||||||
UInt64 StartPosition;
|
|
||||||
UInt64 StartPositionAfterHeader;
|
|
||||||
UInt64 DataStartPosition;
|
|
||||||
UInt64 DataStartPosition2;
|
|
||||||
CRecordVector<UInt64> FileInfoPopIDs;
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
FileInfoPopIDs.Clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct CArchiveDatabaseEx: public CArchiveDatabase
|
|
||||||
{
|
|
||||||
CInArchiveInfo ArchiveInfo;
|
|
||||||
CRecordVector<UInt64> PackStreamStartPositions;
|
|
||||||
CRecordVector<CNum> FolderStartPackStreamIndex;
|
|
||||||
CRecordVector<CNum> FolderStartFileIndex;
|
|
||||||
CRecordVector<CNum> FileIndexToFolderIndexMap;
|
|
||||||
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
CArchiveDatabase::Clear();
|
|
||||||
ArchiveInfo.Clear();
|
|
||||||
PackStreamStartPositions.Clear();
|
|
||||||
FolderStartPackStreamIndex.Clear();
|
|
||||||
FolderStartFileIndex.Clear();
|
|
||||||
FileIndexToFolderIndexMap.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillFolderStartPackStream();
|
|
||||||
void FillStartPos();
|
|
||||||
void FillFolderStartFileIndex();
|
|
||||||
|
|
||||||
void Fill()
|
|
||||||
{
|
|
||||||
FillFolderStartPackStream();
|
|
||||||
FillStartPos();
|
|
||||||
FillFolderStartFileIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
|
|
||||||
{
|
|
||||||
return ArchiveInfo.DataStartPosition +
|
|
||||||
PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] +
|
|
||||||
indexInFolder];
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt64 GetFolderFullPackSize(int folderIndex) const
|
|
||||||
{
|
|
||||||
CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
|
|
||||||
const CFolder &folder = Folders[folderIndex];
|
|
||||||
UInt64 size = 0;
|
|
||||||
for (int i = 0; i < folder.PackStreams.Size(); i++)
|
|
||||||
size += PackSizes[packStreamIndex + i];
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
|
||||||
{
|
|
||||||
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt64 GetFilePackSize(CNum fileIndex) const
|
|
||||||
{
|
|
||||||
CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
|
|
||||||
if (folderIndex >= 0)
|
|
||||||
{
|
|
||||||
const CFolder &folderInfo = Folders[folderIndex];
|
|
||||||
if (FolderStartFileIndex[folderIndex] == fileIndex)
|
|
||||||
return GetFolderFullPackSize(folderIndex);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CInByte2
|
|
||||||
{
|
|
||||||
const Byte *_buffer;
|
|
||||||
size_t _size;
|
|
||||||
size_t _pos;
|
|
||||||
public:
|
|
||||||
void Init(const Byte *buffer, size_t size)
|
|
||||||
{
|
|
||||||
_buffer = buffer;
|
|
||||||
_size = size;
|
|
||||||
_pos = 0;
|
|
||||||
}
|
|
||||||
bool ReadByte(Byte &b)
|
|
||||||
{
|
|
||||||
if(_pos >= _size)
|
|
||||||
return false;
|
|
||||||
b = _buffer[_pos++];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
void ReadBytes(void *data, size_t size, size_t &processedSize)
|
|
||||||
{
|
|
||||||
for(processedSize = 0; processedSize < size && _pos < _size; processedSize++)
|
|
||||||
((Byte *)data)[processedSize] = _buffer[_pos++];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadBytes(void *data, size_t size)
|
|
||||||
{
|
|
||||||
size_t processedSize;
|
|
||||||
ReadBytes(data, size, processedSize);
|
|
||||||
return (processedSize == size);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetProcessedSize() const { return _pos; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class CStreamSwitch;
|
|
||||||
class CInArchive
|
|
||||||
{
|
|
||||||
friend class CStreamSwitch;
|
|
||||||
|
|
||||||
CMyComPtr<IInStream> _stream;
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
bool _finishSignature;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CObjectVector<CInByte2> _inByteVector;
|
|
||||||
CInByte2 *_inByteBack;
|
|
||||||
|
|
||||||
UInt64 _arhiveBeginStreamPosition;
|
|
||||||
UInt64 _position;
|
|
||||||
|
|
||||||
void AddByteStream(const Byte *buffer, size_t size)
|
|
||||||
{
|
|
||||||
_inByteVector.Add(CInByte2());
|
|
||||||
_inByteBack = &_inByteVector.Back();
|
|
||||||
_inByteBack->Init(buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteByteStream()
|
|
||||||
{
|
|
||||||
_inByteVector.DeleteBack();
|
|
||||||
if (!_inByteVector.IsEmpty())
|
|
||||||
_inByteBack = &_inByteVector.Back();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
HRESULT FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HRESULT ReadFileNames(CObjectVector<CFileItem> &files);
|
|
||||||
|
|
||||||
HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size,
|
|
||||||
UInt32 *processedSize);
|
|
||||||
HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
HRESULT SafeReadDirect(void *data, UInt32 size);
|
|
||||||
HRESULT SafeReadDirectByte(Byte &b);
|
|
||||||
HRESULT SafeReadDirectUInt32(UInt32 &value);
|
|
||||||
HRESULT SafeReadDirectUInt64(UInt64 &value);
|
|
||||||
|
|
||||||
HRESULT ReadBytes(void *data, size_t size)
|
|
||||||
{
|
|
||||||
if (!_inByteBack->ReadBytes(data, size))
|
|
||||||
return E_FAIL;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ReadByte(Byte &b)
|
|
||||||
{
|
|
||||||
if (!_inByteBack->ReadByte(b))
|
|
||||||
return E_FAIL;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ReadWideCharLE(wchar_t &c)
|
|
||||||
{
|
|
||||||
Byte b1;
|
|
||||||
if (!_inByteBack->ReadByte(b1))
|
|
||||||
return E_FAIL;
|
|
||||||
Byte b2;
|
|
||||||
if (!_inByteBack->ReadByte(b2))
|
|
||||||
return E_FAIL;
|
|
||||||
c = (wchar_t(b2) << 8) + b1;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ReadNumber(UInt64 &value);
|
|
||||||
HRESULT ReadNum(CNum &value);
|
|
||||||
HRESULT ReadID(UInt64 &value) { return ReadNumber(value); }
|
|
||||||
HRESULT ReadUInt32(UInt32 &value);
|
|
||||||
HRESULT ReadUInt64(UInt64 &value);
|
|
||||||
|
|
||||||
HRESULT SkeepData(UInt64 size);
|
|
||||||
HRESULT SkeepData();
|
|
||||||
HRESULT WaitAttribute(UInt64 attribute);
|
|
||||||
|
|
||||||
HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo);
|
|
||||||
HRESULT GetNextFolderItem(CFolder &itemInfo);
|
|
||||||
HRESULT ReadHashDigests(int numItems,
|
|
||||||
CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
|
|
||||||
|
|
||||||
HRESULT ReadPackInfo(
|
|
||||||
UInt64 &dataOffset,
|
|
||||||
CRecordVector<UInt64> &packSizes,
|
|
||||||
CRecordVector<bool> &packCRCsDefined,
|
|
||||||
CRecordVector<UInt32> &packCRCs);
|
|
||||||
|
|
||||||
HRESULT ReadUnPackInfo(
|
|
||||||
const CObjectVector<CByteBuffer> *dataVector,
|
|
||||||
CObjectVector<CFolder> &folders);
|
|
||||||
|
|
||||||
HRESULT ReadSubStreamsInfo(
|
|
||||||
const CObjectVector<CFolder> &folders,
|
|
||||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
|
||||||
CRecordVector<UInt64> &unPackSizes,
|
|
||||||
CRecordVector<bool> &digestsDefined,
|
|
||||||
CRecordVector<UInt32> &digests);
|
|
||||||
|
|
||||||
HRESULT CInArchive::ReadStreamsInfo(
|
|
||||||
const CObjectVector<CByteBuffer> *dataVector,
|
|
||||||
UInt64 &dataOffset,
|
|
||||||
CRecordVector<UInt64> &packSizes,
|
|
||||||
CRecordVector<bool> &packCRCsDefined,
|
|
||||||
CRecordVector<UInt32> &packCRCs,
|
|
||||||
CObjectVector<CFolder> &folders,
|
|
||||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
|
||||||
CRecordVector<UInt64> &unPackSizes,
|
|
||||||
CRecordVector<bool> &digestsDefined,
|
|
||||||
CRecordVector<UInt32> &digests);
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT GetNextFileItem(CFileItem &itemInfo);
|
|
||||||
HRESULT ReadBoolVector(int numItems, CBoolVector &v);
|
|
||||||
HRESULT ReadBoolVector2(int numItems, CBoolVector &v);
|
|
||||||
HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector,
|
|
||||||
CObjectVector<CFileItem> &files, UInt64 type);
|
|
||||||
HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset,
|
|
||||||
CObjectVector<CByteBuffer> &dataVector
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
HRESULT ReadHeader(CArchiveDatabaseEx &database
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
,ICryptoGetTextPassword *getTextPassword
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
public:
|
|
||||||
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
|
||||||
void Close();
|
|
||||||
|
|
||||||
HRESULT ReadDatabase(CArchiveDatabaseEx &database
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
,ICryptoGetTextPassword *getTextPassword
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
// 7zItem.h
|
|
||||||
|
|
||||||
#ifndef __7Z_ITEM_H
|
|
||||||
#define __7Z_ITEM_H
|
|
||||||
|
|
||||||
#include "../../../Common/Buffer.h"
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
#include "7zHeader.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
struct CAltCoderInfo
|
|
||||||
{
|
|
||||||
CMethodID MethodID;
|
|
||||||
CByteBuffer Properties;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef UInt32 CNum;
|
|
||||||
const CNum kNumMax = 0x7FFFFFFF;
|
|
||||||
const CNum kNumNoIndex = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
struct CCoderInfo
|
|
||||||
{
|
|
||||||
CNum NumInStreams;
|
|
||||||
CNum NumOutStreams;
|
|
||||||
CObjectVector<CAltCoderInfo> AltCoders;
|
|
||||||
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CBindPair
|
|
||||||
{
|
|
||||||
CNum InIndex;
|
|
||||||
CNum OutIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CFolder
|
|
||||||
{
|
|
||||||
CObjectVector<CCoderInfo> Coders;
|
|
||||||
CRecordVector<CBindPair> BindPairs;
|
|
||||||
CRecordVector<CNum> PackStreams;
|
|
||||||
CRecordVector<UInt64> UnPackSizes;
|
|
||||||
UInt32 UnPackCRC;
|
|
||||||
bool UnPackCRCDefined;
|
|
||||||
|
|
||||||
CFolder(): UnPackCRCDefined(false) {}
|
|
||||||
|
|
||||||
UInt64 GetUnPackSize() const // test it
|
|
||||||
{
|
|
||||||
if (UnPackSizes.IsEmpty())
|
|
||||||
return 0;
|
|
||||||
for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
|
|
||||||
if (FindBindPairForOutStream(i) < 0)
|
|
||||||
return UnPackSizes[i];
|
|
||||||
throw 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CNum GetNumOutStreams() const
|
|
||||||
{
|
|
||||||
CNum result = 0;
|
|
||||||
for (int i = 0; i < Coders.Size(); i++)
|
|
||||||
result += Coders[i].NumOutStreams;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FindBindPairForInStream(CNum inStreamIndex) const
|
|
||||||
{
|
|
||||||
for(int i = 0; i < BindPairs.Size(); i++)
|
|
||||||
if (BindPairs[i].InIndex == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int FindBindPairForOutStream(CNum outStreamIndex) const
|
|
||||||
{
|
|
||||||
for(int i = 0; i < BindPairs.Size(); i++)
|
|
||||||
if (BindPairs[i].OutIndex == outStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int FindPackStreamArrayIndex(CNum inStreamIndex) const
|
|
||||||
{
|
|
||||||
for(int i = 0; i < PackStreams.Size(); i++)
|
|
||||||
if (PackStreams[i] == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef FILETIME CArchiveFileTime;
|
|
||||||
|
|
||||||
class CFileItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CArchiveFileTime CreationTime;
|
|
||||||
CArchiveFileTime LastWriteTime;
|
|
||||||
CArchiveFileTime LastAccessTime;
|
|
||||||
UInt64 UnPackSize;
|
|
||||||
UInt64 StartPos;
|
|
||||||
UInt32 Attributes;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
UString Name;
|
|
||||||
|
|
||||||
bool HasStream; // Test it !!! it means that there is
|
|
||||||
// stream in some folder. It can be empty stream
|
|
||||||
bool IsDirectory;
|
|
||||||
bool IsAnti;
|
|
||||||
bool IsFileCRCDefined;
|
|
||||||
bool AreAttributesDefined;
|
|
||||||
bool IsCreationTimeDefined;
|
|
||||||
bool IsLastWriteTimeDefined;
|
|
||||||
bool IsLastAccessTimeDefined;
|
|
||||||
bool IsStartPosDefined;
|
|
||||||
|
|
||||||
/*
|
|
||||||
const bool HasStream() const {
|
|
||||||
return !IsDirectory && !IsAnti && UnPackSize != 0; }
|
|
||||||
*/
|
|
||||||
CFileItem():
|
|
||||||
HasStream(true),
|
|
||||||
IsDirectory(false),
|
|
||||||
IsAnti(false),
|
|
||||||
IsFileCRCDefined(false),
|
|
||||||
AreAttributesDefined(false),
|
|
||||||
IsCreationTimeDefined(false),
|
|
||||||
IsLastWriteTimeDefined(false),
|
|
||||||
IsLastAccessTimeDefined(false),
|
|
||||||
IsStartPosDefined(false)
|
|
||||||
{}
|
|
||||||
void SetAttributes(UInt32 attributes)
|
|
||||||
{
|
|
||||||
AreAttributesDefined = true;
|
|
||||||
Attributes = attributes;
|
|
||||||
}
|
|
||||||
void SetCreationTime(const CArchiveFileTime &creationTime)
|
|
||||||
{
|
|
||||||
IsCreationTimeDefined = true;
|
|
||||||
CreationTime = creationTime;
|
|
||||||
}
|
|
||||||
void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
|
|
||||||
{
|
|
||||||
IsLastWriteTimeDefined = true;
|
|
||||||
LastWriteTime = lastWriteTime;
|
|
||||||
}
|
|
||||||
void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
|
|
||||||
{
|
|
||||||
IsLastAccessTimeDefined = true;
|
|
||||||
LastAccessTime = lastAccessTime;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CArchiveDatabase
|
|
||||||
{
|
|
||||||
CRecordVector<UInt64> PackSizes;
|
|
||||||
CRecordVector<bool> PackCRCsDefined;
|
|
||||||
CRecordVector<UInt32> PackCRCs;
|
|
||||||
CObjectVector<CFolder> Folders;
|
|
||||||
CRecordVector<CNum> NumUnPackStreamsVector;
|
|
||||||
CObjectVector<CFileItem> Files;
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
PackSizes.Clear();
|
|
||||||
PackCRCsDefined.Clear();
|
|
||||||
PackCRCs.Clear();
|
|
||||||
Folders.Clear();
|
|
||||||
NumUnPackStreamsVector.Clear();
|
|
||||||
Files.Clear();
|
|
||||||
}
|
|
||||||
bool IsEmpty() const
|
|
||||||
{
|
|
||||||
return (PackSizes.IsEmpty() &&
|
|
||||||
PackCRCsDefined.IsEmpty() &&
|
|
||||||
PackCRCs.IsEmpty() &&
|
|
||||||
Folders.IsEmpty() &&
|
|
||||||
NumUnPackStreamsVector.IsEmpty() &&
|
|
||||||
Files.IsEmpty());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
// 7zMethodID.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
static wchar_t GetHex(Byte value)
|
|
||||||
{
|
|
||||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool HexCharToInt(wchar_t value, Byte &result)
|
|
||||||
{
|
|
||||||
if (value >= '0' && value <= '9')
|
|
||||||
result = value - '0';
|
|
||||||
else if (value >= 'a' && value <= 'f')
|
|
||||||
result = 10 + value - 'a';
|
|
||||||
else if (value >= 'A' && value <= 'F')
|
|
||||||
result = 10 + value - 'A';
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, Byte &result)
|
|
||||||
{
|
|
||||||
Byte resultHigh, resultLow;
|
|
||||||
if (!HexCharToInt(valueHigh, resultHigh))
|
|
||||||
return false;
|
|
||||||
if (!HexCharToInt(valueLow, resultLow))
|
|
||||||
return false;
|
|
||||||
result = (resultHigh << 4) + resultLow;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UString CMethodID::ConvertToString() const
|
|
||||||
{
|
|
||||||
UString result;
|
|
||||||
for (int i = 0; i < IDSize; i++)
|
|
||||||
{
|
|
||||||
Byte b = ID[i];
|
|
||||||
result += GetHex(b >> 4);
|
|
||||||
result += GetHex(b & 0xF);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMethodID::ConvertFromString(const UString &srcString)
|
|
||||||
{
|
|
||||||
int length = srcString.Length();
|
|
||||||
if ((length & 1) != 0 || (length >> 1) > kMethodIDSize)
|
|
||||||
return false;
|
|
||||||
IDSize = length / 2;
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < IDSize; i++)
|
|
||||||
if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i]))
|
|
||||||
return false;
|
|
||||||
for(; i < kMethodIDSize; i++)
|
|
||||||
ID[i] = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const CMethodID &a1, const CMethodID &a2)
|
|
||||||
{
|
|
||||||
if (a1.IDSize != a2.IDSize)
|
|
||||||
return false;
|
|
||||||
for (UInt32 i = 0; i < a1.IDSize; i++)
|
|
||||||
if (a1.ID[i] != a2.ID[i])
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
// 7zMethodID.h
|
|
||||||
|
|
||||||
#ifndef __7Z_METHOD_ID_H
|
|
||||||
#define __7Z_METHOD_ID_H
|
|
||||||
|
|
||||||
#include "../../../Common/String.h"
|
|
||||||
#include "../../../Common/Types.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
const int kMethodIDSize = 15;
|
|
||||||
|
|
||||||
struct CMethodID
|
|
||||||
{
|
|
||||||
Byte ID[kMethodIDSize];
|
|
||||||
Byte IDSize;
|
|
||||||
UString ConvertToString() const;
|
|
||||||
bool ConvertFromString(const UString &srcString);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator==(const CMethodID &a1, const CMethodID &a2);
|
|
||||||
|
|
||||||
inline bool operator!=(const CMethodID &a1, const CMethodID &a2)
|
|
||||||
{ return !(a1 == a2); }
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
// 7zMethods.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "7zMethods.h"
|
|
||||||
|
|
||||||
#include "../../../Windows/FileFind.h"
|
|
||||||
#include "../../../Windows/DLL.h"
|
|
||||||
#include "../../../Windows/PropVariant.h"
|
|
||||||
#include "../../../Windows/Synchronization.h"
|
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
#include "../Common/CodecsPath.h"
|
|
||||||
|
|
||||||
using namespace NWindows;
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
static CObjectVector<CMethodInfo2> g_Methods;
|
|
||||||
static bool g_Loaded = false;
|
|
||||||
|
|
||||||
typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
|
|
||||||
|
|
||||||
typedef UInt32 (WINAPI *GetMethodPropertyFunc)(
|
|
||||||
UInt32 index, PROPID propID, PROPVARIANT *value);
|
|
||||||
|
|
||||||
static void Load(const CSysString &folderPrefix)
|
|
||||||
{
|
|
||||||
NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
|
|
||||||
NFile::NFind::CFileInfo fileInfo;
|
|
||||||
while (enumerator.Next(fileInfo))
|
|
||||||
{
|
|
||||||
if (fileInfo.IsDirectory())
|
|
||||||
continue;
|
|
||||||
CSysString filePath = folderPrefix + fileInfo.Name;
|
|
||||||
{
|
|
||||||
NDLL::CLibrary library;
|
|
||||||
if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
NDLL::CLibrary library;
|
|
||||||
if (!library.Load(filePath))
|
|
||||||
continue;
|
|
||||||
GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc)
|
|
||||||
library.GetProcAddress("GetMethodProperty");
|
|
||||||
if (getMethodProperty == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
UInt32 numMethods = 1;
|
|
||||||
GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)
|
|
||||||
library.GetProcAddress("GetNumberOfMethods");
|
|
||||||
if (getNumberOfMethodsFunc != NULL)
|
|
||||||
if (getNumberOfMethodsFunc(&numMethods) != S_OK)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for(UInt32 i = 0; i < numMethods; i++)
|
|
||||||
{
|
|
||||||
CMethodInfo2 info;
|
|
||||||
info.FilePath = filePath;
|
|
||||||
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK)
|
|
||||||
continue;
|
|
||||||
if (propVariant.vt != VT_BSTR)
|
|
||||||
continue;
|
|
||||||
info.MethodID.IDSize = SysStringByteLen(propVariant.bstrVal);
|
|
||||||
memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize);
|
|
||||||
propVariant.Clear();
|
|
||||||
|
|
||||||
if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK)
|
|
||||||
continue;
|
|
||||||
if (propVariant.vt == VT_EMPTY)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (propVariant.vt == VT_BSTR)
|
|
||||||
info.Name = propVariant.bstrVal;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
propVariant.Clear();
|
|
||||||
|
|
||||||
if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK)
|
|
||||||
continue;
|
|
||||||
if (propVariant.vt == VT_EMPTY)
|
|
||||||
info.EncoderIsAssigned = false;
|
|
||||||
else if (propVariant.vt == VT_BSTR)
|
|
||||||
{
|
|
||||||
info.EncoderIsAssigned = true;
|
|
||||||
info.Encoder = *(const GUID *)propVariant.bstrVal;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
propVariant.Clear();
|
|
||||||
|
|
||||||
if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK)
|
|
||||||
continue;
|
|
||||||
if (propVariant.vt == VT_EMPTY)
|
|
||||||
info.DecoderIsAssigned = false;
|
|
||||||
else if (propVariant.vt == VT_BSTR)
|
|
||||||
{
|
|
||||||
info.DecoderIsAssigned = true;
|
|
||||||
info.Decoder = *(const GUID *)propVariant.bstrVal;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
propVariant.Clear();
|
|
||||||
|
|
||||||
if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK)
|
|
||||||
continue;
|
|
||||||
if (propVariant.vt == VT_EMPTY)
|
|
||||||
info.NumInStreams = 1;
|
|
||||||
else if (propVariant.vt == VT_UI4)
|
|
||||||
info.NumInStreams = propVariant.ulVal;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
propVariant.Clear();
|
|
||||||
|
|
||||||
if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK)
|
|
||||||
continue;
|
|
||||||
if (propVariant.vt == VT_EMPTY)
|
|
||||||
info.NumOutStreams = 1;
|
|
||||||
else if (propVariant.vt == VT_UI4)
|
|
||||||
info.NumOutStreams = propVariant.ulVal;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
propVariant.Clear();
|
|
||||||
|
|
||||||
g_Methods.Add(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NSynchronization::CCriticalSection g_CriticalSection;
|
|
||||||
|
|
||||||
void LoadMethodMap()
|
|
||||||
{
|
|
||||||
NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
|
|
||||||
if (g_Loaded)
|
|
||||||
return;
|
|
||||||
g_Loaded = true;
|
|
||||||
Load(GetCodecsFolderPrefix());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < g_Methods.Size(); i++)
|
|
||||||
{
|
|
||||||
const CMethodInfo2 &method = g_Methods[i];
|
|
||||||
if (method.MethodID == methodID)
|
|
||||||
{
|
|
||||||
methodInfo = (CMethodInfo)method;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < g_Methods.Size(); i++)
|
|
||||||
{
|
|
||||||
const CMethodInfo2 &method = g_Methods[i];
|
|
||||||
if (method.Name.CollateNoCase(name) == 0)
|
|
||||||
{
|
|
||||||
methodInfo = method;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
// 7zMethods.h
|
|
||||||
|
|
||||||
#ifndef __7Z_METHODS_H
|
|
||||||
#define __7Z_METHODS_H
|
|
||||||
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
struct CMethodInfo
|
|
||||||
{
|
|
||||||
UString Name;
|
|
||||||
bool EncoderIsAssigned;
|
|
||||||
bool DecoderIsAssigned;
|
|
||||||
UInt32 NumInStreams;
|
|
||||||
UInt32 NumOutStreams;
|
|
||||||
CLSID Encoder;
|
|
||||||
CLSID Decoder;
|
|
||||||
// UString Description;
|
|
||||||
CSysString FilePath;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CMethodInfo2: public CMethodInfo
|
|
||||||
{
|
|
||||||
CMethodID MethodID;
|
|
||||||
};
|
|
||||||
|
|
||||||
void LoadMethodMap();
|
|
||||||
bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo);
|
|
||||||
bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo);
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,177 +0,0 @@
|
|||||||
// 7z/Out.h
|
|
||||||
|
|
||||||
#ifndef __7Z_OUT_H
|
|
||||||
#define __7Z_OUT_H
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zCompressionMode.h"
|
|
||||||
#include "7zEncode.h"
|
|
||||||
|
|
||||||
#include "../../Common/OutBuffer.h"
|
|
||||||
#include "../../../Common/DynamicBuffer.h"
|
|
||||||
#include "../../../Common/CRC.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
class CWriteBufferLoc
|
|
||||||
{
|
|
||||||
Byte *_data;
|
|
||||||
size_t _size;
|
|
||||||
size_t _pos;
|
|
||||||
public:
|
|
||||||
CWriteBufferLoc(): _size(0), _pos(0) {}
|
|
||||||
void Init(Byte *data, size_t size)
|
|
||||||
{
|
|
||||||
_pos = 0;
|
|
||||||
_data = data;
|
|
||||||
_size = size;
|
|
||||||
}
|
|
||||||
HRESULT Write(const void *data, size_t size)
|
|
||||||
{
|
|
||||||
if (_pos + size > _size)
|
|
||||||
return E_FAIL;
|
|
||||||
memmove(_data + _pos, data, size);
|
|
||||||
_pos += size;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CWriteDynamicBuffer
|
|
||||||
{
|
|
||||||
CByteDynamicBuffer _buffer;
|
|
||||||
size_t _pos;
|
|
||||||
public:
|
|
||||||
CWriteDynamicBuffer(): _pos(0) {}
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
_pos = 0;
|
|
||||||
}
|
|
||||||
void Write(const void *data, size_t size)
|
|
||||||
{
|
|
||||||
if (_pos + size > _buffer.GetCapacity())
|
|
||||||
_buffer.EnsureCapacity(_pos + size);
|
|
||||||
memmove(((Byte *)_buffer) +_pos, data, size);
|
|
||||||
_pos += size;
|
|
||||||
}
|
|
||||||
operator Byte *() { return (Byte *)_buffer; };
|
|
||||||
operator const Byte *() const { return (const Byte *)_buffer; };
|
|
||||||
size_t GetSize() const { return _pos; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class COutArchive
|
|
||||||
{
|
|
||||||
UInt64 _prefixHeaderPos;
|
|
||||||
|
|
||||||
HRESULT WriteDirect(const void *data, UInt32 size);
|
|
||||||
HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
|
|
||||||
HRESULT WriteDirectUInt32(UInt32 value);
|
|
||||||
HRESULT WriteDirectUInt64(UInt64 value);
|
|
||||||
|
|
||||||
HRESULT WriteBytes(const void *data, size_t size);
|
|
||||||
HRESULT WriteBytes(const CByteBuffer &data);
|
|
||||||
HRESULT WriteByte(Byte b);
|
|
||||||
HRESULT WriteUInt32(UInt32 value);
|
|
||||||
HRESULT WriteNumber(UInt64 value);
|
|
||||||
HRESULT WriteID(UInt64 value) { return WriteNumber(value); }
|
|
||||||
|
|
||||||
HRESULT WriteFolder(const CFolder &folder);
|
|
||||||
HRESULT WriteFileHeader(const CFileItem &itemInfo);
|
|
||||||
HRESULT WriteBoolVector(const CBoolVector &boolVector);
|
|
||||||
HRESULT WriteHashDigests(
|
|
||||||
const CRecordVector<bool> &digestsDefined,
|
|
||||||
const CRecordVector<UInt32> &hashDigests);
|
|
||||||
|
|
||||||
HRESULT WritePackInfo(
|
|
||||||
UInt64 dataOffset,
|
|
||||||
const CRecordVector<UInt64> &packSizes,
|
|
||||||
const CRecordVector<bool> &packCRCsDefined,
|
|
||||||
const CRecordVector<UInt32> &packCRCs);
|
|
||||||
|
|
||||||
HRESULT WriteUnPackInfo(
|
|
||||||
bool externalFolders,
|
|
||||||
CNum externalFoldersStreamIndex,
|
|
||||||
const CObjectVector<CFolder> &folders);
|
|
||||||
|
|
||||||
HRESULT WriteSubStreamsInfo(
|
|
||||||
const CObjectVector<CFolder> &folders,
|
|
||||||
const CRecordVector<CNum> &numUnPackStreamsInFolders,
|
|
||||||
const CRecordVector<UInt64> &unPackSizes,
|
|
||||||
const CRecordVector<bool> &digestsDefined,
|
|
||||||
const CRecordVector<UInt32> &hashDigests);
|
|
||||||
|
|
||||||
/*
|
|
||||||
HRESULT WriteStreamsInfo(
|
|
||||||
UInt64 dataOffset,
|
|
||||||
const CRecordVector<UInt64> &packSizes,
|
|
||||||
const CRecordVector<bool> &packCRCsDefined,
|
|
||||||
const CRecordVector<UInt32> &packCRCs,
|
|
||||||
bool externalFolders,
|
|
||||||
UInt64 externalFoldersStreamIndex,
|
|
||||||
const CObjectVector<CFolder> &folders,
|
|
||||||
const CRecordVector<CNum> &numUnPackStreamsInFolders,
|
|
||||||
const CRecordVector<UInt64> &unPackSizes,
|
|
||||||
const CRecordVector<bool> &digestsDefined,
|
|
||||||
const CRecordVector<UInt32> &hashDigests);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type,
|
|
||||||
bool isExternal, CNum externalDataIndex);
|
|
||||||
|
|
||||||
HRESULT EncodeStream(CEncoder &encoder, const Byte *data, size_t dataSize,
|
|
||||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
|
||||||
HRESULT EncodeStream(CEncoder &encoder, const CByteBuffer &data,
|
|
||||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
|
||||||
HRESULT WriteHeader(const CArchiveDatabase &database,
|
|
||||||
const CCompressionMethodMode *options,
|
|
||||||
UInt64 &headerOffset);
|
|
||||||
|
|
||||||
bool _mainMode;
|
|
||||||
|
|
||||||
bool _dynamicMode;
|
|
||||||
|
|
||||||
bool _countMode;
|
|
||||||
size_t _countSize;
|
|
||||||
COutBuffer _outByte;
|
|
||||||
CWriteBufferLoc _outByte2;
|
|
||||||
CWriteDynamicBuffer _dynamicBuffer;
|
|
||||||
CCRC _crc;
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
bool _endMarker;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HRESULT WriteSignature();
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
HRESULT WriteFinishSignature();
|
|
||||||
#endif
|
|
||||||
HRESULT WriteStartHeader(const CStartHeader &h);
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
HRESULT WriteFinishHeader(const CFinishHeader &h);
|
|
||||||
#endif
|
|
||||||
CMyComPtr<IOutStream> Stream;
|
|
||||||
public:
|
|
||||||
|
|
||||||
COutArchive() { _outByte.Create(1 << 16); }
|
|
||||||
CMyComPtr<ISequentialOutStream> SeqStream;
|
|
||||||
HRESULT Create(ISequentialOutStream *stream, bool endMarker);
|
|
||||||
void Close();
|
|
||||||
HRESULT SkeepPrefixArchiveHeader();
|
|
||||||
HRESULT WriteDatabase(const CArchiveDatabase &database,
|
|
||||||
const CCompressionMethodMode *options,
|
|
||||||
bool useAdditionalHeaderStreams,
|
|
||||||
bool compressMainHeader);
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
|
|
||||||
static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,69 +0,0 @@
|
|||||||
// 7zUpdate.h
|
|
||||||
|
|
||||||
#ifndef __7Z_UPDATE_H
|
|
||||||
#define __7Z_UPDATE_H
|
|
||||||
|
|
||||||
#include "7zIn.h"
|
|
||||||
#include "7zCompressionMode.h"
|
|
||||||
|
|
||||||
#include "../IArchive.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace N7z {
|
|
||||||
|
|
||||||
struct CUpdateItem
|
|
||||||
{
|
|
||||||
bool NewData;
|
|
||||||
bool NewProperties;
|
|
||||||
int IndexInArchive;
|
|
||||||
int IndexInClient;
|
|
||||||
|
|
||||||
UInt32 Attributes;
|
|
||||||
FILETIME CreationTime;
|
|
||||||
FILETIME LastWriteTime;
|
|
||||||
|
|
||||||
UInt64 Size;
|
|
||||||
UString Name;
|
|
||||||
|
|
||||||
bool IsAnti;
|
|
||||||
bool IsDirectory;
|
|
||||||
|
|
||||||
bool CreationTimeIsDefined;
|
|
||||||
bool LastWriteTimeIsDefined;
|
|
||||||
bool AttributesAreDefined;
|
|
||||||
|
|
||||||
const bool HasStream() const
|
|
||||||
{ return !IsDirectory && !IsAnti && Size != 0; }
|
|
||||||
CUpdateItem(): IsAnti(false) {}
|
|
||||||
void SetDirectoryStatusFromAttributes()
|
|
||||||
{ IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
|
|
||||||
|
|
||||||
int GetExtensionPos() const;
|
|
||||||
UString GetExtension() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CUpdateOptions
|
|
||||||
{
|
|
||||||
const CCompressionMethodMode *Method;
|
|
||||||
const CCompressionMethodMode *HeaderMethod;
|
|
||||||
bool UseFilters;
|
|
||||||
bool MaxFilter;
|
|
||||||
bool UseAdditionalHeaderStreams;
|
|
||||||
bool CompressMainHeader;
|
|
||||||
UInt64 NumSolidFiles;
|
|
||||||
UInt64 NumSolidBytes;
|
|
||||||
bool SolidExtension;
|
|
||||||
bool RemoveSfxBlock;
|
|
||||||
bool VolumeMode;
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT Update(
|
|
||||||
IInStream *inStream,
|
|
||||||
const CArchiveDatabaseEx *database,
|
|
||||||
CObjectVector<CUpdateItem> &updateItems,
|
|
||||||
ISequentialOutStream *seqOutStream,
|
|
||||||
IArchiveUpdateCallback *updateCallback,
|
|
||||||
const CUpdateOptions &options);
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
// DLLExports.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "../../../Common/MyInitGuid.h"
|
|
||||||
#include "../../../Common/ComTry.h"
|
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
#include "7zHandler.h"
|
|
||||||
|
|
||||||
#ifndef EXCLUDE_COM
|
|
||||||
// {23170F69-40C1-278B-06F1-070100000100}
|
|
||||||
DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
|
|
||||||
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
|
|
||||||
#else
|
|
||||||
#include "../../Compress/LZ/IMatchFinder.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HINSTANCE g_hInstance;
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
|
||||||
{
|
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
|
||||||
g_hInstance = hInstance;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STDAPI CreateObject(
|
|
||||||
const GUID *classID,
|
|
||||||
const GUID *interfaceID,
|
|
||||||
void **outObject)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
*outObject = 0;
|
|
||||||
if (*classID != NArchive::N7z::CLSID_CFormat7z)
|
|
||||||
return CLASS_E_CLASSNOTAVAILABLE;
|
|
||||||
if (*interfaceID == IID_IInArchive)
|
|
||||||
{
|
|
||||||
CMyComPtr<IInArchive> inArchive = new NArchive::N7z::CHandler;
|
|
||||||
*outObject = inArchive.Detach();
|
|
||||||
}
|
|
||||||
#ifndef EXTRACT_ONLY
|
|
||||||
else if (*interfaceID == IID_IOutArchive)
|
|
||||||
{
|
|
||||||
CMyComPtr<IOutArchive> outArchive = new NArchive::N7z::CHandler;
|
|
||||||
*outObject = outArchive.Detach();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
COM_TRY_END
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case NArchive::kName:
|
|
||||||
propVariant = L"7z";
|
|
||||||
break;
|
|
||||||
case NArchive::kClassID:
|
|
||||||
{
|
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
|
||||||
(const char *)&NArchive::N7z::CLSID_CFormat7z, sizeof(GUID))) != 0)
|
|
||||||
value->vt = VT_BSTR;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case NArchive::kExtension:
|
|
||||||
propVariant = L"7z";
|
|
||||||
break;
|
|
||||||
case NArchive::kUpdate:
|
|
||||||
propVariant = true;
|
|
||||||
break;
|
|
||||||
case NArchive::kKeepName:
|
|
||||||
propVariant = false;
|
|
||||||
break;
|
|
||||||
case NArchive::kStartSignature:
|
|
||||||
{
|
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen((const char *)NArchive::N7z::kSignature,
|
|
||||||
NArchive::N7z::kSignatureSize)) != 0)
|
|
||||||
value->vt = VT_BSTR;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
propVariant.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
@@ -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 +0,0 @@
|
|||||||
//Microsoft Developer Studio generated resource script.
|
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Russian resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
|
||||||
#pragma code_page(1251)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Russian resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "7z.ico"
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 4,20,0,0
|
|
||||||
PRODUCTVERSION 4,20,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, 20, 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, 20, 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
|
|
||||||
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/* 7zAlloc.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_ALLOC_H
|
|
||||||
#define __7Z_ALLOC_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
typedef struct _ISzAlloc
|
|
||||||
{
|
|
||||||
void *(*Alloc)(size_t size);
|
|
||||||
void (*Free)(void *address); /* address can be 0 */
|
|
||||||
} ISzAlloc;
|
|
||||||
|
|
||||||
void *SzAlloc(size_t size);
|
|
||||||
void SzFree(void *address);
|
|
||||||
|
|
||||||
void *SzAllocTemp(size_t size);
|
|
||||||
void SzFreeTemp(void *address);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/* 7zBuffer.c */
|
|
||||||
|
|
||||||
#include "7zBuffer.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
void SzByteBufferInit(CSzByteBuffer *buffer)
|
|
||||||
{
|
|
||||||
buffer->Capacity = 0;
|
|
||||||
buffer->Items = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
|
|
||||||
{
|
|
||||||
buffer->Capacity = newCapacity;
|
|
||||||
buffer->Items = (Byte *)allocFunc(newCapacity);
|
|
||||||
return (buffer->Items != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
|
|
||||||
{
|
|
||||||
freeFunc(buffer->Items);
|
|
||||||
buffer->Items = 0;
|
|
||||||
buffer->Capacity = 0;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/* 7zBuffer.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_BUFFER_H
|
|
||||||
#define __7Z_BUFFER_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
typedef struct _CSzByteBuffer
|
|
||||||
{
|
|
||||||
size_t Capacity;
|
|
||||||
Byte *Items;
|
|
||||||
}CSzByteBuffer;
|
|
||||||
|
|
||||||
void SzByteBufferInit(CSzByteBuffer *buffer);
|
|
||||||
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
|
|
||||||
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/* 7zCrc.c */
|
|
||||||
|
|
||||||
#include "7zCrc.h"
|
|
||||||
|
|
||||||
#define kCrcPoly 0xEDB88320
|
|
||||||
|
|
||||||
UInt32 g_CrcTable[256];
|
|
||||||
|
|
||||||
void InitCrcTable()
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
UInt32 r = i;
|
|
||||||
int j;
|
|
||||||
for (j = 0; j < 8; j++)
|
|
||||||
if (r & 1)
|
|
||||||
r = (r >> 1) ^ kCrcPoly;
|
|
||||||
else
|
|
||||||
r >>= 1;
|
|
||||||
g_CrcTable[i] = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; }
|
|
||||||
UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; }
|
|
||||||
|
|
||||||
void CrcUpdateByte(UInt32 *crc, Byte b)
|
|
||||||
{
|
|
||||||
*crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt16(UInt32 *crc, UInt16 v)
|
|
||||||
{
|
|
||||||
CrcUpdateByte(crc, (Byte)v);
|
|
||||||
CrcUpdateByte(crc, (Byte)(v >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt32(UInt32 *crc, UInt32 v)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
CrcUpdateByte(crc, (Byte)(v >> (8 * i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdateUInt64(UInt32 *crc, UInt64 v)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
CrcUpdateByte(crc, (Byte)(v));
|
|
||||||
v >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrcUpdate(UInt32 *crc, const void *data, size_t size)
|
|
||||||
{
|
|
||||||
UInt32 v = *crc;
|
|
||||||
const Byte *p = (const Byte *)data;
|
|
||||||
for (; size > 0 ; size--, p++)
|
|
||||||
v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8);
|
|
||||||
*crc = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 CrcCalculateDigest(const void *data, size_t size)
|
|
||||||
{
|
|
||||||
UInt32 crc;
|
|
||||||
CrcInit(&crc);
|
|
||||||
CrcUpdate(&crc, data, size);
|
|
||||||
return CrcGetDigest(&crc);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CrcVerifyDigest(UInt32 digest, const void *data, size_t size)
|
|
||||||
{
|
|
||||||
return (CrcCalculateDigest(data, size) == digest);
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/* 7zCrc.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_CRC_H
|
|
||||||
#define __7Z_CRC_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
extern UInt32 g_CrcTable[256];
|
|
||||||
void InitCrcTable();
|
|
||||||
|
|
||||||
void CrcInit(UInt32 *crc);
|
|
||||||
UInt32 CrcGetDigest(UInt32 *crc);
|
|
||||||
void CrcUpdateByte(UInt32 *crc, Byte v);
|
|
||||||
void CrcUpdateUInt16(UInt32 *crc, UInt16 v);
|
|
||||||
void CrcUpdateUInt32(UInt32 *crc, UInt32 v);
|
|
||||||
void CrcUpdateUInt64(UInt32 *crc, UInt64 v);
|
|
||||||
void CrcUpdate(UInt32 *crc, const void *data, size_t size);
|
|
||||||
|
|
||||||
UInt32 CrcCalculateDigest(const void *data, size_t size);
|
|
||||||
int CrcVerifyDigest(UInt32 digest, const void *data, size_t size);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
/* 7zDecode.c */
|
|
||||||
|
|
||||||
#include "7zDecode.h"
|
|
||||||
#ifdef _SZ_ONE_DIRECTORY
|
|
||||||
#include "LzmaDecode.h"
|
|
||||||
#else
|
|
||||||
#include "../../Compress/LZMA_C/LzmaDecode.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CMethodID k_Copy = { { 0x0 }, 1 };
|
|
||||||
CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
|
|
||||||
typedef struct _CLzmaInCallbackImp
|
|
||||||
{
|
|
||||||
ILzmaInCallback InCallback;
|
|
||||||
ISzInStream *InStream;
|
|
||||||
size_t Size;
|
|
||||||
} CLzmaInCallbackImp;
|
|
||||||
|
|
||||||
int LzmaReadImp(void *object, unsigned char **buffer, UInt32 *size)
|
|
||||||
{
|
|
||||||
CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
|
|
||||||
size_t processedSize;
|
|
||||||
SZ_RESULT res;
|
|
||||||
*size = 0;
|
|
||||||
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
|
|
||||||
*size = (UInt32)processedSize;
|
|
||||||
if (processedSize > cb->Size)
|
|
||||||
return (int)SZE_FAIL;
|
|
||||||
cb->Size -= processedSize;
|
|
||||||
if (res == SZ_OK)
|
|
||||||
return 0;
|
|
||||||
return (int)res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ISzInStream *inStream,
|
|
||||||
#else
|
|
||||||
Byte *inBuffer,
|
|
||||||
#endif
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain)
|
|
||||||
{
|
|
||||||
UInt32 si;
|
|
||||||
size_t inSize = 0;
|
|
||||||
CCoderInfo *coder;
|
|
||||||
if (folder->NumPackStreams != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
if (folder->NumCoders != 1)
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
coder = folder->Coders;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
|
|
||||||
for (si = 0; si < folder->NumPackStreams; si++)
|
|
||||||
inSize += (size_t)packSizes[si];
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_Copy))
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
if (inSize != outSize)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
for (i = 0; i < inSize;)
|
|
||||||
{
|
|
||||||
size_t j;
|
|
||||||
Byte *inBuffer;
|
|
||||||
size_t bufferSize;
|
|
||||||
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
|
|
||||||
if (bufferSize == 0)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (bufferSize > inSize - i)
|
|
||||||
return SZE_FAIL;
|
|
||||||
*outSizeProcessed += bufferSize;
|
|
||||||
for (j = 0; j < bufferSize && i < inSize; j++, i++)
|
|
||||||
outBuffer[i] = inBuffer[j];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (i = 0; i < inSize; i++)
|
|
||||||
outBuffer[i] = inBuffer[i];
|
|
||||||
*outSizeProcessed = inSize;
|
|
||||||
#endif
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
CLzmaInCallbackImp lzmaCallback;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int lc, lp, pb;
|
|
||||||
size_t lzmaInternalSize;
|
|
||||||
void *lzmaInternalData;
|
|
||||||
int result;
|
|
||||||
UInt32 outSizeProcessedLoc;
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
lzmaCallback.Size = inSize;
|
|
||||||
lzmaCallback.InStream = inStream;
|
|
||||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (coder->Properties.Capacity < 5)
|
|
||||||
return SZE_FAIL;
|
|
||||||
lc = (unsigned char)coder->Properties.Items[0];
|
|
||||||
if (lc >= (9 * 5 * 5))
|
|
||||||
return SZE_FAIL;
|
|
||||||
for (pb = 0; lc >= (9 * 5); pb++, lc -= (9 * 5));
|
|
||||||
for (lp = 0; lc >= 9; lp++, lc -= 9);
|
|
||||||
|
|
||||||
lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb);
|
|
||||||
lzmaInternalData = allocMain->Alloc(lzmaInternalSize);
|
|
||||||
if (lzmaInternalData == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
|
|
||||||
result = LzmaDecode((Byte *)lzmaInternalData, (UInt32)lzmaInternalSize,
|
|
||||||
lc, lp, pb,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
&lzmaCallback.InCallback,
|
|
||||||
#else
|
|
||||||
inBuffer, (UInt32)inSize,
|
|
||||||
#endif
|
|
||||||
outBuffer, (UInt32)outSize,
|
|
||||||
&outSizeProcessedLoc);
|
|
||||||
*outSizeProcessed = (size_t)outSizeProcessedLoc;
|
|
||||||
allocMain->Free(lzmaInternalData);
|
|
||||||
/*
|
|
||||||
NOT_ENOUGH_MEM error is impossible for this code
|
|
||||||
if (result = LZMA_RESULT_NOT_ENOUGH_MEM)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
*/
|
|
||||||
if (result == LZMA_RESULT_DATA_ERROR)
|
|
||||||
return SZE_DATA_ERROR;
|
|
||||||
if (result != LZMA_RESULT_OK)
|
|
||||||
return SZE_FAIL;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
return SZE_NOTIMPL;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/* 7zDecode.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_DECODE_H
|
|
||||||
#define __7Z_DECODE_H
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
#include "7zIn.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
ISzInStream *stream,
|
|
||||||
#else
|
|
||||||
Byte *inBuffer,
|
|
||||||
#endif
|
|
||||||
Byte *outBuffer, size_t outSize,
|
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
/* 7zExtract.c */
|
|
||||||
|
|
||||||
#include "7zExtract.h"
|
|
||||||
#include "7zDecode.h"
|
|
||||||
#include "7zCrc.h"
|
|
||||||
|
|
||||||
SZ_RESULT SzExtract(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex,
|
|
||||||
UInt32 *blockIndex,
|
|
||||||
Byte **outBuffer,
|
|
||||||
size_t *outBufferSize,
|
|
||||||
size_t *offset,
|
|
||||||
size_t *outSizeProcessed,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp)
|
|
||||||
{
|
|
||||||
UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
|
|
||||||
SZ_RESULT res = SZ_OK;
|
|
||||||
*offset = 0;
|
|
||||||
*outSizeProcessed = 0;
|
|
||||||
if (folderIndex == (UInt32)-1)
|
|
||||||
{
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
*outBuffer = 0;
|
|
||||||
*outBufferSize = 0;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
|
||||||
{
|
|
||||||
CFolder *folder = db->Database.Folders + folderIndex;
|
|
||||||
CFileSize unPackSize = SzFolderGetUnPackSize(folder);
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
|
|
||||||
Byte *inBuffer = 0;
|
|
||||||
size_t processedSize;
|
|
||||||
#endif
|
|
||||||
*blockIndex = folderIndex;
|
|
||||||
allocMain->Free(*outBuffer);
|
|
||||||
*outBuffer = 0;
|
|
||||||
|
|
||||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
|
||||||
if (inBuffer == 0)
|
|
||||||
return SZE_OUTOFMEMORY;
|
|
||||||
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
|
|
||||||
if (res == SZ_OK && processedSize != (size_t)packSize)
|
|
||||||
res = SZE_FAIL;
|
|
||||||
#endif
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
|
|
||||||
*outBufferSize = (size_t)unPackSize;
|
|
||||||
if (*outBuffer != 0)
|
|
||||||
{
|
|
||||||
size_t outRealSize;
|
|
||||||
res = SzDecode(db->Database.PackSizes +
|
|
||||||
db->FolderStartPackStreamIndex[folderIndex], folder,
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
inStream,
|
|
||||||
#else
|
|
||||||
inBuffer,
|
|
||||||
#endif
|
|
||||||
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
if (outRealSize == (size_t)unPackSize)
|
|
||||||
{
|
|
||||||
if (folder->UnPackCRCDefined)
|
|
||||||
{
|
|
||||||
if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = SZE_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
#ifndef _LZMA_IN_CB
|
|
||||||
allocTemp->Free(inBuffer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
|
||||||
*offset = 0;
|
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;
|
|
||||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
|
||||||
return SZE_FAIL;
|
|
||||||
{
|
|
||||||
if (fileItem->IsFileCRCDefined)
|
|
||||||
{
|
|
||||||
if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed))
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/* 7zExtract.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_EXTRACT_H
|
|
||||||
#define __7Z_EXTRACT_H
|
|
||||||
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
SZ_RESULT SzExtract(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
UInt32 fileIndex, /* index of file */
|
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
|
||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
/* 7zHeader.c */
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
|
|
||||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/* 7zHeader.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_HEADER_H
|
|
||||||
#define __7Z_HEADER_H
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
#define k7zSignatureSize 6
|
|
||||||
extern Byte k7zSignature[k7zSignatureSize];
|
|
||||||
|
|
||||||
#define k7zMajorVersion 0
|
|
||||||
|
|
||||||
#define k7zStartHeaderSize 0x20
|
|
||||||
|
|
||||||
enum EIdEnum
|
|
||||||
{
|
|
||||||
k7zIdEnd,
|
|
||||||
|
|
||||||
k7zIdHeader,
|
|
||||||
|
|
||||||
k7zIdArchiveProperties,
|
|
||||||
|
|
||||||
k7zIdAdditionalStreamsInfo,
|
|
||||||
k7zIdMainStreamsInfo,
|
|
||||||
k7zIdFilesInfo,
|
|
||||||
|
|
||||||
k7zIdPackInfo,
|
|
||||||
k7zIdUnPackInfo,
|
|
||||||
k7zIdSubStreamsInfo,
|
|
||||||
|
|
||||||
k7zIdSize,
|
|
||||||
k7zIdCRC,
|
|
||||||
|
|
||||||
k7zIdFolder,
|
|
||||||
|
|
||||||
k7zIdCodersUnPackSize,
|
|
||||||
k7zIdNumUnPackStream,
|
|
||||||
|
|
||||||
k7zIdEmptyStream,
|
|
||||||
k7zIdEmptyFile,
|
|
||||||
k7zIdAnti,
|
|
||||||
|
|
||||||
k7zIdName,
|
|
||||||
k7zIdCreationTime,
|
|
||||||
k7zIdLastAccessTime,
|
|
||||||
k7zIdLastWriteTime,
|
|
||||||
k7zIdWinAttributes,
|
|
||||||
k7zIdComment,
|
|
||||||
|
|
||||||
k7zIdEncodedHeader,
|
|
||||||
|
|
||||||
k7zIdStartPos
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
|||||||
/* 7zIn.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_IN_H
|
|
||||||
#define __7Z_IN_H
|
|
||||||
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
typedef struct _CInArchiveInfo
|
|
||||||
{
|
|
||||||
CFileSize StartPositionAfterHeader;
|
|
||||||
CFileSize DataStartPosition;
|
|
||||||
}CInArchiveInfo;
|
|
||||||
|
|
||||||
typedef struct _CArchiveDatabaseEx
|
|
||||||
{
|
|
||||||
CArchiveDatabase Database;
|
|
||||||
CInArchiveInfo ArchiveInfo;
|
|
||||||
UInt32 *FolderStartPackStreamIndex;
|
|
||||||
CFileSize *PackStreamStartPositions;
|
|
||||||
UInt32 *FolderStartFileIndex;
|
|
||||||
UInt32 *FileIndexToFolderIndexMap;
|
|
||||||
}CArchiveDatabaseEx;
|
|
||||||
|
|
||||||
void SzArDbExInit(CArchiveDatabaseEx *db);
|
|
||||||
void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
|
|
||||||
CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
|
|
||||||
CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex);
|
|
||||||
|
|
||||||
typedef struct _ISzInStream
|
|
||||||
{
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
SZ_RESULT (*Read)(
|
|
||||||
void *object, /* pointer to ISzInStream itself */
|
|
||||||
void **buffer, /* out: pointer to buffer with data */
|
|
||||||
size_t maxRequiredSize, /* max required size to read */
|
|
||||||
size_t *processedSize); /* real processed size.
|
|
||||||
processedSize can be less than maxRequiredSize.
|
|
||||||
If processedSize == 0, then there are no more
|
|
||||||
bytes in stream. */
|
|
||||||
#else
|
|
||||||
SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
|
|
||||||
#endif
|
|
||||||
SZ_RESULT (*Seek)(void *object, CFileSize pos);
|
|
||||||
} ISzInStream;
|
|
||||||
|
|
||||||
|
|
||||||
int SzArchiveOpen(
|
|
||||||
ISzInStream *inStream,
|
|
||||||
CArchiveDatabaseEx *db,
|
|
||||||
ISzAlloc *allocMain,
|
|
||||||
ISzAlloc *allocTemp);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
/* 7zItem.c */
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
void SzCoderInfoInit(CCoderInfo *coder)
|
|
||||||
{
|
|
||||||
SzByteBufferInit(&coder->Properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
SzByteBufferFree(&coder->Properties, freeFunc);
|
|
||||||
SzCoderInfoInit(coder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFolderInit(CFolder *folder)
|
|
||||||
{
|
|
||||||
folder->NumCoders = 0;
|
|
||||||
folder->Coders = 0;
|
|
||||||
folder->NumBindPairs = 0;
|
|
||||||
folder->BindPairs = 0;
|
|
||||||
folder->NumPackStreams = 0;
|
|
||||||
folder->PackStreams = 0;
|
|
||||||
folder->UnPackSizes = 0;
|
|
||||||
folder->UnPackCRCDefined = 0;
|
|
||||||
folder->UnPackCRC = 0;
|
|
||||||
folder->NumUnPackStreams = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < folder->NumCoders; i++)
|
|
||||||
SzCoderInfoFree(&folder->Coders[i], freeFunc);
|
|
||||||
freeFunc(folder->Coders);
|
|
||||||
freeFunc(folder->BindPairs);
|
|
||||||
freeFunc(folder->PackStreams);
|
|
||||||
freeFunc(folder->UnPackSizes);
|
|
||||||
SzFolderInit(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 SzFolderGetNumOutStreams(CFolder *folder)
|
|
||||||
{
|
|
||||||
UInt32 result = 0;
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < folder->NumCoders; i++)
|
|
||||||
result += folder->Coders[i].NumOutStreams;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < folder->NumBindPairs; i++)
|
|
||||||
if (folder->BindPairs[i].InIndex == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < folder->NumBindPairs; i++)
|
|
||||||
if (folder->BindPairs[i].OutIndex == outStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder)
|
|
||||||
{
|
|
||||||
int i = (int)SzFolderGetNumOutStreams(folder);
|
|
||||||
if (i == 0)
|
|
||||||
return 0;
|
|
||||||
for (i--; i >= 0; i--)
|
|
||||||
if (SzFolderFindBindPairForOutStream(folder, i) < 0)
|
|
||||||
return folder->UnPackSizes[i];
|
|
||||||
/* throw 1; */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
int FindPackStreamArrayIndex(int inStreamIndex) const
|
|
||||||
{
|
|
||||||
for(int i = 0; i < PackStreams.Size(); i++)
|
|
||||||
if (PackStreams[i] == inStreamIndex)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void SzFileInit(CFileItem *fileItem)
|
|
||||||
{
|
|
||||||
fileItem->IsFileCRCDefined = 0;
|
|
||||||
fileItem->HasStream = 1;
|
|
||||||
fileItem->IsDirectory = 0;
|
|
||||||
fileItem->IsAnti = 0;
|
|
||||||
fileItem->Name = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
|
|
||||||
{
|
|
||||||
freeFunc(fileItem->Name);
|
|
||||||
SzFileInit(fileItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzArchiveDatabaseInit(CArchiveDatabase *db)
|
|
||||||
{
|
|
||||||
db->NumPackStreams = 0;
|
|
||||||
db->PackSizes = 0;
|
|
||||||
db->PackCRCsDefined = 0;
|
|
||||||
db->PackCRCs = 0;
|
|
||||||
db->NumFolders = 0;
|
|
||||||
db->Folders = 0;
|
|
||||||
db->NumFiles = 0;
|
|
||||||
db->Files = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < db->NumFolders; i++)
|
|
||||||
SzFolderFree(&db->Folders[i], freeFunc);
|
|
||||||
for (i = 0; i < db->NumFiles; i++)
|
|
||||||
SzFileFree(&db->Files[i], freeFunc);
|
|
||||||
freeFunc(db->PackSizes);
|
|
||||||
freeFunc(db->PackCRCsDefined);
|
|
||||||
freeFunc(db->PackCRCs);
|
|
||||||
freeFunc(db->Folders);
|
|
||||||
freeFunc(db->Files);
|
|
||||||
SzArchiveDatabaseInit(db);
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
/* 7zItem.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_ITEM_H
|
|
||||||
#define __7Z_ITEM_H
|
|
||||||
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
#include "7zHeader.h"
|
|
||||||
#include "7zBuffer.h"
|
|
||||||
|
|
||||||
typedef struct _CCoderInfo
|
|
||||||
{
|
|
||||||
UInt32 NumInStreams;
|
|
||||||
UInt32 NumOutStreams;
|
|
||||||
CMethodID MethodID;
|
|
||||||
CSzByteBuffer Properties;
|
|
||||||
}CCoderInfo;
|
|
||||||
|
|
||||||
void SzCoderInfoInit(CCoderInfo *coder);
|
|
||||||
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
|
|
||||||
|
|
||||||
typedef struct _CBindPair
|
|
||||||
{
|
|
||||||
UInt32 InIndex;
|
|
||||||
UInt32 OutIndex;
|
|
||||||
}CBindPair;
|
|
||||||
|
|
||||||
typedef struct _CFolder
|
|
||||||
{
|
|
||||||
UInt32 NumCoders;
|
|
||||||
CCoderInfo *Coders;
|
|
||||||
UInt32 NumBindPairs;
|
|
||||||
CBindPair *BindPairs;
|
|
||||||
UInt32 NumPackStreams;
|
|
||||||
UInt32 *PackStreams;
|
|
||||||
CFileSize *UnPackSizes;
|
|
||||||
int UnPackCRCDefined;
|
|
||||||
UInt32 UnPackCRC;
|
|
||||||
|
|
||||||
UInt32 NumUnPackStreams;
|
|
||||||
}CFolder;
|
|
||||||
|
|
||||||
void SzFolderInit(CFolder *folder);
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder);
|
|
||||||
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
|
|
||||||
UInt32 SzFolderGetNumOutStreams(CFolder *folder);
|
|
||||||
CFileSize SzFolderGetUnPackSize(CFolder *folder);
|
|
||||||
|
|
||||||
/* #define CArchiveFileTime UInt64 */
|
|
||||||
|
|
||||||
typedef struct _CFileItem
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
CArchiveFileTime LastWriteTime;
|
|
||||||
CFileSize StartPos;
|
|
||||||
UInt32 Attributes;
|
|
||||||
*/
|
|
||||||
CFileSize Size;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
char *Name;
|
|
||||||
|
|
||||||
Byte IsFileCRCDefined;
|
|
||||||
Byte HasStream;
|
|
||||||
Byte IsDirectory;
|
|
||||||
Byte IsAnti;
|
|
||||||
/*
|
|
||||||
int AreAttributesDefined;
|
|
||||||
int IsLastWriteTimeDefined;
|
|
||||||
int IsStartPosDefined;
|
|
||||||
*/
|
|
||||||
}CFileItem;
|
|
||||||
|
|
||||||
void SzFileInit(CFileItem *fileItem);
|
|
||||||
|
|
||||||
typedef struct _CArchiveDatabase
|
|
||||||
{
|
|
||||||
UInt32 NumPackStreams;
|
|
||||||
CFileSize *PackSizes;
|
|
||||||
int *PackCRCsDefined;
|
|
||||||
UInt32 *PackCRCs;
|
|
||||||
UInt32 NumFolders;
|
|
||||||
CFolder *Folders;
|
|
||||||
UInt32 NumFiles;
|
|
||||||
CFileItem *Files;
|
|
||||||
}CArchiveDatabase;
|
|
||||||
|
|
||||||
void SzArchiveDatabaseInit(CArchiveDatabase *db);
|
|
||||||
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
/*
|
|
||||||
7zMain.c
|
|
||||||
Test application for 7z Decoder
|
|
||||||
LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-09-24)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "7zCrc.h"
|
|
||||||
#include "7zIn.h"
|
|
||||||
#include "7zExtract.h"
|
|
||||||
|
|
||||||
typedef struct _CFileInStream
|
|
||||||
{
|
|
||||||
ISzInStream InStream;
|
|
||||||
FILE *File;
|
|
||||||
} CFileInStream;
|
|
||||||
|
|
||||||
#ifdef _LZMA_IN_CB
|
|
||||||
|
|
||||||
#define kBufferSize (1 << 12)
|
|
||||||
Byte g_Buffer[kBufferSize];
|
|
||||||
|
|
||||||
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
|
|
||||||
{
|
|
||||||
CFileInStream *s = (CFileInStream *)object;
|
|
||||||
size_t processedSizeLoc;
|
|
||||||
if (maxRequiredSize > kBufferSize)
|
|
||||||
maxRequiredSize = kBufferSize;
|
|
||||||
processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File);
|
|
||||||
*buffer = g_Buffer;
|
|
||||||
if (processedSize != 0)
|
|
||||||
*processedSize = processedSizeLoc;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
|
|
||||||
{
|
|
||||||
CFileInStream *s = (CFileInStream *)object;
|
|
||||||
size_t processedSizeLoc = fread(buffer, 1, size, s->File);
|
|
||||||
if (processedSize != 0)
|
|
||||||
*processedSize = processedSizeLoc;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
|
|
||||||
{
|
|
||||||
CFileInStream *s = (CFileInStream *)object;
|
|
||||||
int res = fseek(s->File, (long)pos, SEEK_SET);
|
|
||||||
if (res == 0)
|
|
||||||
return SZ_OK;
|
|
||||||
return SZE_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintError(char *sz)
|
|
||||||
{
|
|
||||||
printf("\nERROR: %s\n", sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int numargs, char *args[])
|
|
||||||
{
|
|
||||||
CFileInStream archiveStream;
|
|
||||||
CArchiveDatabaseEx db;
|
|
||||||
SZ_RESULT res;
|
|
||||||
ISzAlloc allocImp;
|
|
||||||
ISzAlloc allocTempImp;
|
|
||||||
|
|
||||||
printf("\n7z ANSI-C Decoder 4.16 Copyright (c) 1999-2005 Igor Pavlov 2005-03-29\n");
|
|
||||||
if (numargs == 1)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"\nUsage: 7zDec <command> <archive_name>\n\n"
|
|
||||||
"<Commands>\n"
|
|
||||||
" e: Extract files from archive\n"
|
|
||||||
" l: List contents of archive\n"
|
|
||||||
" t: Test integrity of archive\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (numargs < 3)
|
|
||||||
{
|
|
||||||
PrintError("incorrect command");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
archiveStream.File = fopen(args[2], "rb");
|
|
||||||
if (archiveStream.File == 0)
|
|
||||||
{
|
|
||||||
PrintError("can not open input file");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
archiveStream.InStream.Read = SzFileReadImp;
|
|
||||||
archiveStream.InStream.Seek = SzFileSeekImp;
|
|
||||||
|
|
||||||
allocImp.Alloc = SzAlloc;
|
|
||||||
allocImp.Free = SzFree;
|
|
||||||
|
|
||||||
allocTempImp.Alloc = SzAllocTemp;
|
|
||||||
allocTempImp.Free = SzFreeTemp;
|
|
||||||
|
|
||||||
InitCrcTable();
|
|
||||||
SzArDbExInit(&db);
|
|
||||||
res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
char *command = args[1];
|
|
||||||
int listCommand = 0;
|
|
||||||
int testCommand = 0;
|
|
||||||
int extractCommand = 0;
|
|
||||||
if (strcmp(command, "l") == 0)
|
|
||||||
listCommand = 1;
|
|
||||||
if (strcmp(command, "t") == 0)
|
|
||||||
testCommand = 1;
|
|
||||||
else if (strcmp(command, "e") == 0)
|
|
||||||
extractCommand = 1;
|
|
||||||
|
|
||||||
if (listCommand)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < db.Database.NumFiles; i++)
|
|
||||||
{
|
|
||||||
CFileItem *f = db.Database.Files + i;
|
|
||||||
printf("%10d %s\n", (int)f->Size, f->Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (testCommand || extractCommand)
|
|
||||||
{
|
|
||||||
UInt32 i;
|
|
||||||
UInt32 blockIndex;
|
|
||||||
Byte *outBuffer = 0;
|
|
||||||
size_t outBufferSize;
|
|
||||||
printf("\n");
|
|
||||||
for (i = 0; i < db.Database.NumFiles; i++)
|
|
||||||
{
|
|
||||||
size_t offset;
|
|
||||||
size_t outSizeProcessed;
|
|
||||||
CFileItem *f = db.Database.Files + i;
|
|
||||||
printf(testCommand ?
|
|
||||||
"Tesing ":
|
|
||||||
"Extracting");
|
|
||||||
printf(" %s", f->Name);
|
|
||||||
res = SzExtract(&archiveStream.InStream, &db, i,
|
|
||||||
&blockIndex, &outBuffer, &outBufferSize,
|
|
||||||
&offset, &outSizeProcessed,
|
|
||||||
&allocImp, &allocTempImp);
|
|
||||||
if (res != SZ_OK)
|
|
||||||
break;
|
|
||||||
if (!testCommand)
|
|
||||||
{
|
|
||||||
FILE *outputHandle;
|
|
||||||
UInt32 processedSize;
|
|
||||||
char *fileName = f->Name;
|
|
||||||
size_t nameLen = strlen(f->Name);
|
|
||||||
for (; nameLen > 0; nameLen--)
|
|
||||||
if (f->Name[nameLen - 1] == '/')
|
|
||||||
{
|
|
||||||
fileName = f->Name + nameLen;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
outputHandle = fopen(fileName, "wb+");
|
|
||||||
if (outputHandle == 0)
|
|
||||||
{
|
|
||||||
PrintError("can not open output file");
|
|
||||||
res = SZE_FAIL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
|
|
||||||
if (processedSize != outSizeProcessed)
|
|
||||||
{
|
|
||||||
PrintError("can not write output file");
|
|
||||||
res = SZE_FAIL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (fclose(outputHandle))
|
|
||||||
{
|
|
||||||
PrintError("can not close output file");
|
|
||||||
res = SZE_FAIL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
allocImp.Free(outBuffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PrintError("incorrect command");
|
|
||||||
res = SZE_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SzArDbExFree(&db, allocImp.Free);
|
|
||||||
|
|
||||||
fclose(archiveStream.File);
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
printf("\nEverything is Ok\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (res == SZE_OUTOFMEMORY)
|
|
||||||
PrintError("can not allocate memory");
|
|
||||||
else
|
|
||||||
printf("\nERROR #%d\n", res);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/* 7zMethodID.c */
|
|
||||||
|
|
||||||
#include "7zMethodID.h"
|
|
||||||
|
|
||||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (a1->IDSize != a2->IDSize)
|
|
||||||
return 0;
|
|
||||||
for (i = 0; i < a1->IDSize; i++)
|
|
||||||
if (a1->ID[i] != a2->ID[i])
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
/* 7zMethodID.h */
|
|
||||||
|
|
||||||
#ifndef __7Z_METHOD_ID_H
|
|
||||||
#define __7Z_METHOD_ID_H
|
|
||||||
|
|
||||||
#include "7zTypes.h"
|
|
||||||
|
|
||||||
#define kMethodIDSize 15
|
|
||||||
|
|
||||||
typedef struct _CMethodID
|
|
||||||
{
|
|
||||||
Byte ID[kMethodIDSize];
|
|
||||||
Byte IDSize;
|
|
||||||
} CMethodID;
|
|
||||||
|
|
||||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/* 7zTypes.h */
|
|
||||||
|
|
||||||
#ifndef __COMMON_TYPES_H
|
|
||||||
#define __COMMON_TYPES_H
|
|
||||||
|
|
||||||
#ifndef UInt32
|
|
||||||
#ifdef _LZMA_UINT32_IS_ULONG
|
|
||||||
#define UInt32 unsigned long
|
|
||||||
#else
|
|
||||||
#define UInt32 unsigned int
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Byte
|
|
||||||
#define Byte unsigned char
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UInt16
|
|
||||||
#define UInt16 unsigned short
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* #define _SZ_NO_INT_64 */
|
|
||||||
/* define it your compiler doesn't support long long int */
|
|
||||||
|
|
||||||
#ifdef _SZ_NO_INT_64
|
|
||||||
#define UInt64 unsigned long
|
|
||||||
#else
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#define UInt64 unsigned __int64
|
|
||||||
#else
|
|
||||||
#define UInt64 unsigned long long int
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* #define _SZ_FILE_SIZE_64 */
|
|
||||||
/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/
|
|
||||||
|
|
||||||
#ifndef CFileSize
|
|
||||||
#ifdef _SZ_FILE_SIZE_64
|
|
||||||
#define CFileSize UInt64
|
|
||||||
#else
|
|
||||||
#define CFileSize UInt32
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SZ_RESULT int
|
|
||||||
|
|
||||||
#define SZ_OK (0)
|
|
||||||
#define SZE_DATA_ERROR (1)
|
|
||||||
#define SZE_OUTOFMEMORY (2)
|
|
||||||
#define SZE_CRC_ERROR (3)
|
|
||||||
|
|
||||||
#define SZE_NOTIMPL (4)
|
|
||||||
#define SZE_FAIL (5)
|
|
||||||
|
|
||||||
#define SZE_ARCHIVE_ERROR (6)
|
|
||||||
|
|
||||||
#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; }
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
PROG = 7zDec
|
|
||||||
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
|
|
||||||
|
|
||||||
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,7 +0,0 @@
|
|||||||
; Arj.def
|
|
||||||
|
|
||||||
LIBRARY Arj.dll
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
CreateObject PRIVATE
|
|
||||||
GetHandlerProperty PRIVATE
|
|
||||||
@@ -1,317 +0,0 @@
|
|||||||
# Microsoft Developer Studio Project File - Name="arj" - Package Owner=<4>
|
|
||||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
|
||||||
# ** DO NOT EDIT **
|
|
||||||
|
|
||||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
|
||||||
|
|
||||||
CFG=arj - Win32 Debug
|
|
||||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
|
||||||
!MESSAGE use the Export Makefile command and run
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "arj.mak".
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE You can specify a configuration when running NMAKE
|
|
||||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "arj.mak" CFG="arj - Win32 Debug"
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE Possible choices for configuration are:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE "arj - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE "arj - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE
|
|
||||||
|
|
||||||
# Begin Project
|
|
||||||
# PROP AllowPerConfigDependencies 0
|
|
||||||
# PROP Scc_ProjName ""
|
|
||||||
# PROP Scc_LocalPath ""
|
|
||||||
CPP=cl.exe
|
|
||||||
MTL=midl.exe
|
|
||||||
RSC=rc.exe
|
|
||||||
|
|
||||||
!IF "$(CFG)" == "arj - Win32 Release"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
|
||||||
# PROP BASE Output_Dir "Release"
|
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 0
|
|
||||||
# PROP Output_Dir "Release"
|
|
||||||
# PROP Intermediate_Dir "Release"
|
|
||||||
# PROP Ignore_Export_Lib 1
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /YX /FD /c
|
|
||||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /c
|
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
|
||||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\arj.dll" /opt:NOWIN98
|
|
||||||
# SUBTRACT LINK32 /pdb:none
|
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "arj - Win32 Debug"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
|
||||||
# PROP BASE Output_Dir "Debug"
|
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 1
|
|
||||||
# PROP Output_Dir "Debug"
|
|
||||||
# PROP Intermediate_Dir "Debug"
|
|
||||||
# PROP Ignore_Export_Lib 1
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /YX /FD /GZ /c
|
|
||||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
|
||||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\arj.dll" /pdbtype:sept
|
|
||||||
|
|
||||||
!ENDIF
|
|
||||||
|
|
||||||
# Begin Target
|
|
||||||
|
|
||||||
# Name "arj - Win32 Release"
|
|
||||||
# Name "arj - Win32 Debug"
|
|
||||||
# Begin Group "spec"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\arj.def
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\DllExports.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.rc
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\StdAfx.cpp
|
|
||||||
# ADD CPP /Yc
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\StdAfx.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Common"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Alloc.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Alloc.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\CRC.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\CRC.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\NewHandler.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\String.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\String.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringConvert.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Vector.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Vector.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Windows"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Windows\PropVariant.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Engine"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\ArjHandler.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\ArjHandler.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\ArjHeader.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\ArjIn.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\ArjIn.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\ArjItem.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Compress"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Group "Codecs"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Arj\Decoder1.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Arj\Decoder1.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Arj\Decoder2.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Arj\Decoder2.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "LZ"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\LZ\LZOutWindow.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Copy"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# End Group
|
|
||||||
# Begin Group "7zip common"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\InBuffer.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\InBuffer.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\LimitedStreams.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\LimitedStreams.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\MSBFDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Archive Common"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\ItemNameUtils.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\ItemNameUtils.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\OutStreamWithCRC.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\OutStreamWithCRC.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\arj.ico
|
|
||||||
# End Source File
|
|
||||||
# End Target
|
|
||||||
# End Project
|
|
||||||
@@ -1,482 +0,0 @@
|
|||||||
// ArjHandler.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/CRC.h"
|
|
||||||
#include "Common/StringConvert.h"
|
|
||||||
#include "Common/ComTry.h"
|
|
||||||
|
|
||||||
#include "Windows/Time.h"
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#include "ArjHandler.h"
|
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
#include "../../Common/StreamObjects.h"
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
|
||||||
#include "../../Common/LimitedStreams.h"
|
|
||||||
|
|
||||||
#include "../../Compress/Copy/CopyCoder.h"
|
|
||||||
#include "../../Compress/Arj/Decoder1.h"
|
|
||||||
#include "../../Compress/Arj/Decoder2.h"
|
|
||||||
|
|
||||||
#include "../Common/ItemNameUtils.h"
|
|
||||||
#include "../Common/OutStreamWithCRC.h"
|
|
||||||
|
|
||||||
using namespace NWindows;
|
|
||||||
using namespace NTime;
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj{
|
|
||||||
|
|
||||||
const wchar_t *kHostOS[] =
|
|
||||||
{
|
|
||||||
L"MSDOS",
|
|
||||||
L"PRIMOS",
|
|
||||||
L"Unix",
|
|
||||||
L"AMIGA",
|
|
||||||
L"Mac",
|
|
||||||
L"OS/2",
|
|
||||||
L"APPLE GS",
|
|
||||||
L"Atari ST",
|
|
||||||
L"Next",
|
|
||||||
L"VAX VMS",
|
|
||||||
L"WIN95"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
|
||||||
|
|
||||||
const wchar_t *kUnknownOS = L"Unknown";
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
enum // PropID
|
|
||||||
{
|
|
||||||
kpidHostOS = kpidUserDefined,
|
|
||||||
kpidUnPackVersion,
|
|
||||||
kpidMethod,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
STATPROPSTG kProperties[] =
|
|
||||||
{
|
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
|
||||||
{ NULL, kpidIsFolder, VT_BOOL},
|
|
||||||
{ NULL, kpidSize, VT_UI8},
|
|
||||||
{ NULL, kpidPackedSize, VT_UI8},
|
|
||||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
|
||||||
{ NULL, kpidAttributes, VT_UI4},
|
|
||||||
|
|
||||||
{ NULL, kpidEncrypted, VT_BOOL},
|
|
||||||
// { NULL, kpidCommented, VT_BOOL},
|
|
||||||
|
|
||||||
{ NULL, kpidCRC, VT_UI4},
|
|
||||||
|
|
||||||
{ NULL, kpidMethod, VT_UI1},
|
|
||||||
{ NULL, kpidHostOS, VT_BSTR}
|
|
||||||
|
|
||||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
|
|
||||||
// { L"Method", kpidMethod, VT_UI1},
|
|
||||||
// { L"Host OS", kpidHostOS, VT_BSTR}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
CHandler::CHandler()
|
|
||||||
{}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
value->vt = VT_EMPTY;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
|
||||||
{
|
|
||||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
|
||||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const STATPROPSTG &srcItem = kProperties[index];
|
|
||||||
*propID = srcItem.propid;
|
|
||||||
*varType = srcItem.vt;
|
|
||||||
*name = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
|
||||||
{
|
|
||||||
*numProperties = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|
||||||
{
|
|
||||||
*numItems = _items.Size();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
const CItemEx &item = _items[index];
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case kpidPath:
|
|
||||||
propVariant =
|
|
||||||
NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
|
||||||
/*
|
|
||||||
NItemName::GetOSName2(
|
|
||||||
MultiByteToUnicodeString(item.Name, item.GetCodePage()));
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case kpidIsFolder:
|
|
||||||
propVariant = item.IsDirectory();
|
|
||||||
break;
|
|
||||||
case kpidSize:
|
|
||||||
propVariant = item.Size;
|
|
||||||
break;
|
|
||||||
case kpidPackedSize:
|
|
||||||
propVariant = item.PackSize;
|
|
||||||
break;
|
|
||||||
case kpidLastWriteTime:
|
|
||||||
{
|
|
||||||
FILETIME localFileTime, utcFileTime;
|
|
||||||
if (DosTimeToFileTime(item.ModifiedTime, localFileTime))
|
|
||||||
{
|
|
||||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
|
||||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
|
||||||
propVariant = utcFileTime;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kpidAttributes:
|
|
||||||
propVariant = item.GetWinAttributes();
|
|
||||||
break;
|
|
||||||
case kpidEncrypted:
|
|
||||||
propVariant = item.IsEncrypted();
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
case kpidCommented:
|
|
||||||
propVariant = item.IsCommented();
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
case kpidCRC:
|
|
||||||
propVariant = item.FileCRC;
|
|
||||||
break;
|
|
||||||
case kpidMethod:
|
|
||||||
propVariant = item.Method;
|
|
||||||
break;
|
|
||||||
case kpidHostOS:
|
|
||||||
propVariant = (item.HostOS < kNumHostOSes) ?
|
|
||||||
(kHostOS[item.HostOS]) : kUnknownOS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
propVariant.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
class CPropgressImp: public CProgressVirt
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CMyComPtr<IArchiveOpenCallback> Callback;
|
|
||||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
|
||||||
};
|
|
||||||
|
|
||||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
|
||||||
{
|
|
||||||
if (Callback)
|
|
||||||
return Callback->SetCompleted(numFiles, NULL);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|
||||||
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_items.Clear();
|
|
||||||
CInArchive archive;
|
|
||||||
if(!archive.Open(inStream, maxCheckStartPosition))
|
|
||||||
return S_FALSE;
|
|
||||||
if (callback != NULL)
|
|
||||||
{
|
|
||||||
RINOK(callback->SetTotal(NULL, NULL));
|
|
||||||
UInt64 numFiles = _items.Size();
|
|
||||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
|
||||||
}
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
CItemEx itemInfo;
|
|
||||||
bool filled;
|
|
||||||
HRESULT result = archive.GetNextItem(filled, itemInfo);
|
|
||||||
if (result == S_FALSE)
|
|
||||||
return S_FALSE;
|
|
||||||
if (result != S_OK)
|
|
||||||
return S_FALSE;
|
|
||||||
if (!filled)
|
|
||||||
break;
|
|
||||||
_items.Add(itemInfo);
|
|
||||||
archive.IncreaseRealPosition(itemInfo.PackSize);
|
|
||||||
if (callback != NULL)
|
|
||||||
{
|
|
||||||
UInt64 numFiles = _items.Size();
|
|
||||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_stream = inStream;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
COM_TRY_END
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Close()
|
|
||||||
{
|
|
||||||
_stream.Release();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// CHandler::DecompressItems
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
bool testMode = (testModeSpec != 0);
|
|
||||||
UInt64 totalUnPacked = 0, totalPacked = 0;
|
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
|
||||||
numItems = _items.Size();
|
|
||||||
if(numItems == 0)
|
|
||||||
return S_OK;
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < numItems; i++)
|
|
||||||
{
|
|
||||||
const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]];
|
|
||||||
totalUnPacked += itemInfo.Size;
|
|
||||||
totalPacked += itemInfo.PackSize;
|
|
||||||
}
|
|
||||||
extractCallback->SetTotal(totalUnPacked);
|
|
||||||
|
|
||||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
|
||||||
UInt64 currentItemUnPacked, currentItemPacked;
|
|
||||||
|
|
||||||
CMyComPtr<ICompressCoder> arj1Decoder;
|
|
||||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
|
||||||
CMyComPtr<ICompressCoder> copyCoder;
|
|
||||||
|
|
||||||
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
|
||||||
currentTotalPacked += currentItemPacked)
|
|
||||||
{
|
|
||||||
currentItemUnPacked = 0;
|
|
||||||
currentItemPacked = 0;
|
|
||||||
|
|
||||||
RINOK(extractCallback->SetCompleted(¤tTotalUnPacked));
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
|
||||||
Int32 askMode;
|
|
||||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
|
||||||
const CItemEx &itemInfo = _items[index];
|
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
|
||||||
|
|
||||||
if(itemInfo.IsDirectory())
|
|
||||||
{
|
|
||||||
// if (!testMode)
|
|
||||||
{
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
|
||||||
currentItemUnPacked = itemInfo.Size;
|
|
||||||
currentItemPacked = itemInfo.PackSize;
|
|
||||||
|
|
||||||
{
|
|
||||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
|
||||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
|
||||||
outStreamSpec->Init(realOutStream);
|
|
||||||
realOutStream.Release();
|
|
||||||
|
|
||||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
|
||||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
|
||||||
|
|
||||||
UInt64 pos;
|
|
||||||
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
|
|
||||||
|
|
||||||
streamSpec->Init(_stream, itemInfo.PackSize);
|
|
||||||
|
|
||||||
|
|
||||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
|
||||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
|
||||||
localProgressSpec->Init(extractCallback, false);
|
|
||||||
|
|
||||||
|
|
||||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
|
||||||
new CLocalCompressProgressInfo;
|
|
||||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
|
||||||
localCompressProgressSpec->Init(progress,
|
|
||||||
¤tTotalPacked,
|
|
||||||
¤tTotalUnPacked);
|
|
||||||
|
|
||||||
if (itemInfo.IsEncrypted())
|
|
||||||
{
|
|
||||||
RINOK(extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT result;
|
|
||||||
|
|
||||||
switch(itemInfo.Method)
|
|
||||||
{
|
|
||||||
case NFileHeader::NCompressionMethod::kStored:
|
|
||||||
{
|
|
||||||
if(!copyCoder)
|
|
||||||
copyCoder = new NCompress::CCopyCoder;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (itemInfo.IsEncrypted())
|
|
||||||
{
|
|
||||||
RINOK(extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = copyCoder->Code(inStream, outStream,
|
|
||||||
NULL, NULL, compressProgress);
|
|
||||||
}
|
|
||||||
if (result == S_FALSE)
|
|
||||||
throw "data error";
|
|
||||||
if (result != S_OK)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
outStream.Release();
|
|
||||||
RINOK(extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NFileHeader::NCompressionMethod::kCompressed1a:
|
|
||||||
case NFileHeader::NCompressionMethod::kCompressed1b:
|
|
||||||
case NFileHeader::NCompressionMethod::kCompressed1c:
|
|
||||||
{
|
|
||||||
if(!arj1Decoder)
|
|
||||||
{
|
|
||||||
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (itemInfo.IsEncrypted())
|
|
||||||
{
|
|
||||||
RINOK(extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = arj1Decoder->Code(inStream, outStream,
|
|
||||||
NULL, ¤tItemUnPacked, compressProgress);
|
|
||||||
}
|
|
||||||
if (result == S_FALSE)
|
|
||||||
throw "data error";
|
|
||||||
if (result != S_OK)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
outStream.Release();
|
|
||||||
RINOK(extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NFileHeader::NCompressionMethod::kCompressed2:
|
|
||||||
{
|
|
||||||
if(!arj2Decoder)
|
|
||||||
{
|
|
||||||
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (itemInfo.IsEncrypted())
|
|
||||||
{
|
|
||||||
RINOK(extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = arj2Decoder->Code(inStream, outStream,
|
|
||||||
NULL, ¤tItemUnPacked, compressProgress);
|
|
||||||
}
|
|
||||||
if (result == S_FALSE)
|
|
||||||
throw "data error";
|
|
||||||
if (result != S_OK)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
outStream.Release();
|
|
||||||
RINOK(extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
RINOK(extractCallback->SetOperationResult(
|
|
||||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bool crcOK = outStreamSpec->GetCRC() == itemInfo.FileCRC;
|
|
||||||
outStream.Release();
|
|
||||||
if(crcOK)
|
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
|
|
||||||
else
|
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
// ArjHandler.h
|
|
||||||
|
|
||||||
#ifndef __ARJ_HANDLER_H
|
|
||||||
#define __ARJ_HANDLER_H
|
|
||||||
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "../IArchive.h"
|
|
||||||
#include "ArjIn.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
class CHandler:
|
|
||||||
public IInArchive,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
STDMETHOD(Open)(IInStream *inStream,
|
|
||||||
const UInt64 *maxCheckStartPosition,
|
|
||||||
IArchiveOpenCallback *callback);
|
|
||||||
STDMETHOD(Close)();
|
|
||||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
|
|
||||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
|
||||||
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 testMode, IArchiveExtractCallback *anExtractCallback);
|
|
||||||
|
|
||||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
|
||||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
|
||||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
|
||||||
|
|
||||||
CHandler();
|
|
||||||
private:
|
|
||||||
CObjectVector<CItemEx> _items;
|
|
||||||
CMyComPtr<IInStream> _stream;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
// Archive/Arj/Header.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_ARJ_HEADER_H
|
|
||||||
#define __ARCHIVE_ARJ_HEADER_H
|
|
||||||
|
|
||||||
#include "Common/Types.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
const int kMaxBlockSize = 2600;
|
|
||||||
|
|
||||||
namespace NSignature
|
|
||||||
{
|
|
||||||
const Byte kSig0 = 0x60;
|
|
||||||
const Byte kSig1 = 0xEA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct CArchiveHeader
|
|
||||||
{
|
|
||||||
// UInt16 BasicHeaderSize;
|
|
||||||
Byte FirstHeaderSize;
|
|
||||||
Byte Version;
|
|
||||||
Byte ExtractVersion;
|
|
||||||
Byte HostOS;
|
|
||||||
Byte Flags;
|
|
||||||
Byte SecuryVersion;
|
|
||||||
Byte FileType;
|
|
||||||
Byte Reserved;
|
|
||||||
UInt32 CreatedTime;
|
|
||||||
UInt32 ModifiedTime;
|
|
||||||
UInt32 ArchiveSize;
|
|
||||||
UInt32 SecurityEnvelopeFilePosition;
|
|
||||||
UInt16 FilespecPositionInFilename;
|
|
||||||
UInt16 LengthOfSecurityEnvelopeSata;
|
|
||||||
Byte EncryptionVersion;
|
|
||||||
Byte LastChapter;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace NFileHeader
|
|
||||||
{
|
|
||||||
namespace NCompressionMethod
|
|
||||||
{
|
|
||||||
enum EType
|
|
||||||
{
|
|
||||||
kStored = 0,
|
|
||||||
kCompressed1a = 1,
|
|
||||||
kCompressed1b = 2,
|
|
||||||
kCompressed1c = 3,
|
|
||||||
kCompressed2 = 4,
|
|
||||||
kNoDataNoCRC = 8,
|
|
||||||
kNoData = 9,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
namespace NFileType
|
|
||||||
{
|
|
||||||
enum EType
|
|
||||||
{
|
|
||||||
kBinary = 0,
|
|
||||||
k7BitText = 1,
|
|
||||||
kDirectory = 3,
|
|
||||||
kVolumeLablel = 4,
|
|
||||||
kChapterLabel = 5,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
namespace NFlags
|
|
||||||
{
|
|
||||||
const Byte kGarbled = 1;
|
|
||||||
const Byte kVolume = 4;
|
|
||||||
const Byte kExtFile = 8;
|
|
||||||
const Byte kPathSym = 0x10;
|
|
||||||
const Byte kBackup= 0x20;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct CHeader
|
|
||||||
{
|
|
||||||
Byte FirstHeaderSize;
|
|
||||||
Byte Version;
|
|
||||||
Byte ExtractVersion;
|
|
||||||
Byte HostOS;
|
|
||||||
Byte Flags;
|
|
||||||
Byte Method;
|
|
||||||
Byte FileType;
|
|
||||||
Byte Reserved;
|
|
||||||
UInt32 ModifiedTime;
|
|
||||||
UInt32 PackSize;
|
|
||||||
UInt32 Size;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
UInt16 FilespecPositionInFilename;
|
|
||||||
UInt16 FileAccessMode;
|
|
||||||
Byte FirstChapter;
|
|
||||||
Byte LastChapter;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace NHostOS
|
|
||||||
{
|
|
||||||
enum EEnum
|
|
||||||
{
|
|
||||||
kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32
|
|
||||||
// pkarj 2.50 (FAT / VFAT / FAT32 file systems)
|
|
||||||
kPRIMOS = 1,
|
|
||||||
kUnix = 2, // VAX/VMS
|
|
||||||
kAMIGA = 3,
|
|
||||||
kMac = 4,
|
|
||||||
kOS_2 = 5, // what if it's a minix filesystem? [cjh]
|
|
||||||
kAPPLE_GS = 6, // filesystem used by OS/2 (and NT 3.x)
|
|
||||||
kAtari_ST = 7,
|
|
||||||
kNext = 8,
|
|
||||||
kVAX_VMS = 9,
|
|
||||||
kWIN95 = 10
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,281 +0,0 @@
|
|||||||
// Archive/arj/InEngine.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/StringConvert.h"
|
|
||||||
#include "Common/Buffer.h"
|
|
||||||
#include "Common/CRC.h"
|
|
||||||
|
|
||||||
#include "ArjIn.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
IncreasePositionValue(realProcessedSize);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline UInt16 GetUInt16FromMemLE(const Byte *p)
|
|
||||||
{
|
|
||||||
return p[0] | (((UInt32)p[1]) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
|
|
||||||
{
|
|
||||||
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool TestMarkerCandidate(const void *testBytes, UInt32 maxSize)
|
|
||||||
{
|
|
||||||
if (maxSize < 2 + 2 + 4)
|
|
||||||
return false;
|
|
||||||
const Byte *block = ((const Byte *)(testBytes));
|
|
||||||
if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1)
|
|
||||||
return false;
|
|
||||||
UInt32 blockSize = GetUInt16FromMemLE(block + 2);
|
|
||||||
if (maxSize < 2 + 2 + blockSize + 4)
|
|
||||||
return false;
|
|
||||||
block += 4;
|
|
||||||
if (blockSize == 0 || blockSize > 2600)
|
|
||||||
return false;
|
|
||||||
UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize);
|
|
||||||
return (CCRC::VerifyDigest(crcFromFile, block, blockSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
|
|
||||||
{
|
|
||||||
// _archiveInfo.StartPosition = 0;
|
|
||||||
_position = _streamStartPosition;
|
|
||||||
if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4;
|
|
||||||
|
|
||||||
CByteBuffer byteBuffer;
|
|
||||||
static const UInt32 kSearchMarkerBufferSize = 0x10000;
|
|
||||||
byteBuffer.SetCapacity(kSearchMarkerBufferSize);
|
|
||||||
Byte *buffer = byteBuffer;
|
|
||||||
|
|
||||||
UInt32 processedSize;
|
|
||||||
ReadBytes(buffer, kMarkerSizeMax, &processedSize);
|
|
||||||
if (processedSize == 0)
|
|
||||||
return false;
|
|
||||||
if (TestMarkerCandidate(buffer, processedSize))
|
|
||||||
{
|
|
||||||
_position = _streamStartPosition;
|
|
||||||
if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 numBytesPrev = processedSize - 1;
|
|
||||||
memmove(buffer, buffer + 1, numBytesPrev);
|
|
||||||
UInt64 curTestPos = _streamStartPosition + 1;
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
if (searchHeaderSizeLimit != NULL)
|
|
||||||
if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit)
|
|
||||||
return false;
|
|
||||||
UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
|
|
||||||
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
|
|
||||||
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
|
|
||||||
if (numBytesInBuffer < 1)
|
|
||||||
return false;
|
|
||||||
UInt32 numTests = numBytesInBuffer;
|
|
||||||
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
|
|
||||||
{
|
|
||||||
if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos))
|
|
||||||
{
|
|
||||||
// _archiveInfo.StartPosition = curTestPos;
|
|
||||||
_position = curTestPos;
|
|
||||||
if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
numBytesPrev = numBytesInBuffer - numTests;
|
|
||||||
memmove(buffer, buffer + numTests, numBytesPrev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::IncreasePositionValue(UInt64 addValue)
|
|
||||||
{
|
|
||||||
_position += addValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::IncreaseRealPosition(UInt64 addValue)
|
|
||||||
{
|
|
||||||
if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK)
|
|
||||||
throw CInArchiveException(CInArchiveException::kSeekStreamError);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
if(ReadBytes(data, size, &realProcessedSize) != S_OK)
|
|
||||||
throw CInArchiveException(CInArchiveException::kReadStreamError);
|
|
||||||
return (realProcessedSize == size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::SafeReadBytes(void *data, UInt32 size)
|
|
||||||
{
|
|
||||||
if(!ReadBytesAndTestSize(data, size))
|
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte CInArchive::SafeReadByte()
|
|
||||||
{
|
|
||||||
Byte b;
|
|
||||||
SafeReadBytes(&b, 1);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt16 CInArchive::SafeReadUInt16()
|
|
||||||
{
|
|
||||||
UInt16 value = 0;
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
Byte b = SafeReadByte();
|
|
||||||
value |= (UInt16(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 CInArchive::SafeReadUInt32()
|
|
||||||
{
|
|
||||||
UInt32 value = 0;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
Byte b = SafeReadByte();
|
|
||||||
value |= (UInt32(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::ReadBlock()
|
|
||||||
{
|
|
||||||
_blockPos = 0;
|
|
||||||
_blockSize = SafeReadUInt16();
|
|
||||||
if (_blockSize == 0)
|
|
||||||
return false;
|
|
||||||
SafeReadBytes(_block, _blockSize);
|
|
||||||
UInt32 crcFromFile = SafeReadUInt32();
|
|
||||||
if (!CCRC::VerifyDigest(crcFromFile, _block, _blockSize))
|
|
||||||
throw CInArchiveException(CInArchiveException::kCRCError);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::ReadBlock2()
|
|
||||||
{
|
|
||||||
Byte id[2];
|
|
||||||
ReadBytesAndTestSize(id, 2);
|
|
||||||
if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
|
|
||||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
|
||||||
return ReadBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
|
|
||||||
{
|
|
||||||
_stream = inStream;
|
|
||||||
if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK)
|
|
||||||
return false;
|
|
||||||
_position = _streamStartPosition;
|
|
||||||
if (!FindAndReadMarker(searchHeaderSizeLimit))
|
|
||||||
return false;
|
|
||||||
if (!ReadBlock2())
|
|
||||||
return false;
|
|
||||||
while(true)
|
|
||||||
if (!ReadBlock())
|
|
||||||
break;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::Close()
|
|
||||||
{
|
|
||||||
_stream.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::ThrowIncorrectArchiveException()
|
|
||||||
{
|
|
||||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte CInArchive::ReadByte()
|
|
||||||
{
|
|
||||||
if (_blockPos >= _blockSize)
|
|
||||||
ThrowIncorrectArchiveException();
|
|
||||||
return _block[_blockPos++];
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt16 CInArchive::ReadUInt16()
|
|
||||||
{
|
|
||||||
UInt16 value = 0;
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
Byte b = ReadByte();
|
|
||||||
value |= (UInt16(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 CInArchive::ReadUInt32()
|
|
||||||
{
|
|
||||||
UInt32 value = 0;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
Byte b = ReadByte();
|
|
||||||
value |= (UInt32(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
|
||||||
{
|
|
||||||
filled = false;
|
|
||||||
if (!ReadBlock2())
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
Byte firstHeaderSize = ReadByte();
|
|
||||||
item.Version = ReadByte();
|
|
||||||
item.ExtractVersion = ReadByte();
|
|
||||||
item.HostOS = ReadByte();
|
|
||||||
item.Flags = ReadByte();
|
|
||||||
item.Method = ReadByte();
|
|
||||||
item.FileType = ReadByte();
|
|
||||||
ReadByte(); // Reserved
|
|
||||||
item.ModifiedTime = ReadUInt32();
|
|
||||||
item.PackSize = ReadUInt32();
|
|
||||||
item.Size = ReadUInt32();
|
|
||||||
item.FileCRC = ReadUInt32();
|
|
||||||
ReadUInt16(); // FilespecPositionInFilename
|
|
||||||
item.FileAccessMode = ReadUInt16();
|
|
||||||
ReadByte(); // FirstChapter
|
|
||||||
ReadByte(); // LastChapter
|
|
||||||
|
|
||||||
/*
|
|
||||||
UInt32 extraData;
|
|
||||||
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
|
|
||||||
extraData = GetUInt32FromMemLE(_block + pos);
|
|
||||||
*/
|
|
||||||
_blockPos = firstHeaderSize;
|
|
||||||
|
|
||||||
for (; _blockPos < _blockSize;)
|
|
||||||
item.Name += (char)ReadByte();
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
if (!ReadBlock())
|
|
||||||
break;
|
|
||||||
|
|
||||||
item.DataPosition = _position;
|
|
||||||
|
|
||||||
filled = true;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
// Archive/ArjIn.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_ARJIN_H
|
|
||||||
#define __ARCHIVE_ARJIN_H
|
|
||||||
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "../../IStream.h"
|
|
||||||
|
|
||||||
#include "ArjItem.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
class CInArchiveException
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum CCauseType
|
|
||||||
{
|
|
||||||
kUnexpectedEndOfArchive = 0,
|
|
||||||
kCRCError,
|
|
||||||
kIncorrectArchive,
|
|
||||||
kReadStreamError,
|
|
||||||
kSeekStreamError
|
|
||||||
}
|
|
||||||
Cause;
|
|
||||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
class CProgressVirt
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CInArchive
|
|
||||||
{
|
|
||||||
CMyComPtr<IInStream> _stream;
|
|
||||||
UInt64 _streamStartPosition;
|
|
||||||
UInt64 _position;
|
|
||||||
UInt16 _blockSize;
|
|
||||||
Byte _block[kMaxBlockSize];
|
|
||||||
UInt32 _blockPos;
|
|
||||||
|
|
||||||
|
|
||||||
bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
|
|
||||||
|
|
||||||
bool ReadBlock();
|
|
||||||
bool ReadBlock2();
|
|
||||||
|
|
||||||
Byte ReadByte();
|
|
||||||
UInt16 ReadUInt16();
|
|
||||||
UInt32 ReadUInt32();
|
|
||||||
|
|
||||||
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
bool ReadBytesAndTestSize(void *data, UInt32 size);
|
|
||||||
void SafeReadBytes(void *data, UInt32 size);
|
|
||||||
Byte SafeReadByte();
|
|
||||||
UInt16 SafeReadUInt16();
|
|
||||||
UInt32 SafeReadUInt32();
|
|
||||||
|
|
||||||
void IncreasePositionValue(UInt64 addValue);
|
|
||||||
void ThrowIncorrectArchiveException();
|
|
||||||
|
|
||||||
public:
|
|
||||||
HRESULT GetNextItem(bool &filled, CItemEx &item);
|
|
||||||
|
|
||||||
bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
|
|
||||||
void Close();
|
|
||||||
|
|
||||||
void IncreaseRealPosition(UInt64 addValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
// Archive/ArjItem.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_ARJ_ITEM_H
|
|
||||||
#define __ARCHIVE_ARJ_ITEM_H
|
|
||||||
|
|
||||||
#include "Common/Types.h"
|
|
||||||
#include "Common/String.h"
|
|
||||||
#include "ArjHeader.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
struct CVersion
|
|
||||||
{
|
|
||||||
Byte Version;
|
|
||||||
Byte HostOS;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(const CVersion &v1, const CVersion &v2)
|
|
||||||
{ return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); }
|
|
||||||
inline bool operator!=(const CVersion &v1, const CVersion &v2)
|
|
||||||
{ return !(v1 == v2); }
|
|
||||||
|
|
||||||
class CItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Byte Version;
|
|
||||||
Byte ExtractVersion;
|
|
||||||
Byte HostOS;
|
|
||||||
Byte Flags;
|
|
||||||
Byte Method;
|
|
||||||
Byte FileType;
|
|
||||||
UInt32 ModifiedTime;
|
|
||||||
UInt32 PackSize;
|
|
||||||
UInt32 Size;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
|
|
||||||
// UInt16 FilespecPositionInFilename;
|
|
||||||
UInt16 FileAccessMode;
|
|
||||||
// Byte FirstChapter;
|
|
||||||
// Byte LastChapter;
|
|
||||||
|
|
||||||
AString Name;
|
|
||||||
|
|
||||||
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
|
|
||||||
bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); }
|
|
||||||
UInt32 GetWinAttributes() const
|
|
||||||
{
|
|
||||||
UInt32 winAtrributes;
|
|
||||||
switch(HostOS)
|
|
||||||
{
|
|
||||||
case NFileHeader::NHostOS::kMSDOS:
|
|
||||||
case NFileHeader::NHostOS::kWIN95:
|
|
||||||
winAtrributes = FileAccessMode;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
winAtrributes = 0;
|
|
||||||
}
|
|
||||||
if (IsDirectory())
|
|
||||||
winAtrributes |= FILE_ATTRIBUTE_DIRECTORY;
|
|
||||||
return winAtrributes;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CItemEx: public CItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UInt64 DataPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
// DLLExports.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/MyInitGuid.h"
|
|
||||||
#include "Common/ComTry.h"
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
#include "ArjHandler.h"
|
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-0001100A0000}
|
|
||||||
DEFINE_GUID(CLSID_CArjHandler,
|
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0A, 0x00, 0x00);
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI CreateObject(
|
|
||||||
const GUID *classID,
|
|
||||||
const GUID *interfaceID,
|
|
||||||
void **outObject)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
*outObject = 0;
|
|
||||||
if (*classID != CLSID_CArjHandler)
|
|
||||||
return CLASS_E_CLASSNOTAVAILABLE;
|
|
||||||
if (*interfaceID != IID_IInArchive)
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NArj::CHandler;
|
|
||||||
*outObject = inArchive.Detach();
|
|
||||||
COM_TRY_END
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case NArchive::kName:
|
|
||||||
propVariant = L"Arj";
|
|
||||||
break;
|
|
||||||
case NArchive::kClassID:
|
|
||||||
{
|
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
|
||||||
(const char *)&CLSID_CArjHandler, sizeof(GUID))) != 0)
|
|
||||||
value->vt = VT_BSTR;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case NArchive::kExtension:
|
|
||||||
propVariant = L"arj";
|
|
||||||
break;
|
|
||||||
case NArchive::kAddExtension:
|
|
||||||
propVariant = L".cpio.gz";
|
|
||||||
break;
|
|
||||||
case NArchive::kUpdate:
|
|
||||||
propVariant = false;
|
|
||||||
break;
|
|
||||||
case NArchive::kKeepName:
|
|
||||||
propVariant = false;
|
|
||||||
break;
|
|
||||||
case NArchive::kStartSignature:
|
|
||||||
{
|
|
||||||
const unsigned char sig[] = { 0x60, 0xEA };
|
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0)
|
|
||||||
value->vt = VT_BSTR;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
propVariant.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
@@ -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 +0,0 @@
|
|||||||
//Microsoft Developer Studio generated resource script.
|
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Russian resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
|
||||||
#pragma code_page(1251)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Russian resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "arj.ico"
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 4,13,0,0
|
|
||||||
PRODUCTVERSION 4,13,0,0
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS 0x1L
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS 0x40004L
|
|
||||||
FILETYPE 0x2L
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Comments", "\0"
|
|
||||||
VALUE "CompanyName", "Igor Pavlov\0"
|
|
||||||
VALUE "FileDescription", "Arj Plugin for 7-Zip\0"
|
|
||||||
VALUE "FileVersion", "4, 13, 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, 13, 0, 0\0"
|
|
||||||
VALUE "SpecialBuild", "\0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // !_MAC
|
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
; BZip2.def
|
|
||||||
|
|
||||||
LIBRARY bz2.dll
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
CreateObject PRIVATE
|
|
||||||
GetHandlerProperty PRIVATE
|
|
||||||
|
|
||||||
@@ -1,269 +0,0 @@
|
|||||||
# Microsoft Developer Studio Project File - Name="BZip2" - Package Owner=<4>
|
|
||||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
|
||||||
# ** DO NOT EDIT **
|
|
||||||
|
|
||||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
|
||||||
|
|
||||||
CFG=BZip2 - Win32 Debug
|
|
||||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
|
||||||
!MESSAGE use the Export Makefile command and run
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "BZip2.mak".
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE You can specify a configuration when running NMAKE
|
|
||||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "BZip2.mak" CFG="BZip2 - Win32 Debug"
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE Possible choices for configuration are:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE "BZip2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE "BZip2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE
|
|
||||||
|
|
||||||
# Begin Project
|
|
||||||
# PROP AllowPerConfigDependencies 0
|
|
||||||
# PROP Scc_ProjName ""
|
|
||||||
# PROP Scc_LocalPath ""
|
|
||||||
CPP=cl.exe
|
|
||||||
MTL=midl.exe
|
|
||||||
RSC=rc.exe
|
|
||||||
|
|
||||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
|
||||||
# PROP BASE Output_Dir "Release"
|
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 0
|
|
||||||
# PROP Output_Dir "Release"
|
|
||||||
# PROP Intermediate_Dir "Release"
|
|
||||||
# PROP Ignore_Export_Lib 1
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c
|
|
||||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /c
|
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
|
||||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\bz2.dll" /opt:NOWIN98
|
|
||||||
# SUBTRACT LINK32 /pdb:none
|
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
|
||||||
# PROP BASE Output_Dir "Debug"
|
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 1
|
|
||||||
# PROP Output_Dir "Debug"
|
|
||||||
# PROP Intermediate_Dir "Debug"
|
|
||||||
# PROP Ignore_Export_Lib 1
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c
|
|
||||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
|
||||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\bz2.dll" /pdbtype:sept
|
|
||||||
|
|
||||||
!ENDIF
|
|
||||||
|
|
||||||
# Begin Target
|
|
||||||
|
|
||||||
# Name "BZip2 - Win32 Release"
|
|
||||||
# Name "BZip2 - Win32 Debug"
|
|
||||||
# Begin Group "Spec"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BZip2.def
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BZip2.ico
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\DllExports.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.rc
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\StdAfx.cpp
|
|
||||||
# ADD CPP /Yc"StdAfx.h"
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\StdAfx.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Common"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Alloc.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Alloc.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\NewHandler.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\String.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\String.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringConvert.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringToInt.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringToInt.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Windows"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Windows\DLL.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Windows\DLL.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Windows\PropVariant.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Compression"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Archive Common"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\CodecsPath.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\CodecsPath.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\CoderLoader.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\DummyOutStream.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\DummyOutStream.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Engine"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BZip2Handler.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BZip2Handler.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BZip2HandlerOut.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BZip2Item.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BZip2Update.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BZip2Update.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "7zip common"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\bz2.ico
|
|
||||||
# End Source File
|
|
||||||
# End Target
|
|
||||||
# End Project
|
|
||||||
@@ -1,275 +0,0 @@
|
|||||||
// BZip2Handler.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "BZip2Handler.h"
|
|
||||||
|
|
||||||
#include "Common/Defs.h"
|
|
||||||
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
|
||||||
// #include "Interface/EnumStatProp.h"
|
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
#include "Windows/Defs.h"
|
|
||||||
#include "Common/ComTry.h"
|
|
||||||
|
|
||||||
#include "../Common/DummyOutStream.h"
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BZIP2
|
|
||||||
#include "../../Compress/BZip2/BZip2Decoder.h"
|
|
||||||
#else
|
|
||||||
// {23170F69-40C1-278B-0402-020000000000}
|
|
||||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
|
||||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
|
||||||
#include "../Common/CoderLoader.h"
|
|
||||||
extern CSysString GetBZip2CodecPath();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace NWindows;
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NBZip2 {
|
|
||||||
|
|
||||||
STATPROPSTG kProperties[] =
|
|
||||||
{
|
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
|
||||||
// { NULL, kpidIsFolder, VT_BOOL},
|
|
||||||
// { NULL, kpidSize, VT_UI8},
|
|
||||||
{ NULL, kpidPackedSize, VT_UI8},
|
|
||||||
};
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
value->vt = VT_EMPTY;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
|
||||||
{
|
|
||||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
|
||||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const STATPROPSTG &srcItem = kProperties[index];
|
|
||||||
*propID = srcItem.propid;
|
|
||||||
*varType = srcItem.vt;
|
|
||||||
*name = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
|
||||||
{
|
|
||||||
*numProperties = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|
||||||
{
|
|
||||||
*numItems = 1;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
if (index != 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case kpidIsFolder:
|
|
||||||
propVariant = false;
|
|
||||||
break;
|
|
||||||
case kpidPackedSize:
|
|
||||||
propVariant = _item.PackSize;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
propVariant.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
|
||||||
const UInt64 *maxCheckStartPosition,
|
|
||||||
IArchiveOpenCallback *openArchiveCallback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
try
|
|
||||||
{
|
|
||||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition));
|
|
||||||
const int kSignatureSize = 3;
|
|
||||||
Byte buffer[kSignatureSize];
|
|
||||||
UInt32 processedSize;
|
|
||||||
RINOK(stream->Read(buffer, kSignatureSize, &processedSize));
|
|
||||||
if (processedSize != kSignatureSize)
|
|
||||||
return S_FALSE;
|
|
||||||
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
|
|
||||||
return S_FALSE;
|
|
||||||
|
|
||||||
UInt64 endPosition;
|
|
||||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition));
|
|
||||||
_item.PackSize = endPosition - _streamStartPosition;
|
|
||||||
|
|
||||||
_stream = stream;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Close()
|
|
||||||
{
|
|
||||||
_stream.Release();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (!allFilesMode)
|
|
||||||
{
|
|
||||||
if (numItems == 0)
|
|
||||||
return S_OK;
|
|
||||||
if (numItems != 1)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
if (indices[0] != 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool testMode = (testModeSpec != 0);
|
|
||||||
|
|
||||||
extractCallback->SetTotal(_item.PackSize);
|
|
||||||
|
|
||||||
UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0;
|
|
||||||
|
|
||||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
|
||||||
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
|
||||||
Int32 askMode;
|
|
||||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
|
||||||
|
|
||||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
|
||||||
|
|
||||||
if(!testMode && !realOutStream)
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
|
|
||||||
extractCallback->PrepareOperation(askMode);
|
|
||||||
|
|
||||||
#ifndef COMPRESS_BZIP2
|
|
||||||
CCoderLibrary lib;
|
|
||||||
#endif
|
|
||||||
CMyComPtr<ICompressCoder> decoder;
|
|
||||||
#ifdef COMPRESS_BZIP2
|
|
||||||
decoder = new NCompress::NBZip2::CDecoder;
|
|
||||||
#else
|
|
||||||
HRESULT loadResult = lib.LoadAndCreateCoder(
|
|
||||||
GetBZip2CodecPath(),
|
|
||||||
CLSID_CCompressBZip2Decoder, &decoder);
|
|
||||||
if (loadResult != S_OK)
|
|
||||||
{
|
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
|
||||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
|
||||||
outStreamSpec->Init(realOutStream);
|
|
||||||
|
|
||||||
realOutStream.Release();
|
|
||||||
|
|
||||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
|
||||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
|
||||||
localProgressSpec->Init(extractCallback, true);
|
|
||||||
|
|
||||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
|
||||||
new CLocalCompressProgressInfo;
|
|
||||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
|
||||||
|
|
||||||
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT result;
|
|
||||||
|
|
||||||
bool firstItem = true;
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
localCompressProgressSpec->Init(progress,
|
|
||||||
¤tTotalPacked,
|
|
||||||
¤tTotalUnPacked);
|
|
||||||
|
|
||||||
const int kSignatureSize = 3;
|
|
||||||
Byte buffer[kSignatureSize];
|
|
||||||
UInt32 processedSize;
|
|
||||||
RINOK(_stream->Read(buffer, kSignatureSize, &processedSize));
|
|
||||||
if (processedSize < kSignatureSize)
|
|
||||||
{
|
|
||||||
if (firstItem)
|
|
||||||
return E_FAIL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
|
|
||||||
{
|
|
||||||
if (firstItem)
|
|
||||||
return E_FAIL;
|
|
||||||
outStream.Release();
|
|
||||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
firstItem = false;
|
|
||||||
|
|
||||||
UInt64 dataStartPos;
|
|
||||||
RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos));
|
|
||||||
|
|
||||||
result = decoder->Code(_stream, outStream, NULL, NULL, compressProgress);
|
|
||||||
|
|
||||||
if (result != S_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
|
|
||||||
decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize,
|
|
||||||
&getInStreamProcessedSize);
|
|
||||||
if (!getInStreamProcessedSize)
|
|
||||||
break;
|
|
||||||
|
|
||||||
UInt64 packSize;
|
|
||||||
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize));
|
|
||||||
UInt64 pos;
|
|
||||||
RINOK(_stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos));
|
|
||||||
currentTotalPacked = pos - _streamStartPosition;
|
|
||||||
}
|
|
||||||
outStream.Release();
|
|
||||||
|
|
||||||
int retResult;
|
|
||||||
if (result == S_OK)
|
|
||||||
retResult = NArchive::NExtract::NOperationResult::kOK;
|
|
||||||
else
|
|
||||||
retResult = NArchive::NExtract::NOperationResult::kDataError;
|
|
||||||
|
|
||||||
RINOK(extractCallback->SetOperationResult(retResult));
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
// BZip2/Handler.h
|
|
||||||
|
|
||||||
#ifndef __BZIP2_HANDLER_H
|
|
||||||
#define __BZIP2_HANDLER_H
|
|
||||||
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "../IArchive.h"
|
|
||||||
#include "BZip2Item.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NBZip2 {
|
|
||||||
|
|
||||||
class CHandler:
|
|
||||||
public IInArchive,
|
|
||||||
public IOutArchive,
|
|
||||||
public ISetProperties,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
CMyComPtr<IInStream> _stream;
|
|
||||||
NArchive::NBZip2::CItem _item;
|
|
||||||
UInt64 _streamStartPosition;
|
|
||||||
|
|
||||||
UInt32 _numPasses;
|
|
||||||
void InitMethodProperties() { _numPasses = 1; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP3(
|
|
||||||
IInArchive,
|
|
||||||
IOutArchive,
|
|
||||||
ISetProperties
|
|
||||||
)
|
|
||||||
|
|
||||||
STDMETHOD(Open)(IInStream *stream,
|
|
||||||
const UInt64 *maxCheckStartPosition,
|
|
||||||
IArchiveOpenCallback *openArchiveCallback);
|
|
||||||
STDMETHOD(Close)();
|
|
||||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
|
|
||||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
|
||||||
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 testMode, IArchiveExtractCallback *extractCallback);
|
|
||||||
|
|
||||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
|
||||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
|
||||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
|
||||||
|
|
||||||
// IOutArchiveHandler
|
|
||||||
|
|
||||||
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
|
|
||||||
IArchiveUpdateCallback *updateCallback);
|
|
||||||
STDMETHOD(GetFileTimeType)(UInt32 *type);
|
|
||||||
|
|
||||||
// ISetProperties
|
|
||||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
|
||||||
|
|
||||||
CHandler() { InitMethodProperties(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
// BZip2/OutHandler.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "BZip2Handler.h"
|
|
||||||
#include "BZip2Update.h"
|
|
||||||
|
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/String.h"
|
|
||||||
#include "Common/StringToInt.h"
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#include "../../Compress/Copy/CopyCoder.h"
|
|
||||||
|
|
||||||
using namespace NWindows;
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NBZip2 {
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
|
||||||
{
|
|
||||||
*type = NFileTimeType::kUnix;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT CopyStreams(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream, IArchiveUpdateCallback *updateCallback)
|
|
||||||
{
|
|
||||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
|
||||||
return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
|
|
||||||
IArchiveUpdateCallback *updateCallback)
|
|
||||||
{
|
|
||||||
if (numItems != 1)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
Int32 newData;
|
|
||||||
Int32 newProperties;
|
|
||||||
UInt32 indexInArchive;
|
|
||||||
if (!updateCallback)
|
|
||||||
return E_FAIL;
|
|
||||||
RINOK(updateCallback->GetUpdateItemInfo(0,
|
|
||||||
&newData, &newProperties, &indexInArchive));
|
|
||||||
|
|
||||||
if (IntToBool(newProperties))
|
|
||||||
{
|
|
||||||
{
|
|
||||||
NCOM::CPropVariant propVariant;
|
|
||||||
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant));
|
|
||||||
if (propVariant.vt == VT_BOOL)
|
|
||||||
{
|
|
||||||
if (propVariant.boolVal != VARIANT_FALSE)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
else if (propVariant.vt != VT_EMPTY)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IntToBool(newData))
|
|
||||||
{
|
|
||||||
UInt64 size;
|
|
||||||
{
|
|
||||||
NCOM::CPropVariant propVariant;
|
|
||||||
RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant));
|
|
||||||
if (propVariant.vt != VT_UI8)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
size = propVariant.uhVal.QuadPart;
|
|
||||||
}
|
|
||||||
return UpdateArchive(size, outStream, 0, _numPasses, updateCallback);
|
|
||||||
}
|
|
||||||
if (indexInArchive != 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
|
|
||||||
return CopyStreams(_stream, outStream, updateCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
|
||||||
{
|
|
||||||
InitMethodProperties();
|
|
||||||
for (int i = 0; i < numProperties; i++)
|
|
||||||
{
|
|
||||||
UString name = UString(names[i]);
|
|
||||||
name.MakeUpper();
|
|
||||||
if (name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
const PROPVARIANT &value = values[i];
|
|
||||||
|
|
||||||
if (name[0] == 'X')
|
|
||||||
{
|
|
||||||
name.Delete(0);
|
|
||||||
UInt32 level = 9;
|
|
||||||
if (value.vt == VT_UI4)
|
|
||||||
{
|
|
||||||
if (!name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
level = value.ulVal;
|
|
||||||
}
|
|
||||||
else if (value.vt == VT_EMPTY)
|
|
||||||
{
|
|
||||||
if(!name.IsEmpty())
|
|
||||||
{
|
|
||||||
const wchar_t *start = name;
|
|
||||||
const wchar_t *end;
|
|
||||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
|
||||||
if (end - start != name.Length())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
level = (UInt32)v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
if (level < 7)
|
|
||||||
_numPasses = 1;
|
|
||||||
else if (level < 9)
|
|
||||||
_numPasses = 2;
|
|
||||||
else
|
|
||||||
_numPasses = 7;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (name.Left(4) == L"PASS")
|
|
||||||
{
|
|
||||||
name.Delete(0, 4);
|
|
||||||
UInt32 numPasses = 1;
|
|
||||||
if (value.vt == VT_UI4)
|
|
||||||
{
|
|
||||||
if (!name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
numPasses = 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;
|
|
||||||
numPasses = (UInt32)v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
if (numPasses < 1 || numPasses > 10)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
_numPasses = numPasses;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
// Archive/BZip2Item.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_BZIP2_ITEM_H
|
|
||||||
#define __ARCHIVE_BZIP2_ITEM_H
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NBZip2 {
|
|
||||||
|
|
||||||
struct CItem
|
|
||||||
{
|
|
||||||
UInt64 PackSize;
|
|
||||||
UInt64 UnPackSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
// BZip2Update.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#include "BZip2Update.h"
|
|
||||||
|
|
||||||
#ifdef COMPRESS_BZIP2
|
|
||||||
#include "../../Compress/BZip2/BZip2Encoder.h"
|
|
||||||
#else
|
|
||||||
// {23170F69-40C1-278B-0402-020000000100}
|
|
||||||
DEFINE_GUID(CLSID_CCompressBZip2Encoder,
|
|
||||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
|
|
||||||
#include "../Common/CoderLoader.h"
|
|
||||||
extern CSysString GetBZip2CodecPath();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NBZip2 {
|
|
||||||
|
|
||||||
HRESULT UpdateArchive(UInt64 unpackSize,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
int indexInClient,
|
|
||||||
UInt32 numPasses,
|
|
||||||
IArchiveUpdateCallback *updateCallback)
|
|
||||||
{
|
|
||||||
RINOK(updateCallback->SetTotal(unpackSize));
|
|
||||||
UInt64 complexity = 0;
|
|
||||||
RINOK(updateCallback->SetCompleted(&complexity));
|
|
||||||
|
|
||||||
CMyComPtr<ISequentialInStream> fileInStream;
|
|
||||||
|
|
||||||
RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
|
|
||||||
|
|
||||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
|
||||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
|
||||||
localProgressSpec->Init(updateCallback, true);
|
|
||||||
|
|
||||||
#ifndef COMPRESS_BZIP2
|
|
||||||
CCoderLibrary lib;
|
|
||||||
#endif
|
|
||||||
CMyComPtr<ICompressCoder> encoder;
|
|
||||||
#ifdef COMPRESS_BZIP2
|
|
||||||
encoder = new NCompress::NBZip2::CEncoder;
|
|
||||||
#else
|
|
||||||
RINOK(lib.LoadAndCreateCoder(GetBZip2CodecPath(),
|
|
||||||
CLSID_CCompressBZip2Encoder, &encoder));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
|
||||||
encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
|
||||||
if (setCoderProperties)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
NWindows::NCOM::CPropVariant properties[2] =
|
|
||||||
{
|
|
||||||
dictionary, numPasses
|
|
||||||
};
|
|
||||||
PROPID propIDs[2] =
|
|
||||||
{
|
|
||||||
NCoderPropID::kDictionarySize,
|
|
||||||
NCoderPropID::kNumPasses,
|
|
||||||
};
|
|
||||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2));
|
|
||||||
*/
|
|
||||||
NWindows::NCOM::CPropVariant property = numPasses;
|
|
||||||
PROPID propID = NCoderPropID::kNumPasses;
|
|
||||||
RINOK(setCoderProperties->SetCoderProperties(&propID, &property, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
|
|
||||||
|
|
||||||
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
// BZip2Update.h
|
|
||||||
|
|
||||||
#ifndef __BZIP2_UPDATE_H
|
|
||||||
#define __BZIP2_UPDATE_H
|
|
||||||
|
|
||||||
#include "../IArchive.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NBZip2 {
|
|
||||||
|
|
||||||
HRESULT UpdateArchive(
|
|
||||||
UInt64 unpackSize,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
int indexInClient,
|
|
||||||
UInt32 numPasses,
|
|
||||||
IArchiveUpdateCallback *updateCallback);
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
// DLLExports.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/MyInitGuid.h"
|
|
||||||
#include "Common/ComTry.h"
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
#include "BZip2Handler.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
// {23170F69-40C1-278B-0402-020000000100}
|
|
||||||
DEFINE_GUID(CLSID_CCompressBZip2Encoder,
|
|
||||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
|
|
||||||
|
|
||||||
// {23170F69-40C1-278B-0402-020000000000}
|
|
||||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
|
||||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-000110070000}
|
|
||||||
DEFINE_GUID(CLSID_CBZip2Handler,
|
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
|
|
||||||
|
|
||||||
HINSTANCE g_hInstance;
|
|
||||||
|
|
||||||
#ifndef COMPRESS_BZIP2
|
|
||||||
#include "../Common/CodecsPath.h"
|
|
||||||
CSysString GetBZip2CodecPath()
|
|
||||||
{
|
|
||||||
return GetCodecsFolderPrefix() + TEXT("BZip2.dll");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
|
||||||
{
|
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
|
||||||
g_hInstance = hInstance;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI CreateObject(
|
|
||||||
const GUID *classID,
|
|
||||||
const GUID *interfaceID,
|
|
||||||
void **outObject)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
*outObject = 0;
|
|
||||||
if (*classID != CLSID_CBZip2Handler)
|
|
||||||
return CLASS_E_CLASSNOTAVAILABLE;
|
|
||||||
int needIn = *interfaceID == IID_IInArchive;
|
|
||||||
int needOut = *interfaceID == IID_IOutArchive;
|
|
||||||
if (needIn || needOut)
|
|
||||||
{
|
|
||||||
NArchive::NBZip2::CHandler *temp = new NArchive::NBZip2::CHandler;
|
|
||||||
if (needIn)
|
|
||||||
{
|
|
||||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
|
|
||||||
*outObject = inArchive.Detach();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
|
|
||||||
*outObject = outArchive.Detach();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
COM_TRY_END
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case NArchive::kName:
|
|
||||||
propVariant = L"BZip2";
|
|
||||||
break;
|
|
||||||
case NArchive::kClassID:
|
|
||||||
{
|
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
|
||||||
(const char *)&CLSID_CBZip2Handler, sizeof(GUID))) != 0)
|
|
||||||
value->vt = VT_BSTR;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case NArchive::kExtension:
|
|
||||||
propVariant = L"bz2 tbz2";
|
|
||||||
break;
|
|
||||||
case NArchive::kAddExtension:
|
|
||||||
propVariant = L"* .tar";
|
|
||||||
break;
|
|
||||||
case NArchive::kUpdate:
|
|
||||||
propVariant = true;
|
|
||||||
break;
|
|
||||||
case NArchive::kKeepName:
|
|
||||||
propVariant = true;
|
|
||||||
break;
|
|
||||||
case NArchive::kStartSignature:
|
|
||||||
{
|
|
||||||
const char sig[] = { 'B', 'Z', 'h' };
|
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen(sig, 3)) != 0)
|
|
||||||
value->vt = VT_BSTR;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
propVariant.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
@@ -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 +0,0 @@
|
|||||||
//Microsoft Developer Studio generated resource script.
|
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Russian resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
|
||||||
#pragma code_page(1251)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Russian resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "bz2.ico"
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 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
|
|
||||||
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
; Cab.def
|
|
||||||
|
|
||||||
LIBRARY cab.dll
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
CreateObject PRIVATE
|
|
||||||
GetHandlerProperty PRIVATE
|
|
||||||
@@ -1,345 +0,0 @@
|
|||||||
# Microsoft Developer Studio Project File - Name="Cab" - Package Owner=<4>
|
|
||||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
|
||||||
# ** DO NOT EDIT **
|
|
||||||
|
|
||||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
|
||||||
|
|
||||||
CFG=Cab - Win32 Debug
|
|
||||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
|
||||||
!MESSAGE use the Export Makefile command and run
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "Cab.mak".
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE You can specify a configuration when running NMAKE
|
|
||||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "Cab.mak" CFG="Cab - Win32 Debug"
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE Possible choices for configuration are:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE "Cab - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE "Cab - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE
|
|
||||||
|
|
||||||
# Begin Project
|
|
||||||
# PROP AllowPerConfigDependencies 0
|
|
||||||
# PROP Scc_ProjName ""
|
|
||||||
# PROP Scc_LocalPath ""
|
|
||||||
CPP=cl.exe
|
|
||||||
MTL=midl.exe
|
|
||||||
RSC=rc.exe
|
|
||||||
|
|
||||||
!IF "$(CFG)" == "Cab - Win32 Release"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
|
||||||
# PROP BASE Output_Dir "Release"
|
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 0
|
|
||||||
# PROP Output_Dir "Release"
|
|
||||||
# PROP Intermediate_Dir "Release"
|
|
||||||
# PROP Ignore_Export_Lib 1
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /c
|
|
||||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /c
|
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
|
||||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\cab.dll" /opt:NOWIN98
|
|
||||||
# SUBTRACT LINK32 /pdb:none
|
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
|
||||||
# PROP BASE Output_Dir "Debug"
|
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 1
|
|
||||||
# PROP Output_Dir "Debug"
|
|
||||||
# PROP Intermediate_Dir "Debug"
|
|
||||||
# PROP Ignore_Export_Lib 1
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /GZ /c
|
|
||||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
|
||||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\cab.dll" /pdbtype:sept
|
|
||||||
|
|
||||||
!ENDIF
|
|
||||||
|
|
||||||
# Begin Target
|
|
||||||
|
|
||||||
# Name "Cab - Win32 Release"
|
|
||||||
# Name "Cab - Win32 Debug"
|
|
||||||
# Begin Group "Spec"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\Cab.def
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\DllExports.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\resource.rc
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\StdAfx.cpp
|
|
||||||
# ADD CPP /Yc
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\StdAfx.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Common"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Alloc.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Alloc.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\IntToString.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\IntToString.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\NewHandler.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\String.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\String.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringConvert.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\UTFConvert.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\UTFConvert.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Vector.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Vector.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Windows"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Windows\PropVariant.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Engine"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabCopyDecoder.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabCopyDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabHandler.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabHandler.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabHeader.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabHeader.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabIn.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabIn.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabInBuffer.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabInBuffer.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CabItem.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXBitDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXConst.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXDecoder.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXExtConst.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXi86Converter.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\LZXi86Converter.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\MSZipConst.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\MSZipDecoder.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\MSZipDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\MSZipExtConst.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "7zip Common"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\InBuffer.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\InBuffer.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\LSBFDecoder.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\LSBFDecoder.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\OutBuffer.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\OutBuffer.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Common\ProgressUtils.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Compress"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Group "LZ"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Compress\LZ\LZOutWindow.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# End Group
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\bitmap1.bmp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\cab.ico
|
|
||||||
# End Source File
|
|
||||||
# End Target
|
|
||||||
# End Project
|
|
||||||
@@ -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
|
|
||||||
@@ -1,639 +0,0 @@
|
|||||||
// Cab/Handler.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/StringConvert.h"
|
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/UTFConvert.h"
|
|
||||||
#include "Common/ComTry.h"
|
|
||||||
#include "Common/IntToString.h"
|
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
#include "Windows/Time.h"
|
|
||||||
|
|
||||||
#include "CabCopyDecoder.h"
|
|
||||||
#include "LZXDecoder.h"
|
|
||||||
#include "MSZipDecoder.h"
|
|
||||||
|
|
||||||
#include "CabHandler.h"
|
|
||||||
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
|
||||||
|
|
||||||
using namespace NWindows;
|
|
||||||
using namespace NTime;
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
|
|
||||||
STATPROPSTG kProperties[] =
|
|
||||||
{
|
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
|
||||||
{ NULL, kpidIsFolder, VT_BOOL},
|
|
||||||
{ NULL, kpidSize, VT_UI8},
|
|
||||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
|
||||||
{ NULL, kpidAttributes, VT_UI4},
|
|
||||||
|
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
|
||||||
// { NULL, kpidDictionarySize, VT_UI4},
|
|
||||||
|
|
||||||
{ NULL, kpidBlock, VT_UI4}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
|
||||||
|
|
||||||
static const wchar_t *kMethods[] =
|
|
||||||
{
|
|
||||||
L"None",
|
|
||||||
L"MSZip",
|
|
||||||
L"Quantum",
|
|
||||||
L"LZX"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
|
||||||
static const wchar_t *kUnknownMethod = L"Unknown";
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
value->vt = VT_EMPTY;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
|
||||||
{
|
|
||||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
|
||||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const STATPROPSTG &srcItem = kProperties[index];
|
|
||||||
*propID = srcItem.propid;
|
|
||||||
*varType = srcItem.vt;
|
|
||||||
*name = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
|
||||||
{
|
|
||||||
*numProperties = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
const CItem &fileInfo = m_Files[index];
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case kpidPath:
|
|
||||||
if (fileInfo.IsNameUTF())
|
|
||||||
{
|
|
||||||
UString unicodeName;
|
|
||||||
if (!ConvertUTF8ToUnicode(fileInfo.Name, unicodeName))
|
|
||||||
propVariant = L"";
|
|
||||||
else
|
|
||||||
propVariant = unicodeName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
propVariant = MultiByteToUnicodeString(fileInfo.Name, CP_ACP);
|
|
||||||
break;
|
|
||||||
case kpidIsFolder:
|
|
||||||
propVariant = fileInfo.IsDirectory();
|
|
||||||
break;
|
|
||||||
case kpidSize:
|
|
||||||
propVariant = fileInfo.UnPackSize;
|
|
||||||
break;
|
|
||||||
case kpidLastWriteTime:
|
|
||||||
{
|
|
||||||
FILETIME localFileTime, utcFileTime;
|
|
||||||
if (DosTimeToFileTime(fileInfo.Time, localFileTime))
|
|
||||||
{
|
|
||||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
|
||||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
|
||||||
propVariant = utcFileTime;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kpidAttributes:
|
|
||||||
propVariant = fileInfo.GetWinAttributes();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kpidMethod:
|
|
||||||
{
|
|
||||||
UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
|
||||||
m_Folders.Size(), fileInfo.FolderIndex);
|
|
||||||
const NHeader::CFolder &folder = m_Folders[realFolderIndex];
|
|
||||||
UString method;
|
|
||||||
int methodIndex = folder.GetCompressionMethod();
|
|
||||||
if (methodIndex < kNumMethods)
|
|
||||||
method = kMethods[methodIndex];
|
|
||||||
else
|
|
||||||
method = kUnknownMethod;
|
|
||||||
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX)
|
|
||||||
{
|
|
||||||
method += L":";
|
|
||||||
wchar_t temp[32];
|
|
||||||
ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
|
|
||||||
method += temp;
|
|
||||||
}
|
|
||||||
propVariant = method;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kpidBlock:
|
|
||||||
propVariant = UInt32(fileInfo.FolderIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
propVariant.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
class CPropgressImp: public CProgressVirt
|
|
||||||
{
|
|
||||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
|
||||||
public:
|
|
||||||
STDMETHOD(SetTotal)(const UInt64 *numFiles);
|
|
||||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
|
||||||
void Init(IArchiveOpenCallback *openArchiveCallback)
|
|
||||||
{ m_OpenArchiveCallback = openArchiveCallback; }
|
|
||||||
};
|
|
||||||
|
|
||||||
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
|
|
||||||
{
|
|
||||||
if (m_OpenArchiveCallback)
|
|
||||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
|
||||||
{
|
|
||||||
if (m_OpenArchiveCallback)
|
|
||||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|
||||||
const UInt64 *maxCheckStartPosition,
|
|
||||||
IArchiveOpenCallback *openArchiveCallback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
m_Stream.Release();
|
|
||||||
// try
|
|
||||||
{
|
|
||||||
CInArchive archive;
|
|
||||||
m_Files.Clear();
|
|
||||||
CPropgressImp progressImp;
|
|
||||||
progressImp.Init(openArchiveCallback);
|
|
||||||
RINOK(archive.Open(inStream, maxCheckStartPosition,
|
|
||||||
m_ArchiveInfo, m_Folders, m_Files, &progressImp));
|
|
||||||
m_Stream = inStream;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
COM_TRY_END
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Close()
|
|
||||||
{
|
|
||||||
m_Stream.Release();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
class CCabFolderOutStream:
|
|
||||||
public ISequentialOutStream,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
private:
|
|
||||||
const CObjectVector<NHeader::CFolder> *m_Folders;
|
|
||||||
const CObjectVector<CItem> *m_Files;
|
|
||||||
const CRecordVector<int> *m_FileIndexes;
|
|
||||||
const CRecordVector<bool> *m_ExtractStatuses;
|
|
||||||
int m_StartIndex;
|
|
||||||
int m_CurrentIndex;
|
|
||||||
int m_NumFiles;
|
|
||||||
UInt64 m_CurrentDataPos;
|
|
||||||
CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
|
|
||||||
bool m_TestMode;
|
|
||||||
|
|
||||||
bool m_FileIsOpen;
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
|
||||||
UInt64 m_FilePos;
|
|
||||||
|
|
||||||
HRESULT OpenFile(int indexIndex, ISequentialOutStream **realOutStream);
|
|
||||||
HRESULT WriteEmptyFiles();
|
|
||||||
UInt64 m_StartImportantTotalUnPacked;
|
|
||||||
public:
|
|
||||||
void Init(
|
|
||||||
const CObjectVector<NHeader::CFolder> *folders,
|
|
||||||
const CObjectVector<CItem> *files,
|
|
||||||
const CRecordVector<int> *fileIndices,
|
|
||||||
const CRecordVector<bool> *extractStatuses,
|
|
||||||
int startIndex,
|
|
||||||
int numFiles,
|
|
||||||
IArchiveExtractCallback *extractCallback,
|
|
||||||
UInt64 startImportantTotalUnPacked,
|
|
||||||
bool testMode);
|
|
||||||
HRESULT FlushCorrupted();
|
|
||||||
HRESULT Unsupported();
|
|
||||||
};
|
|
||||||
|
|
||||||
void CCabFolderOutStream::Init(
|
|
||||||
const CObjectVector<NHeader::CFolder> *folders,
|
|
||||||
const CObjectVector<CItem> *files,
|
|
||||||
const CRecordVector<int> *fileIndices,
|
|
||||||
const CRecordVector<bool> *extractStatuses,
|
|
||||||
int startIndex,
|
|
||||||
int numFiles,
|
|
||||||
IArchiveExtractCallback *extractCallback,
|
|
||||||
UInt64 startImportantTotalUnPacked,
|
|
||||||
bool testMode)
|
|
||||||
{
|
|
||||||
m_Folders = folders;
|
|
||||||
m_Files = files;
|
|
||||||
m_FileIndexes = fileIndices;
|
|
||||||
m_ExtractStatuses = extractStatuses;
|
|
||||||
m_StartIndex = startIndex;
|
|
||||||
m_NumFiles = numFiles;
|
|
||||||
m_ExtractCallback = extractCallback;
|
|
||||||
m_StartImportantTotalUnPacked = startImportantTotalUnPacked;
|
|
||||||
m_TestMode = testMode;
|
|
||||||
|
|
||||||
m_CurrentIndex = 0;
|
|
||||||
m_FileIsOpen = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **realOutStream)
|
|
||||||
{
|
|
||||||
// RINOK(m_ExtractCallback->SetCompleted(&m_StartImportantTotalUnPacked));
|
|
||||||
|
|
||||||
int fullIndex = m_StartIndex + indexIndex;
|
|
||||||
|
|
||||||
Int32 askMode;
|
|
||||||
if((*m_ExtractStatuses)[fullIndex])
|
|
||||||
askMode = m_TestMode ?
|
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
|
||||||
else
|
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
|
||||||
|
|
||||||
int index = (*m_FileIndexes)[fullIndex];
|
|
||||||
const CItem &fileInfo = (*m_Files)[index];
|
|
||||||
UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
|
||||||
m_Folders->Size(), fileInfo.FolderIndex);
|
|
||||||
|
|
||||||
RINOK(m_ExtractCallback->GetStream(index, realOutStream, askMode));
|
|
||||||
|
|
||||||
UInt64 currentUnPackSize = fileInfo.UnPackSize;
|
|
||||||
|
|
||||||
bool mustBeProcessedAnywhere = (indexIndex < m_NumFiles - 1);
|
|
||||||
|
|
||||||
if (realOutStream || mustBeProcessedAnywhere)
|
|
||||||
{
|
|
||||||
if (!realOutStream && !m_TestMode)
|
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
|
||||||
RINOK(m_ExtractCallback->PrepareOperation(askMode));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CCabFolderOutStream::WriteEmptyFiles()
|
|
||||||
{
|
|
||||||
for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
|
|
||||||
{
|
|
||||||
int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
|
|
||||||
const CItem &fileInfo = (*m_Files)[index];
|
|
||||||
if (fileInfo.UnPackSize != 0)
|
|
||||||
return S_OK;
|
|
||||||
realOutStream.Release();
|
|
||||||
HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
|
|
||||||
realOutStream.Release();
|
|
||||||
if (result == S_FALSE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (result == S_OK)
|
|
||||||
{
|
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CCabFolderOutStream::Write(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 processedSizeReal = 0;
|
|
||||||
while(m_CurrentIndex < m_NumFiles)
|
|
||||||
{
|
|
||||||
if (m_FileIsOpen)
|
|
||||||
{
|
|
||||||
int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
|
|
||||||
const CItem &fileInfo = (*m_Files)[index];
|
|
||||||
UInt64 fileSize = fileInfo.UnPackSize;
|
|
||||||
|
|
||||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - m_FilePos,
|
|
||||||
UInt64(size - processedSizeReal));
|
|
||||||
|
|
||||||
UInt32 processedSizeLocal;
|
|
||||||
if (!realOutStream)
|
|
||||||
{
|
|
||||||
processedSizeLocal = numBytesToWrite;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RINOK(realOutStream->Write((const Byte *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal));
|
|
||||||
}
|
|
||||||
m_FilePos += processedSizeLocal;
|
|
||||||
processedSizeReal += processedSizeLocal;
|
|
||||||
if (m_FilePos == fileInfo.UnPackSize)
|
|
||||||
{
|
|
||||||
realOutStream.Release();
|
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
|
||||||
m_FileIsOpen = false;
|
|
||||||
m_CurrentIndex++;
|
|
||||||
}
|
|
||||||
if (processedSizeReal == size)
|
|
||||||
{
|
|
||||||
RINOK(WriteEmptyFiles());
|
|
||||||
if (processedSize != NULL)
|
|
||||||
*processedSize = processedSizeReal;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
|
|
||||||
if (result != S_FALSE && result != S_OK)
|
|
||||||
return result;
|
|
||||||
m_FileIsOpen = true;
|
|
||||||
m_FilePos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (processedSize != NULL)
|
|
||||||
*processedSize = size;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CCabFolderOutStream::FlushCorrupted()
|
|
||||||
{
|
|
||||||
// UInt32 processedSizeReal = 0;
|
|
||||||
while(m_CurrentIndex < m_NumFiles)
|
|
||||||
{
|
|
||||||
if (m_FileIsOpen)
|
|
||||||
{
|
|
||||||
int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
|
|
||||||
const CItem &fileInfo = (*m_Files)[index];
|
|
||||||
UInt64 fileSize = fileInfo.UnPackSize;
|
|
||||||
|
|
||||||
realOutStream.Release();
|
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError));
|
|
||||||
m_FileIsOpen = false;
|
|
||||||
m_CurrentIndex++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
|
|
||||||
if (result != S_FALSE && result != S_OK)
|
|
||||||
return result;
|
|
||||||
m_FileIsOpen = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CCabFolderOutStream::Unsupported()
|
|
||||||
{
|
|
||||||
while(m_CurrentIndex < m_NumFiles)
|
|
||||||
{
|
|
||||||
HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
|
|
||||||
if (result != S_FALSE && result != S_OK)
|
|
||||||
return result;
|
|
||||||
realOutStream.Release();
|
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
|
||||||
m_CurrentIndex++;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CCabFolderOutStream::WritePart(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
return Write(data, size, processedSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
|
||||||
numItems = m_Files.Size();
|
|
||||||
if(numItems == 0)
|
|
||||||
return S_OK;
|
|
||||||
bool testMode = (_aTestMode != 0);
|
|
||||||
UInt64 censoredTotalUnPacked = 0, importantTotalUnPacked = 0;
|
|
||||||
int lastIndex = 0;
|
|
||||||
CRecordVector<int> folderIndexes;
|
|
||||||
CRecordVector<int> importantIndices;
|
|
||||||
CRecordVector<bool> extractStatuses;
|
|
||||||
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < numItems; i++)
|
|
||||||
{
|
|
||||||
int index = allFilesMode ? i : indices[i];
|
|
||||||
const CItem &fileInfo = m_Files[index];
|
|
||||||
censoredTotalUnPacked += fileInfo.UnPackSize;
|
|
||||||
|
|
||||||
int folderIndex = fileInfo.FolderIndex;
|
|
||||||
if (folderIndexes.IsEmpty())
|
|
||||||
folderIndexes.Add(folderIndex);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (folderIndex != folderIndexes.Back())
|
|
||||||
folderIndexes.Add(folderIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int j;
|
|
||||||
for(j = index - 1; j >= lastIndex; j--)
|
|
||||||
if(m_Files[j].FolderIndex != folderIndex)
|
|
||||||
break;
|
|
||||||
for(j++; j <= index; j++)
|
|
||||||
{
|
|
||||||
const CItem &fileInfo = m_Files[j];
|
|
||||||
importantTotalUnPacked += fileInfo.UnPackSize;
|
|
||||||
importantIndices.Add(j);
|
|
||||||
extractStatuses.Add(j == index);
|
|
||||||
}
|
|
||||||
lastIndex = index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extractCallback->SetTotal(importantTotalUnPacked);
|
|
||||||
UInt64 currentImportantTotalUnPacked = 0;
|
|
||||||
UInt64 currentImportantTotalPacked = 0;
|
|
||||||
|
|
||||||
CCopyDecoder *storeDecoderSpec = NULL;
|
|
||||||
CMyComPtr<ICompressCoder> storeDecoder;
|
|
||||||
|
|
||||||
NMSZip::CDecoder *msZipDecoderSpec = NULL;
|
|
||||||
CMyComPtr<ICompressCoder> msZipDecoder;
|
|
||||||
|
|
||||||
NLZX::CDecoder *lzxDecoderSpec = NULL;
|
|
||||||
CMyComPtr<ICompressCoder> lzxDecoder;
|
|
||||||
|
|
||||||
|
|
||||||
int curImportantIndexIndex = 0;
|
|
||||||
UInt64 totalFolderUnPacked;
|
|
||||||
for(i = 0; i < (UInt32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked)
|
|
||||||
{
|
|
||||||
int folderIndex = folderIndexes[i];
|
|
||||||
UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
|
||||||
m_Folders.Size(), folderIndex);
|
|
||||||
|
|
||||||
RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked));
|
|
||||||
totalFolderUnPacked = 0;
|
|
||||||
int j;
|
|
||||||
for (j = curImportantIndexIndex; j < importantIndices.Size(); j++)
|
|
||||||
{
|
|
||||||
const CItem &fileInfo = m_Files[importantIndices[j]];
|
|
||||||
if (fileInfo.FolderIndex != folderIndex)
|
|
||||||
break;
|
|
||||||
totalFolderUnPacked += fileInfo.UnPackSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
|
|
||||||
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
|
|
||||||
|
|
||||||
const NHeader::CFolder &folder = m_Folders[realFolderIndex];
|
|
||||||
|
|
||||||
cabFolderOutStream->Init(&m_Folders, &m_Files, &importantIndices,
|
|
||||||
&extractStatuses, curImportantIndexIndex, j - curImportantIndexIndex,
|
|
||||||
extractCallback, currentImportantTotalUnPacked,
|
|
||||||
folder.GetCompressionMethod() == NHeader::NCompressionMethodMajor::kQuantum?
|
|
||||||
true: testMode);
|
|
||||||
|
|
||||||
curImportantIndexIndex = j;
|
|
||||||
|
|
||||||
UInt64 pos = folder.DataStart; // test it (+ archiveStart)
|
|
||||||
RINOK(m_Stream->Seek(pos, STREAM_SEEK_SET, NULL));
|
|
||||||
|
|
||||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
|
||||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
|
||||||
localProgressSpec->Init(extractCallback, false);
|
|
||||||
|
|
||||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
|
||||||
new CLocalCompressProgressInfo;
|
|
||||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
|
||||||
localCompressProgressSpec->Init(progress,
|
|
||||||
NULL, ¤tImportantTotalUnPacked);
|
|
||||||
|
|
||||||
Byte reservedSize = m_ArchiveInfo.ReserveBlockPresent() ?
|
|
||||||
m_ArchiveInfo.PerDataSizes.PerDatablockAreaSize : 0;
|
|
||||||
|
|
||||||
switch(folder.GetCompressionMethod())
|
|
||||||
{
|
|
||||||
case NHeader::NCompressionMethodMajor::kNone:
|
|
||||||
{
|
|
||||||
if(storeDecoderSpec == NULL)
|
|
||||||
{
|
|
||||||
storeDecoderSpec = new CCopyDecoder;
|
|
||||||
storeDecoder = storeDecoderSpec;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
storeDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks);
|
|
||||||
RINOK(storeDecoder->Code(m_Stream, outStream,
|
|
||||||
NULL, &totalFolderUnPacked, compressProgress));
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
RINOK(cabFolderOutStream->FlushCorrupted());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NHeader::NCompressionMethodMajor::kMSZip:
|
|
||||||
{
|
|
||||||
if(lzxDecoderSpec == NULL)
|
|
||||||
{
|
|
||||||
msZipDecoderSpec = new NMSZip::CDecoder;
|
|
||||||
msZipDecoder = msZipDecoderSpec;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
msZipDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks);
|
|
||||||
RINOK(msZipDecoder->Code(m_Stream, outStream,
|
|
||||||
NULL, &totalFolderUnPacked, compressProgress));
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
RINOK(cabFolderOutStream->FlushCorrupted());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NHeader::NCompressionMethodMajor::kLZX:
|
|
||||||
{
|
|
||||||
if(lzxDecoderSpec == NULL)
|
|
||||||
{
|
|
||||||
lzxDecoderSpec = new NLZX::CDecoder;
|
|
||||||
lzxDecoder = lzxDecoderSpec;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
lzxDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks,
|
|
||||||
folder.CompressionTypeMinor);
|
|
||||||
RINOK(lzxDecoder->Code(m_Stream, outStream,
|
|
||||||
NULL, &totalFolderUnPacked, compressProgress));
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
RINOK(cabFolderOutStream->FlushCorrupted());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
RINOK(cabFolderOutStream->Unsupported());
|
|
||||||
// return E_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
*numItems = m_Files.Size();
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
// CabHandler.h
|
|
||||||
|
|
||||||
#ifndef __CAB_HANDLER_H
|
|
||||||
#define __CAB_HANDLER_H
|
|
||||||
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "../IArchive.h"
|
|
||||||
#include "CabIn.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
|
|
||||||
class CHandler:
|
|
||||||
public IInArchive,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
STDMETHOD(Open)(IInStream *stream,
|
|
||||||
const UInt64 *maxCheckStartPosition,
|
|
||||||
IArchiveOpenCallback *openArchiveCallback);
|
|
||||||
STDMETHOD(Close)();
|
|
||||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
|
|
||||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
|
||||||
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 testMode, IArchiveExtractCallback *extractCallback);
|
|
||||||
|
|
||||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
|
||||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
|
||||||
|
|
||||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
|
||||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CObjectVector<NHeader::CFolder> m_Folders;
|
|
||||||
CObjectVector<CItem> m_Files;
|
|
||||||
CInArchiveInfo m_ArchiveInfo;
|
|
||||||
CMyComPtr<IInStream> m_Stream;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// Archive/Cab/Header.h
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "CabHeader.h"
|
|
||||||
|
|
||||||
namespace NArchive{
|
|
||||||
namespace NCab{
|
|
||||||
namespace NHeader{
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
|
|
||||||
UInt32 kSignature = 0x4643534d + 1;
|
|
||||||
static class CSignatureInitializer
|
|
||||||
{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}}}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
// Archive/Cab/Header.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_HEADER_H
|
|
||||||
#define __ARCHIVE_CAB_HEADER_H
|
|
||||||
|
|
||||||
#include "Common/Types.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
namespace NHeader{
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
|
|
||||||
extern UInt32 kSignature;
|
|
||||||
|
|
||||||
namespace NFlags
|
|
||||||
{
|
|
||||||
const int kPrevCabinet = 0x0001;
|
|
||||||
const int kNextCabinet = 0x0002;
|
|
||||||
const int kReservePresent = 0x0004;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
const Byte kNone = 0;
|
|
||||||
const Byte kMSZip = 1;
|
|
||||||
const Byte kQuantum = 2;
|
|
||||||
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;
|
|
||||||
|
|
||||||
namespace NFolderIndex
|
|
||||||
{
|
|
||||||
const int kContinuedFromPrev = 0xFFFD;
|
|
||||||
const int kContinuedToNext = 0xFFFE;
|
|
||||||
const int kContinuedPrevAndNext = 0xFFFF;
|
|
||||||
inline UInt16 GetRealFolderIndex(UInt16 aNumFolders, UInt16 aFolderIndex)
|
|
||||||
{
|
|
||||||
switch(aFolderIndex)
|
|
||||||
{
|
|
||||||
case kContinuedFromPrev:
|
|
||||||
return 0;
|
|
||||||
case kContinuedToNext:
|
|
||||||
case kContinuedPrevAndNext:
|
|
||||||
return aNumFolders - 1;
|
|
||||||
default:
|
|
||||||
return aFolderIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
// Archive/CabIn.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/StringConvert.h"
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "CabIn.h"
|
|
||||||
#include "Windows/Defs.h"
|
|
||||||
#include "../../Common/InBuffer.h"
|
|
||||||
|
|
||||||
namespace NArchive{
|
|
||||||
namespace NCab{
|
|
||||||
|
|
||||||
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
RINOK(inStream->Read(data, size, &realProcessedSize));
|
|
||||||
if(realProcessedSize != size)
|
|
||||||
return S_FALSE;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
RINOK(inStream->Read(data, size, &realProcessedSize));
|
|
||||||
if(realProcessedSize != size)
|
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
inBuffer.ReadBytes(data, size, realProcessedSize);
|
|
||||||
if(realProcessedSize != size)
|
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SafeReadName(::CInBuffer &inBuffer, AString &name)
|
|
||||||
{
|
|
||||||
name.Empty();
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
Byte b;
|
|
||||||
if (!inBuffer.ReadByte(b))
|
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
|
||||||
if (b == 0)
|
|
||||||
return;
|
|
||||||
name += char(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte CInArchive::ReadByte()
|
|
||||||
{
|
|
||||||
if (_blockPos >= _blockSize)
|
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
|
||||||
return _block[_blockPos++];
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt16 CInArchive::ReadUInt16()
|
|
||||||
{
|
|
||||||
UInt16 value = 0;
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
Byte b = ReadByte();
|
|
||||||
value |= (UInt16(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 CInArchive::ReadUInt32()
|
|
||||||
{
|
|
||||||
UInt32 value = 0;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
Byte b = ReadByte();
|
|
||||||
value |= (UInt32(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CInArchive::Open(IInStream *inStream,
|
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
|
||||||
CInArchiveInfo &inArchiveInfo,
|
|
||||||
CObjectVector<NHeader::CFolder> &folders,
|
|
||||||
CObjectVector<CItem> &files,
|
|
||||||
CProgressVirt *progressVirt)
|
|
||||||
{
|
|
||||||
UInt64 startPosition;
|
|
||||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition));
|
|
||||||
|
|
||||||
// NHeader::NArchive::CBlock archiveHeader;
|
|
||||||
|
|
||||||
{
|
|
||||||
::CInBuffer inBuffer;
|
|
||||||
if (!inBuffer.Create(1 << 17))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
inBuffer.SetStream(inStream);
|
|
||||||
inBuffer.Init();
|
|
||||||
UInt64 value = 0;
|
|
||||||
const int kSignatureSize = 8;
|
|
||||||
UInt64 kSignature64 = NHeader::NArchive::kSignature;
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
Byte b;
|
|
||||||
if (!inBuffer.ReadByte(b))
|
|
||||||
return S_FALSE;
|
|
||||||
value >>= 8;
|
|
||||||
value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
|
|
||||||
if (inBuffer.GetProcessedSize() >= kSignatureSize)
|
|
||||||
{
|
|
||||||
if (value == kSignature64)
|
|
||||||
break;
|
|
||||||
if (searchHeaderSizeLimit != NULL)
|
|
||||||
if (inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startPosition += inBuffer.GetProcessedSize() - kSignatureSize;
|
|
||||||
}
|
|
||||||
RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL));
|
|
||||||
|
|
||||||
RINOK(ReadBytes(inStream, _block, NHeader::NArchive::kArchiveHeaderSize));
|
|
||||||
_blockSize = NHeader::NArchive::kArchiveHeaderSize;
|
|
||||||
_blockPos = 0;
|
|
||||||
|
|
||||||
ReadUInt32(); // Signature; // cabinet file signature
|
|
||||||
// if (archiveHeader.Signature != NHeader::NArchive::kSignature)
|
|
||||||
// return S_FALSE;
|
|
||||||
|
|
||||||
UInt32 reserved1 = ReadUInt32();
|
|
||||||
UInt32 size = ReadUInt32(); // size of this cabinet file in bytes
|
|
||||||
UInt32 reserved2 = ReadUInt32();
|
|
||||||
UInt32 fileOffset = ReadUInt32(); // offset of the first CFFILE entry
|
|
||||||
UInt32 reserved3 = ReadUInt32();
|
|
||||||
|
|
||||||
inArchiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor
|
|
||||||
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));
|
|
||||||
_blockSize = NHeader::NArchive::kPerDataSizesHeaderSize;
|
|
||||||
_blockPos = 0;
|
|
||||||
|
|
||||||
inArchiveInfo.PerDataSizes.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area
|
|
||||||
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;
|
|
||||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition));
|
|
||||||
::CInBuffer inBuffer;
|
|
||||||
if (!inBuffer.Create(1 << 17))
|
|
||||||
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;
|
|
||||||
for(i = 0; i < inArchiveInfo.NumFolders; i++)
|
|
||||||
{
|
|
||||||
if (progressVirt != NULL)
|
|
||||||
{
|
|
||||||
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.NumDataBlocks = ReadUInt16();
|
|
||||||
folder.CompressionTypeMajor = ReadByte();
|
|
||||||
folder.CompressionTypeMinor = ReadByte();
|
|
||||||
|
|
||||||
if (inArchiveInfo.ReserveBlockPresent())
|
|
||||||
{
|
|
||||||
RINOK(inStream->Seek(
|
|
||||||
inArchiveInfo.PerDataSizes.PerFolderAreaSize, STREAM_SEEK_CUR, NULL));
|
|
||||||
}
|
|
||||||
folder.DataStart += (UInt32)startPosition;
|
|
||||||
folders.Add(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
RINOK(inStream->Seek(startPosition + fileOffset,
|
|
||||||
STREAM_SEEK_SET, NULL));
|
|
||||||
|
|
||||||
::CInBuffer inBuffer;
|
|
||||||
if (!inBuffer.Create(1 << 17))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
inBuffer.SetStream(inStream);
|
|
||||||
inBuffer.Init();
|
|
||||||
files.Clear();
|
|
||||||
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;
|
|
||||||
item.UnPackSize = ReadUInt32();
|
|
||||||
item.UnPackOffset = ReadUInt32();
|
|
||||||
item.FolderIndex = ReadUInt16();
|
|
||||||
UInt16 pureDate = ReadUInt16();
|
|
||||||
UInt16 pureTime = ReadUInt16();
|
|
||||||
item.Time = ((UInt32(pureDate) << 16)) | pureTime;
|
|
||||||
item.Attributes = ReadUInt16();
|
|
||||||
SafeReadName(inBuffer, item.Name);
|
|
||||||
files.Add(item);
|
|
||||||
if (progressVirt != NULL)
|
|
||||||
{
|
|
||||||
UInt64 numFiles = files.Size();
|
|
||||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
// Archive/CabIn.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_CAB_IN_H
|
|
||||||
#define __ARCHIVE_CAB_IN_H
|
|
||||||
|
|
||||||
#include "../../IStream.h"
|
|
||||||
#include "CabHeader.h"
|
|
||||||
#include "CabItem.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
|
|
||||||
class CInArchiveException
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum CCauseType
|
|
||||||
{
|
|
||||||
kUnexpectedEndOfArchive = 0,
|
|
||||||
kIncorrectArchive,
|
|
||||||
kUnsupported,
|
|
||||||
} Cause;
|
|
||||||
CInArchiveException(CCauseType cause) : Cause(cause) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CInArchiveInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UInt32 Size; /* size of this cabinet file in bytes */
|
|
||||||
Byte VersionMinor; /* cabinet file format version, minor */
|
|
||||||
Byte VersionMajor; /* cabinet file format version, major */
|
|
||||||
UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */
|
|
||||||
UInt16 NumFiles; /* number of CFFILE entries in this cabinet */
|
|
||||||
UInt16 Flags; /* cabinet file option indicators */
|
|
||||||
UInt16 SetID; /* must be the same for all cabinets in a set */
|
|
||||||
UInt16 CabinetNumber; /* number of this cabinet file in a set */
|
|
||||||
|
|
||||||
bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }
|
|
||||||
NHeader::NArchive::CPerDataSizes PerDataSizes;
|
|
||||||
|
|
||||||
AString PreviousCabinetName;
|
|
||||||
AString PreviousDiskName;
|
|
||||||
AString NextCabinetName;
|
|
||||||
AString NextDiskName;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CProgressVirt
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE;
|
|
||||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
|
||||||
};
|
|
||||||
|
|
||||||
const UInt32 kMaxBlockSize = NHeader::NArchive::kArchiveHeaderSize;
|
|
||||||
|
|
||||||
class CInArchive
|
|
||||||
{
|
|
||||||
UInt16 _blockSize;
|
|
||||||
Byte _block[kMaxBlockSize];
|
|
||||||
UInt32 _blockPos;
|
|
||||||
|
|
||||||
Byte ReadByte();
|
|
||||||
UInt16 ReadUInt16();
|
|
||||||
UInt32 ReadUInt32();
|
|
||||||
public:
|
|
||||||
HRESULT Open(IInStream *inStream,
|
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
|
||||||
CInArchiveInfo &inArchiveInfo,
|
|
||||||
CObjectVector<NHeader::CFolder> &folders,
|
|
||||||
CObjectVector<CItem> &files,
|
|
||||||
CProgressVirt *progressVirt);
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -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,32 +0,0 @@
|
|||||||
// Archive/Cab/ItemInfo.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_RAR_ITEMINFO_H
|
|
||||||
#define __ARCHIVE_RAR_ITEMINFO_H
|
|
||||||
|
|
||||||
#include "Common/Types.h"
|
|
||||||
#include "Common/String.h"
|
|
||||||
#include "CabHeader.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NCab {
|
|
||||||
|
|
||||||
class CItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UInt16 Flags;
|
|
||||||
UInt64 UnPackSize;
|
|
||||||
UInt32 UnPackOffset;
|
|
||||||
UInt16 FolderIndex;
|
|
||||||
UInt32 Time;
|
|
||||||
UInt16 Attributes;
|
|
||||||
UInt32 GetWinAttributes() const { return Attributes & (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
|
|
||||||
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
|
|
||||||
bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
|
|
||||||
AString Name;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
// DLLExports.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/MyInitGuid.h"
|
|
||||||
#include "Common/ComTry.h"
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
#include "CabHandler.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-000110060000}
|
|
||||||
DEFINE_GUID(CLSID_CCabHandler,
|
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00);
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI CreateObject(
|
|
||||||
const GUID *classID,
|
|
||||||
const GUID *interfaceID,
|
|
||||||
void **outObject)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
*outObject = 0;
|
|
||||||
if (*classID != CLSID_CCabHandler)
|
|
||||||
return CLASS_E_CLASSNOTAVAILABLE;
|
|
||||||
if (*interfaceID != IID_IInArchive)
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NCab::CHandler;
|
|
||||||
*outObject = inArchive.Detach();
|
|
||||||
COM_TRY_END
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
NWindows::NCOM::CPropVariant propVariant;
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case NArchive::kName:
|
|
||||||
propVariant = L"Cab";
|
|
||||||
break;
|
|
||||||
case NArchive::kClassID:
|
|
||||||
{
|
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
|
||||||
(const char *)&CLSID_CCabHandler, sizeof(GUID))) != 0)
|
|
||||||
value->vt = VT_BSTR;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case NArchive::kExtension:
|
|
||||||
propVariant = L"cab";
|
|
||||||
break;
|
|
||||||
case NArchive::kUpdate:
|
|
||||||
propVariant = false;
|
|
||||||
break;
|
|
||||||
case NArchive::kKeepName:
|
|
||||||
propVariant = false;
|
|
||||||
break;
|
|
||||||
case NArchive::kStartSignature:
|
|
||||||
{
|
|
||||||
const char sig[] = { 0x4D, 0x53, 0x43, 0x46 };
|
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0)
|
|
||||||
value->vt = VT_BSTR;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
propVariant.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
@@ -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,270 +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
|
|
||||||
@@ -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 +0,0 @@
|
|||||||
//Microsoft Developer Studio generated resource script.
|
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Russian resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
|
||||||
#pragma code_page(1251)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Russian resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 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", "Cab Plugin for 7-Zip\0"
|
|
||||||
VALUE "FileVersion", "4, 19, 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, 19, 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
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// CodecsPath.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "../../../Common/String.h"
|
|
||||||
|
|
||||||
extern HINSTANCE g_hInstance;
|
|
||||||
|
|
||||||
static CSysString GetLibraryPath()
|
|
||||||
{
|
|
||||||
TCHAR fullPath[MAX_PATH + 1];
|
|
||||||
::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
|
|
||||||
return fullPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CSysString GetLibraryFolderPrefix()
|
|
||||||
{
|
|
||||||
CSysString path = GetLibraryPath();
|
|
||||||
int pos = path.ReverseFind(TEXT('\\'));
|
|
||||||
return path.Left(pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
CSysString GetBaseFolderPrefix()
|
|
||||||
{
|
|
||||||
CSysString libPrefix = GetLibraryFolderPrefix();
|
|
||||||
CSysString temp = libPrefix;
|
|
||||||
temp.Delete(temp.Length() - 1);
|
|
||||||
int pos = temp.ReverseFind(TEXT('\\'));
|
|
||||||
return temp.Left(pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
CSysString GetCodecsFolderPrefix()
|
|
||||||
{
|
|
||||||
return GetBaseFolderPrefix() + TEXT("Codecs\\");
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// CodecsPath.h
|
|
||||||
|
|
||||||
#ifndef __CODECSPATH_H
|
|
||||||
#define __CODECSPATH_H
|
|
||||||
|
|
||||||
#include "../../../Common/String.h"
|
|
||||||
|
|
||||||
CSysString GetBaseFolderPrefix();
|
|
||||||
CSysString GetCodecsFolderPrefix();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
// CoderLoader.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "CoderLoader.h"
|
|
||||||
#include "FilterCoder.h"
|
|
||||||
|
|
||||||
HRESULT CCoderLibrary::CreateCoderSpec(REFGUID clsID, ICompressCoder **coder)
|
|
||||||
{
|
|
||||||
HRESULT result = CreateObject(clsID, IID_ICompressCoder, (void **)coder);
|
|
||||||
if (result == S_OK || result != E_NOINTERFACE)
|
|
||||||
return result;
|
|
||||||
CMyComPtr<ICompressFilter> filter;
|
|
||||||
RINOK(CreateObject(clsID, IID_ICompressFilter, (void **)&filter));
|
|
||||||
CFilterCoder *filterCoderSpec = new CFilterCoder;
|
|
||||||
CMyComPtr<ICompressCoder> filterCoder = filterCoderSpec;
|
|
||||||
filterCoderSpec->Filter = filter;
|
|
||||||
*coder = filterCoder.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CCoderLibrary::LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder)
|
|
||||||
{
|
|
||||||
CCoderLibrary libTemp;
|
|
||||||
if (!libTemp.Load(filePath))
|
|
||||||
return GetLastError();
|
|
||||||
RINOK(libTemp.CreateCoderSpec(clsID, coder));
|
|
||||||
Attach(libTemp.Detach());
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
// CoderLoader.h
|
|
||||||
|
|
||||||
#ifndef __CODERLOADER_H
|
|
||||||
#define __CODERLOADER_H
|
|
||||||
|
|
||||||
#include "../../../Common/String.h"
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
#include "../../../Windows/DLL.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
typedef UInt32 (WINAPI * CreateObjectPointer)(
|
|
||||||
const GUID *clsID,
|
|
||||||
const GUID *interfaceID,
|
|
||||||
void **outObject);
|
|
||||||
|
|
||||||
class CCoderLibrary: public NWindows::NDLL::CLibrary
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HRESULT CreateObject(REFGUID clsID, REFGUID iid, void **obj)
|
|
||||||
{
|
|
||||||
CreateObjectPointer createObject = (CreateObjectPointer)
|
|
||||||
GetProcAddress("CreateObject");
|
|
||||||
if (createObject == NULL)
|
|
||||||
return GetLastError();
|
|
||||||
return createObject(&clsID, &iid, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CreateFilter(REFGUID clsID, ICompressFilter **filter)
|
|
||||||
{
|
|
||||||
return CreateObject(clsID, IID_ICompressFilter, (void **)filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CreateCoder(REFGUID clsID, ICompressCoder **coder)
|
|
||||||
{
|
|
||||||
return CreateObject(clsID, IID_ICompressCoder, (void **)coder);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CreateCoderSpec(REFGUID clsID, ICompressCoder **coder);
|
|
||||||
|
|
||||||
HRESULT LoadAndCreateFilter(LPCTSTR filePath, REFGUID clsID, ICompressFilter **filter)
|
|
||||||
{
|
|
||||||
CCoderLibrary libTemp;
|
|
||||||
if (!libTemp.Load(filePath))
|
|
||||||
return GetLastError();
|
|
||||||
RINOK(libTemp.CreateFilter(clsID, filter));
|
|
||||||
Attach(libTemp.Detach());
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT LoadAndCreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder)
|
|
||||||
{
|
|
||||||
CCoderLibrary libTemp;
|
|
||||||
if (!libTemp.Load(filePath))
|
|
||||||
return GetLastError();
|
|
||||||
RINOK(libTemp.CreateCoder(clsID, coder));
|
|
||||||
Attach(libTemp.Detach());
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder);
|
|
||||||
HRESULT CreateCoder2(REFGUID clsID, ICompressCoder2 **coder)
|
|
||||||
{
|
|
||||||
CreateObjectPointer createObject = (CreateObjectPointer)
|
|
||||||
GetProcAddress("CreateObject");
|
|
||||||
if (createObject == NULL)
|
|
||||||
return GetLastError();
|
|
||||||
return createObject(&clsID, &IID_ICompressCoder2, (void **)coder);
|
|
||||||
}
|
|
||||||
HRESULT LoadAndCreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder)
|
|
||||||
{
|
|
||||||
CCoderLibrary libTemp;
|
|
||||||
if (!libTemp.Load(filePath))
|
|
||||||
return GetLastError();
|
|
||||||
RINOK(libTemp.CreateCoder2(clsID, coder));
|
|
||||||
Attach(libTemp.Detach());
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class CCoderLibraries
|
|
||||||
{
|
|
||||||
struct CPathToLibraryPair
|
|
||||||
{
|
|
||||||
CSysString Path;
|
|
||||||
CCoderLibrary Libary;
|
|
||||||
};
|
|
||||||
CObjectVector<CPathToLibraryPair> Pairs;
|
|
||||||
public:
|
|
||||||
int FindPath(LPCTSTR filePath)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Pairs.Size(); i++)
|
|
||||||
if (Pairs[i].Path.CollateNoCase(filePath) == 0)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder)
|
|
||||||
{
|
|
||||||
int index = FindPath(filePath);
|
|
||||||
if (index < 0)
|
|
||||||
{
|
|
||||||
CPathToLibraryPair pair;
|
|
||||||
RINOK(pair.Libary.LoadAndCreateCoder(filePath, clsID, coder));
|
|
||||||
pair.Path = filePath;
|
|
||||||
Pairs.Add(pair);
|
|
||||||
pair.Libary.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return Pairs[index].Libary.CreateCoder(clsID, coder);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder)
|
|
||||||
{
|
|
||||||
int index = FindPath(filePath);
|
|
||||||
if (index < 0)
|
|
||||||
{
|
|
||||||
CPathToLibraryPair pair;
|
|
||||||
RINOK(pair.Libary.LoadAndCreateCoderSpec(filePath, clsID, coder));
|
|
||||||
pair.Path = filePath;
|
|
||||||
Pairs.Add(pair);
|
|
||||||
pair.Libary.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return Pairs[index].Libary.CreateCoderSpec(clsID, coder);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder)
|
|
||||||
{
|
|
||||||
int index = FindPath(filePath);
|
|
||||||
if (index < 0)
|
|
||||||
{
|
|
||||||
CPathToLibraryPair pair;
|
|
||||||
RINOK(pair.Libary.LoadAndCreateCoder2(filePath, clsID, coder));
|
|
||||||
pair.Path = filePath;
|
|
||||||
Pairs.Add(pair);
|
|
||||||
pair.Libary.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return Pairs[index].Libary.CreateCoder2(clsID, coder);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,360 +0,0 @@
|
|||||||
// CoderMixer2MT.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "CoderMixer2MT.h"
|
|
||||||
#include "CrossThreadProgress.h"
|
|
||||||
|
|
||||||
using namespace NWindows;
|
|
||||||
using namespace NSynchronization;
|
|
||||||
|
|
||||||
namespace NCoderMixer2 {
|
|
||||||
|
|
||||||
CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams):
|
|
||||||
ExitEvent(NULL),
|
|
||||||
CompressEvent(NULL),
|
|
||||||
CompressionCompletedEvent(NULL),
|
|
||||||
CCoderInfo(numInStreams, numOutStreams)
|
|
||||||
{
|
|
||||||
InStreams.Reserve(NumInStreams);
|
|
||||||
InStreamPointers.Reserve(NumInStreams);
|
|
||||||
OutStreams.Reserve(NumOutStreams);
|
|
||||||
OutStreamPointers.Reserve(NumOutStreams);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CThreadCoderInfo::CreateEvents()
|
|
||||||
{
|
|
||||||
CompressEvent = new CAutoResetEvent(false);
|
|
||||||
CompressionCompletedEvent = new CAutoResetEvent(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CThreadCoderInfo::~CThreadCoderInfo()
|
|
||||||
{
|
|
||||||
if (CompressEvent != NULL)
|
|
||||||
delete CompressEvent;
|
|
||||||
if (CompressionCompletedEvent != NULL)
|
|
||||||
delete CompressionCompletedEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
class CCoderInfoFlusher2
|
|
||||||
{
|
|
||||||
CThreadCoderInfo *m_CoderInfo;
|
|
||||||
public:
|
|
||||||
CCoderInfoFlusher2(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {}
|
|
||||||
~CCoderInfoFlusher2()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < m_CoderInfo->InStreams.Size(); i++)
|
|
||||||
m_CoderInfo->InStreams[i].Release();
|
|
||||||
for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++)
|
|
||||||
m_CoderInfo->OutStreams[i].Release();
|
|
||||||
m_CoderInfo->CompressionCompletedEvent->Set();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool CThreadCoderInfo::WaitAndCode()
|
|
||||||
{
|
|
||||||
HANDLE events[2] = { ExitEvent, *CompressEvent };
|
|
||||||
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
|
|
||||||
if (waitResult == WAIT_OBJECT_0 + 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
{
|
|
||||||
InStreamPointers.Clear();
|
|
||||||
OutStreamPointers.Clear();
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < NumInStreams; i++)
|
|
||||||
{
|
|
||||||
if (InSizePointers[i] != NULL)
|
|
||||||
InSizePointers[i] = &InSizes[i];
|
|
||||||
InStreamPointers.Add(InStreams[i]);
|
|
||||||
}
|
|
||||||
for (i = 0; i < NumOutStreams; i++)
|
|
||||||
{
|
|
||||||
if (OutSizePointers[i] != NULL)
|
|
||||||
OutSizePointers[i] = &OutSizes[i];
|
|
||||||
OutStreamPointers.Add(OutStreams[i]);
|
|
||||||
}
|
|
||||||
CCoderInfoFlusher2 coderInfoFlusher(this);
|
|
||||||
if (Coder)
|
|
||||||
Result = Coder->Code(InStreamPointers[0],
|
|
||||||
OutStreamPointers[0],
|
|
||||||
InSizePointers[0],
|
|
||||||
OutSizePointers[0],
|
|
||||||
Progress);
|
|
||||||
else
|
|
||||||
Result = Coder2->Code(&InStreamPointers.Front(),
|
|
||||||
&InSizePointers.Front(),
|
|
||||||
NumInStreams,
|
|
||||||
&OutStreamPointers.Front(),
|
|
||||||
&OutSizePointers.Front(),
|
|
||||||
NumOutStreams,
|
|
||||||
Progress);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
|
||||||
CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
|
|
||||||
{
|
|
||||||
sizes.Clear();
|
|
||||||
sizePointers.Clear();
|
|
||||||
for(UInt32 i = 0; i < numItems; i++)
|
|
||||||
{
|
|
||||||
if (srcSizes == 0 || srcSizes[i] == NULL)
|
|
||||||
{
|
|
||||||
sizes.Add(0);
|
|
||||||
sizePointers.Add(NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sizes.Add(*srcSizes[i]);
|
|
||||||
sizePointers.Add(&sizes.Back());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes,
|
|
||||||
const UInt64 **outSizes, ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
Progress = progress;
|
|
||||||
SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
|
|
||||||
SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD WINAPI CoderThread(void *threadCoderInfo)
|
|
||||||
{
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode())
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// CCoderMixer2MT
|
|
||||||
|
|
||||||
static DWORD WINAPI MainCoderThread(void *threadCoderInfo)
|
|
||||||
{
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode())
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CCoderMixer2MT::CCoderMixer2MT()
|
|
||||||
{
|
|
||||||
if (!_mainThread.Create(MainCoderThread, this))
|
|
||||||
throw 271825;
|
|
||||||
}
|
|
||||||
|
|
||||||
CCoderMixer2MT::~CCoderMixer2MT()
|
|
||||||
{
|
|
||||||
_exitEvent.Set();
|
|
||||||
_mainThread.Wait();
|
|
||||||
for(int i = 0; i < _threads.Size(); i++)
|
|
||||||
{
|
|
||||||
_threads[i].Wait();
|
|
||||||
_threads[i].Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
|
|
||||||
{
|
|
||||||
_bindInfo = bindInfo;
|
|
||||||
_streamBinders.Clear();
|
|
||||||
for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
|
||||||
{
|
|
||||||
_streamBinders.Add(CStreamBinder());
|
|
||||||
_streamBinders.Back().CreateEvents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCoderMixer2MT::AddCoderCommon()
|
|
||||||
{
|
|
||||||
int index = _coderInfoVector.Size();
|
|
||||||
const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index];
|
|
||||||
|
|
||||||
CThreadCoderInfo threadCoderInfo(CoderStreamsInfo.NumInStreams,
|
|
||||||
CoderStreamsInfo.NumOutStreams);
|
|
||||||
_coderInfoVector.Add(threadCoderInfo);
|
|
||||||
_coderInfoVector.Back().CreateEvents();
|
|
||||||
_coderInfoVector.Back().ExitEvent = _exitEvent;
|
|
||||||
_compressingCompletedEvents.Add(*_coderInfoVector.Back().CompressionCompletedEvent);
|
|
||||||
|
|
||||||
NWindows::CThread newThread;
|
|
||||||
_threads.Add(newThread);
|
|
||||||
if (!_threads.Back().Create(CoderThread, &_coderInfoVector.Back()))
|
|
||||||
throw 271824;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
|
|
||||||
{
|
|
||||||
AddCoderCommon();
|
|
||||||
_coderInfoVector.Back().Coder = coder;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
|
|
||||||
{
|
|
||||||
AddCoderCommon();
|
|
||||||
_coderInfoVector.Back().Coder2 = coder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void CCoderMixer2MT::FinishAddingCoders()
|
|
||||||
{
|
|
||||||
for(int i = 0; i < _coderInfoVector.Size(); i++)
|
|
||||||
{
|
|
||||||
DWORD id;
|
|
||||||
HANDLE newThread = ::CreateThread(NULL, 0, CoderThread,
|
|
||||||
&_coderInfoVector[i], 0, &id);
|
|
||||||
if (newThread == 0)
|
|
||||||
throw 271824;
|
|
||||||
_threads.Add(newThread);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void CCoderMixer2MT::ReInit()
|
|
||||||
{
|
|
||||||
for(int i = 0; i < _streamBinders.Size(); i++)
|
|
||||||
_streamBinders[i].ReInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams,
|
|
||||||
ISequentialOutStream **outStreams)
|
|
||||||
{
|
|
||||||
if (_coderInfoVector.Size() != _bindInfo.Coders.Size())
|
|
||||||
throw 0;
|
|
||||||
UInt32 numInStreams = 0, numOutStreams = 0;
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < _coderInfoVector.Size(); i++)
|
|
||||||
{
|
|
||||||
CThreadCoderInfo &coderInfo = _coderInfoVector[i];
|
|
||||||
const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
|
|
||||||
coderInfo.InStreams.Clear();
|
|
||||||
UInt32 j;
|
|
||||||
for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
|
|
||||||
coderInfo.InStreams.Add(NULL);
|
|
||||||
coderInfo.OutStreams.Clear();
|
|
||||||
for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
|
|
||||||
coderInfo.OutStreams.Add(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
|
||||||
{
|
|
||||||
const CBindPair &bindPair = _bindInfo.BindPairs[i];
|
|
||||||
UInt32 inCoderIndex, inCoderStreamIndex;
|
|
||||||
UInt32 outCoderIndex, outCoderStreamIndex;
|
|
||||||
_bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
|
|
||||||
_bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
|
|
||||||
|
|
||||||
_streamBinders[i].CreateStreams(
|
|
||||||
&_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex],
|
|
||||||
&_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < _bindInfo.InStreams.Size(); i++)
|
|
||||||
{
|
|
||||||
UInt32 inCoderIndex, inCoderStreamIndex;
|
|
||||||
_bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
|
|
||||||
_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
|
||||||
{
|
|
||||||
UInt32 outCoderIndex, outCoderStreamIndex;
|
|
||||||
_bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
|
|
||||||
_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CCoderMixer2MT::MyCode()
|
|
||||||
{
|
|
||||||
HANDLE events[2] = { _exitEvent, _startCompressingEvent };
|
|
||||||
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
|
|
||||||
if (waitResult == WAIT_OBJECT_0 + 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for(int i = 0; i < _coderInfoVector.Size(); i++)
|
|
||||||
_coderInfoVector[i].CompressEvent->Set();
|
|
||||||
DWORD result = ::WaitForMultipleObjects(_compressingCompletedEvents.Size(),
|
|
||||||
&_compressingCompletedEvents.Front(), TRUE, INFINITE);
|
|
||||||
|
|
||||||
_compressingFinishedEvent.Set();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
|
||||||
const UInt64 **inSizes,
|
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 **outSizes,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
|
|
||||||
numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
Init(inStreams, outStreams);
|
|
||||||
|
|
||||||
_compressingFinishedEvent.Reset(); // ?
|
|
||||||
|
|
||||||
CCrossThreadProgress *progressSpec = new CCrossThreadProgress;
|
|
||||||
CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec;
|
|
||||||
progressSpec->Init();
|
|
||||||
_coderInfoVector[_progressCoderIndex].Progress = crossProgress;
|
|
||||||
|
|
||||||
_startCompressingEvent.Set();
|
|
||||||
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent };
|
|
||||||
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
|
|
||||||
if (waitResult == WAIT_OBJECT_0 + 0)
|
|
||||||
break;
|
|
||||||
if (progress != NULL)
|
|
||||||
progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize,
|
|
||||||
progressSpec->OutSize);
|
|
||||||
else
|
|
||||||
progressSpec->Result = S_OK;
|
|
||||||
progressSpec->WaitEvent.Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < _coderInfoVector.Size(); i++)
|
|
||||||
{
|
|
||||||
HRESULT result = _coderInfoVector[i].Result;
|
|
||||||
if (result == S_FALSE)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
for(i = 0; i < _coderInfoVector.Size(); i++)
|
|
||||||
{
|
|
||||||
HRESULT result = _coderInfoVector[i].Result;
|
|
||||||
if (result != S_OK && result != E_FAIL)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
for(i = 0; i < _coderInfoVector.Size(); i++)
|
|
||||||
{
|
|
||||||
HRESULT result = _coderInfoVector[i].Result;
|
|
||||||
if (result != S_OK)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt64 CCoderMixer2MT::GetWriteProcessedSize(UInt32 binderIndex) const
|
|
||||||
{
|
|
||||||
return _streamBinders[binderIndex].ProcessedSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
// CoderMixer2MT.h
|
|
||||||
|
|
||||||
#ifndef __CODER_MIXER2_MT_H
|
|
||||||
#define __CODER_MIXER2_MT_H
|
|
||||||
|
|
||||||
#include "CoderMixer2.h"
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
#include "../../../Windows/Thread.h"
|
|
||||||
#include "../../Common/StreamBinder.h"
|
|
||||||
|
|
||||||
namespace NCoderMixer2 {
|
|
||||||
|
|
||||||
// CreateEvents();
|
|
||||||
// {
|
|
||||||
// SetCoderInfo()
|
|
||||||
// Init Streams
|
|
||||||
// set CompressEvent()
|
|
||||||
// wait CompressionCompletedEvent
|
|
||||||
// }
|
|
||||||
|
|
||||||
struct CThreadCoderInfo: public CCoderInfo
|
|
||||||
{
|
|
||||||
NWindows::NSynchronization::CAutoResetEvent *CompressEvent;
|
|
||||||
HANDLE ExitEvent;
|
|
||||||
NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent;
|
|
||||||
|
|
||||||
CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
|
|
||||||
CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
|
|
||||||
CRecordVector<ISequentialInStream *> InStreamPointers;
|
|
||||||
CRecordVector<ISequentialOutStream *> OutStreamPointers;
|
|
||||||
|
|
||||||
CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr
|
|
||||||
HRESULT Result;
|
|
||||||
|
|
||||||
CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams);
|
|
||||||
void SetCoderInfo(const UInt64 **inSizes,
|
|
||||||
const UInt64 **outSizes, ICompressProgressInfo *progress);
|
|
||||||
~CThreadCoderInfo();
|
|
||||||
bool WaitAndCode();
|
|
||||||
void CreateEvents();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// SetBindInfo()
|
|
||||||
// for each coder
|
|
||||||
// {
|
|
||||||
// AddCoder[2]()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for each file
|
|
||||||
// {
|
|
||||||
// ReInit()
|
|
||||||
// for each coder
|
|
||||||
// {
|
|
||||||
// SetCoderInfo
|
|
||||||
// }
|
|
||||||
// SetProgressIndex(UInt32 coderIndex);
|
|
||||||
// Code
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
class CCoderMixer2MT:
|
|
||||||
public ICompressCoder2,
|
|
||||||
public CCoderMixer2,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
public:
|
|
||||||
STDMETHOD(Init)(ISequentialInStream **inStreams,
|
|
||||||
ISequentialOutStream **outStreams);
|
|
||||||
|
|
||||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
|
||||||
const UInt64 **inSizes,
|
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 **outSizes,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress);
|
|
||||||
|
|
||||||
|
|
||||||
CCoderMixer2MT();
|
|
||||||
~CCoderMixer2MT();
|
|
||||||
void AddCoderCommon();
|
|
||||||
void AddCoder(ICompressCoder *coder);
|
|
||||||
void AddCoder2(ICompressCoder2 *coder);
|
|
||||||
|
|
||||||
void ReInit();
|
|
||||||
void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
|
|
||||||
{ _coderInfoVector[coderIndex].SetCoderInfo(inSizes, outSizes, NULL); }
|
|
||||||
void SetProgressCoderIndex(UInt32 coderIndex)
|
|
||||||
{ _progressCoderIndex = coderIndex; }
|
|
||||||
|
|
||||||
|
|
||||||
UInt64 GetWriteProcessedSize(UInt32 binderIndex) const;
|
|
||||||
|
|
||||||
|
|
||||||
bool MyCode();
|
|
||||||
|
|
||||||
private:
|
|
||||||
CBindInfo _bindInfo;
|
|
||||||
CObjectVector<CStreamBinder> _streamBinders;
|
|
||||||
CObjectVector<CThreadCoderInfo> _coderInfoVector;
|
|
||||||
CRecordVector<NWindows::CThread> _threads;
|
|
||||||
NWindows::CThread _mainThread;
|
|
||||||
|
|
||||||
NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent;
|
|
||||||
CRecordVector<HANDLE> _compressingCompletedEvents;
|
|
||||||
NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent;
|
|
||||||
|
|
||||||
NWindows::NSynchronization::CManualResetEvent _exitEvent;
|
|
||||||
UInt32 _progressCoderIndex;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void SetBindInfo(const CBindInfo &bindInfo);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
// DummyOutStream.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "DummyOutStream.h"
|
|
||||||
|
|
||||||
void CDummyOutStream::Init(ISequentialOutStream *outStream)
|
|
||||||
{
|
|
||||||
m_Stream = outStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CDummyOutStream::Write(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
if(m_Stream)
|
|
||||||
return m_Stream->Write(data, size, processedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = size;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CDummyOutStream::WritePart(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
if(m_Stream)
|
|
||||||
return m_Stream->WritePart(data, size, processedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = size;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
// InStreamWithCRC.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "InStreamWithCRC.h"
|
|
||||||
|
|
||||||
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
|
||||||
_size += realProcessedSize;
|
|
||||||
_crc.Update(data, realProcessedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CSequentialInStreamWithCRC::ReadPart(void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
|
|
||||||
_size += realProcessedSize;
|
|
||||||
_crc.Update(data, realProcessedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CInStreamWithCRC::Read(void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
|
||||||
_size += realProcessedSize;
|
|
||||||
_crc.Update(data, realProcessedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CInStreamWithCRC::ReadPart(void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
|
|
||||||
_size += realProcessedSize;
|
|
||||||
_crc.Update(data, realProcessedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset,
|
|
||||||
UInt32 seekOrigin, UInt64 *newPosition)
|
|
||||||
{
|
|
||||||
if (seekOrigin != STREAM_SEEK_SET || offset != 0)
|
|
||||||
return E_FAIL;
|
|
||||||
_size = 0;
|
|
||||||
_crc.Init();
|
|
||||||
return _stream->Seek(offset, seekOrigin, newPosition);
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
// OutStreamWithCRC.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "OutStreamWithCRC.h"
|
|
||||||
|
|
||||||
STDMETHODIMP COutStreamWithCRC::Write(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
HRESULT result;
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
if(!_stream)
|
|
||||||
{
|
|
||||||
realProcessedSize = size;
|
|
||||||
result = S_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = _stream->Write(data, size, &realProcessedSize);
|
|
||||||
_crc.Update(data, realProcessedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP COutStreamWithCRC::WritePart(const void *data,
|
|
||||||
UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
HRESULT result;
|
|
||||||
if(!_stream)
|
|
||||||
{
|
|
||||||
realProcessedSize = size;
|
|
||||||
result = S_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = _stream->WritePart(data, size, &realProcessedSize);
|
|
||||||
_crc.Update(data, realProcessedSize);
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// OutStreamWithCRC.h
|
|
||||||
|
|
||||||
#ifndef __OUTSTREAMWITHCRC_H
|
|
||||||
#define __OUTSTREAMWITHCRC_H
|
|
||||||
|
|
||||||
#include "../../../Common/CRC.h"
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
#include "../../IStream.h"
|
|
||||||
|
|
||||||
class COutStreamWithCRC:
|
|
||||||
public ISequentialOutStream,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
private:
|
|
||||||
CCRC _crc;
|
|
||||||
CMyComPtr<ISequentialOutStream> _stream;
|
|
||||||
public:
|
|
||||||
void Init(ISequentialOutStream *stream)
|
|
||||||
{
|
|
||||||
_stream = stream;
|
|
||||||
_crc.Init();
|
|
||||||
}
|
|
||||||
void ReleaseStream() { _stream.Release(); }
|
|
||||||
UInt32 GetCRC() const { return _crc.GetDigest(); }
|
|
||||||
void InitCRC() { _crc.Init(); }
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
; Deb.def
|
|
||||||
|
|
||||||
LIBRARY deb.dll
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
CreateObject PRIVATE
|
|
||||||
GetHandlerProperty PRIVATE
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user