mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 11:14:58 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
@@ -282,6 +282,14 @@ SOURCE=..\..\PropID.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Buffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -294,6 +302,10 @@ SOURCE=..\..\..\Common\CRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynamicBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -302,6 +314,14 @@ 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
|
||||
@@ -346,6 +366,10 @@ SOURCE=..\Common\CodecsPath.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderLoader.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderLoader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -358,6 +382,14 @@ SOURCE=..\Common\CoderMixer2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer2MT.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CoderMixer2MT.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CrossThreadProgress.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -366,6 +398,14 @@ SOURCE=..\Common\CrossThreadProgress.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\FilterCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\FilterCoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\InStreamWithCRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -382,6 +422,14 @@ SOURCE=..\Common\ItemNameUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\MultiStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\MultiStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\OutStreamWithCRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -410,11 +458,11 @@ SOURCE=..\..\Common\LimitedStreams.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MultiStream.cpp
|
||||
SOURCE=..\..\Common\LockedStream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MultiStream.h
|
||||
SOURCE=..\..\Common\LockedStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7zCompressionMode.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_COMPRESSION_MODE_H
|
||||
#define __7Z_COMPRESSION_MODE_H
|
||||
|
||||
@@ -21,8 +19,8 @@ struct CProperty
|
||||
struct CMethodFull
|
||||
{
|
||||
CMethodID MethodID;
|
||||
UINT32 NumInStreams;
|
||||
UINT32 NumOutStreams;
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
bool IsSimpleCoder() const
|
||||
{ return (NumInStreams == 1) && (NumOutStreams == 1); }
|
||||
|
||||
@@ -37,10 +35,10 @@ struct CMethodFull
|
||||
|
||||
struct CBind
|
||||
{
|
||||
UINT32 InCoder;
|
||||
UINT32 InStream;
|
||||
UINT32 OutCoder;
|
||||
UINT32 OutStream;
|
||||
UInt32 InCoder;
|
||||
UInt32 InStream;
|
||||
UInt32 OutCoder;
|
||||
UInt32 OutStream;
|
||||
};
|
||||
|
||||
struct CCompressionMethodMode
|
||||
|
||||
@@ -4,16 +4,15 @@
|
||||
|
||||
#include "7zDecode.h"
|
||||
|
||||
#include "../../Common/MultiStream.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"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
|
||||
|
||||
#ifdef COMPRESS_LZMA
|
||||
#include "../../Compress/LZMA/LZMADecoder.h"
|
||||
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||
@@ -35,11 +34,23 @@ 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
|
||||
@@ -60,35 +71,31 @@ namespace N7z {
|
||||
static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
|
||||
CBindInfoEx &bindInfo)
|
||||
{
|
||||
bindInfo.Coders.Clear();
|
||||
bindInfo.CoderMethodIDs.Clear();
|
||||
bindInfo.OutStreams.Clear();
|
||||
bindInfo.InStreams.Clear();
|
||||
bindInfo.BindPairs.Clear();
|
||||
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;
|
||||
bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
|
||||
bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
|
||||
bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
UINT32 outStreamIndex = 0;
|
||||
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;
|
||||
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++)
|
||||
for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
|
||||
if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
|
||||
bindInfo.OutStreams.Add(outStreamIndex);
|
||||
}
|
||||
for (i = 0; i < folder.PackStreams.Size(); i++)
|
||||
bindInfo.InStreams.Add((UINT32)folder.PackStreams[i].Index);
|
||||
bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
|
||||
}
|
||||
|
||||
static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1,
|
||||
@@ -127,8 +134,12 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
|
||||
return true;
|
||||
}
|
||||
|
||||
CDecoder::CDecoder()
|
||||
CDecoder::CDecoder(bool multiThread)
|
||||
{
|
||||
_multiThread = true;
|
||||
#ifdef _ST_MODE
|
||||
_multiThread = multiThread;
|
||||
#endif
|
||||
_bindInfoExPrevIsDefinded = false;
|
||||
#ifndef EXCLUDE_COM
|
||||
LoadMethodMap();
|
||||
@@ -136,8 +147,8 @@ CDecoder::CDecoder()
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
UINT64 startPos,
|
||||
const UINT64 *packSizes,
|
||||
UInt64 startPos,
|
||||
const UInt64 *packSizes,
|
||||
const CFolder &folderInfo,
|
||||
ISequentialOutStream *outStream,
|
||||
ICompressProgressInfo *compressProgress
|
||||
@@ -182,11 +193,23 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
// _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);
|
||||
|
||||
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2;
|
||||
_mixerCoder = _mixerCoderSpec;
|
||||
|
||||
_mixerCoderSpec->SetBindInfo(bindInfo);
|
||||
for (i = 0; i < numCoders; i++)
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
@@ -200,6 +223,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
if (coderInfo.IsSimpleCoder())
|
||||
{
|
||||
CMyComPtr<ICompressCoder> decoder;
|
||||
CMyComPtr<ICompressFilter> filter;
|
||||
|
||||
#ifdef COMPRESS_LZMA
|
||||
if (altCoderInfo.MethodID == k_LZMA)
|
||||
@@ -213,15 +237,15 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
|
||||
#ifdef COMPRESS_BCJ_X86
|
||||
if (altCoderInfo.MethodID == k_BCJ_X86)
|
||||
decoder = new CBCJ_x86_Decoder;
|
||||
filter = new CBCJ_x86_Decoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#ifdef COMPRESS_DEFLATE_DECODER
|
||||
if (altCoderInfo.MethodID == k_Deflate)
|
||||
decoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#ifdef COMPRESS_BZIP2_DECODER
|
||||
if (altCoderInfo.MethodID == k_BZip2)
|
||||
decoder = new NCompress::NBZip2::CDecoder;
|
||||
#endif
|
||||
@@ -233,13 +257,19 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
|
||||
#ifdef CRYPTO_7ZAES
|
||||
if (altCoderInfo.MethodID == k_7zAES)
|
||||
decoder = new NCrypto::NSevenZ::CDecoder;
|
||||
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.CreateCoder(methodInfo.FilePath,
|
||||
RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath,
|
||||
methodInfo.Decoder, &decoder));
|
||||
}
|
||||
#endif
|
||||
@@ -249,7 +279,12 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
|
||||
_decoders.Add((IUnknown *)decoder);
|
||||
|
||||
_mixerCoderSpec->AddCoder(decoder);
|
||||
if (_multiThread)
|
||||
_mixerCoderMTSpec->AddCoder(decoder);
|
||||
#ifdef _ST_MODE
|
||||
else
|
||||
_mixerCoderSTSpec->AddCoder(decoder, false);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -272,37 +307,39 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
return E_NOTIMPL;
|
||||
|
||||
_decoders.Add((IUnknown *)decoder);
|
||||
_mixerCoderSpec->AddCoder2(decoder);
|
||||
if (_multiThread)
|
||||
_mixerCoderMTSpec->AddCoder2(decoder);
|
||||
#ifdef _ST_MODE
|
||||
else
|
||||
_mixerCoderSTSpec->AddCoder2(decoder, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
_bindInfoExPrev = bindInfo;
|
||||
_bindInfoExPrevIsDefinded = true;
|
||||
}
|
||||
int i;
|
||||
_mixerCoderSpec->ReInit();
|
||||
_mixerCoderCommon->ReInit();
|
||||
|
||||
UINT32 packStreamIndex = 0, unPackStreamIndex = 0;
|
||||
UINT32 coderIndex = 0;
|
||||
// UINT32 coder2Index = 0;
|
||||
UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
|
||||
UInt32 coderIndex = 0;
|
||||
// UInt32 coder2Index = 0;
|
||||
|
||||
for (i = 0; i < numCoders; i++)
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
|
||||
CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties;
|
||||
CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
|
||||
HRESULT result = _decoders[coderIndex].QueryInterface(
|
||||
IID_ICompressSetDecoderProperties, &compressSetDecoderProperties);
|
||||
IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
const CByteBuffer &properties = altCoderInfo.Properties;
|
||||
UINT32 size = properties.GetCapacity();
|
||||
UInt32 size = properties.GetCapacity();
|
||||
if (size > 0)
|
||||
{
|
||||
CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> inStream(inStreamSpec);
|
||||
inStreamSpec->Init((const BYTE *)properties, size);
|
||||
RINOK(compressSetDecoderProperties->SetDecoderProperties(inStream));
|
||||
RINOK(compressSetDecoderProperties->SetDecoderProperties2((const Byte *)properties, size));
|
||||
}
|
||||
}
|
||||
else if (result != E_NOINTERFACE)
|
||||
@@ -319,10 +356,18 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
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 *)(const wchar_t *)unicodePassword,
|
||||
unicodePassword.Length() * sizeof(wchar_t)));
|
||||
(const Byte *)buffer, sizeInBytes));
|
||||
}
|
||||
else if (result != E_NOINTERFACE)
|
||||
return result;
|
||||
@@ -330,13 +375,13 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
|
||||
coderIndex++;
|
||||
|
||||
UINT32 numInStreams = (UINT32)coderInfo.NumInStreams;
|
||||
UINT32 numOutStreams = (UINT32)coderInfo.NumOutStreams;
|
||||
CRecordVector<const UINT64 *> packSizesPointers;
|
||||
CRecordVector<const UINT64 *> unPackSizesPointers;
|
||||
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;
|
||||
UInt32 j;
|
||||
for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
|
||||
unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
|
||||
|
||||
@@ -345,7 +390,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
|
||||
if (bindPairIndex >= 0)
|
||||
packSizesPointers.Add(
|
||||
&folderInfo.UnPackSizes[(UINT32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
|
||||
&folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
|
||||
else
|
||||
{
|
||||
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
|
||||
@@ -355,13 +400,19 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
}
|
||||
}
|
||||
|
||||
_mixerCoderSpec->SetCoderInfo(i,
|
||||
&packSizesPointers.Front(),
|
||||
&unPackSizesPointers.Front());
|
||||
_mixerCoderCommon->SetCoderInfo(i,
|
||||
&packSizesPointers.Front(),
|
||||
&unPackSizesPointers.Front());
|
||||
}
|
||||
UINT32 mainCoder, temp;
|
||||
UInt32 mainCoder, temp;
|
||||
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
|
||||
_mixerCoderSpec->SetProgressCoderIndex(mainCoder);
|
||||
|
||||
if (_multiThread)
|
||||
_mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
|
||||
/*
|
||||
else
|
||||
_mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
|
||||
*/
|
||||
|
||||
if (numCoders == 0)
|
||||
return 0;
|
||||
@@ -370,7 +421,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
|
||||
for (i = 0; i < inStreams.Size(); i++)
|
||||
inStreamPointers.Add(inStreams[i]);
|
||||
ISequentialOutStream *outStreamPointer = outStream;
|
||||
return _mixerCoderSpec->Code(&inStreamPointers.Front(), NULL,
|
||||
return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
|
||||
inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7zDecode.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_DECODE_H
|
||||
#define __7Z_DECODE_H
|
||||
|
||||
@@ -9,6 +7,10 @@
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "../Common/CoderMixer2.h"
|
||||
#include "../Common/CoderMixer2MT.h"
|
||||
#ifdef _ST_MODE
|
||||
#include "../Common/CoderMixer2ST.h"
|
||||
#endif
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "../Common/CoderLoader.h"
|
||||
#endif
|
||||
@@ -21,6 +23,11 @@ namespace N7z {
|
||||
struct CBindInfoEx: public NCoderMixer2::CBindInfo
|
||||
{
|
||||
CRecordVector<CMethodID> CoderMethodIDs;
|
||||
void Clear()
|
||||
{
|
||||
CBindInfo::Clear();
|
||||
CoderMethodIDs.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
@@ -31,15 +38,22 @@ class CDecoder
|
||||
|
||||
bool _bindInfoExPrevIsDefinded;
|
||||
CBindInfoEx _bindInfoExPrev;
|
||||
NCoderMixer2::CCoderMixer2 *_mixerCoderSpec;
|
||||
|
||||
bool _multiThread;
|
||||
#ifdef _ST_MODE
|
||||
NCoderMixer2::CCoderMixer2ST *_mixerCoderSTSpec;
|
||||
#endif
|
||||
NCoderMixer2::CCoderMixer2MT *_mixerCoderMTSpec;
|
||||
NCoderMixer2::CCoderMixer2 *_mixerCoderCommon;
|
||||
|
||||
CMyComPtr<ICompressCoder2> _mixerCoder;
|
||||
CObjectVector<CMyComPtr<IUnknown> > _decoders;
|
||||
// CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
|
||||
public:
|
||||
CDecoder();
|
||||
CDecoder(bool multiThread);
|
||||
HRESULT Decode(IInStream *inStream,
|
||||
UINT64 startPos,
|
||||
const UINT64 *packSizes,
|
||||
UInt64 startPos,
|
||||
const UInt64 *packSizes,
|
||||
const CFolder &folder,
|
||||
ISequentialOutStream *outStream,
|
||||
ICompressProgressInfo *compressProgress
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Common/InOutTempBuffer.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../Common/FilterCoder.h"
|
||||
|
||||
#ifdef COMPRESS_COPY
|
||||
static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
|
||||
@@ -38,11 +39,23 @@ static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#ifndef COMPRESS_DEFLATE_ENCODER
|
||||
#define COMPRESS_DEFLATE_ENCODER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE_ENCODER
|
||||
#include "../../Compress/Deflate/DeflateEncoder.h"
|
||||
static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#ifndef COMPRESS_BZIP2_ENCODER
|
||||
#define COMPRESS_BZIP2_ENCODER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2_ENCODER
|
||||
#include "../../Compress/BZip2/BZip2Encoder.h"
|
||||
static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
||||
#endif
|
||||
@@ -98,16 +111,12 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindI
|
||||
folder.Coders.Add(coderInfo);
|
||||
}
|
||||
for (i = 0; i < bindInfo.InStreams.Size(); i++)
|
||||
{
|
||||
CPackStreamInfo packStreamInfo;
|
||||
packStreamInfo.Index = bindInfo.InStreams[i];
|
||||
folder.PackStreams.Add(packStreamInfo);
|
||||
}
|
||||
folder.PackStreams.Add(bindInfo.InStreams[i]);
|
||||
}
|
||||
|
||||
HRESULT CEncoder::CreateMixerCoder()
|
||||
{
|
||||
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2;
|
||||
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT;
|
||||
_mixerCoder = _mixerCoderSpec;
|
||||
_mixerCoderSpec->SetBindInfo(_bindInfo);
|
||||
for (int i = 0; i < _options.Methods.Size(); i++)
|
||||
@@ -116,6 +125,7 @@ HRESULT CEncoder::CreateMixerCoder()
|
||||
_codersInfo.Add(CCoderInfo());
|
||||
CCoderInfo &encodingInfo = _codersInfo.Back();
|
||||
CMyComPtr<ICompressCoder> encoder;
|
||||
CMyComPtr<ICompressFilter> filter;
|
||||
CMyComPtr<ICompressCoder2> encoder2;
|
||||
|
||||
if (methodFull.IsSimpleCoder())
|
||||
@@ -132,7 +142,7 @@ HRESULT CEncoder::CreateMixerCoder()
|
||||
|
||||
#ifdef COMPRESS_BCJ_X86
|
||||
if (methodFull.MethodID == k_BCJ_X86)
|
||||
encoder = new CBCJ_x86_Encoder;
|
||||
filter = new CBCJ_x86_Encoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_COPY
|
||||
@@ -140,25 +150,32 @@ HRESULT CEncoder::CreateMixerCoder()
|
||||
encoder = new NCompress::CCopyCoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#ifdef COMPRESS_BZIP2_ENCODER
|
||||
if (methodFull.MethodID == k_BZip2)
|
||||
encoder = new NCompress::NBZip2::CEncoder;
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#ifdef COMPRESS_DEFLATE_ENCODER
|
||||
if (methodFull.MethodID == k_Deflate)
|
||||
encoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_7ZAES
|
||||
if (methodFull.MethodID == k_AES)
|
||||
encoder = new NCrypto::NSevenZ::CEncoder;
|
||||
filter = new NCrypto::NSevenZ::CEncoder;
|
||||
#endif
|
||||
|
||||
if (filter)
|
||||
{
|
||||
CFilterCoder *coderSpec = new CFilterCoder;
|
||||
encoder = coderSpec;
|
||||
coderSpec->Filter = filter;
|
||||
}
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
if (encoder == 0)
|
||||
{
|
||||
RINOK(_libraries.CreateCoder(methodFull.FilePath,
|
||||
RINOK(_libraries.CreateCoderSpec(methodFull.FilePath,
|
||||
methodFull.EncoderClassID, &encoder));
|
||||
}
|
||||
#endif
|
||||
@@ -189,29 +206,36 @@ HRESULT CEncoder::CreateMixerCoder()
|
||||
|
||||
if (methodFull.CoderProperties.Size() > 0)
|
||||
{
|
||||
std::vector<NWindows::NCOM::CPropVariant> properties;
|
||||
std::vector<PROPID> propIDs;
|
||||
INT32 numProperties = methodFull.CoderProperties.Size();
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
CRecordVector<PROPID> propIDs;
|
||||
int numProperties = methodFull.CoderProperties.Size();
|
||||
NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties];
|
||||
try
|
||||
{
|
||||
const CProperty &property = methodFull.CoderProperties[i];
|
||||
propIDs.push_back(property.PropID);
|
||||
properties.push_back(property.Value);
|
||||
}
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties,
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
const CProperty &property = methodFull.CoderProperties[i];
|
||||
propIDs.Add(property.PropID);
|
||||
values[i] = property.Value;
|
||||
}
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
if (methodFull.IsSimpleCoder())
|
||||
{
|
||||
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties,
|
||||
&setCoderProperties));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
|
||||
&setCoderProperties));
|
||||
}
|
||||
RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
|
||||
}
|
||||
|
||||
RINOK(setCoderProperties->SetCoderProperties(&propIDs.front(),
|
||||
&properties.front(), numProperties));
|
||||
catch(...)
|
||||
{
|
||||
delete []values;
|
||||
throw;
|
||||
}
|
||||
delete []values;
|
||||
}
|
||||
|
||||
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
||||
@@ -234,7 +258,7 @@ HRESULT CEncoder::CreateMixerCoder()
|
||||
outStreamSpec->Init();
|
||||
writeCoderProperties->WriteCoderProperties(outStream);
|
||||
|
||||
UINT32 size = outStreamSpec->GetSize();
|
||||
UInt32 size = outStreamSpec->GetSize();
|
||||
|
||||
// encodingInfo.Properties.SetCapacity(size);
|
||||
if (encodingInfo.AltCoders.Size() == 0)
|
||||
@@ -257,9 +281,17 @@ HRESULT CEncoder::CreateMixerCoder()
|
||||
|
||||
if (cryptoSetPassword)
|
||||
{
|
||||
CByteBuffer buffer;
|
||||
const UInt32 sizeInBytes = _options.Password.Length() * 2;
|
||||
buffer.SetCapacity(sizeInBytes);
|
||||
for (int i = 0; i < _options.Password.Length(); i++)
|
||||
{
|
||||
wchar_t c = _options.Password[i];
|
||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||
}
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
||||
(const BYTE *)(const wchar_t *)_options.Password,
|
||||
_options.Password.Length() * sizeof(wchar_t)));
|
||||
(const Byte *)buffer, sizeInBytes));
|
||||
}
|
||||
|
||||
// public ICompressWriteCoderProperties,
|
||||
@@ -276,10 +308,10 @@ HRESULT CEncoder::CreateMixerCoder()
|
||||
}
|
||||
|
||||
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
||||
const UINT64 *inStreamSize,
|
||||
const UInt64 *inStreamSize,
|
||||
CFolder &folderItem,
|
||||
ISequentialOutStream *outStream,
|
||||
CRecordVector<UINT64> &packSizes,
|
||||
CRecordVector<UInt64> &packSizes,
|
||||
ICompressProgressInfo *compressProgress)
|
||||
{
|
||||
if (_mixerCoderSpec == NULL)
|
||||
@@ -315,13 +347,13 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
||||
|
||||
if (_bindInfo.InStreams.IsEmpty())
|
||||
return E_FAIL;
|
||||
UINT32 mainCoderIndex, mainStreamIndex;
|
||||
UInt32 mainCoderIndex, mainStreamIndex;
|
||||
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
|
||||
_mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
|
||||
if (inStreamSize != NULL)
|
||||
{
|
||||
CRecordVector<const UINT64 *> sizePointers;
|
||||
for (int i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
|
||||
CRecordVector<const UInt64 *> sizePointers;
|
||||
for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
|
||||
if (i == mainStreamIndex)
|
||||
sizePointers.Add(inStreamSize);
|
||||
else
|
||||
@@ -330,7 +362,7 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
||||
}
|
||||
|
||||
|
||||
// UINT64 outStreamStartPos;
|
||||
// UInt64 outStreamStartPos;
|
||||
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
|
||||
|
||||
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
|
||||
@@ -367,11 +399,11 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
|
||||
packSizes.Add(inOutTempBuffer.GetDataSize());
|
||||
}
|
||||
|
||||
for (i = 0; i < _bindReverseConverter->NumSrcInStreams; i++)
|
||||
for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
|
||||
{
|
||||
int binder = _bindInfo.FindBinderForInStream(
|
||||
_bindReverseConverter->DestOutToSrcInMap[i]);
|
||||
UINT64 streamSize;
|
||||
UInt64 streamSize;
|
||||
if (binder < 0)
|
||||
streamSize = inStreamSizeCountSpec->GetSize();
|
||||
else
|
||||
@@ -433,7 +465,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
|
||||
else
|
||||
{
|
||||
|
||||
UINT32 numInStreams = 0, numOutStreams = 0;
|
||||
UInt32 numInStreams = 0, numOutStreams = 0;
|
||||
int i;
|
||||
for (i = 0; i < options.Methods.Size(); i++)
|
||||
{
|
||||
@@ -452,7 +484,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
|
||||
}
|
||||
else
|
||||
_bindInfo.OutStreams.Insert(0, numOutStreams);
|
||||
for (UINT32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
|
||||
for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
|
||||
_bindInfo.OutStreams.Add(numOutStreams + j);
|
||||
}
|
||||
|
||||
@@ -464,7 +496,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
|
||||
|
||||
if (!options.Binds.IsEmpty())
|
||||
{
|
||||
for (int i = 0; i < options.Binds.Size(); i++)
|
||||
for (i = 0; i < options.Binds.Size(); i++)
|
||||
{
|
||||
NCoderMixer2::CBindPair bindPair;
|
||||
const CBind &bind = options.Binds[i];
|
||||
@@ -472,12 +504,12 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
|
||||
bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
|
||||
_bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
for (i = 0; i < numOutStreams; i++)
|
||||
for (i = 0; i < (int)numOutStreams; i++)
|
||||
if (_bindInfo.FindBinderForOutStream(i) == -1)
|
||||
_bindInfo.OutStreams.Add(i);
|
||||
}
|
||||
|
||||
for (i = 0; i < numInStreams; i++)
|
||||
for (i = 0; i < (int)numInStreams; i++)
|
||||
if (_bindInfo.FindBinderForInStream(i) == -1)
|
||||
_bindInfo.InStreams.Add(i);
|
||||
|
||||
@@ -488,9 +520,9 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
|
||||
int inIndex = _bindInfo.InStreams[0];
|
||||
while (true)
|
||||
{
|
||||
UINT32 coderIndex, coderStreamIndex;
|
||||
UInt32 coderIndex, coderStreamIndex;
|
||||
_bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
|
||||
UINT32 outIndex = _bindInfo.GetCoderStartOutStream(coderIndex);
|
||||
UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
|
||||
int binder = _bindInfo.FindBinderForOutStream(outIndex);
|
||||
if (binder >= 0)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7zEncode.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_ENCODE_H
|
||||
#define __7Z_ENCODE_H
|
||||
|
||||
@@ -10,6 +8,8 @@
|
||||
#include "7zCompressionMode.h"
|
||||
|
||||
#include "../Common/CoderMixer2.h"
|
||||
#include "../Common/CoderMixer2MT.h"
|
||||
#include "../Common/CoderMixer2ST.h"
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "../Common/CoderLoader.h"
|
||||
#endif
|
||||
@@ -27,7 +27,7 @@ class CEncoder
|
||||
CCoderLibraries _libraries;
|
||||
#endif
|
||||
|
||||
NCoderMixer2::CCoderMixer2 *_mixerCoderSpec;
|
||||
NCoderMixer2::CCoderMixer2MT *_mixerCoderSpec;
|
||||
CMyComPtr<ICompressCoder2> _mixerCoder;
|
||||
|
||||
CObjectVector<CCoderInfo> _codersInfo;
|
||||
@@ -44,10 +44,10 @@ public:
|
||||
CEncoder(const CCompressionMethodMode &options);
|
||||
~CEncoder();
|
||||
HRESULT Encode(ISequentialInStream *inStream,
|
||||
const UINT64 *inStreamSize,
|
||||
const UInt64 *inStreamSize,
|
||||
CFolder &folderItem,
|
||||
ISequentialOutStream *outStream,
|
||||
CRecordVector<UINT64> &packSizes,
|
||||
CRecordVector<UInt64> &packSizes,
|
||||
ICompressProgressInfo *compressProgress);
|
||||
};
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include "7zFolderOutStream.h"
|
||||
#include "7zMethods.h"
|
||||
#include "7zDecode.h"
|
||||
// #include "7z1Decode.h"
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../Common/MultiStream.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
@@ -18,16 +18,26 @@ namespace N7z {
|
||||
|
||||
struct CExtractFolderInfo
|
||||
{
|
||||
int FileIndex;
|
||||
int FolderIndex;
|
||||
#ifdef _7Z_VOL
|
||||
int VolumeIndex;
|
||||
#endif
|
||||
CNum FileIndex;
|
||||
CNum FolderIndex;
|
||||
CBoolVector ExtractStatuses;
|
||||
UINT64 UnPackSize;
|
||||
CExtractFolderInfo(int fileIndex, int folderIndex):
|
||||
UInt64 UnPackSize;
|
||||
CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
int volumeIndex,
|
||||
#endif
|
||||
CNum fileIndex, CNum folderIndex):
|
||||
#ifdef _7Z_VOL
|
||||
VolumeIndex(volumeIndex),
|
||||
#endif
|
||||
FileIndex(fileIndex),
|
||||
FolderIndex(folderIndex),
|
||||
UnPackSize(0)
|
||||
{
|
||||
if (fileIndex >= 0)
|
||||
if (fileIndex != kNumNoIndex)
|
||||
{
|
||||
ExtractStatuses.Reserve(1);
|
||||
ExtractStatuses.Add(true);
|
||||
@@ -35,116 +45,150 @@ struct CExtractFolderInfo
|
||||
};
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (testModeSpec != 0);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
UINT64 importantTotalUnPacked = 0;
|
||||
UINT64 censoredTotalUnPacked = 0, censoredTotalPacked = 0;
|
||||
UInt64 importantTotalUnPacked = 0;
|
||||
UInt64 censoredTotalUnPacked = 0, censoredTotalPacked = 0;
|
||||
|
||||
bool allFilesMode = (numItems == UINT32(-1));
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _database.Files.Size();
|
||||
numItems =
|
||||
#ifdef _7Z_VOL
|
||||
_refs.Size();
|
||||
#else
|
||||
_database.Files.Size();
|
||||
#endif
|
||||
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
if(_volumes.Size() != 1)
|
||||
return E_FAIL;
|
||||
const CVolume &volume = _volumes.Front();
|
||||
const CArchiveDatabaseEx &_database = volume.Database;
|
||||
IInStream *_inStream = volume.Stream;
|
||||
*/
|
||||
|
||||
CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
|
||||
for(UINT32 indexIndex = 0; indexIndex < numItems; indexIndex++)
|
||||
for(UInt32 ii = 0; ii < numItems; ii++)
|
||||
{
|
||||
int fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[fileIndex];
|
||||
if (folderIndex < 0)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(fileIndex, -1));
|
||||
continue;
|
||||
}
|
||||
if (extractFolderInfoVector.IsEmpty() ||
|
||||
folderIndex != extractFolderInfoVector.Back().FolderIndex)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(-1, folderIndex));
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
// Count full_folder_size
|
||||
UINT64 unPackSize = folderInfo.GetUnPackSize();
|
||||
importantTotalUnPacked += unPackSize;
|
||||
extractFolderInfoVector.Back().UnPackSize = unPackSize;
|
||||
}
|
||||
// UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
|
||||
UInt32 ref2Index = allFilesMode ? ii : indices[ii];
|
||||
// const CRef2 &ref2 = _refs[ref2Index];
|
||||
|
||||
CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector.Back();
|
||||
|
||||
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
|
||||
UINT32 startIndex = (UINT32)_database.FolderStartFileIndex[folderIndex];
|
||||
for (UINT32 index = extractFolderInfo.ExtractStatuses.Size();
|
||||
index <= fileIndex - startIndex; index++)
|
||||
// for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
|
||||
{
|
||||
UINT64 unPackSize = _database.Files[startIndex + index].UnPackSize;
|
||||
// Count partial_folder_size
|
||||
// extractFolderInfo.UnPackSize += unPackSize;
|
||||
// importantTotalUnPacked += unPackSize;
|
||||
extractFolderInfo.ExtractStatuses.Add(index == fileIndex - startIndex);
|
||||
#ifdef _7Z_VOL
|
||||
// const CRef &ref = ref2.Refs[ri];
|
||||
const CRef &ref = _refs[ref2Index];
|
||||
|
||||
int volumeIndex = ref.VolumeIndex;
|
||||
const CVolume &volume = _volumes[volumeIndex];
|
||||
const CArchiveDatabaseEx &database = volume.Database;
|
||||
UInt32 fileIndex = ref.ItemIndex;
|
||||
#else
|
||||
const CArchiveDatabaseEx &database = _database;
|
||||
UInt32 fileIndex = ref2Index;
|
||||
#endif
|
||||
|
||||
CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex];
|
||||
if (folderIndex == kNumNoIndex)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
volumeIndex,
|
||||
#endif
|
||||
fileIndex, kNumNoIndex));
|
||||
continue;
|
||||
}
|
||||
if (extractFolderInfoVector.IsEmpty() ||
|
||||
folderIndex != extractFolderInfoVector.Back().FolderIndex
|
||||
#ifdef _7Z_VOL
|
||||
|| volumeIndex != extractFolderInfoVector.Back().VolumeIndex
|
||||
#endif
|
||||
)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
volumeIndex,
|
||||
#endif
|
||||
kNumNoIndex, folderIndex));
|
||||
const CFolder &folderInfo = database.Folders[folderIndex];
|
||||
UInt64 unPackSize = folderInfo.GetUnPackSize();
|
||||
importantTotalUnPacked += unPackSize;
|
||||
extractFolderInfoVector.Back().UnPackSize = unPackSize;
|
||||
}
|
||||
|
||||
CExtractFolderInfo &efi = extractFolderInfoVector.Back();
|
||||
|
||||
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
|
||||
CNum startIndex = database.FolderStartFileIndex[folderIndex];
|
||||
for (CNum index = efi.ExtractStatuses.Size();
|
||||
index <= fileIndex - startIndex; index++)
|
||||
{
|
||||
// UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize;
|
||||
// Count partial_folder_size
|
||||
// efi.UnPackSize += unPackSize;
|
||||
// importantTotalUnPacked += unPackSize;
|
||||
efi.ExtractStatuses.Add(index == fileIndex - startIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extractCallback->SetTotal(importantTotalUnPacked);
|
||||
|
||||
CDecoder decoder;
|
||||
CDecoder decoder(true);
|
||||
// CDecoder1 decoder;
|
||||
|
||||
UINT64 currentImportantTotalUnPacked = 0;
|
||||
UINT64 totalFolderUnPacked;
|
||||
UInt64 currentImportantTotalUnPacked = 0;
|
||||
UInt64 totalFolderUnPacked;
|
||||
|
||||
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
|
||||
currentImportantTotalUnPacked += totalFolderUnPacked)
|
||||
{
|
||||
CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector[i];
|
||||
totalFolderUnPacked = extractFolderInfo.UnPackSize;
|
||||
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
||||
totalFolderUnPacked = efi.UnPackSize;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked));
|
||||
|
||||
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||
|
||||
UINT32 startIndex;
|
||||
if (extractFolderInfo.FileIndex >= 0)
|
||||
startIndex = extractFolderInfo.FileIndex;
|
||||
#ifdef _7Z_VOL
|
||||
const CVolume &volume = _volumes[efi.VolumeIndex];
|
||||
const CArchiveDatabaseEx &database = volume.Database;
|
||||
#else
|
||||
const CArchiveDatabaseEx &database = _database;
|
||||
#endif
|
||||
|
||||
CNum startIndex;
|
||||
if (efi.FileIndex != kNumNoIndex)
|
||||
startIndex = efi.FileIndex;
|
||||
else
|
||||
startIndex = (UINT32)_database.FolderStartFileIndex[extractFolderInfo.FolderIndex];
|
||||
startIndex = database.FolderStartFileIndex[efi.FolderIndex];
|
||||
|
||||
|
||||
RINOK(folderOutStream->Init(&_database, startIndex,
|
||||
&extractFolderInfo.ExtractStatuses, extractCallback, testMode));
|
||||
HRESULT result = folderOutStream->Init(&database,
|
||||
#ifdef _7Z_VOL
|
||||
volume.StartRef2Index,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
startIndex,
|
||||
&efi.ExtractStatuses, extractCallback, testMode);
|
||||
|
||||
if (extractFolderInfo.FileIndex >= 0)
|
||||
RINOK(result);
|
||||
|
||||
if (efi.FileIndex != kNumNoIndex)
|
||||
continue;
|
||||
|
||||
UINT32 folderIndex = extractFolderInfo.FolderIndex;
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
|
||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
||||
|
||||
CLockedInStream lockedInStream;
|
||||
lockedInStream.Init(_inStream);
|
||||
|
||||
|
||||
UINT64 folderStartPackStreamIndex = _database.FolderStartPackStreamIndex[folderIndex];
|
||||
|
||||
for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
|
||||
{
|
||||
const CPackStreamInfo &packStreamInfo = folderInfo.PackStreams[j];
|
||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
||||
CLockedSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
||||
UINT64 streamStartPos = _database.GetFolderStreamPos(folderIndex, j);
|
||||
lockedStreamImpSpec->Init(&lockedInStream, streamStartPos);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
||||
streamSpec->Init(lockedStreamImp,
|
||||
_database.PackSizes[(UINT32)folderStartPackStreamIndex + j]);
|
||||
inStreams.Add(inStream);
|
||||
}
|
||||
CNum folderIndex = efi.FolderIndex;
|
||||
const CFolder &folderInfo = database.Folders[folderIndex];
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
@@ -155,8 +199,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress, NULL, ¤tImportantTotalUnPacked);
|
||||
|
||||
UINT32 packStreamIndex = _database.FolderStartPackStreamIndex[folderIndex];
|
||||
UINT64 folderStartPackPos = _database.GetFolderStreamPos(folderIndex, 0);
|
||||
CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
|
||||
UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
@@ -166,9 +210,14 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
|
||||
try
|
||||
{
|
||||
HRESULT result = decoder.Decode(_inStream,
|
||||
HRESULT result = decoder.Decode(
|
||||
#ifdef _7Z_VOL
|
||||
volume.Stream,
|
||||
#else
|
||||
_inStream,
|
||||
#endif
|
||||
folderStartPackPos,
|
||||
&_database.PackSizes[packStreamIndex],
|
||||
&database.PackSizes[packStreamIndex],
|
||||
folderInfo,
|
||||
outStream,
|
||||
compressProgress
|
||||
@@ -189,7 +238,11 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
}
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
RINOK(folderOutStream->WasWritingFinished());
|
||||
if (folderOutStream->WasWritingFinished() != S_OK)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
||||
@@ -9,17 +9,18 @@ namespace N7z {
|
||||
|
||||
CFolderInStream::CFolderInStream()
|
||||
{
|
||||
_inStreamWithHashSpec = new CInStreamWithCRC;
|
||||
_inStreamWithHashSpec = new CSequentialInStreamWithCRC;
|
||||
_inStreamWithHash = _inStreamWithHashSpec;
|
||||
}
|
||||
|
||||
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
||||
const UINT32 *fileIndices, UINT32 numFiles)
|
||||
const UInt32 *fileIndices, UInt32 numFiles)
|
||||
{
|
||||
_updateCallback = updateCallback;
|
||||
_numFiles = numFiles;
|
||||
_fileIndex = 0;
|
||||
_fileIndices = fileIndices;
|
||||
Processed.Clear();
|
||||
CRCs.Clear();
|
||||
Sizes.Clear();
|
||||
_fileIsOpen = false;
|
||||
@@ -32,14 +33,17 @@ HRESULT CFolderInStream::OpenStream()
|
||||
while (_fileIndex < _numFiles)
|
||||
{
|
||||
_currentSizeIsDefined = false;
|
||||
CMyComPtr<IInStream> stream;
|
||||
RINOK(_updateCallback->GetStream(_fileIndices[_fileIndex], &stream));
|
||||
CMyComPtr<ISequentialInStream> stream;
|
||||
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
|
||||
if (result != S_OK && result != S_FALSE)
|
||||
return result;
|
||||
_fileIndex++;
|
||||
_inStreamWithHashSpec->Init(stream);
|
||||
if (!stream)
|
||||
{
|
||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
Sizes.Add(0);
|
||||
Processed.Add(result == S_OK);
|
||||
AddDigest();
|
||||
continue;
|
||||
}
|
||||
@@ -69,21 +73,22 @@ HRESULT CFolderInStream::CloseStream()
|
||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
_inStreamWithHashSpec->ReleaseStream();
|
||||
_fileIsOpen = false;
|
||||
Processed.Add(true);
|
||||
Sizes.Add(_filePos);
|
||||
AddDigest();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
|
||||
STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize = 0;
|
||||
UInt32 realProcessedSize = 0;
|
||||
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
UINT32 localProcessedSize;
|
||||
RINOK(_inStreamWithHash->Read(
|
||||
((BYTE *)data) + realProcessedSize, size, &localProcessedSize));
|
||||
UInt32 localProcessedSize;
|
||||
RINOK(_inStreamWithHash->ReadPart(
|
||||
((Byte *)data) + realProcessedSize, size, &localProcessedSize));
|
||||
if (localProcessedSize == 0)
|
||||
{
|
||||
RINOK(CloseStream());
|
||||
@@ -104,13 +109,13 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processe
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSize)
|
||||
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize = 0;
|
||||
UInt32 realProcessedSize = 0;
|
||||
while (size > 0)
|
||||
{
|
||||
UINT32 localProcessedSize;
|
||||
RINOK(ReadPart(((BYTE *)data) + realProcessedSize, size, &localProcessedSize));
|
||||
UInt32 localProcessedSize;
|
||||
RINOK(ReadPart(((Byte *)data) + realProcessedSize, size, &localProcessedSize));
|
||||
if (localProcessedSize == 0)
|
||||
break;
|
||||
size -= localProcessedSize;
|
||||
@@ -122,12 +127,12 @@ STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSiz
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CFolderInStream::GetSubStreamSize(UINT64 subStream, UINT64 *value)
|
||||
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
||||
{
|
||||
*value = 0;
|
||||
if (subStream < Sizes.Size())
|
||||
{
|
||||
*value= Sizes[subStream];
|
||||
*value= Sizes[(size_t)subStream];
|
||||
return S_OK;
|
||||
}
|
||||
if (subStream > Sizes.Size())
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7z/FolderInStream.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_FOLDERINSTREAM_H
|
||||
#define __7Z_FOLDERINSTREAM_H
|
||||
|
||||
@@ -27,36 +25,37 @@ public:
|
||||
|
||||
CFolderInStream();
|
||||
|
||||
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value);
|
||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||
private:
|
||||
CInStreamWithCRC *_inStreamWithHashSpec;
|
||||
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
|
||||
CMyComPtr<ISequentialInStream> _inStreamWithHash;
|
||||
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
||||
|
||||
bool _currentSizeIsDefined;
|
||||
UINT64 _currentSize;
|
||||
UInt64 _currentSize;
|
||||
|
||||
bool _fileIsOpen;
|
||||
UINT64 _filePos;
|
||||
UInt64 _filePos;
|
||||
|
||||
const UINT32 *_fileIndices;
|
||||
UINT32 _numFiles;
|
||||
UINT32 _fileIndex;
|
||||
const UInt32 *_fileIndices;
|
||||
UInt32 _numFiles;
|
||||
UInt32 _fileIndex;
|
||||
|
||||
HRESULT OpenStream();
|
||||
HRESULT CloseStream();
|
||||
void AddDigest();
|
||||
public:
|
||||
void Init(IArchiveUpdateCallback *updateCallback,
|
||||
const UINT32 *fileIndices, UINT32 numFiles);
|
||||
CRecordVector<UINT32> CRCs;
|
||||
CRecordVector<UINT64> Sizes;
|
||||
UINT64 GetFullSize() const
|
||||
const UInt32 *fileIndices, UInt32 numFiles);
|
||||
CRecordVector<bool> Processed;
|
||||
CRecordVector<UInt32> CRCs;
|
||||
CRecordVector<UInt64> Sizes;
|
||||
UInt64 GetFullSize() const
|
||||
{
|
||||
UINT64 size = 0;
|
||||
UInt64 size = 0;
|
||||
for (int i = 0; i < Sizes.Size(); i++)
|
||||
size += Sizes[i];
|
||||
return size;
|
||||
|
||||
@@ -14,13 +14,15 @@ CFolderOutStream::CFolderOutStream()
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::Init(
|
||||
CArchiveDatabaseEx *archiveDatabase,
|
||||
UINT32 startIndex,
|
||||
const CArchiveDatabaseEx *archiveDatabase,
|
||||
UInt32 ref2Offset,
|
||||
UInt32 startIndex,
|
||||
const CBoolVector *extractStatuses,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode)
|
||||
{
|
||||
_archiveDatabase = archiveDatabase;
|
||||
_ref2Offset = ref2Offset;
|
||||
_startIndex = startIndex;
|
||||
|
||||
_extractStatuses = extractStatuses;
|
||||
@@ -34,7 +36,7 @@ HRESULT CFolderOutStream::Init(
|
||||
|
||||
HRESULT CFolderOutStream::OpenFile()
|
||||
{
|
||||
INT32 askMode;
|
||||
Int32 askMode;
|
||||
if((*_extractStatuses)[_currentIndex])
|
||||
askMode = _testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
@@ -43,14 +45,13 @@ HRESULT CFolderOutStream::OpenFile()
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
|
||||
UINT32 index = _startIndex + _currentIndex;
|
||||
RINOK(_extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
|
||||
|
||||
_outStreamWithHashSpec->Init(realOutStream);
|
||||
if (askMode == NArchive::NExtract::NAskMode::kExtract &&
|
||||
(!realOutStream))
|
||||
{
|
||||
UINT32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
@@ -62,7 +63,7 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
|
||||
{
|
||||
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
|
||||
{
|
||||
UINT32 index = _startIndex + _currentIndex;
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
|
||||
return S_OK;
|
||||
@@ -75,29 +76,29 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||
UINT32 size, UINT32 *processedSize)
|
||||
UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize = 0;
|
||||
UInt32 realProcessedSize = 0;
|
||||
while(_currentIndex < _extractStatuses->Size())
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
UINT32 index = _startIndex + _currentIndex;
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
||||
UINT64 fileSize = fileInfo.UnPackSize;
|
||||
UInt64 fileSize = fileInfo.UnPackSize;
|
||||
|
||||
UINT32 numBytesToWrite = (UINT32)MyMin(fileSize - _filePos,
|
||||
UINT64(size - realProcessedSize));
|
||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
|
||||
UInt64(size - realProcessedSize));
|
||||
|
||||
UINT32 processedSizeLocal;
|
||||
RINOK(_outStreamWithHash->Write((const BYTE *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal));
|
||||
UInt32 processedSizeLocal;
|
||||
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal));
|
||||
|
||||
_filePos += processedSizeLocal;
|
||||
realProcessedSize += processedSizeLocal;
|
||||
if (_filePos == fileSize)
|
||||
{
|
||||
bool digestsAreEqual;
|
||||
if (fileInfo.FileCRCIsDefined)
|
||||
if (fileInfo.IsFileCRCDefined)
|
||||
digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
|
||||
else
|
||||
digestsAreEqual = true;
|
||||
@@ -130,12 +131,12 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderOutStream::WritePart(const void *data,
|
||||
UINT32 size, UINT32 *processedSize)
|
||||
UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return Write(data, size, processedSize);
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::FlushCorrupted(INT32 resultEOperationResult)
|
||||
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
||||
{
|
||||
while(_currentIndex < _extractStatuses->Size())
|
||||
{
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7zFolderOutStream.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_FOLDEROUTSTREAM_H
|
||||
#define __7Z_FOLDEROUTSTREAM_H
|
||||
|
||||
@@ -23,33 +21,35 @@ public:
|
||||
|
||||
CFolderOutStream();
|
||||
|
||||
STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
private:
|
||||
|
||||
COutStreamWithCRC *_outStreamWithHashSpec;
|
||||
CMyComPtr<ISequentialOutStream> _outStreamWithHash;
|
||||
CArchiveDatabaseEx *_archiveDatabase;
|
||||
const CArchiveDatabaseEx *_archiveDatabase;
|
||||
const CBoolVector *_extractStatuses;
|
||||
UINT32 _startIndex;
|
||||
UInt32 _startIndex;
|
||||
UInt32 _ref2Offset;
|
||||
int _currentIndex;
|
||||
// UINT64 _currentDataPos;
|
||||
// UInt64 _currentDataPos;
|
||||
CMyComPtr<IArchiveExtractCallback> _extractCallback;
|
||||
bool _testMode;
|
||||
|
||||
bool _fileIsOpen;
|
||||
UINT64 _filePos;
|
||||
UInt64 _filePos;
|
||||
|
||||
HRESULT OpenFile();
|
||||
HRESULT WriteEmptyFiles();
|
||||
public:
|
||||
HRESULT Init(
|
||||
CArchiveDatabaseEx *archiveDatabase,
|
||||
UINT32 startIndex,
|
||||
const CArchiveDatabaseEx *archiveDatabase,
|
||||
UInt32 ref2Offset,
|
||||
UInt32 startIndex,
|
||||
const CBoolVector *extractStatuses,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode);
|
||||
HRESULT FlushCorrupted(INT32 resultEOperationResult);
|
||||
HRESULT FlushCorrupted(Int32 resultEOperationResult);
|
||||
HRESULT WasWritingFinished();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 7z/Handler.cpp
|
||||
// 7zHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
#include "7zProperties.h"
|
||||
|
||||
#include "../../../Common/IntToString.h"
|
||||
// #include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "../../../Windows/Defs.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
#ifdef _7Z_VOL
|
||||
#include "../Common/MultiStream.h"
|
||||
#endif
|
||||
|
||||
// #include "7zMethods.h"
|
||||
using namespace NWindows;
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
@@ -28,31 +29,15 @@ CHandler::CHandler()
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
STDMETHODIMP CHandler::EnumProperties(IEnumSTATPROPSTG **enumerator)
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
#ifndef _SFX
|
||||
COM_TRY_BEGIN
|
||||
CComObjectNoLock<CEnumArchiveItemProperty> *enumeratorSpec =
|
||||
new CComObjectNoLock<CEnumArchiveItemProperty>;
|
||||
if (enumeratorSpec == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
CMyComPtr<IEnumSTATPROPSTG> tempEnumerator(enumeratorSpec);
|
||||
enumeratorSpec->Init(_database.ArchiveInfo.FileInfoPopIDs);
|
||||
*enumerator = tempEnumerator.Detach();
|
||||
return S_OK;
|
||||
// return tempEnumerator->QueryInterface(IID_IEnumSTATPROPSTG, (LPVOID*)enumerator);
|
||||
COM_TRY_END
|
||||
*numItems =
|
||||
#ifdef _7Z_VOL
|
||||
_refs.Size();
|
||||
#else
|
||||
return E_NOTIMPL;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*numItems = _database.Files.Size();
|
||||
#endif
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -65,12 +50,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
|
||||
#ifdef _SFX
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
@@ -79,13 +64,13 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
#endif
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
@@ -95,30 +80,22 @@ STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
static void MySetFileTime(bool timeDefined, FILETIME unixTime,
|
||||
NWindows::NCOM::CPropVariant &propVariant)
|
||||
{
|
||||
// FILETIME fileTime;
|
||||
if (timeDefined)
|
||||
propVariant = unixTime;
|
||||
// NTime::UnixTimeToFileTime((time_t)unixTime, fileTime);
|
||||
else
|
||||
{
|
||||
return;
|
||||
// fileTime.dwHighDateTime = fileTime.dwLowDateTime = 0;
|
||||
}
|
||||
// propVariant = fileTime;
|
||||
}
|
||||
|
||||
/*
|
||||
inline static wchar_t GetHex(BYTE value)
|
||||
inline static wchar_t GetHex(Byte value)
|
||||
{
|
||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
||||
}
|
||||
|
||||
static UString ConvertBytesToHexString(const BYTE *data, UINT32 size)
|
||||
static UString ConvertBytesToHexString(const Byte *data, UInt32 size)
|
||||
{
|
||||
UString result;
|
||||
for (UINT32 i = 0; i < size; i++)
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
{
|
||||
BYTE b = data[i];
|
||||
Byte b = data[i];
|
||||
result += GetHex(b >> 4);
|
||||
result += GetHex(b & 0xF);
|
||||
}
|
||||
@@ -129,32 +106,32 @@ static UString ConvertBytesToHexString(const BYTE *data, UINT32 size)
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
static UString ConvertUINT32ToString(UINT32 value)
|
||||
static UString ConvertUInt32ToString(UInt32 value)
|
||||
{
|
||||
wchar_t buffer[32];
|
||||
ConvertUINT64ToString(value, buffer);
|
||||
ConvertUInt64ToString(value, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static UString GetStringForSizeValue(UINT32 value)
|
||||
static UString GetStringForSizeValue(UInt32 value)
|
||||
{
|
||||
for (int i = 31; i >= 0; i--)
|
||||
if ((UINT32(1) << i) == value)
|
||||
return ConvertUINT32ToString(i);
|
||||
if ((UInt32(1) << i) == value)
|
||||
return ConvertUInt32ToString(i);
|
||||
UString result;
|
||||
if (value % (1 << 20) == 0)
|
||||
{
|
||||
result += ConvertUINT32ToString(value >> 20);
|
||||
result += ConvertUInt32ToString(value >> 20);
|
||||
result += L"m";
|
||||
}
|
||||
else if (value % (1 << 10) == 0)
|
||||
{
|
||||
result += ConvertUINT32ToString(value >> 10);
|
||||
result += ConvertUInt32ToString(value >> 10);
|
||||
result += L"k";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += ConvertUINT32ToString(value);
|
||||
result += ConvertUInt32ToString(value);
|
||||
result += L"b";
|
||||
}
|
||||
return result;
|
||||
@@ -168,11 +145,11 @@ 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)
|
||||
static inline char GetHex(Byte value)
|
||||
{
|
||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
||||
}
|
||||
static inline UString GetHex2(BYTE value)
|
||||
static inline UString GetHex2(Byte value)
|
||||
{
|
||||
UString result;
|
||||
result += GetHex(value >> 4);
|
||||
@@ -182,39 +159,78 @@ static inline UString GetHex2(BYTE value)
|
||||
|
||||
#endif
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
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:
|
||||
{
|
||||
propVariant = NArchive::NItemName::GetOSName(item.Name);
|
||||
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;
|
||||
{
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[index];
|
||||
if (folderIndex >= 0)
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
if (_database.FolderStartFileIndex[folderIndex] == index)
|
||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
||||
propVariant = _database.GetFolderFullPackSize(folderIndex);
|
||||
/*
|
||||
else
|
||||
propVariant = UINT64(0);
|
||||
propVariant = UInt64(0);
|
||||
*/
|
||||
}
|
||||
else
|
||||
propVariant = UINT64(0);
|
||||
propVariant = UInt64(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -232,14 +248,14 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
propVariant = item.Attributes;
|
||||
break;
|
||||
case kpidCRC:
|
||||
if (item.FileCRCIsDefined)
|
||||
if (item.IsFileCRCDefined)
|
||||
propVariant = item.FileCRC;
|
||||
break;
|
||||
#ifndef _SFX
|
||||
case kpidMethod:
|
||||
{
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[index];
|
||||
if (folderIndex >= 0)
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
UString methodsString;
|
||||
@@ -292,24 +308,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
methodsString += methodName;
|
||||
if (altCoderInfo.MethodID == k_LZMA)
|
||||
{
|
||||
if (altCoderInfo.Properties.GetCapacity() == 5)
|
||||
if (altCoderInfo.Properties.GetCapacity() >= 5)
|
||||
{
|
||||
methodsString += L":";
|
||||
UINT32 dicSize = *(const UINT32 *)
|
||||
((const BYTE *)altCoderInfo.Properties + 1);
|
||||
UInt32 dicSize = GetUInt32FromMemLE(
|
||||
((const Byte *)altCoderInfo.Properties + 1));
|
||||
methodsString += GetStringForSizeValue(dicSize);
|
||||
}
|
||||
}
|
||||
else if (altCoderInfo.MethodID == k_PPMD)
|
||||
{
|
||||
if (altCoderInfo.Properties.GetCapacity() == 5)
|
||||
if (altCoderInfo.Properties.GetCapacity() >= 5)
|
||||
{
|
||||
BYTE order = *(const BYTE *)altCoderInfo.Properties;
|
||||
Byte order = *(const Byte *)altCoderInfo.Properties;
|
||||
methodsString += L":o";
|
||||
methodsString += ConvertUINT32ToString(order);
|
||||
methodsString += ConvertUInt32ToString(order);
|
||||
methodsString += L":mem";
|
||||
UINT32 dicSize = *(const UINT32 *)
|
||||
((const BYTE *)altCoderInfo.Properties + 1);
|
||||
UInt32 dicSize = GetUInt32FromMemLE(
|
||||
((const Byte *)altCoderInfo.Properties + 1));
|
||||
methodsString += GetStringForSizeValue(dicSize);
|
||||
}
|
||||
}
|
||||
@@ -318,7 +334,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
if (altCoderInfo.Properties.GetCapacity() > 0)
|
||||
{
|
||||
methodsString += L":[";
|
||||
for (int bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
|
||||
for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
|
||||
{
|
||||
if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())
|
||||
{
|
||||
@@ -344,9 +360,9 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
break;
|
||||
case kpidBlock:
|
||||
{
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[index];
|
||||
if (folderIndex >= 0)
|
||||
propVariant = (UINT32)folderIndex;
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
propVariant = (UInt32)folderIndex;
|
||||
}
|
||||
break;
|
||||
case kpidPackedSize0:
|
||||
@@ -355,20 +371,20 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
case kpidPackedSize3:
|
||||
case kpidPackedSize4:
|
||||
{
|
||||
int folderIndex = _database.FileIndexToFolderIndexMap[index];
|
||||
if (folderIndex >= 0)
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
||||
if (_database.FolderStartFileIndex[folderIndex] == index &&
|
||||
folderInfo.PackStreams.Size() > propID - kpidPackedSize0)
|
||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
||||
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
|
||||
{
|
||||
propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
||||
}
|
||||
else
|
||||
propVariant = UINT64(0);
|
||||
propVariant = UInt64(0);
|
||||
}
|
||||
else
|
||||
propVariant = UINT64(0);
|
||||
propVariant = UInt64(0);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -381,49 +397,238 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
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,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
_inStream.Release();
|
||||
_database.Clear();
|
||||
Close();
|
||||
#ifndef _SFX
|
||||
_fileInfoPopIDs.Clear();
|
||||
#endif
|
||||
try
|
||||
{
|
||||
CInArchive archive;
|
||||
RINOK(archive.Open(stream, maxCheckStartPosition));
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
|
||||
#ifdef _7Z_VOL
|
||||
CVolumeName seqName;
|
||||
|
||||
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
||||
#endif
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
if (openArchiveCallback)
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = 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);
|
||||
result = archive.CheckIntegrity();
|
||||
if (result != S_OK)
|
||||
return E_FAIL;
|
||||
_database.FillFolderStartPackStream();
|
||||
_database.FillStartPos();
|
||||
_database.FillFolderStartFileIndex();
|
||||
_database.Fill();
|
||||
_inStream = stream;
|
||||
#endif
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
Close();
|
||||
return S_FALSE;
|
||||
}
|
||||
_inStream = stream;
|
||||
// _inStream = stream;
|
||||
#ifndef _SFX
|
||||
FillPopIDs();
|
||||
#endif
|
||||
@@ -434,9 +639,73 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
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,12 +1,9 @@
|
||||
// 7z/Handler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_HANDLER_H
|
||||
#define __7Z_HANDLER_H
|
||||
|
||||
#include "../IArchive.h"
|
||||
// #include "../../../Compress/Interface/CompressInterface.h"
|
||||
#include "7zIn.h"
|
||||
|
||||
#include "7zCompressionMode.h"
|
||||
@@ -18,6 +15,32 @@
|
||||
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
|
||||
@@ -33,6 +56,9 @@ DEFINE_GUID(CLSID_CFormat7z,
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
#ifdef _7Z_VOL
|
||||
public IInArchiveGetStream,
|
||||
#endif
|
||||
#ifndef EXTRACT_ONLY
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
@@ -40,46 +66,50 @@ class CHandler:
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
#ifdef EXTRACT_ONLY
|
||||
MY_UNKNOWN_IMP
|
||||
#else
|
||||
MY_UNKNOWN_IMP3(
|
||||
IInArchive,
|
||||
IOutArchive,
|
||||
ISetProperties
|
||||
)
|
||||
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,
|
||||
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(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,
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
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)(IOutStream *outStream, UINT32 numItems,
|
||||
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
STDMETHOD(GetFileTimeType)(UINT32 *type);
|
||||
STDMETHOD(GetFileTimeType)(UInt32 *type);
|
||||
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties);
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
|
||||
HRESULT SetSolidSettings(const UString &s);
|
||||
HRESULT SetSolidSettings(const PROPVARIANT &value);
|
||||
@@ -88,16 +118,20 @@ public:
|
||||
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;
|
||||
UInt64 _numSolidFiles;
|
||||
UInt64 _numSolidBytes;
|
||||
bool _numSolidBytesDefined;
|
||||
bool _solidExtension;
|
||||
|
||||
@@ -106,13 +140,17 @@ private:
|
||||
bool _encryptHeaders;
|
||||
|
||||
bool _copyMode;
|
||||
UINT32 _defaultDicSize;
|
||||
UINT32 _defaultAlgorithm;
|
||||
UINT32 _defaultFastBytes;
|
||||
UInt32 _defaultDicSize;
|
||||
UInt32 _defaultAlgorithm;
|
||||
UInt32 _defaultFastBytes;
|
||||
UString _defaultMatchFinder;
|
||||
UInt32 _defaultBZip2Passes;
|
||||
bool _autoFilter;
|
||||
bool _multiThread;
|
||||
UINT32 _level;
|
||||
UInt32 _level;
|
||||
|
||||
bool _volumeMode;
|
||||
|
||||
|
||||
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
|
||||
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
|
||||
@@ -132,25 +170,15 @@ private:
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
CRecordVector<UINT64> _fileInfoPopIDs;
|
||||
CRecordVector<UInt64> _fileInfoPopIDs;
|
||||
void FillPopIDs();
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
UINT64 GetUINT64MAX() const
|
||||
{
|
||||
return
|
||||
#if (__GNUC__)
|
||||
0xFFFFFFFFFFFFFFFFLL
|
||||
#else
|
||||
0xFFFFFFFFFFFFFFFF
|
||||
#endif
|
||||
;
|
||||
}
|
||||
void InitSolidFiles() { _numSolidFiles = GetUINT64MAX(); }
|
||||
void InitSolidSize() { _numSolidBytes = GetUINT64MAX(); }
|
||||
void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); }
|
||||
void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); }
|
||||
void InitSolid()
|
||||
{
|
||||
InitSolidFiles();
|
||||
@@ -167,8 +195,8 @@ private:
|
||||
*/
|
||||
void SetSolidBytesLimit()
|
||||
{
|
||||
_numSolidBytes = ((UINT64)_defaultDicSize) << 7;
|
||||
const UINT64 kMinSize = (1<<24);
|
||||
_numSolidBytes = ((UInt64)_defaultDicSize) << 7;
|
||||
const UInt64 kMinSize = (1<<24);
|
||||
if (_numSolidBytes < kMinSize)
|
||||
_numSolidBytes = kMinSize;
|
||||
}
|
||||
@@ -192,11 +220,13 @@ private:
|
||||
_multiThread = false;
|
||||
_copyMode = false;
|
||||
_defaultDicSize = (1 << 21);
|
||||
_defaultBZip2Passes = 1;
|
||||
_defaultAlgorithm = 1;
|
||||
_defaultFastBytes = 32;
|
||||
_defaultMatchFinder = L"BT4";
|
||||
_level = 5;
|
||||
_autoFilter = true;
|
||||
_volumeMode = false;
|
||||
InitSolid();
|
||||
SetSolidBytesLimit();
|
||||
}
|
||||
|
||||
@@ -41,41 +41,57 @@ static CMethodID k_Copy = { { 0x0 }, 1 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#ifndef COMPRESS_DEFLATE_ENCODER
|
||||
#define COMPRESS_DEFLATE_ENCODER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE_ENCODER
|
||||
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#ifndef COMPRESS_BZIP2_ENCODER
|
||||
#define COMPRESS_BZIP2_ENCODER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2_ENCODER
|
||||
static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
|
||||
#endif
|
||||
|
||||
const wchar_t *kCopyMethod = L"Copy";
|
||||
const wchar_t *kLZMAMethodName = L"LZMA";
|
||||
const wchar_t *kBZip2MethodName = L"BZip2";
|
||||
|
||||
const UINT32 kAlgorithmForX7 = 2;
|
||||
const UINT32 kDicSizeForX7 = 1 << 23;
|
||||
const UINT32 kFastBytesForX7 = 64;
|
||||
const UInt32 kAlgorithmForX7 = 2;
|
||||
const UInt32 kDicSizeForX7 = 1 << 23;
|
||||
const UInt32 kFastBytesForX7 = 64;
|
||||
|
||||
const UINT32 kAlgorithmForX9 = 2;
|
||||
const UINT32 kDicSizeForX9 = 1 << 25;
|
||||
const UINT32 kFastBytesForX9 = 64;
|
||||
const UInt32 kAlgorithmForX9 = 2;
|
||||
const UInt32 kDicSizeForX9 = 1 << 25;
|
||||
const UInt32 kFastBytesForX9 = 64;
|
||||
static const wchar_t *kMatchFinderForX9 = L"BT4b";
|
||||
|
||||
const UINT32 kAlgorithmForFast = 0;
|
||||
const UINT32 kDicSizeForFast = 1 << 15;
|
||||
const UInt32 kAlgorithmForFast = 0;
|
||||
const UInt32 kDicSizeForFast = 1 << 15;
|
||||
static const wchar_t *kMatchFinderForFast = L"HC3";
|
||||
|
||||
const wchar_t *kDefaultMethodName = kLZMAMethodName;
|
||||
|
||||
static const wchar_t *kMatchFinderForHeaders = L"BT2";
|
||||
static const UINT32 kDictionaryForHeaders = 1 << 20;
|
||||
static const UINT32 kNumFastBytesForHeaders = 254;
|
||||
static const UInt32 kDictionaryForHeaders = 1 << 20;
|
||||
static const UInt32 kNumFastBytesForHeaders = 254;
|
||||
|
||||
static bool IsLZMAMethod(const UString &methodName)
|
||||
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
|
||||
static bool IsLZMethod(const UString &methodName)
|
||||
{ return IsLZMAMethod(methodName); }
|
||||
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type)
|
||||
static bool IsBZip2Method(const UString &methodName)
|
||||
{ return (methodName.CompareNoCase(kBZip2MethodName) == 0); }
|
||||
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
||||
{
|
||||
*type = NFileTimeType::kWindows;
|
||||
return S_OK;
|
||||
@@ -94,7 +110,7 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
|
||||
if (getTextPassword)
|
||||
{
|
||||
CMyComBSTR password;
|
||||
INT32 passwordIsDefined;
|
||||
Int32 passwordIsDefined;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword2(
|
||||
&passwordIsDefined, &password));
|
||||
if (methodMode.PasswordIsDefined = IntToBool(passwordIsDefined))
|
||||
@@ -105,52 +121,6 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// it's work only for non-solid archives
|
||||
/*
|
||||
STDMETHODIMP CHandler::DeleteItems(IOutStream *outStream,
|
||||
const UINT32* indices, UINT32 numItems, IUpdateCallback *updateCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CRecordVector<bool> compressStatuses;
|
||||
CRecordVector<UINT32> copyIndices;
|
||||
int index = 0;
|
||||
int i;
|
||||
for(i = 0; i < _database.NumUnPackStreamsVector.Size(); i++)
|
||||
{
|
||||
if (_database.NumUnPackStreamsVector[i] != 1)
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
for(i = 0; i < _database.Files.Size(); i++)
|
||||
{
|
||||
// bool copyMode = true;
|
||||
if(index < numItems && i == indices[index])
|
||||
index++;
|
||||
else
|
||||
{
|
||||
compressStatuses.Add(false);
|
||||
copyIndices.Add(i);
|
||||
}
|
||||
}
|
||||
CCompressionMethodMode methodMode, headerMethod;
|
||||
RINOK(SetCompressionMethod(methodMode, headerMethod));
|
||||
methodMode.MultiThread = _multiThread;
|
||||
methodMode.MultiThreadMult = _multiThreadMult;
|
||||
|
||||
headerMethod.MultiThread = false;
|
||||
bool useAdditionalHeaderStreams = true;
|
||||
bool compressMainHeader = false;
|
||||
|
||||
// headerMethod.MultiThreadMult = _multiThreadMult;
|
||||
|
||||
return UpdateMain(_database, compressStatuses,
|
||||
CObjectVector<CUpdateItem>(), copyIndices,
|
||||
outStream, _inStream, &_database.ArchiveInfo,
|
||||
NULL, (_compressHeaders ? &headerMethod: 0),
|
||||
useAdditionalHeaderStreams, compressMainHeader,
|
||||
updateCallback, false, _removeSfxBlock);
|
||||
COM_TRY_END
|
||||
}
|
||||
*/
|
||||
struct CNameToPropID
|
||||
{
|
||||
PROPID PropID;
|
||||
@@ -184,10 +154,10 @@ bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
|
||||
{
|
||||
if(srcProp.vt == VT_UI4)
|
||||
{
|
||||
UINT32 value = srcProp.ulVal;
|
||||
UInt32 value = srcProp.ulVal;
|
||||
if (value > 0xFF)
|
||||
return false;
|
||||
destProp = BYTE(value);
|
||||
destProp = Byte(value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -235,13 +205,13 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
{
|
||||
CProperty property;
|
||||
property.PropID = NCoderPropID::kNumFastBytes;
|
||||
property.Value = UINT32(kNumFastBytesForHeaders);
|
||||
property.Value = UInt32(kNumFastBytesForHeaders);
|
||||
oneMethodInfo.CoderProperties.Add(property);
|
||||
}
|
||||
{
|
||||
CProperty property;
|
||||
property.PropID = NCoderPropID::kDictionarySize;
|
||||
property.Value = UINT32(kDictionaryForHeaders);
|
||||
property.Value = UInt32(kDictionaryForHeaders);
|
||||
oneMethodInfo.CoderProperties.Add(property);
|
||||
}
|
||||
headerMethodInfoVector.Add(oneMethodInfo);
|
||||
@@ -309,6 +279,13 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
NCoderPropID::kMultiThread, true);
|
||||
}
|
||||
}
|
||||
else if (IsBZip2Method(oneMethodInfo.MethodName))
|
||||
{
|
||||
SetOneMethodProp(oneMethodInfo,
|
||||
NCoderPropID::kNumPasses, _defaultBZip2Passes);
|
||||
}
|
||||
|
||||
|
||||
CMethodFull methodFull;
|
||||
methodFull.NumInStreams = 1;
|
||||
methodFull.NumOutStreams = 1;
|
||||
@@ -349,7 +326,7 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_DEFLATE
|
||||
#ifdef COMPRESS_DEFLATE_ENCODER
|
||||
if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0)
|
||||
{
|
||||
defined = true;
|
||||
@@ -357,7 +334,7 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPRESS_BZIP2
|
||||
#ifdef COMPRESS_BZIP2_ENCODER
|
||||
if (oneMethodInfo.MethodName.CompareNoCase(L"BZip2") == 0)
|
||||
{
|
||||
defined = true;
|
||||
@@ -410,24 +387,39 @@ HRESULT CHandler::SetCompressionMethod(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
|
||||
const CArchiveDatabaseEx *database = 0;
|
||||
#ifdef _7Z_VOL
|
||||
if(_volumes.Size() > 1)
|
||||
return E_FAIL;
|
||||
const CVolume *volume = 0;
|
||||
if (_volumes.Size() == 1)
|
||||
{
|
||||
volume = &_volumes.Front();
|
||||
database = &volume->Database;
|
||||
}
|
||||
#else
|
||||
if (_inStream != 0)
|
||||
database = &_database;
|
||||
#endif
|
||||
|
||||
// CRecordVector<bool> compressStatuses;
|
||||
CObjectVector<CUpdateItem> updateItems;
|
||||
// CRecordVector<UINT32> copyIndices;
|
||||
// CRecordVector<UInt32> copyIndices;
|
||||
|
||||
// CMyComPtr<IUpdateCallback2> updateCallback2;
|
||||
// updateCallback->QueryInterface(&updateCallback2);
|
||||
|
||||
int index = 0;
|
||||
for(int i = 0; i < numItems; i++)
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
INT32 newData;
|
||||
INT32 newProperties;
|
||||
UINT32 indexInArchive;
|
||||
Int32 newData;
|
||||
Int32 newProperties;
|
||||
UInt32 indexInArchive;
|
||||
if (!updateCallback)
|
||||
return E_FAIL;
|
||||
RINOK(updateCallback->GetUpdateItemInfo(i,
|
||||
@@ -442,7 +434,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
|
||||
if (updateItem.IndexInArchive != -1)
|
||||
{
|
||||
const CFileItem &fileItem = _database.Files[updateItem.IndexInArchive];
|
||||
const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
|
||||
updateItem.Name = fileItem.Name;
|
||||
updateItem.IsDirectory = fileItem.IsDirectory;
|
||||
updateItem.Size = fileItem.UnPackSize;
|
||||
@@ -550,7 +542,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
updateItem.Size = *(const UINT64 *)(&propVariant.uhVal);
|
||||
updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
|
||||
if (updateItem.Size != 0 && updateItem.IsAnti)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
@@ -605,40 +597,43 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
if (numItems < 2)
|
||||
compressMainHeader = false;
|
||||
|
||||
CInArchiveInfo *inArchiveInfo;
|
||||
if (!_inStream)
|
||||
inArchiveInfo = 0;
|
||||
else
|
||||
inArchiveInfo = &_database.ArchiveInfo;
|
||||
|
||||
return Update(_database,
|
||||
// compressStatuses,
|
||||
updateItems,
|
||||
// copyIndices,
|
||||
outStream, _inStream, inArchiveInfo,
|
||||
methodMode,
|
||||
(_compressHeaders ||
|
||||
(methodMode.PasswordIsDefined && _encryptHeaders)) ?
|
||||
&headerMethod : 0,
|
||||
_level != 0 && _autoFilter, // useFilters
|
||||
_level >= 8, // maxFilter
|
||||
useAdditionalHeaderStreams, compressMainHeader,
|
||||
updateCallback, _numSolidFiles, _numSolidBytes, _solidExtension,
|
||||
_removeSfxBlock);
|
||||
CUpdateOptions options;
|
||||
options.Method = &methodMode;
|
||||
options.HeaderMethod = (_compressHeaders ||
|
||||
(methodMode.PasswordIsDefined && _encryptHeaders)) ?
|
||||
&headerMethod : 0;
|
||||
options.UseFilters = _level != 0 && _autoFilter;
|
||||
options.MaxFilter = _level >= 8;
|
||||
options.UseAdditionalHeaderStreams = useAdditionalHeaderStreams;
|
||||
options.CompressMainHeader = compressMainHeader;
|
||||
options.NumSolidFiles = _numSolidFiles;
|
||||
options.NumSolidBytes = _numSolidBytes;
|
||||
options.SolidExtension = _solidExtension;
|
||||
options.RemoveSfxBlock = _removeSfxBlock;
|
||||
options.VolumeMode = _volumeMode;
|
||||
return Update(
|
||||
#ifdef _7Z_VOL
|
||||
volume ? volume->Stream: 0,
|
||||
volume ? database: 0,
|
||||
#else
|
||||
_inStream,
|
||||
database,
|
||||
#endif
|
||||
updateItems, outStream, updateCallback, options);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static int ParseStringToUINT32(const UString &srcString, UINT32 &number)
|
||||
static int ParseStringToUInt32(const UString &srcString, UInt32 &number)
|
||||
{
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UINT64 number64 = ConvertStringToUINT64(start, &end);
|
||||
if (number64 >= (UINT64(1) << 32))
|
||||
UInt64 number64 = ConvertStringToUInt64(start, &end);
|
||||
if (number64 > 0xFFFFFFFF)
|
||||
{
|
||||
number = 0;
|
||||
return 0;
|
||||
}
|
||||
number = number64;
|
||||
number = (UInt32)number64;
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@@ -647,14 +642,14 @@ static const char kByteSymbol = 'B';
|
||||
static const char kKiloByteSymbol = 'K';
|
||||
static const char kMegaByteSymbol = 'M';
|
||||
|
||||
HRESULT ParseDictionaryValues(const UString &srcStringSpec, UINT32 &dicSize)
|
||||
HRESULT ParseDictionaryValues(const UString &srcStringSpec, UInt32 &dicSize)
|
||||
{
|
||||
UString srcString = srcStringSpec;
|
||||
srcString.MakeUpper();
|
||||
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UINT64 number = ConvertStringToUINT64(start, &end);
|
||||
UInt64 number = ConvertStringToUInt64(start, &end);
|
||||
int numDigits = end - start;
|
||||
if (numDigits == 0 || srcString.Length() > numDigits + 1)
|
||||
return E_INVALIDARG;
|
||||
@@ -662,25 +657,25 @@ HRESULT ParseDictionaryValues(const UString &srcStringSpec, UINT32 &dicSize)
|
||||
{
|
||||
if (number >= kLogarithmicSizeLimit)
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UINT32)1 << number;
|
||||
dicSize = (UInt32)1 << (int)number;
|
||||
return S_OK;
|
||||
}
|
||||
switch (srcString[numDigits])
|
||||
{
|
||||
case kByteSymbol:
|
||||
if (number >= ((UINT64)1 << kLogarithmicSizeLimit))
|
||||
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UINT32)number;
|
||||
dicSize = (UInt32)number;
|
||||
break;
|
||||
case kKiloByteSymbol:
|
||||
if (number >= ((UINT64)1 << (kLogarithmicSizeLimit - 10)))
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = UINT32(number << 10);
|
||||
dicSize = UInt32(number << 10);
|
||||
break;
|
||||
case kMegaByteSymbol:
|
||||
if (number >= ((UINT64)1 << (kLogarithmicSizeLimit - 20)))
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = UINT32(number << 20);
|
||||
dicSize = UInt32(number << 20);
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
@@ -724,7 +719,7 @@ static HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
|
||||
}
|
||||
|
||||
/*
|
||||
static HRESULT SetComplexProperty(bool &boolStatus, UINT32 &number,
|
||||
static HRESULT SetComplexProperty(bool &boolStatus, UInt32 &number,
|
||||
const PROPVARIANT &value)
|
||||
{
|
||||
switch(value.vt)
|
||||
@@ -746,17 +741,17 @@ static HRESULT SetComplexProperty(bool &boolStatus, UINT32 &number,
|
||||
}
|
||||
*/
|
||||
|
||||
static HRESULT GetBindInfoPart(UString &srcString, UINT32 &coder, UINT32 &stream)
|
||||
static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
|
||||
{
|
||||
stream = 0;
|
||||
int index = ParseStringToUINT32(srcString, coder);
|
||||
int index = ParseStringToUInt32(srcString, coder);
|
||||
if (index == 0)
|
||||
return E_INVALIDARG;
|
||||
srcString.Delete(0, index);
|
||||
if (srcString[0] == 'S')
|
||||
{
|
||||
srcString.Delete(0);
|
||||
int index = ParseStringToUINT32(srcString, stream);
|
||||
int index = ParseStringToUInt32(srcString, stream);
|
||||
if (index == 0)
|
||||
return E_INVALIDARG;
|
||||
srcString.Delete(0, index);
|
||||
@@ -824,7 +819,7 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
|
||||
CProperty property;
|
||||
if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
|
||||
{
|
||||
UINT32 dicSize;
|
||||
UInt32 dicSize;
|
||||
RINOK(ParseDictionaryValues(value, dicSize));
|
||||
if (name.CompareNoCase(L"D") == 0)
|
||||
property.PropID = NCoderPropID::kDictionarySize;
|
||||
@@ -849,8 +844,8 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
|
||||
propValue = value;
|
||||
else
|
||||
{
|
||||
UINT32 number;
|
||||
if (ParseStringToUINT32(value, number) == value.Length())
|
||||
UInt32 number;
|
||||
if (ParseStringToUInt32(value, number) == value.Length())
|
||||
propValue = number;
|
||||
else
|
||||
propValue = value;
|
||||
@@ -898,7 +893,7 @@ HRESULT CHandler::SetSolidSettings(const UString &s)
|
||||
{
|
||||
const wchar_t *start = ((const wchar_t *)s2) + i;
|
||||
const wchar_t *end;
|
||||
UINT64 v = ConvertStringToUINT64(start, &end);
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (start == end)
|
||||
{
|
||||
if (s2[i++] != 'E')
|
||||
@@ -954,14 +949,14 @@ HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value)
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *values, INT32 numProperties)
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||
{
|
||||
UINT codePage = GetCurrentFileCodePage();
|
||||
COM_TRY_BEGIN
|
||||
_methods.Clear();
|
||||
_binds.Clear();
|
||||
Init();
|
||||
int minNumber = 0;
|
||||
UInt32 minNumber = 0;
|
||||
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
@@ -986,7 +981,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
int index = ParseStringToUINT32(name, _level);
|
||||
int index = ParseStringToUInt32(name, _level);
|
||||
if (index != name.Length())
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
@@ -996,15 +991,18 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
|
||||
if (_level == 0)
|
||||
{
|
||||
_copyMode = true;
|
||||
_defaultBZip2Passes = 1;
|
||||
}
|
||||
else if (_level < 5)
|
||||
{
|
||||
_defaultAlgorithm = kAlgorithmForFast;
|
||||
_defaultDicSize = kDicSizeForFast;
|
||||
_defaultMatchFinder = kMatchFinderForFast;
|
||||
_defaultBZip2Passes = 1;
|
||||
}
|
||||
else if (_level < 7)
|
||||
{
|
||||
_defaultBZip2Passes = 1;
|
||||
// normal;
|
||||
}
|
||||
else if(_level < 9)
|
||||
@@ -1012,6 +1010,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
|
||||
_defaultAlgorithm = kAlgorithmForX7;
|
||||
_defaultDicSize = kDicSizeForX7;
|
||||
_defaultFastBytes = kFastBytesForX7;
|
||||
_defaultBZip2Passes = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1019,6 +1018,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
|
||||
_defaultDicSize = kDicSizeForX9;
|
||||
_defaultFastBytes = kFastBytesForX9;
|
||||
_defaultMatchFinder = kMatchFinderForX9;
|
||||
_defaultBZip2Passes = 7;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1047,8 +1047,8 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
|
||||
}
|
||||
|
||||
|
||||
UINT32 number;
|
||||
int index = ParseStringToUINT32(name, number);
|
||||
UInt32 number;
|
||||
int index = ParseStringToUInt32(name, number);
|
||||
UString realName = name.Mid(index);
|
||||
if (index == 0)
|
||||
{
|
||||
@@ -1057,7 +1057,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
|
||||
RINOK(SetBoolProperty(_removeSfxBlock, value));
|
||||
continue;
|
||||
}
|
||||
if (name.CompareNoCase(L"F") == 0)
|
||||
else if (name.CompareNoCase(L"F") == 0)
|
||||
{
|
||||
RINOK(SetBoolProperty(_autoFilter, value));
|
||||
continue;
|
||||
@@ -1084,16 +1084,19 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
|
||||
// RINOK(SetComplexProperty(MultiThread, _multiThreadMult, value));
|
||||
continue;
|
||||
}
|
||||
else if (name.CompareNoCase(L"V") == 0)
|
||||
{
|
||||
RINOK(SetBoolProperty(_volumeMode, value));
|
||||
continue;
|
||||
}
|
||||
number = 0;
|
||||
}
|
||||
if (number > 100)
|
||||
if (number > 10000)
|
||||
return E_FAIL;
|
||||
if (number < minNumber)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
number -= minNumber;
|
||||
for(int j = _methods.Size(); j <= number; j++)
|
||||
for(int j = _methods.Size(); j <= (int)number; j++)
|
||||
{
|
||||
COneMethodInfo oneMethodInfo;
|
||||
_methods.Add(oneMethodInfo);
|
||||
@@ -1114,13 +1117,13 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
|
||||
CProperty property;
|
||||
if (realName.CompareNoCase(L"D") == 0 || realName.CompareNoCase(L"MEM") == 0)
|
||||
{
|
||||
UINT32 dicSize;
|
||||
UInt32 dicSize;
|
||||
if (value.vt == VT_UI4)
|
||||
{
|
||||
UINT32 logDicSize = value.ulVal;
|
||||
UInt32 logDicSize = value.ulVal;
|
||||
if (logDicSize >= 32)
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UINT32)1 << logDicSize;
|
||||
dicSize = (UInt32)1 << logDicSize;
|
||||
}
|
||||
else if (value.vt == VT_BSTR)
|
||||
{
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
BYTE kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
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]--; };
|
||||
SignatureInitializer() { kSignature[0]--; kFinishSignature[0]--;};
|
||||
} g_SignatureInitializer;
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,37 +1,53 @@
|
||||
// 7z/Header.h
|
||||
|
||||
#pragma once
|
||||
// 7z/7zHeader.h
|
||||
|
||||
#ifndef __7Z_HEADER_H
|
||||
#define __7Z_HEADER_H
|
||||
|
||||
// #include "Common/Types.h"
|
||||
// #include "../../../Common/CRC.h"
|
||||
|
||||
#include "7zMethodID.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
#pragma pack( push, Pragma7zHeaders)
|
||||
#pragma pack( push, 1)
|
||||
|
||||
const int kSignatureSize = 6;
|
||||
extern BYTE kSignature[kSignatureSize];
|
||||
extern Byte kSignature[kSignatureSize];
|
||||
|
||||
// #define _7Z_VOL
|
||||
// 7z-MultiVolume is not finished yet.
|
||||
// It can work already, but I still do not like some
|
||||
// things of that new multivolume format.
|
||||
// So please keep it commented.
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
extern Byte kFinishSignature[kSignatureSize];
|
||||
#endif
|
||||
|
||||
struct CArchiveVersion
|
||||
{
|
||||
BYTE Major;
|
||||
BYTE Minor;
|
||||
Byte Major;
|
||||
Byte Minor;
|
||||
};
|
||||
|
||||
const Byte kMajorVersion = 0;
|
||||
|
||||
struct CStartHeader
|
||||
{
|
||||
UINT64 NextHeaderOffset;
|
||||
UINT64 NextHeaderSize;
|
||||
UINT32 NextHeaderCRC;
|
||||
UInt64 NextHeaderOffset;
|
||||
UInt64 NextHeaderSize;
|
||||
UInt32 NextHeaderCRC;
|
||||
};
|
||||
|
||||
const UInt32 kStartHeaderSize = 20;
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
struct CFinishHeader: public CStartHeader
|
||||
{
|
||||
UInt64 ArchiveStartOffset; // data offset from end if that struct
|
||||
UInt64 AdditionalStartBlockSize; // start signature & start header size
|
||||
};
|
||||
|
||||
const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;
|
||||
#endif
|
||||
|
||||
namespace NID
|
||||
{
|
||||
enum EEnum
|
||||
@@ -70,16 +86,11 @@ namespace NID
|
||||
kComment,
|
||||
|
||||
kEncodedHeader,
|
||||
|
||||
kStartPos
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, Pragma7zHeaders)
|
||||
|
||||
const BYTE kMajorVersion = 0;
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,5 @@
|
||||
// 7zIn.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_IN_H
|
||||
#define __7Z_IN_H
|
||||
|
||||
@@ -31,11 +29,11 @@ public:
|
||||
struct CInArchiveInfo
|
||||
{
|
||||
CArchiveVersion Version;
|
||||
UINT64 StartPosition;
|
||||
UINT64 StartPositionAfterHeader;
|
||||
UINT64 DataStartPosition;
|
||||
UINT64 DataStartPosition2;
|
||||
CRecordVector<UINT64> FileInfoPopIDs;
|
||||
UInt64 StartPosition;
|
||||
UInt64 StartPositionAfterHeader;
|
||||
UInt64 DataStartPosition;
|
||||
UInt64 DataStartPosition2;
|
||||
CRecordVector<UInt64> FileInfoPopIDs;
|
||||
void Clear()
|
||||
{
|
||||
FileInfoPopIDs.Clear();
|
||||
@@ -46,10 +44,10 @@ struct CInArchiveInfo
|
||||
struct CArchiveDatabaseEx: public CArchiveDatabase
|
||||
{
|
||||
CInArchiveInfo ArchiveInfo;
|
||||
CRecordVector<UINT64> PackStreamStartPositions;
|
||||
CRecordVector<UINT32> FolderStartPackStreamIndex;
|
||||
CRecordVector<UINT64> FolderStartFileIndex;
|
||||
CRecordVector<int> FileIndexToFolderIndexMap;
|
||||
CRecordVector<UInt64> PackStreamStartPositions;
|
||||
CRecordVector<CNum> FolderStartPackStreamIndex;
|
||||
CRecordVector<CNum> FolderStartFileIndex;
|
||||
CRecordVector<CNum> FileIndexToFolderIndexMap;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
@@ -58,69 +56,88 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
||||
PackStreamStartPositions.Clear();
|
||||
FolderStartPackStreamIndex.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
FileIndexToFolderIndexMap.Clear();
|
||||
}
|
||||
|
||||
void FillFolderStartPackStream();
|
||||
void FillStartPos();
|
||||
void FillFolderStartFileIndex();
|
||||
|
||||
void Fill()
|
||||
{
|
||||
FillFolderStartPackStream();
|
||||
FillStartPos();
|
||||
FillFolderStartFileIndex();
|
||||
}
|
||||
|
||||
UINT64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
|
||||
UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
|
||||
{
|
||||
return ArchiveInfo.DataStartPosition +
|
||||
PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] +
|
||||
indexInFolder];
|
||||
}
|
||||
|
||||
UINT64 GetFolderFullPackSize(int folderIndex) const
|
||||
UInt64 GetFolderFullPackSize(int folderIndex) const
|
||||
{
|
||||
UINT32 packStreamIndex = FolderStartPackStreamIndex[folderIndex];
|
||||
CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
|
||||
const CFolder &folder = Folders[folderIndex];
|
||||
UINT64 size = 0;
|
||||
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
|
||||
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;
|
||||
UINT32 _size;
|
||||
UINT32 _pos;
|
||||
const Byte *_buffer;
|
||||
size_t _size;
|
||||
size_t _pos;
|
||||
public:
|
||||
void Init(const BYTE *buffer, UINT32 size)
|
||||
void Init(const Byte *buffer, size_t size)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_size = size;
|
||||
_pos = 0;
|
||||
}
|
||||
bool ReadByte(BYTE &b)
|
||||
bool ReadByte(Byte &b)
|
||||
{
|
||||
if(_pos >= _size)
|
||||
return false;
|
||||
b = _buffer[_pos++];
|
||||
return true;
|
||||
}
|
||||
void ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
|
||||
void ReadBytes(void *data, size_t size, size_t &processedSize)
|
||||
{
|
||||
for(processedSize = 0; processedSize < size && _pos < _size; processedSize++)
|
||||
((BYTE *)data)[processedSize] = _buffer[_pos++];
|
||||
((Byte *)data)[processedSize] = _buffer[_pos++];
|
||||
}
|
||||
|
||||
bool ReadBytes(void *data, UINT32 size)
|
||||
bool ReadBytes(void *data, size_t size)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
size_t processedSize;
|
||||
ReadBytes(data, size, processedSize);
|
||||
return (processedSize == size);
|
||||
}
|
||||
|
||||
UINT32 GetProcessedSize() const { return _pos; }
|
||||
size_t GetProcessedSize() const { return _pos; }
|
||||
};
|
||||
|
||||
class CStreamSwitch;
|
||||
@@ -129,14 +146,17 @@ class CInArchive
|
||||
friend class CStreamSwitch;
|
||||
|
||||
CMyComPtr<IInStream> _stream;
|
||||
#ifdef _7Z_VOL
|
||||
bool _finishSignature;
|
||||
#endif
|
||||
|
||||
CObjectVector<CInByte2> _inByteVector;
|
||||
CInByte2 *_inByteBack;
|
||||
|
||||
UINT64 _arhiveBeginStreamPosition;
|
||||
UINT64 _position;
|
||||
UInt64 _arhiveBeginStreamPosition;
|
||||
UInt64 _position;
|
||||
|
||||
void AddByteStream(const BYTE *buffer, UINT32 size)
|
||||
void AddByteStream(const Byte *buffer, size_t size)
|
||||
{
|
||||
_inByteVector.Add(CInByte2());
|
||||
_inByteBack = &_inByteVector.Back();
|
||||
@@ -151,62 +171,67 @@ class CInArchive
|
||||
}
|
||||
|
||||
private:
|
||||
HRESULT FindAndReadSignature(IInStream *stream, const UINT64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
||||
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 ReadBytes(IInStream *stream, void *data, UINT32 size,
|
||||
UINT32 *processedSize);
|
||||
HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize);
|
||||
HRESULT SafeReadBytes(void *data, UINT32 size);
|
||||
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 SafeReadBytes2(void *data, UINT32 size)
|
||||
HRESULT ReadBytes(void *data, size_t size)
|
||||
{
|
||||
if (!_inByteBack->ReadBytes(data, size))
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SafeReadByte2(BYTE &b)
|
||||
HRESULT ReadByte(Byte &b)
|
||||
{
|
||||
if (!_inByteBack->ReadByte(b))
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SafeReadWideCharLE(wchar_t &c)
|
||||
HRESULT ReadWideCharLE(wchar_t &c)
|
||||
{
|
||||
BYTE b1;
|
||||
Byte b1;
|
||||
if (!_inByteBack->ReadByte(b1))
|
||||
return E_FAIL;
|
||||
BYTE b2;
|
||||
Byte b2;
|
||||
if (!_inByteBack->ReadByte(b2))
|
||||
return E_FAIL;
|
||||
c = (int(b2) << 8) + b1;
|
||||
c = (wchar_t(b2) << 8) + b1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ReadNumber(UINT64 &value);
|
||||
|
||||
HRESULT ReadID(UINT64 &value)
|
||||
{
|
||||
return ReadNumber(value);
|
||||
}
|
||||
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(UInt64 size);
|
||||
HRESULT SkeepData();
|
||||
HRESULT WaitAttribute(UINT64 attribute);
|
||||
HRESULT WaitAttribute(UInt64 attribute);
|
||||
|
||||
HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo);
|
||||
HRESULT GetNextFolderItem(CFolder &itemInfo);
|
||||
HRESULT ReadHashDigests(int numItems,
|
||||
CRecordVector<bool> &digestsDefined, CRecordVector<UINT32> &digests);
|
||||
CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
|
||||
|
||||
HRESULT ReadPackInfo(
|
||||
UINT64 &dataOffset,
|
||||
CRecordVector<UINT64> &packSizes,
|
||||
UInt64 &dataOffset,
|
||||
CRecordVector<UInt64> &packSizes,
|
||||
CRecordVector<bool> &packCRCsDefined,
|
||||
CRecordVector<UINT32> &packCRCs);
|
||||
CRecordVector<UInt32> &packCRCs);
|
||||
|
||||
HRESULT ReadUnPackInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
@@ -214,31 +239,30 @@ private:
|
||||
|
||||
HRESULT ReadSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
CRecordVector<UINT64> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UINT64> &unPackSizes,
|
||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unPackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UINT32> &digests);
|
||||
CRecordVector<UInt32> &digests);
|
||||
|
||||
HRESULT CInArchive::ReadStreamsInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
UINT64 &dataOffset,
|
||||
CRecordVector<UINT64> &packSizes,
|
||||
UInt64 &dataOffset,
|
||||
CRecordVector<UInt64> &packSizes,
|
||||
CRecordVector<bool> &packCRCsDefined,
|
||||
CRecordVector<UINT32> &packCRCs,
|
||||
CRecordVector<UInt32> &packCRCs,
|
||||
CObjectVector<CFolder> &folders,
|
||||
CRecordVector<UINT64> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UINT64> &unPackSizes,
|
||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unPackSizes,
|
||||
CRecordVector<bool> &digestsDefined,
|
||||
CRecordVector<UINT32> &digests);
|
||||
|
||||
CRecordVector<UInt32> &digests);
|
||||
|
||||
|
||||
HRESULT GetNextFileItem(CFileItem &itemInfo);
|
||||
HRESULT ReadBoolVector(UINT32 numItems, CBoolVector &vector);
|
||||
HRESULT ReadBoolVector2(UINT32 numItems, CBoolVector &vector);
|
||||
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<CFileItem> &files, UInt64 type);
|
||||
HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset,
|
||||
CObjectVector<CByteBuffer> &dataVector
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword
|
||||
@@ -250,7 +274,7 @@ private:
|
||||
#endif
|
||||
);
|
||||
public:
|
||||
HRESULT Open(IInStream *stream, const UINT64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
||||
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
||||
void Close();
|
||||
|
||||
HRESULT ReadDatabase(CArchiveDatabaseEx &database
|
||||
@@ -258,7 +282,6 @@ public:
|
||||
,ICryptoGetTextPassword *getTextPassword
|
||||
#endif
|
||||
);
|
||||
HRESULT CheckIntegrity();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7zItem.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_ITEM_H
|
||||
#define __7Z_ITEM_H
|
||||
|
||||
@@ -18,38 +16,36 @@ struct CAltCoderInfo
|
||||
CByteBuffer Properties;
|
||||
};
|
||||
|
||||
typedef UInt32 CNum;
|
||||
const CNum kNumMax = 0x7FFFFFFF;
|
||||
const CNum kNumNoIndex = 0xFFFFFFFF;
|
||||
|
||||
struct CCoderInfo
|
||||
{
|
||||
UINT64 NumInStreams;
|
||||
UINT64 NumOutStreams;
|
||||
CNum NumInStreams;
|
||||
CNum NumOutStreams;
|
||||
CObjectVector<CAltCoderInfo> AltCoders;
|
||||
bool IsSimpleCoder() const
|
||||
{ return (NumInStreams == 1) && (NumOutStreams == 1); }
|
||||
};
|
||||
|
||||
struct CPackStreamInfo
|
||||
{
|
||||
UINT64 Index;
|
||||
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
|
||||
};
|
||||
|
||||
struct CBindPair
|
||||
{
|
||||
UINT64 InIndex;
|
||||
UINT64 OutIndex;
|
||||
CNum InIndex;
|
||||
CNum OutIndex;
|
||||
};
|
||||
|
||||
struct CFolder
|
||||
{
|
||||
CObjectVector<CCoderInfo> Coders;
|
||||
CRecordVector<CBindPair> BindPairs;
|
||||
CRecordVector<CPackStreamInfo> PackStreams;
|
||||
CRecordVector<UINT64> UnPackSizes;
|
||||
CRecordVector<CNum> PackStreams;
|
||||
CRecordVector<UInt64> UnPackSizes;
|
||||
UInt32 UnPackCRC;
|
||||
bool UnPackCRCDefined;
|
||||
UINT32 UnPackCRC;
|
||||
|
||||
CFolder(): UnPackCRCDefined(false) {}
|
||||
|
||||
UINT64 GetUnPackSize() const // test it
|
||||
UInt64 GetUnPackSize() const // test it
|
||||
{
|
||||
if (UnPackSizes.IsEmpty())
|
||||
return 0;
|
||||
@@ -58,33 +54,33 @@ struct CFolder
|
||||
return UnPackSizes[i];
|
||||
throw 1;
|
||||
}
|
||||
UINT64 GetNumOutStreams() const
|
||||
|
||||
CNum GetNumOutStreams() const
|
||||
{
|
||||
UINT64 result = 0;
|
||||
CNum result = 0;
|
||||
for (int i = 0; i < Coders.Size(); i++)
|
||||
result += Coders[i].NumOutStreams;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int FindBindPairForInStream(int inStreamIndex) const
|
||||
int FindBindPairForInStream(CNum inStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].InIndex == inStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
int FindBindPairForOutStream(int outStreamIndex) const
|
||||
int FindBindPairForOutStream(CNum outStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].OutIndex == outStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
int FindPackStreamArrayIndex(int inStreamIndex) const
|
||||
int FindPackStreamArrayIndex(CNum inStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < PackStreams.Size(); i++)
|
||||
if (PackStreams[i].Index == inStreamIndex)
|
||||
if (PackStreams[i] == inStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
@@ -98,51 +94,54 @@ public:
|
||||
CArchiveFileTime CreationTime;
|
||||
CArchiveFileTime LastWriteTime;
|
||||
CArchiveFileTime LastAccessTime;
|
||||
UINT64 UnPackSize;
|
||||
UINT32 Attributes;
|
||||
UINT32 FileCRC;
|
||||
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 FileCRCIsDefined;
|
||||
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),
|
||||
IsDirectory(false),
|
||||
FileCRCIsDefined(false),
|
||||
IsAnti(false),
|
||||
HasStream(true)
|
||||
IsStartPosDefined(false)
|
||||
{}
|
||||
void SetAttributes(UINT32 attributes)
|
||||
void SetAttributes(UInt32 attributes)
|
||||
{
|
||||
AreAttributesDefined = true;
|
||||
Attributes = attributes;
|
||||
}
|
||||
void SetCreationTime(CArchiveFileTime creationTime)
|
||||
void SetCreationTime(const CArchiveFileTime &creationTime)
|
||||
{
|
||||
IsCreationTimeDefined = true;
|
||||
CreationTime = creationTime;
|
||||
}
|
||||
void SetLastWriteTime(CArchiveFileTime lastWriteTime)
|
||||
void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
|
||||
{
|
||||
IsLastWriteTimeDefined = true;
|
||||
LastWriteTime = lastWriteTime;
|
||||
}
|
||||
void SetLastAccessTime(CArchiveFileTime lastAccessTime)
|
||||
void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
|
||||
{
|
||||
IsLastAccessTimeDefined = true;
|
||||
LastAccessTime = lastAccessTime;
|
||||
@@ -151,11 +150,11 @@ public:
|
||||
|
||||
struct CArchiveDatabase
|
||||
{
|
||||
CRecordVector<UINT64> PackSizes;
|
||||
CRecordVector<UInt64> PackSizes;
|
||||
CRecordVector<bool> PackCRCsDefined;
|
||||
CRecordVector<UINT32> PackCRCs;
|
||||
CRecordVector<UInt32> PackCRCs;
|
||||
CObjectVector<CFolder> Folders;
|
||||
CRecordVector<UINT64> NumUnPackStreamsVector;
|
||||
CRecordVector<CNum> NumUnPackStreamsVector;
|
||||
CObjectVector<CFileItem> Files;
|
||||
void Clear()
|
||||
{
|
||||
@@ -177,19 +176,6 @@ struct CArchiveDatabase
|
||||
}
|
||||
};
|
||||
|
||||
struct CArchiveHeaderDatabase
|
||||
{
|
||||
CRecordVector<UINT64> PackSizes;
|
||||
CObjectVector<CFolder> Folders;
|
||||
CRecordVector<UINT32> CRCs;
|
||||
void Clear()
|
||||
{
|
||||
PackSizes.Clear();
|
||||
Folders.Clear();
|
||||
CRCs.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static inline wchar_t GetHex(BYTE value)
|
||||
static wchar_t GetHex(Byte value)
|
||||
{
|
||||
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
|
||||
}
|
||||
|
||||
static bool HexCharToInt(wchar_t value, BYTE &result)
|
||||
static bool HexCharToInt(wchar_t value, Byte &result)
|
||||
{
|
||||
if (value >= '0' && value <= '9')
|
||||
result = value - '0';
|
||||
@@ -25,9 +25,9 @@ static bool HexCharToInt(wchar_t value, BYTE &result)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, BYTE &result)
|
||||
static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, Byte &result)
|
||||
{
|
||||
BYTE resultHigh, resultLow;
|
||||
Byte resultHigh, resultLow;
|
||||
if (!HexCharToInt(valueHigh, resultHigh))
|
||||
return false;
|
||||
if (!HexCharToInt(valueLow, resultLow))
|
||||
@@ -41,7 +41,7 @@ UString CMethodID::ConvertToString() const
|
||||
UString result;
|
||||
for (int i = 0; i < IDSize; i++)
|
||||
{
|
||||
BYTE b = ID[i];
|
||||
Byte b = ID[i];
|
||||
result += GetHex(b >> 4);
|
||||
result += GetHex(b & 0xF);
|
||||
}
|
||||
@@ -51,18 +51,26 @@ UString CMethodID::ConvertToString() const
|
||||
bool CMethodID::ConvertFromString(const UString &srcString)
|
||||
{
|
||||
int length = srcString.Length();
|
||||
if ((length & 1) != 0)
|
||||
if ((length & 1) != 0 || (length >> 1) > kMethodIDSize)
|
||||
return false;
|
||||
IDSize = length / 2;
|
||||
if (IDSize > kMethodIDSize)
|
||||
return false;
|
||||
UINT32 i;
|
||||
UInt32 i;
|
||||
for(i = 0; i < IDSize; i++)
|
||||
if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i]))
|
||||
return false;
|
||||
for(i = IDSize; i < kMethodIDSize; i++)
|
||||
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,34 +1,25 @@
|
||||
// 7zMethodID.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#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 = 16;
|
||||
const int kMethodIDSize = 15;
|
||||
|
||||
struct CMethodID
|
||||
{
|
||||
BYTE ID[kMethodIDSize];
|
||||
UINT32 IDSize;
|
||||
Byte ID[kMethodIDSize];
|
||||
Byte IDSize;
|
||||
UString ConvertToString() const;
|
||||
bool ConvertFromString(const UString &srcString);
|
||||
};
|
||||
|
||||
inline bool operator==(const CMethodID &a1, const CMethodID &a2)
|
||||
{
|
||||
if (a1.IDSize != a2.IDSize)
|
||||
return false;
|
||||
for (UINT32 i = 0; i < a1.IDSize; i++)
|
||||
if (a1.ID[i] != a2.ID[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool operator==(const CMethodID &a1, const CMethodID &a2);
|
||||
|
||||
inline bool operator!=(const CMethodID &a1, const CMethodID &a2)
|
||||
{ return !(a1 == a2); }
|
||||
|
||||
@@ -20,10 +20,10 @@ namespace N7z {
|
||||
static CObjectVector<CMethodInfo2> g_Methods;
|
||||
static bool g_Loaded = false;
|
||||
|
||||
typedef UINT32 (WINAPI *GetNumberOfMethodsFunc)(UINT32 *numMethods);
|
||||
typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
|
||||
|
||||
typedef UINT32 (WINAPI *GetMethodPropertyFunc)(
|
||||
UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
typedef UInt32 (WINAPI *GetMethodPropertyFunc)(
|
||||
UInt32 index, PROPID propID, PROPVARIANT *value);
|
||||
|
||||
static void Load(const CSysString &folderPrefix)
|
||||
{
|
||||
@@ -47,14 +47,14 @@ static void Load(const CSysString &folderPrefix)
|
||||
if (getMethodProperty == NULL)
|
||||
continue;
|
||||
|
||||
UINT32 numMethods = 1;
|
||||
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++)
|
||||
for(UInt32 i = 0; i < numMethods; i++)
|
||||
{
|
||||
CMethodInfo2 info;
|
||||
info.FilePath = filePath;
|
||||
|
||||
@@ -13,8 +13,8 @@ struct CMethodInfo
|
||||
UString Name;
|
||||
bool EncoderIsAssigned;
|
||||
bool DecoderIsAssigned;
|
||||
UINT32 NumInStreams;
|
||||
UINT32 NumOutStreams;
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
CLSID Encoder;
|
||||
CLSID Decoder;
|
||||
// UString Description;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,5 @@
|
||||
// 7z/Out.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_OUT_H
|
||||
#define __7Z_OUT_H
|
||||
|
||||
@@ -19,18 +17,18 @@ namespace N7z {
|
||||
|
||||
class CWriteBufferLoc
|
||||
{
|
||||
BYTE *_data;
|
||||
UINT32 _size;
|
||||
UINT32 _pos;
|
||||
Byte *_data;
|
||||
size_t _size;
|
||||
size_t _pos;
|
||||
public:
|
||||
CWriteBufferLoc(): _size(0), _pos(0) {}
|
||||
void Init(BYTE *data, UINT32 size)
|
||||
void Init(Byte *data, size_t size)
|
||||
{
|
||||
_pos = 0;
|
||||
_data = data;
|
||||
_size = size;
|
||||
}
|
||||
HRESULT Write(const void *data, UINT32 size)
|
||||
HRESULT Write(const void *data, size_t size)
|
||||
{
|
||||
if (_pos + size > _size)
|
||||
return E_FAIL;
|
||||
@@ -43,110 +41,135 @@ public:
|
||||
class CWriteDynamicBuffer
|
||||
{
|
||||
CByteDynamicBuffer _buffer;
|
||||
UINT32 _pos;
|
||||
size_t _pos;
|
||||
public:
|
||||
CWriteDynamicBuffer(): _pos(0) {}
|
||||
void Init()
|
||||
{
|
||||
_pos = 0;
|
||||
}
|
||||
void Write(const void *data, UINT32 size)
|
||||
void Write(const void *data, size_t size)
|
||||
{
|
||||
if (_pos + size > _buffer.GetCapacity())
|
||||
_buffer.EnsureCapacity(_pos + size);
|
||||
memmove(((BYTE *)_buffer) +_pos, data, size);
|
||||
memmove(((Byte *)_buffer) +_pos, data, size);
|
||||
_pos += size;
|
||||
}
|
||||
operator BYTE *() { return (BYTE *)_buffer; };
|
||||
operator const BYTE *() const { return (const BYTE *)_buffer; };
|
||||
UINT32 GetSize() const { return _pos; }
|
||||
operator Byte *() { return (Byte *)_buffer; };
|
||||
operator const Byte *() const { return (const Byte *)_buffer; };
|
||||
size_t GetSize() const { return _pos; }
|
||||
};
|
||||
|
||||
|
||||
class COutArchive
|
||||
{
|
||||
UINT64 _prefixHeaderPos;
|
||||
UInt64 _prefixHeaderPos;
|
||||
|
||||
HRESULT WriteBytes(const void *data, UINT32 size);
|
||||
HRESULT WriteBytes2(const void *data, UINT32 size);
|
||||
HRESULT WriteBytes2(const CByteBuffer &data);
|
||||
HRESULT WriteByte2(BYTE b);
|
||||
HRESULT WriteNumber(UINT64 value);
|
||||
HRESULT WriteID(UINT64 value)
|
||||
{
|
||||
return WriteNumber(value);
|
||||
}
|
||||
HRESULT 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 WriteFolderHeader(const CFolder &itemInfo);
|
||||
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);
|
||||
const CRecordVector<UInt32> &hashDigests);
|
||||
|
||||
HRESULT WritePackInfo(
|
||||
UINT64 dataOffset,
|
||||
const CRecordVector<UINT64> &packSizes,
|
||||
UInt64 dataOffset,
|
||||
const CRecordVector<UInt64> &packSizes,
|
||||
const CRecordVector<bool> &packCRCsDefined,
|
||||
const CRecordVector<UINT32> &packCRCs);
|
||||
const CRecordVector<UInt32> &packCRCs);
|
||||
|
||||
HRESULT WriteUnPackInfo(
|
||||
bool externalFolders,
|
||||
UINT64 externalFoldersStreamIndex,
|
||||
CNum externalFoldersStreamIndex,
|
||||
const CObjectVector<CFolder> &folders);
|
||||
|
||||
HRESULT WriteSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
const CRecordVector<UINT64> &numUnPackStreamsInFolders,
|
||||
const CRecordVector<UINT64> &unPackSizes,
|
||||
const CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
const CRecordVector<UInt64> &unPackSizes,
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UINT32> &hashDigests);
|
||||
const CRecordVector<UInt32> &hashDigests);
|
||||
|
||||
/*
|
||||
HRESULT WriteStreamsInfo(
|
||||
UINT64 dataOffset,
|
||||
const CRecordVector<UINT64> &packSizes,
|
||||
UInt64 dataOffset,
|
||||
const CRecordVector<UInt64> &packSizes,
|
||||
const CRecordVector<bool> &packCRCsDefined,
|
||||
const CRecordVector<UINT32> &packCRCs,
|
||||
const CRecordVector<UInt32> &packCRCs,
|
||||
bool externalFolders,
|
||||
UINT64 externalFoldersStreamIndex,
|
||||
UInt64 externalFoldersStreamIndex,
|
||||
const CObjectVector<CFolder> &folders,
|
||||
const CRecordVector<UINT64> &numUnPackStreamsInFolders,
|
||||
const CRecordVector<UINT64> &unPackSizes,
|
||||
const CRecordVector<CNum> &numUnPackStreamsInFolders,
|
||||
const CRecordVector<UInt64> &unPackSizes,
|
||||
const CRecordVector<bool> &digestsDefined,
|
||||
const CRecordVector<UINT32> &hashDigests);
|
||||
const CRecordVector<UInt32> &hashDigests);
|
||||
*/
|
||||
|
||||
|
||||
HRESULT WriteTime(const CObjectVector<CFileItem> &files, BYTE type,
|
||||
bool isExternal, int externalDataIndex);
|
||||
HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type,
|
||||
bool isExternal, CNum externalDataIndex);
|
||||
|
||||
HRESULT EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 dataSize,
|
||||
CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders);
|
||||
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);
|
||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
||||
HRESULT WriteHeader(const CArchiveDatabase &database,
|
||||
const CCompressionMethodMode *options,
|
||||
UINT64 &headerOffset);
|
||||
UInt64 &headerOffset);
|
||||
|
||||
bool _mainMode;
|
||||
|
||||
bool _dynamicMode;
|
||||
|
||||
bool _countMode;
|
||||
UINT32 _countSize;
|
||||
size_t _countSize;
|
||||
COutBuffer _outByte;
|
||||
CWriteBufferLoc _outByte2;
|
||||
CWriteDynamicBuffer _dynamicBuffer;
|
||||
CCRC _crc;
|
||||
|
||||
public:
|
||||
#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;
|
||||
HRESULT Create(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
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace N7z {
|
||||
|
||||
struct CPropMap
|
||||
{
|
||||
UINT64 FilePropID;
|
||||
UInt64 FilePropID;
|
||||
STATPROPSTG StatPROPSTG;
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@ CPropMap kPropMap[] =
|
||||
{ NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
|
||||
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
|
||||
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
|
||||
|
||||
|
||||
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
|
||||
@@ -52,7 +53,7 @@ CPropMap kPropMap[] =
|
||||
|
||||
static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
|
||||
|
||||
static int FindPropInMap(UINT64 filePropID)
|
||||
static int FindPropInMap(UInt64 filePropID)
|
||||
{
|
||||
for (int i = 0; i < kPropMapSize; i++)
|
||||
if (kPropMap[i].FilePropID == filePropID)
|
||||
@@ -60,8 +61,8 @@ static int FindPropInMap(UINT64 filePropID)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void CopyOneItem(CRecordVector<UINT64> &src,
|
||||
CRecordVector<UINT64> &dest, UINT32 item)
|
||||
static void CopyOneItem(CRecordVector<UInt64> &src,
|
||||
CRecordVector<UInt64> &dest, UInt32 item)
|
||||
{
|
||||
for (int i = 0; i < src.Size(); i++)
|
||||
if (src[i] == item)
|
||||
@@ -72,7 +73,7 @@ static void CopyOneItem(CRecordVector<UINT64> &src,
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveOneItem(CRecordVector<UINT64> &src, UINT32 item)
|
||||
static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
|
||||
{
|
||||
for (int i = 0; i < src.Size(); i++)
|
||||
if (src[i] == item)
|
||||
@@ -82,7 +83,7 @@ static void RemoveOneItem(CRecordVector<UINT64> &src, UINT32 item)
|
||||
}
|
||||
}
|
||||
|
||||
static void InsertToHead(CRecordVector<UINT64> &dest, UINT32 item)
|
||||
static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
|
||||
{
|
||||
for (int i = 0; i < dest.Size(); i++)
|
||||
if (dest[i] == item)
|
||||
@@ -96,7 +97,15 @@ static void InsertToHead(CRecordVector<UINT64> &dest, UINT32 item)
|
||||
void CHandler::FillPopIDs()
|
||||
{
|
||||
_fileInfoPopIDs.Clear();
|
||||
CRecordVector<UINT64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
if(_volumes.Size() < 1)
|
||||
return;
|
||||
const CVolume &volume = _volumes.Front();
|
||||
const CArchiveDatabaseEx &_database = volume.Database;
|
||||
#endif
|
||||
|
||||
CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
|
||||
|
||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
|
||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
|
||||
@@ -133,16 +142,16 @@ void CHandler::FillPopIDs()
|
||||
#endif
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = _fileInfoPopIDs.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= _fileInfoPopIDs.Size())
|
||||
if((int)index >= _fileInfoPopIDs.Size())
|
||||
return E_INVALIDARG;
|
||||
int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
|
||||
if (indexInMap == -1)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7zProperties.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_PROPERTIES_H
|
||||
#define __7Z_PROPERTIES_H
|
||||
|
||||
@@ -19,33 +17,6 @@ enum // PropID
|
||||
kpidPackedSize4,
|
||||
};
|
||||
|
||||
/*
|
||||
class CEnumArchiveItemProperty:
|
||||
public IEnumSTATPROPSTG,
|
||||
public CComObjectRoot
|
||||
{
|
||||
CRecordVector<UINT32> _fileInfoPopIDs;
|
||||
int _index;
|
||||
public:
|
||||
|
||||
BEGIN_COM_MAP(CEnumArchiveItemProperty)
|
||||
COM_INTERFACE_ENTRY(IEnumSTATPROPSTG)
|
||||
END_COM_MAP()
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CEnumArchiveItemProperty)
|
||||
|
||||
DECLARE_NO_REGISTRY()
|
||||
public:
|
||||
CEnumArchiveItemProperty(): _index(0) {};
|
||||
void Init(const CRecordVector<UINT32> &fileInfoPopIDs);
|
||||
|
||||
STDMETHOD(Next) (ULONG numItems, STATPROPSTG *items, ULONG *numFetched);
|
||||
STDMETHOD(Skip) (ULONG numItems);
|
||||
STDMETHOD(Reset) ();
|
||||
STDMETHOD(Clone) (IEnumSTATPROPSTG **enumerator);
|
||||
};
|
||||
*/
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "7zSpecStream.h"
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UINT32 size, UINT32 *processedSize)
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if (processedSize != 0)
|
||||
@@ -14,9 +14,9 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UINT32 size, UINT32
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if (processedSize != 0)
|
||||
@@ -25,7 +25,7 @@ STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UINT32 size, UI
|
||||
}
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
|
||||
UINT64 subStream, UINT64 *value)
|
||||
UInt64 subStream, UInt64 *value)
|
||||
{
|
||||
if (_getSubStreamSize == NULL)
|
||||
return E_NOTIMPL;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7zSpecStream.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_SPEC_STREAM_H
|
||||
#define __7Z_SPEC_STREAM_H
|
||||
|
||||
@@ -16,7 +14,7 @@ class CSequentialInStreamSizeCount2:
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> _stream;
|
||||
CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
|
||||
UINT64 _size;
|
||||
UInt64 _size;
|
||||
public:
|
||||
void Init(ISequentialInStream *stream)
|
||||
{
|
||||
@@ -25,14 +23,14 @@ public:
|
||||
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
|
||||
_size = 0;
|
||||
}
|
||||
UINT64 GetSize() const { return _size; }
|
||||
UInt64 GetSize() const { return _size; }
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||
|
||||
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value);
|
||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
|
||||
static const UINT32 kDictionaryForBCJ2_LZMA = 1 << 20;
|
||||
const UINT32 kAlgorithmForBCJ2_LZMA = 2;
|
||||
const UINT32 kNumFastBytesForBCJ2_LZMA = 64;
|
||||
static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
|
||||
static const UInt32 kAlgorithmForBCJ2_LZMA = 2;
|
||||
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, ICompressProgressInfo *progress)
|
||||
@@ -33,19 +33,17 @@ static HRESULT CopyBlock(ISequentialInStream *inStream,
|
||||
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
}
|
||||
|
||||
static HRESULT WriteRange(IInStream *inStream,
|
||||
static HRESULT WriteRange(
|
||||
ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const CUpdateRange &range,
|
||||
UInt64 size,
|
||||
IProgress *progress,
|
||||
UINT64 ¤tComplexity)
|
||||
UInt64 ¤tComplexity)
|
||||
{
|
||||
UINT64 position;
|
||||
inStream->Seek(range.Position, STREAM_SEEK_SET, &position);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream;
|
||||
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
|
||||
streamSpec->Init(inStream, range.Size);
|
||||
streamSpec->Init(inStream, size);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
@@ -58,10 +56,23 @@ static HRESULT WriteRange(IInStream *inStream,
|
||||
localCompressProgressSpec->Init(localProgress, ¤tComplexity, ¤tComplexity);
|
||||
|
||||
HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress);
|
||||
currentComplexity += range.Size;
|
||||
currentComplexity += size;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WriteRange(IInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
UInt64 position,
|
||||
UInt64 size,
|
||||
IProgress *progress,
|
||||
UInt64 ¤tComplexity)
|
||||
{
|
||||
inStream->Seek(position, STREAM_SEEK_SET, 0);
|
||||
return WriteRange(inStream, outStream,
|
||||
size, progress, currentComplexity);
|
||||
}
|
||||
|
||||
int CUpdateItem::GetExtensionPos() const
|
||||
{
|
||||
int slash1Pos = Name.ReverseFind(L'\\');
|
||||
@@ -163,8 +174,8 @@ static int __cdecl CompareFolderRefs(const void *p1, const void *p2)
|
||||
if (d1.NumUnPackStreamsVector[a1.FolderIndex] == 0)
|
||||
return 0;
|
||||
return CompareFiles(
|
||||
d1.Files[d1.FolderStartFileIndex[a1.FolderIndex]],
|
||||
d2.Files[d2.FolderStartFileIndex[a2.FolderIndex]]);
|
||||
d1.Files[(size_t)d1.FolderStartFileIndex[a1.FolderIndex]],
|
||||
d2.Files[(size_t)d2.FolderStartFileIndex[a2.FolderIndex]]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@@ -193,12 +204,12 @@ static int __cdecl CompareEmptyItems(const void *p1, const void *p2)
|
||||
|
||||
struct CRefItem
|
||||
{
|
||||
UINT32 Index;
|
||||
UInt32 Index;
|
||||
const CUpdateItem *UpdateItem;
|
||||
UINT32 ExtensionPos;
|
||||
UINT32 NamePos;
|
||||
UInt32 ExtensionPos;
|
||||
UInt32 NamePos;
|
||||
bool SortByType;
|
||||
CRefItem(UINT32 index, const CUpdateItem &updateItem, bool sortByType):
|
||||
CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
|
||||
SortByType(sortByType),
|
||||
Index(index),
|
||||
UpdateItem(&updateItem),
|
||||
@@ -257,7 +268,7 @@ static int __cdecl CompareUpdateItems(const void *p1, const void *p2)
|
||||
struct CSolidGroup
|
||||
{
|
||||
CCompressionMethodMode Method;
|
||||
CRecordVector<UINT32> Indices;
|
||||
CRecordVector<UInt32> Indices;
|
||||
};
|
||||
|
||||
static wchar_t *g_ExeExts[] =
|
||||
@@ -282,7 +293,7 @@ static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
|
||||
static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||
|
||||
static bool GetMethodFull(const CMethodID &methodID,
|
||||
UINT32 numInStreams, CMethodFull &methodResult)
|
||||
UInt32 numInStreams, CMethodFull &methodResult)
|
||||
{
|
||||
methodResult.MethodID = methodID;
|
||||
methodResult.NumInStreams = numInStreams;
|
||||
@@ -441,40 +452,43 @@ static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
|
||||
file.HasStream = updateItem.HasStream();
|
||||
}
|
||||
|
||||
HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
CObjectVector<CUpdateItem> &updateItems,
|
||||
IOutStream *outStream,
|
||||
static HRESULT Update2(
|
||||
IInStream *inStream,
|
||||
NArchive::N7z::CInArchiveInfo *inArchiveInfo,
|
||||
const CCompressionMethodMode &method,
|
||||
const CCompressionMethodMode *headerMethod,
|
||||
bool useFilters,
|
||||
bool maxFilter,
|
||||
bool useAdditionalHeaderStreams,
|
||||
bool compressMainHeader,
|
||||
const CArchiveDatabaseEx *database,
|
||||
CObjectVector<CUpdateItem> &updateItems,
|
||||
ISequentialOutStream *seqOutStream,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension,
|
||||
bool removeSfxBlock)
|
||||
const CUpdateOptions &options)
|
||||
{
|
||||
UInt64 numSolidFiles = options.NumSolidFiles;
|
||||
if (numSolidFiles == 0)
|
||||
numSolidFiles = 1;
|
||||
/*
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
|
||||
if (!outStream)
|
||||
return E_NOTIMPL;
|
||||
*/
|
||||
|
||||
UINT64 startBlockSize = inArchiveInfo != 0 ?
|
||||
inArchiveInfo->StartPosition: 0;
|
||||
if (startBlockSize > 0 && !removeSfxBlock)
|
||||
UInt64 startBlockSize = database != 0 ?
|
||||
database->ArchiveInfo.StartPosition: 0;
|
||||
if (startBlockSize > 0 && !options.RemoveSfxBlock)
|
||||
{
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(inStream, startBlockSize);
|
||||
RINOK(CopyBlock(limitedStream, outStream, NULL));
|
||||
RINOK(CopyBlock(limitedStream, seqOutStream, NULL));
|
||||
}
|
||||
|
||||
CRecordVector<int> fileIndexToUpdateIndexMap;
|
||||
fileIndexToUpdateIndexMap.Reserve(database.Files.Size());
|
||||
if (database != 0)
|
||||
{
|
||||
fileIndexToUpdateIndexMap.Reserve(database->Files.Size());
|
||||
for (int i = 0; i < database->Files.Size(); i++)
|
||||
fileIndexToUpdateIndexMap.Add(-1);
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < database.Files.Size(); i++)
|
||||
fileIndexToUpdateIndexMap.Add(-1);
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
int index = updateItems[i].IndexInArchive;
|
||||
@@ -483,15 +497,17 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
}
|
||||
|
||||
CRecordVector<CFolderRef> folderRefs;
|
||||
for(i = 0; i < database.Folders.Size(); i++)
|
||||
if (database != 0)
|
||||
{
|
||||
UINT64 indexInFolder = 0;
|
||||
UINT64 numCopyItems = 0;
|
||||
UINT64 numUnPackStreams = database.NumUnPackStreamsVector[i];
|
||||
for (int fileIndex = database.FolderStartFileIndex[i];
|
||||
for(i = 0; i < database->Folders.Size(); i++)
|
||||
{
|
||||
CNum indexInFolder = 0;
|
||||
CNum numCopyItems = 0;
|
||||
CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
|
||||
for (CNum fileIndex = database->FolderStartFileIndex[i];
|
||||
indexInFolder < numUnPackStreams; fileIndex++)
|
||||
{
|
||||
if (database.Files[fileIndex].HasStream)
|
||||
if (database->Files[fileIndex].HasStream)
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
|
||||
@@ -505,13 +521,14 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
if (numCopyItems > 0)
|
||||
{
|
||||
CFolderRef folderRef;
|
||||
folderRef.Database = &database;
|
||||
folderRef.Database = database;
|
||||
folderRef.FolderIndex = i;
|
||||
folderRefs.Add(folderRef);
|
||||
}
|
||||
}
|
||||
qsort(&folderRefs.Front(), folderRefs.Size(), sizeof(folderRefs[0]),
|
||||
CompareFolderRefs);
|
||||
}
|
||||
|
||||
CArchiveDatabase newDatabase;
|
||||
|
||||
@@ -529,7 +546,7 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
}
|
||||
else
|
||||
if (updateItem.IndexInArchive != -1)
|
||||
if (database.Files[updateItem.IndexInArchive].HasStream)
|
||||
if (database->Files[updateItem.IndexInArchive].HasStream)
|
||||
continue;
|
||||
emptyRefs.Add(&updateItem);
|
||||
}
|
||||
@@ -542,18 +559,18 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
else
|
||||
file = database.Files[updateItem.IndexInArchive];
|
||||
file = database->Files[updateItem.IndexInArchive];
|
||||
newDatabase.Files.Add(file);
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
||||
COutArchive archive;
|
||||
archive.Create(outStream);
|
||||
archive.Create(seqOutStream, false);
|
||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
||||
UINT64 complexity = 0;
|
||||
UInt64 complexity = 0;
|
||||
for(i = 0; i < folderRefs.Size(); i++)
|
||||
complexity += database.GetFolderFullPackSize(folderRefs[i].FolderIndex);
|
||||
complexity += database->GetFolderFullPackSize(folderRefs[i].FolderIndex);
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[i];
|
||||
@@ -571,34 +588,33 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
{
|
||||
int folderIndex = folderRefs[i].FolderIndex;
|
||||
|
||||
RINOK(WriteRange(inStream, archive.Stream,
|
||||
CUpdateRange(database.GetFolderStreamPos(folderIndex, 0),
|
||||
database.GetFolderFullPackSize(folderIndex)),
|
||||
RINOK(WriteRange(inStream, archive.SeqStream,
|
||||
database->GetFolderStreamPos(folderIndex, 0),
|
||||
database->GetFolderFullPackSize(folderIndex),
|
||||
updateCallback, complexity));
|
||||
|
||||
const CFolder &folder = database.Folders[folderIndex];
|
||||
UINT32 startIndex = database.FolderStartPackStreamIndex[folderIndex];
|
||||
int j;
|
||||
for (j = 0; j < folder.PackStreams.Size(); j++)
|
||||
const CFolder &folder = database->Folders[folderIndex];
|
||||
CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
|
||||
for (int j = 0; j < folder.PackStreams.Size(); j++)
|
||||
{
|
||||
newDatabase.PackSizes.Add(database.PackSizes[startIndex + j]);
|
||||
newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]);
|
||||
// newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
|
||||
// newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
|
||||
}
|
||||
newDatabase.Folders.Add(folder);
|
||||
|
||||
UINT64 numUnPackStreams = database.NumUnPackStreamsVector[folderIndex];
|
||||
CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex];
|
||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
||||
|
||||
UINT64 indexInFolder = 0;
|
||||
for (j = database.FolderStartFileIndex[folderIndex];
|
||||
indexInFolder < numUnPackStreams; j++)
|
||||
CNum indexInFolder = 0;
|
||||
for (CNum fi = database->FolderStartFileIndex[folderIndex];
|
||||
indexInFolder < numUnPackStreams; fi++)
|
||||
{
|
||||
CFileItem file = database.Files[j];
|
||||
CFileItem file = database->Files[fi];
|
||||
if (file.HasStream)
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[j];
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
||||
if (updateIndex >= 0)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[updateIndex];
|
||||
@@ -608,7 +624,7 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
FromUpdateItemToFileItem(updateItem, file2);
|
||||
file2.UnPackSize = file.UnPackSize;
|
||||
file2.FileCRC = file.FileCRC;
|
||||
file2.FileCRCIsDefined = file.FileCRCIsDefined;
|
||||
file2.IsFileCRCDefined = file.IsFileCRCDefined;
|
||||
file2.HasStream = file.HasStream;
|
||||
file = file2;
|
||||
}
|
||||
@@ -622,7 +638,8 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
// Compress New Files
|
||||
|
||||
CObjectVector<CSolidGroup> groups;
|
||||
SplitFilesToGroups(method, useFilters, maxFilter, updateItems, groups);
|
||||
SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
|
||||
updateItems, groups);
|
||||
|
||||
for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++)
|
||||
{
|
||||
@@ -637,14 +654,14 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
updateItems[group.Indices[i]], numSolidFiles > 1));
|
||||
qsort(&refItems.Front(), refItems.Size(), sizeof(refItems[0]), CompareUpdateItems);
|
||||
|
||||
CRecordVector<UINT32> indices;
|
||||
CRecordVector<UInt32> indices;
|
||||
indices.Reserve(numFiles);
|
||||
|
||||
int startFileIndexInDatabase = newDatabase.Files.Size();
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
UINT32 index = refItems[i].Index;
|
||||
UInt32 index = refItems[i].Index;
|
||||
indices.Add(index);
|
||||
/*
|
||||
const CUpdateItem &updateItem = updateItems[index];
|
||||
CFileItem file;
|
||||
if (updateItem.NewProperties)
|
||||
@@ -654,13 +671,14 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
if (file.IsAnti || file.IsDirectory)
|
||||
return E_FAIL;
|
||||
newDatabase.Files.Add(file);
|
||||
*/
|
||||
}
|
||||
|
||||
CEncoder encoder(group.Method);
|
||||
|
||||
for (i = 0; i < numFiles;)
|
||||
{
|
||||
UINT64 totalSize = 0;
|
||||
UInt64 totalSize = 0;
|
||||
int numSubFiles;
|
||||
UString prevExtension;
|
||||
for (numSubFiles = 0; i + numSubFiles < numFiles &&
|
||||
@@ -668,9 +686,9 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
|
||||
totalSize += updateItem.Size;
|
||||
if (totalSize > numSolidBytes)
|
||||
if (totalSize > options.NumSolidBytes)
|
||||
break;
|
||||
if (solidExtension)
|
||||
if (options.SolidExtension)
|
||||
{
|
||||
UString ext = updateItem.GetExtension();
|
||||
if (numSubFiles == 0)
|
||||
@@ -696,42 +714,296 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
|
||||
RINOK(encoder.Encode(solidInStream, NULL, folderItem,
|
||||
archive.Stream, newDatabase.PackSizes, compressProgress));
|
||||
archive.SeqStream, newDatabase.PackSizes, compressProgress));
|
||||
// for()
|
||||
// newDatabase.PackCRCsDefined.Add(false);
|
||||
// newDatabase.PackCRCs.Add(0);
|
||||
|
||||
newDatabase.Folders.Add(folderItem);
|
||||
|
||||
UINT32 numUnPackStreams = 0;
|
||||
CNum numUnPackStreams = 0;
|
||||
for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
|
||||
{
|
||||
const CUpdateItem &updateItem = updateItems[indices[i + subIndex]];
|
||||
CFileItem file;
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
else
|
||||
file = database->Files[updateItem.IndexInArchive];
|
||||
if (file.IsAnti || file.IsDirectory)
|
||||
return E_FAIL;
|
||||
|
||||
/*
|
||||
CFileItem &file = newDatabase.Files[
|
||||
startFileIndexInDatabase + i + subIndex];
|
||||
startFileIndexInDatabase + i + subIndex];
|
||||
*/
|
||||
if (!inStreamSpec->Processed[subIndex])
|
||||
{
|
||||
continue;
|
||||
// file.Name += L".locked";
|
||||
}
|
||||
|
||||
file.FileCRC = inStreamSpec->CRCs[subIndex];
|
||||
file.UnPackSize = inStreamSpec->Sizes[subIndex];
|
||||
if (file.UnPackSize != 0)
|
||||
{
|
||||
file.FileCRCIsDefined = true;
|
||||
file.IsFileCRCDefined = true;
|
||||
file.HasStream = true;
|
||||
numUnPackStreams++;
|
||||
complexity += file.UnPackSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
file.FileCRCIsDefined = false;
|
||||
file.IsFileCRCDefined = false;
|
||||
file.HasStream = false;
|
||||
}
|
||||
newDatabase.Files.Add(file);
|
||||
}
|
||||
// numUnPackStreams = 0 is very bad case for locked files
|
||||
// v3.13 doesn't understand it.
|
||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
||||
i += numSubFiles;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (newDatabase.Files.Size() != updateItems.Size())
|
||||
return E_FAIL;
|
||||
*/
|
||||
|
||||
return archive.WriteDatabase(newDatabase, headerMethod,
|
||||
useAdditionalHeaderStreams, compressMainHeader);
|
||||
return archive.WriteDatabase(newDatabase, options.HeaderMethod,
|
||||
options.UseAdditionalHeaderStreams, options.CompressMainHeader);
|
||||
}
|
||||
|
||||
static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options)
|
||||
{
|
||||
CAltCoderInfo altCoder;
|
||||
altCoder.MethodID.IDSize = 1;
|
||||
altCoder.MethodID.ID[0] = 0;
|
||||
CCoderInfo coder;
|
||||
coder.NumInStreams = coder.NumOutStreams = 1;
|
||||
coder.AltCoders.Add(altCoder);
|
||||
|
||||
CFolder folder;
|
||||
folder.Coders.Add(coder);
|
||||
folder.PackStreams.Add(0);
|
||||
|
||||
CNum numUnPackStreams = 0;
|
||||
if (file.UnPackSize != 0)
|
||||
{
|
||||
file.IsFileCRCDefined = true;
|
||||
file.HasStream = true;
|
||||
numUnPackStreams++;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw 1;
|
||||
file.IsFileCRCDefined = false;
|
||||
file.HasStream = false;
|
||||
}
|
||||
folder.UnPackSizes.Add(file.UnPackSize);
|
||||
|
||||
CArchiveDatabase newDatabase;
|
||||
newDatabase.Files.Add(file);
|
||||
newDatabase.Folders.Add(folder);
|
||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
||||
newDatabase.PackSizes.Add(file.UnPackSize);
|
||||
newDatabase.PackCRCsDefined.Add(false);
|
||||
newDatabase.PackCRCs.Add(file.FileCRC);
|
||||
|
||||
return archive.WriteDatabase(newDatabase,
|
||||
options.HeaderMethod,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
HRESULT UpdateVolume(
|
||||
IInStream *inStream,
|
||||
const CArchiveDatabaseEx *database,
|
||||
CObjectVector<CUpdateItem> &updateItems,
|
||||
ISequentialOutStream *seqOutStream,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
const CUpdateOptions &options)
|
||||
{
|
||||
if (updateItems.Size() != 1)
|
||||
return E_NOTIMPL;
|
||||
|
||||
CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
|
||||
RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
|
||||
if (!volumeCallback)
|
||||
return E_NOTIMPL;
|
||||
|
||||
CMyComPtr<ISequentialInStream> fileStream;
|
||||
HRESULT result = updateCallback->GetStream(0, &fileStream);
|
||||
if (result != S_OK && result != S_FALSE)
|
||||
return result;
|
||||
if (result == S_FALSE)
|
||||
return E_FAIL;
|
||||
|
||||
CFileItem file;
|
||||
|
||||
const CUpdateItem &updateItem = updateItems[0];
|
||||
if (updateItem.NewProperties)
|
||||
FromUpdateItemToFileItem(updateItem, file);
|
||||
else
|
||||
file = database->Files[updateItem.IndexInArchive];
|
||||
if (file.IsAnti || file.IsDirectory)
|
||||
return E_FAIL;
|
||||
|
||||
UInt64 complexity = 0;
|
||||
file.IsStartPosDefined = true;
|
||||
file.StartPos = 0;
|
||||
for (UInt64 volumeIndex = 0; true; volumeIndex++)
|
||||
{
|
||||
UInt64 volSize;
|
||||
RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize));
|
||||
UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true);
|
||||
CMyComPtr<ISequentialOutStream> volumeStream;
|
||||
RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
|
||||
|
||||
COutArchive archive;
|
||||
archive.Create(volumeStream, true);
|
||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
||||
|
||||
CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
|
||||
CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
|
||||
inCrcStreamSpec->Init(fileStream);
|
||||
|
||||
RINOK(WriteRange(inCrcStream, volumeStream, pureSize,
|
||||
updateCallback, complexity));
|
||||
file.UnPackSize = inCrcStreamSpec->GetSize();
|
||||
if (file.UnPackSize == 0)
|
||||
break;
|
||||
file.FileCRC = inCrcStreamSpec->GetCRC();
|
||||
RINOK(WriteVolumeHeader(archive, file, options));
|
||||
file.StartPos += file.UnPackSize;
|
||||
if (file.UnPackSize < pureSize)
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
class COutVolumeStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
int _volIndex;
|
||||
UInt64 _volSize;
|
||||
UInt64 _curPos;
|
||||
CMyComPtr<ISequentialOutStream> _volumeStream;
|
||||
COutArchive _archive;
|
||||
CCRC _crc;
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
CFileItem _file;
|
||||
CUpdateOptions _options;
|
||||
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
||||
void Init(IArchiveUpdateCallback2 *volumeCallback,
|
||||
const UString &name)
|
||||
{
|
||||
_file.Name = name;
|
||||
_file.IsStartPosDefined = true;
|
||||
_file.StartPos = 0;
|
||||
|
||||
VolumeCallback = volumeCallback;
|
||||
_volIndex = 0;
|
||||
_volSize = 0;
|
||||
}
|
||||
|
||||
HRESULT Flush();
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
HRESULT COutVolumeStream::Flush()
|
||||
{
|
||||
if (_volumeStream)
|
||||
{
|
||||
_file.UnPackSize = _curPos;
|
||||
_file.FileCRC = _crc.GetDigest();
|
||||
RINOK(WriteVolumeHeader(_archive, _file, _options));
|
||||
_archive.Close();
|
||||
_volumeStream.Release();
|
||||
_file.StartPos += _file.UnPackSize;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
while(size > 0)
|
||||
{
|
||||
if (!_volumeStream)
|
||||
{
|
||||
RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
|
||||
RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
|
||||
_volIndex++;
|
||||
_curPos = 0;
|
||||
_archive.Create(_volumeStream, true);
|
||||
RINOK(_archive.SkeepPrefixArchiveHeader());
|
||||
_crc.Init();
|
||||
continue;
|
||||
}
|
||||
UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
|
||||
UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);
|
||||
|
||||
_crc.Update(data, curSize);
|
||||
UInt32 realProcessed;
|
||||
RINOK(_volumeStream->Write(data, curSize, &realProcessed))
|
||||
data = (void *)((Byte *)data + realProcessed);
|
||||
size -= realProcessed;
|
||||
if(processedSize != NULL)
|
||||
*processedSize += realProcessed;
|
||||
_curPos += realProcessed;
|
||||
if (realProcessed != curSize)
|
||||
return E_FAIL;
|
||||
if (_curPos == pureSize)
|
||||
{
|
||||
RINOK(Flush());
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COutVolumeStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return Write(data, size, processedSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT Update(
|
||||
IInStream *inStream,
|
||||
const CArchiveDatabaseEx *database,
|
||||
CObjectVector<CUpdateItem> &updateItems,
|
||||
ISequentialOutStream *seqOutStream,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
const CUpdateOptions &options)
|
||||
{
|
||||
#ifdef _7Z_VOL
|
||||
if (seqOutStream)
|
||||
#endif
|
||||
return Update2(inStream, database, updateItems,
|
||||
seqOutStream, updateCallback, options);
|
||||
#ifdef _7Z_VOL
|
||||
if (options.VolumeMode)
|
||||
return UpdateVolume(inStream, database, updateItems,
|
||||
seqOutStream, updateCallback, options);
|
||||
COutVolumeStream *volStreamSpec = new COutVolumeStream;
|
||||
CMyComPtr<ISequentialOutStream> volStream = volStreamSpec;
|
||||
CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
|
||||
RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
|
||||
if (!volumeCallback)
|
||||
return E_NOTIMPL;
|
||||
volStreamSpec->Init(volumeCallback, L"a.7z");
|
||||
volStreamSpec->_options = options;
|
||||
RINOK(Update2(inStream, database, updateItems,
|
||||
volStream, updateCallback, options));
|
||||
return volStreamSpec->Flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 7zUpdate.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __7Z_UPDATE_H
|
||||
#define __7Z_UPDATE_H
|
||||
|
||||
@@ -13,14 +11,6 @@
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CUpdateRange
|
||||
{
|
||||
UINT64 Position;
|
||||
UINT64 Size;
|
||||
CUpdateRange() {};
|
||||
CUpdateRange(UINT64 position, UINT64 size): Position(position), Size(size) {};
|
||||
};
|
||||
|
||||
struct CUpdateItem
|
||||
{
|
||||
bool NewData;
|
||||
@@ -28,11 +18,11 @@ struct CUpdateItem
|
||||
int IndexInArchive;
|
||||
int IndexInClient;
|
||||
|
||||
UINT32 Attributes;
|
||||
UInt32 Attributes;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastWriteTime;
|
||||
|
||||
UINT64 Size;
|
||||
UInt64 Size;
|
||||
UString Name;
|
||||
|
||||
bool IsAnti;
|
||||
@@ -52,21 +42,28 @@ struct CUpdateItem
|
||||
UString GetExtension() const;
|
||||
};
|
||||
|
||||
HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
|
||||
CObjectVector<CUpdateItem> &updateItems,
|
||||
IOutStream *outStream,
|
||||
IInStream *inStream,
|
||||
CInArchiveInfo *inArchiveInfo,
|
||||
const CCompressionMethodMode &method,
|
||||
const CCompressionMethodMode *headerMethod,
|
||||
bool useFilters,
|
||||
bool maxFilter,
|
||||
bool useAdditionalHeaderStreams,
|
||||
bool compressMainHeader,
|
||||
IArchiveUpdateCallback *updateCallback,
|
||||
UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension,
|
||||
bool removeSfxBlock);
|
||||
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
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <initguid.h>
|
||||
#include "../../../Common/MyInitGuid.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#include "7zHandler.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../../Common/NewHandler.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
// {23170F69-40C1-278B-06F1-070100000100}
|
||||
@@ -38,22 +37,18 @@ STDAPI CreateObject(
|
||||
*outObject = 0;
|
||||
if (*classID != NArchive::N7z::CLSID_CFormat7z)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
int needIn = *interfaceID == IID_IInArchive;
|
||||
int needOut = *interfaceID == IID_IOutArchive;
|
||||
if (needIn || needOut)
|
||||
if (*interfaceID == IID_IInArchive)
|
||||
{
|
||||
NArchive::N7z::CHandler *temp = new NArchive::N7z::CHandler;
|
||||
if (needIn)
|
||||
{
|
||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
|
||||
*outObject = inArchive.Detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
|
||||
*outObject = outArchive.Detach();
|
||||
}
|
||||
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
|
||||
@@ -84,6 +79,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
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,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,23 +1,8 @@
|
||||
// stdafx.h
|
||||
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
/*
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <atlcom.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlguid.h>
|
||||
|
||||
#include <memory>
|
||||
#include <new.h>
|
||||
|
||||
#include <time.h>
|
||||
*/
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "7z.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,12,0,0
|
||||
PRODUCTVERSION 3,12,0,0
|
||||
FILEVERSION 4,20,0,0
|
||||
PRODUCTVERSION 4,20,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -94,14 +94,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "7z Plugin for 7-Zip\0"
|
||||
VALUE "FileVersion", "3, 12, 0, 0\0"
|
||||
VALUE "FileVersion", "4, 20, 0, 0\0"
|
||||
VALUE "InternalName", "7z\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\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", "3, 12, 0, 0\0"
|
||||
VALUE "ProductVersion", "4, 20, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
55
7zip/Archive/7z_C/7zAlloc.c
Executable file
55
7zip/Archive/7z_C/7zAlloc.c
Executable file
@@ -0,0 +1,55 @@
|
||||
/* 7zAlloc.c */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "7zAlloc.h"
|
||||
|
||||
/* #define _SZ_ALLOC_DEBUG */
|
||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
#include <stdio.h>
|
||||
int g_allocCount = 0;
|
||||
int g_allocCountTemp = 0;
|
||||
#endif
|
||||
|
||||
void *SzAlloc(size_t size)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
||||
g_allocCount++;
|
||||
#endif
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
{
|
||||
g_allocCount--;
|
||||
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
|
||||
}
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
||||
void *SzAllocTemp(size_t size)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
||||
g_allocCountTemp++;
|
||||
#endif
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFreeTemp(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
{
|
||||
g_allocCountTemp--;
|
||||
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
||||
}
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
20
7zip/Archive/7z_C/7zAlloc.h
Executable file
20
7zip/Archive/7z_C/7zAlloc.h
Executable file
@@ -0,0 +1,20 @@
|
||||
/* 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
|
||||
24
7zip/Archive/7z_C/7zBuffer.c
Executable file
24
7zip/Archive/7z_C/7zBuffer.c
Executable file
@@ -0,0 +1,24 @@
|
||||
/* 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;
|
||||
}
|
||||
19
7zip/Archive/7z_C/7zBuffer.h
Executable file
19
7zip/Archive/7z_C/7zBuffer.h
Executable file
@@ -0,0 +1,19 @@
|
||||
/* 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
|
||||
76
7zip/Archive/7z_C/7zCrc.c
Executable file
76
7zip/Archive/7z_C/7zCrc.c
Executable file
@@ -0,0 +1,76 @@
|
||||
/* 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);
|
||||
}
|
||||
24
7zip/Archive/7z_C/7zCrc.h
Executable file
24
7zip/Archive/7z_C/7zCrc.h
Executable file
@@ -0,0 +1,24 @@
|
||||
/* 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
|
||||
144
7zip/Archive/7z_C/7zDecode.c
Executable file
144
7zip/Archive/7z_C/7zDecode.c
Executable file
@@ -0,0 +1,144 @@
|
||||
/* 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;
|
||||
}
|
||||
21
7zip/Archive/7z_C/7zDecode.h
Executable file
21
7zip/Archive/7z_C/7zDecode.h
Executable file
@@ -0,0 +1,21 @@
|
||||
/* 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
|
||||
110
7zip/Archive/7z_C/7zExtract.c
Executable file
110
7zip/Archive/7z_C/7zExtract.c
Executable file
@@ -0,0 +1,110 @@
|
||||
/* 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;
|
||||
}
|
||||
20
7zip/Archive/7z_C/7zExtract.h
Executable file
20
7zip/Archive/7z_C/7zExtract.h
Executable file
@@ -0,0 +1,20 @@
|
||||
/* 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
|
||||
5
7zip/Archive/7z_C/7zHeader.c
Executable file
5
7zip/Archive/7z_C/7zHeader.c
Executable file
@@ -0,0 +1,5 @@
|
||||
/* 7zHeader.c */
|
||||
|
||||
#include "7zHeader.h"
|
||||
|
||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
55
7zip/Archive/7z_C/7zHeader.h
Executable file
55
7zip/Archive/7z_C/7zHeader.h
Executable file
@@ -0,0 +1,55 @@
|
||||
/* 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
|
||||
1300
7zip/Archive/7z_C/7zIn.c
Executable file
1300
7zip/Archive/7z_C/7zIn.c
Executable file
File diff suppressed because it is too large
Load Diff
55
7zip/Archive/7z_C/7zIn.h
Executable file
55
7zip/Archive/7z_C/7zIn.h
Executable file
@@ -0,0 +1,55 @@
|
||||
/* 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
|
||||
133
7zip/Archive/7z_C/7zItem.c
Executable file
133
7zip/Archive/7z_C/7zItem.c
Executable file
@@ -0,0 +1,133 @@
|
||||
/* 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);
|
||||
}
|
||||
90
7zip/Archive/7z_C/7zItem.h
Executable file
90
7zip/Archive/7z_C/7zItem.h
Executable file
@@ -0,0 +1,90 @@
|
||||
/* 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
|
||||
211
7zip/Archive/7z_C/7zMain.c
Executable file
211
7zip/Archive/7z_C/7zMain.c
Executable file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
14
7zip/Archive/7z_C/7zMethodID.c
Executable file
14
7zip/Archive/7z_C/7zMethodID.c
Executable file
@@ -0,0 +1,14 @@
|
||||
/* 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;
|
||||
}
|
||||
18
7zip/Archive/7z_C/7zMethodID.h
Executable file
18
7zip/Archive/7z_C/7zMethodID.h
Executable file
@@ -0,0 +1,18 @@
|
||||
/* 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
|
||||
61
7zip/Archive/7z_C/7zTypes.h
Executable file
61
7zip/Archive/7z_C/7zTypes.h
Executable file
@@ -0,0 +1,61 @@
|
||||
/* 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
|
||||
178
7zip/Archive/7z_C/7z_C.dsp
Executable file
178
7zip/Archive/7z_C/7z_C.dsp
Executable file
@@ -0,0 +1,178 @@
|
||||
# Microsoft Developer Studio Project File - Name="7z_C" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=7z_C - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "7z_C.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "7z_C.mak" CFG="7z_C - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "7z_C - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "7z_C - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "7z_C - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe"
|
||||
|
||||
!ELSEIF "$(CFG)" == "7z_C - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "7z_C - Win32 Release"
|
||||
# Name "7z_C - Win32 Debug"
|
||||
# Begin Group "LZMA"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\LZMA_C\LzmaDecode.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\LZMA_C\LzmaDecode.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zAlloc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zAlloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zBuffer.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zCrc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zCrc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zDecode.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zDecode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zExtract.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zExtract.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zHeader.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zHeader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zIn.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zIn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zItem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zItem.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zMain.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zMethodID.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zMethodID.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zTypes.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Archive/7z_C/7z_C.dsw
Executable file
29
7zip/Archive/7z_C/7z_C.dsw
Executable file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "7z_C"=.\7z_C.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
50
7zip/Archive/7z_C/makefile
Executable file
50
7zip/Archive/7z_C/makefile
Executable file
@@ -0,0 +1,50 @@
|
||||
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)
|
||||
|
||||
@@ -122,6 +122,14 @@ SOURCE=.\StdAfx.h
|
||||
# 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
|
||||
@@ -201,10 +209,6 @@ SOURCE=.\ArjIn.h
|
||||
SOURCE=.\ArjItem.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Compression"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "Compress"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
@@ -274,6 +278,10 @@ 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
|
||||
|
||||
@@ -93,13 +93,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
@@ -111,25 +111,25 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = _items.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
@@ -193,24 +193,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
/*
|
||||
class CPropgressImp: public CProgressVirt
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallBack;
|
||||
public:
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles);
|
||||
void Init(IArchiveOpenCallback *openArchiveCallback)
|
||||
{ m_OpenArchiveCallBack = openArchiveCallback; }
|
||||
CMyComPtr<IArchiveOpenCallback> Callback;
|
||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
||||
};
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles)
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallBack)
|
||||
return m_OpenArchiveCallBack->SetCompleted(numFiles, NULL);
|
||||
if (Callback)
|
||||
return Callback->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UINT64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback)
|
||||
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
try
|
||||
@@ -219,11 +219,11 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
CInArchive archive;
|
||||
if(!archive.Open(inStream, maxCheckStartPosition))
|
||||
return S_FALSE;
|
||||
if (openArchiveCallback != NULL)
|
||||
if (callback != NULL)
|
||||
{
|
||||
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
|
||||
UINT64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
RINOK(callback->SetTotal(NULL, NULL));
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
@@ -238,10 +238,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
break;
|
||||
_items.Add(itemInfo);
|
||||
archive.IncreaseRealPosition(itemInfo.PackSize);
|
||||
if (openArchiveCallback != NULL)
|
||||
if (callback != NULL)
|
||||
{
|
||||
UINT64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
}
|
||||
_stream = inStream;
|
||||
@@ -265,18 +265,18 @@ STDMETHODIMP CHandler::Close()
|
||||
//////////////////////////////////////
|
||||
// CHandler::DecompressItems
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
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));
|
||||
UInt64 totalUnPacked = 0, totalPacked = 0;
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
UINT32 i;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
{
|
||||
const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]];
|
||||
@@ -285,8 +285,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
}
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
|
||||
UINT64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UINT64 currentItemUnPacked, currentItemPacked;
|
||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UInt64 currentItemUnPacked, currentItemPacked;
|
||||
|
||||
CMyComPtr<ICompressCoder> arj1Decoder;
|
||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
||||
@@ -300,10 +300,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalUnPacked));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
INT32 askMode;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
INT32 index = allFilesMode ? i : indices[i];
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &itemInfo = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
@@ -333,7 +333,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
|
||||
UINT64 pos;
|
||||
UInt64 pos;
|
||||
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
|
||||
|
||||
streamSpec->Init(_stream, itemInfo.PackSize);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// ArjHandler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARJ_HANDLER_H
|
||||
#define __ARJ_HANDLER_H
|
||||
|
||||
@@ -19,23 +17,23 @@ class CHandler:
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Open)(IInStream *aStream,
|
||||
const UINT64 *aMaxCheckStartPosition,
|
||||
IArchiveOpenCallback *anOpenArchiveCallback);
|
||||
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(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,
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
CHandler();
|
||||
@@ -46,4 +44,4 @@ private:
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Archive/Arj/Header.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_ARJ_HEADER_H
|
||||
#define __ARCHIVE_ARJ_HEADER_H
|
||||
|
||||
@@ -14,33 +12,32 @@ const int kMaxBlockSize = 2600;
|
||||
|
||||
namespace NSignature
|
||||
{
|
||||
const BYTE kSig0 = 0x60;
|
||||
const BYTE kSig1 = 0xEA;
|
||||
const Byte kSig0 = 0x60;
|
||||
const Byte kSig1 = 0xEA;
|
||||
}
|
||||
|
||||
#pragma pack( push, Pragma_Arj_Headers)
|
||||
#pragma pack( push, 1)
|
||||
|
||||
/*
|
||||
struct CArchiveHeader
|
||||
{
|
||||
// UINT16 BasicHeaderSize;
|
||||
BYTE FirstHeaderSize;
|
||||
BYTE Version;
|
||||
BYTE ExtractVersion;
|
||||
BYTE HostOS;
|
||||
BYTE Flags;
|
||||
BYTE SecuryVersion;
|
||||
BYTE FileType;
|
||||
BYTE Reserved;
|
||||
UINT32 CreatedTime;
|
||||
UINT32 ModifiedTime;
|
||||
UINT32 ArchiveSize;
|
||||
UINT32 SecurityEnvelopeFilePosition;
|
||||
UINT16 FilespecPositionInFilename;
|
||||
UINT16 LengthOfSecurityEnvelopeSata;
|
||||
BYTE EncryptionVersion;
|
||||
BYTE LastChapter;
|
||||
// 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
|
||||
{
|
||||
@@ -70,32 +67,35 @@ namespace NFileHeader
|
||||
}
|
||||
namespace NFlags
|
||||
{
|
||||
const BYTE kGarbled = 1;
|
||||
const BYTE kVolume = 4;
|
||||
const BYTE kExtFile = 8;
|
||||
const BYTE kPathSym = 0x10;
|
||||
const BYTE kBackup= 0x20;
|
||||
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;
|
||||
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
|
||||
@@ -116,9 +116,6 @@ namespace NFileHeader
|
||||
}
|
||||
}
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, Pragma_Arj_Headers)
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,20 +6,14 @@
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/CRC.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "ArjIn.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NArj {
|
||||
|
||||
CInArchiveException::CInArchiveException(CCauseType cause):
|
||||
Cause(cause)
|
||||
{}
|
||||
|
||||
HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
|
||||
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
@@ -27,39 +21,49 @@ HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool TestMarkerCandidate(const void *testBytes, UINT32 maxSize)
|
||||
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));
|
||||
const Byte *block = ((const Byte *)(testBytes));
|
||||
if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1)
|
||||
return false;
|
||||
UINT32 blockSize = *((const UINT16 *)(block + 2));
|
||||
UInt32 blockSize = GetUInt16FromMemLE(block + 2);
|
||||
if (maxSize < 2 + 2 + blockSize + 4)
|
||||
return false;
|
||||
block += 4;
|
||||
if (blockSize == 0 || blockSize > 2600)
|
||||
return false;
|
||||
UINT32 crcFromFile = *(const UINT32 *)(block + blockSize);
|
||||
UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize);
|
||||
return (CCRC::VerifyDigest(crcFromFile, block, blockSize));
|
||||
}
|
||||
|
||||
bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit)
|
||||
bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
// _archiveInfo.StartPosition = 0;
|
||||
_position = _streamStartPosition;
|
||||
if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
|
||||
return false;
|
||||
|
||||
const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + sizeof(UINT32);
|
||||
const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4;
|
||||
|
||||
CByteBuffer byteBuffer;
|
||||
static const UINT32 kSearchMarkerBufferSize = 0x10000;
|
||||
static const UInt32 kSearchMarkerBufferSize = 0x10000;
|
||||
byteBuffer.SetCapacity(kSearchMarkerBufferSize);
|
||||
BYTE *buffer = byteBuffer;
|
||||
Byte *buffer = byteBuffer;
|
||||
|
||||
UINT32 processedSize;
|
||||
ReadBytes(buffer, 2 + 2 + kMaxBlockSize + sizeof(UINT32), &processedSize);
|
||||
UInt32 processedSize;
|
||||
ReadBytes(buffer, kMarkerSizeMax, &processedSize);
|
||||
if (processedSize == 0)
|
||||
return false;
|
||||
if (TestMarkerCandidate(buffer, processedSize))
|
||||
@@ -70,21 +74,21 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit)
|
||||
return true;
|
||||
}
|
||||
|
||||
UINT32 numBytesPrev = processedSize - 1;
|
||||
UInt32 numBytesPrev = processedSize - 1;
|
||||
memmove(buffer, buffer + 1, numBytesPrev);
|
||||
UINT64 curTestPos = _streamStartPosition + 1;
|
||||
UInt64 curTestPos = _streamStartPosition + 1;
|
||||
while(true)
|
||||
{
|
||||
if (searchHeaderSizeLimit != NULL)
|
||||
if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit)
|
||||
return false;
|
||||
UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
|
||||
UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
|
||||
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
|
||||
UINT32 numBytesInBuffer = numBytesPrev + processedSize;
|
||||
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
|
||||
if (numBytesInBuffer < 1)
|
||||
return false;
|
||||
UINT32 numTests = numBytesInBuffer;
|
||||
for(UINT32 pos = 0; pos < numTests; pos++, curTestPos++)
|
||||
UInt32 numTests = numBytesInBuffer;
|
||||
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
|
||||
{
|
||||
if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos))
|
||||
{
|
||||
@@ -100,39 +104,68 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit)
|
||||
}
|
||||
}
|
||||
|
||||
void CInArchive::IncreasePositionValue(UINT64 addValue)
|
||||
void CInArchive::IncreasePositionValue(UInt64 addValue)
|
||||
{
|
||||
_position += addValue;
|
||||
}
|
||||
|
||||
void CInArchive::IncreaseRealPosition(UINT64 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)
|
||||
bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
UInt32 realProcessedSize;
|
||||
if(ReadBytes(data, size, &realProcessedSize) != S_OK)
|
||||
throw CInArchiveException(CInArchiveException::kReadStreamError);
|
||||
return (realProcessedSize == size);
|
||||
}
|
||||
|
||||
void CInArchive::SafeReadBytes(void *data, UINT32 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()
|
||||
{
|
||||
SafeReadBytes(&_blockSize, sizeof(_blockSize));
|
||||
_blockPos = 0;
|
||||
_blockSize = SafeReadUInt16();
|
||||
if (_blockSize == 0)
|
||||
return false;
|
||||
SafeReadBytes(_block, _blockSize);
|
||||
UINT32 crcFromFile;
|
||||
ReadBytesAndTestSize(&crcFromFile, sizeof(crcFromFile));
|
||||
UInt32 crcFromFile = SafeReadUInt32();
|
||||
if (!CCRC::VerifyDigest(crcFromFile, _block, _blockSize))
|
||||
throw CInArchiveException(CInArchiveException::kCRCError);
|
||||
return true;
|
||||
@@ -140,14 +173,14 @@ bool CInArchive::ReadBlock()
|
||||
|
||||
bool CInArchive::ReadBlock2()
|
||||
{
|
||||
BYTE id[2];
|
||||
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)
|
||||
bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
_stream = inStream;
|
||||
if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK)
|
||||
@@ -173,40 +206,67 @@ 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;
|
||||
|
||||
const NFileHeader::CHeader &header = *(const NFileHeader::CHeader *)_block;
|
||||
|
||||
item.Version = header.Version;
|
||||
item.ExtractVersion = header.ExtractVersion;
|
||||
item.HostOS = header.HostOS;
|
||||
item.Flags = header.Flags;
|
||||
item.Method = header.Method;
|
||||
item.FileType = header.FileType;
|
||||
item.ModifiedTime = header.ModifiedTime;
|
||||
item.PackSize = header.PackSize;
|
||||
item.Size = header.Size;
|
||||
item.FileCRC = header.FileCRC;
|
||||
item.FileAccessMode = header.FileAccessMode;
|
||||
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;
|
||||
UInt32 extraData;
|
||||
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
|
||||
extraData = *(const UINT32 *)(_block + pos);
|
||||
extraData = GetUInt32FromMemLE(_block + pos);
|
||||
*/
|
||||
int pos = header.FirstHeaderSize;
|
||||
_blockPos = firstHeaderSize;
|
||||
|
||||
for (; pos < _blockSize; pos++)
|
||||
{
|
||||
char aByte = _block[pos];
|
||||
if (aByte == 0)
|
||||
break;
|
||||
item.Name += aByte;
|
||||
}
|
||||
for (; _blockPos < _blockSize;)
|
||||
item.Name += (char)ReadByte();
|
||||
|
||||
while(true)
|
||||
if (!ReadBlock())
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
// Archive/ArjIn.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_ARJIN_H
|
||||
#define __ARCHIVE_ARJIN_H
|
||||
|
||||
#include "Common/Exception.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
#include "Header.h"
|
||||
#include "ArjItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
@@ -27,42 +23,51 @@ public:
|
||||
kSeekStreamError
|
||||
}
|
||||
Cause;
|
||||
CInArchiveException(CCauseType cause);
|
||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
||||
};
|
||||
|
||||
class CProgressVirt
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE;
|
||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
||||
};
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
CMyComPtr<IInStream> _stream;
|
||||
UINT64 _streamStartPosition;
|
||||
UINT64 _position;
|
||||
UINT16 _blockSize;
|
||||
BYTE _block[kMaxBlockSize];
|
||||
UInt64 _streamStartPosition;
|
||||
UInt64 _position;
|
||||
UInt16 _blockSize;
|
||||
Byte _block[kMaxBlockSize];
|
||||
UInt32 _blockPos;
|
||||
|
||||
|
||||
bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit);
|
||||
bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
|
||||
|
||||
bool ReadBlock();
|
||||
bool ReadBlock2();
|
||||
|
||||
HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize);
|
||||
bool ReadBytesAndTestSize(void *data, UINT32 size);
|
||||
void SafeReadBytes(void *data, UINT32 size);
|
||||
|
||||
void IncreasePositionValue(UINT64 addValue);
|
||||
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);
|
||||
bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
|
||||
void Close();
|
||||
|
||||
void IncreaseRealPosition(UINT64 addValue);
|
||||
void IncreaseRealPosition(UInt64 addValue);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// Archive/Arj/ItemInfo.h
|
||||
// Archive/ArjItem.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_ARJ_ITEMINFO_H
|
||||
#define __ARCHIVE_ARJ_ITEMINFO_H
|
||||
#ifndef __ARCHIVE_ARJ_ITEM_H
|
||||
#define __ARCHIVE_ARJ_ITEM_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/String.h"
|
||||
@@ -14,8 +12,8 @@ namespace NArj {
|
||||
|
||||
struct CVersion
|
||||
{
|
||||
BYTE Version;
|
||||
BYTE HostOS;
|
||||
Byte Version;
|
||||
Byte HostOS;
|
||||
};
|
||||
|
||||
inline bool operator==(const CVersion &v1, const CVersion &v2)
|
||||
@@ -26,29 +24,29 @@ inline bool operator!=(const CVersion &v1, const CVersion &v2)
|
||||
class CItem
|
||||
{
|
||||
public:
|
||||
BYTE Version;
|
||||
BYTE ExtractVersion;
|
||||
BYTE HostOS;
|
||||
BYTE Flags;
|
||||
BYTE Method;
|
||||
BYTE FileType;
|
||||
UINT32 ModifiedTime;
|
||||
UINT32 PackSize;
|
||||
UINT32 Size;
|
||||
UINT32 FileCRC;
|
||||
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;
|
||||
// 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 GetWinAttributes() const
|
||||
{
|
||||
DWORD winAtrributes;
|
||||
UInt32 winAtrributes;
|
||||
switch(HostOS)
|
||||
{
|
||||
case NFileHeader::NHostOS::kMSDOS:
|
||||
@@ -67,7 +65,7 @@ public:
|
||||
class CItemEx: public CItem
|
||||
{
|
||||
public:
|
||||
UINT64 DataPosition;
|
||||
UInt64 DataPosition;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../ICoder.h"
|
||||
@@ -63,6 +62,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
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,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <limits.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "arj.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEVERSION 4,13,0,0
|
||||
PRODUCTVERSION 4,13,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -94,14 +94,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "Arj Plugin for 7-Zip\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "FileVersion", "4, 13, 0, 0\0"
|
||||
VALUE "InternalName", "arj\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\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", "3, 9, 2, 0\0"
|
||||
VALUE "ProductVersion", "4, 13, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -126,6 +126,14 @@ SOURCE=.\StdAfx.h
|
||||
# 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
|
||||
@@ -134,12 +142,28 @@ 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"
|
||||
|
||||
@@ -186,6 +210,10 @@ 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
|
||||
|
||||
@@ -44,13 +44,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
@@ -62,25 +62,25 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
@@ -101,7 +101,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -109,15 +109,15 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
{
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition));
|
||||
const int kSignatureSize = 3;
|
||||
BYTE buffer[kSignatureSize];
|
||||
UINT32 processedSize;
|
||||
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;
|
||||
UInt64 endPosition;
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition));
|
||||
_item.PackSize = endPosition - _streamStartPosition;
|
||||
|
||||
@@ -138,11 +138,11 @@ STDMETHODIMP CHandler::Close()
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == UINT32(-1));
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (!allFilesMode)
|
||||
{
|
||||
if (numItems == 0)
|
||||
@@ -157,12 +157,12 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
|
||||
extractCallback->SetTotal(_item.PackSize);
|
||||
|
||||
UINT64 currentTotalPacked = 0;
|
||||
UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
INT32 askMode;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
|
||||
@@ -171,8 +171,27 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
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);
|
||||
@@ -182,31 +201,72 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
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));
|
||||
|
||||
#ifndef COMPRESS_BZIP2
|
||||
CCoderLibrary lib;
|
||||
#endif
|
||||
CMyComPtr<ICompressCoder> decoder;
|
||||
#ifdef COMPRESS_BZIP2
|
||||
decoder = new NCompress::NBZip2::CDecoder;
|
||||
#else
|
||||
RINOK(lib.LoadAndCreateCoder(
|
||||
GetBZip2CodecPath(),
|
||||
CLSID_CCompressBZip2Decoder, &decoder));
|
||||
#endif
|
||||
|
||||
HRESULT result = decoder->Code(_stream, outStream, NULL, NULL, progress);
|
||||
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();
|
||||
if (result == S_FALSE)
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError))
|
||||
else if (result == S_OK)
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kOK))
|
||||
|
||||
int retResult;
|
||||
if (result == S_OK)
|
||||
retResult = NArchive::NExtract::NOperationResult::kOK;
|
||||
else
|
||||
return result;
|
||||
retResult = NArchive::NExtract::NOperationResult::kDataError;
|
||||
|
||||
RINOK(extractCallback->SetOperationResult(retResult));
|
||||
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// BZip2/Handler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BZIP2_HANDLER_H
|
||||
#define __BZIP2_HANDLER_H
|
||||
|
||||
@@ -15,45 +13,52 @@ 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_IMP2(
|
||||
MY_UNKNOWN_IMP3(
|
||||
IInArchive,
|
||||
IOutArchive
|
||||
IOutArchive,
|
||||
ISetProperties
|
||||
)
|
||||
|
||||
STDMETHOD(Open)(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
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(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,
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
|
||||
// IOutArchiveHandler
|
||||
|
||||
STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
|
||||
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
STDMETHOD(GetFileTimeType)(UInt32 *type);
|
||||
|
||||
STDMETHOD(GetFileTimeType)(UINT32 *type);
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
|
||||
private:
|
||||
CMyComPtr<IInStream> _stream;
|
||||
NArchive::NBZip2::CItem _item;
|
||||
UINT64 _streamStartPosition;
|
||||
CHandler() { InitMethodProperties(); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -5,41 +5,40 @@
|
||||
#include "BZip2Handler.h"
|
||||
#include "BZip2Update.h"
|
||||
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/Defs.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;
|
||||
|
||||
static const int kNumItemInArchive = 1;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type)
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
||||
{
|
||||
*type = NFileTimeType::kUnix;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT CopyStreams(IInStream *inStream, IOutStream *outStream,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
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(IOutStream *outStream, UINT32 numItems,
|
||||
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
if (numItems != 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
INT32 newData;
|
||||
INT32 newProperties;
|
||||
UINT32 indexInArchive;
|
||||
Int32 newData;
|
||||
Int32 newProperties;
|
||||
UInt32 indexInArchive;
|
||||
if (!updateCallback)
|
||||
return E_FAIL;
|
||||
RINOK(updateCallback->GetUpdateItemInfo(0,
|
||||
@@ -47,17 +46,6 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
|
||||
if (IntToBool(newProperties))
|
||||
{
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(0, kpidAttributes, &propVariant));
|
||||
if (propVariant.vt == VT_UI4)
|
||||
{
|
||||
if (NFile::NFind::NAttributes::IsDirectory(propVariant.ulVal))
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (propVariant.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant));
|
||||
@@ -73,15 +61,15 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
|
||||
if (IntToBool(newData))
|
||||
{
|
||||
UINT64 size;
|
||||
UInt64 size;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = *(UINT64 *)(&propVariant.uhVal);
|
||||
size = propVariant.uhVal.QuadPart;
|
||||
}
|
||||
return UpdateArchive(size, outStream, 0, updateCallback);
|
||||
return UpdateArchive(size, outStream, 0, _numPasses, updateCallback);
|
||||
}
|
||||
if (indexInArchive != 0)
|
||||
return E_INVALIDARG;
|
||||
@@ -89,4 +77,83 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
|
||||
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,7 +1,5 @@
|
||||
// Archive/BZip2Item.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_BZIP2_ITEM_H
|
||||
#define __ARCHIVE_BZIP2_ITEM_H
|
||||
|
||||
@@ -10,8 +8,8 @@ namespace NBZip2 {
|
||||
|
||||
struct CItem
|
||||
{
|
||||
UINT64 PackSize;
|
||||
UINT64 UnPackSize;
|
||||
UInt64 PackSize;
|
||||
UInt64 UnPackSize;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "BZip2Update.h"
|
||||
|
||||
@@ -21,17 +20,17 @@ extern CSysString GetBZip2CodecPath();
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
HRESULT UpdateArchive(UINT64 unpackSize,
|
||||
IOutStream *outStream,
|
||||
HRESULT UpdateArchive(UInt64 unpackSize,
|
||||
ISequentialOutStream *outStream,
|
||||
int indexInClient,
|
||||
UInt32 numPasses,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
RINOK(updateCallback->SetTotal(unpackSize));
|
||||
|
||||
UINT64 complexity = 0;
|
||||
UInt64 complexity = 0;
|
||||
RINOK(updateCallback->SetCompleted(&complexity));
|
||||
|
||||
CMyComPtr<IInStream> fileInStream;
|
||||
CMyComPtr<ISequentialInStream> fileInStream;
|
||||
|
||||
RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
|
||||
|
||||
@@ -49,6 +48,27 @@ HRESULT UpdateArchive(UINT64 unpackSize,
|
||||
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));
|
||||
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
// BZip2Update.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BZIP2_UPDATE_H
|
||||
#define __BZIP2_UPDATE_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
#include "../IArchive.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
HRESULT UpdateArchive(
|
||||
UINT64 unpackSize,
|
||||
IOutStream *outStream,
|
||||
UInt64 unpackSize,
|
||||
ISequentialOutStream *outStream,
|
||||
int indexInClient,
|
||||
UInt32 numPasses,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
}}
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/String.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "BZip2Handler.h"
|
||||
#include "../../ICoder.h"
|
||||
@@ -99,6 +97,14 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
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,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "bz2.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,12,0,0
|
||||
PRODUCTVERSION 3,12,0,0
|
||||
FILEVERSION 4,19,0,0
|
||||
PRODUCTVERSION 4,19,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -94,14 +94,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "BZip2 Plugin for 7-Zip\0"
|
||||
VALUE "FileVersion", "3, 12, 0, 0\0"
|
||||
VALUE "FileVersion", "4, 19, 0, 0\0"
|
||||
VALUE "InternalName", "bz2\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "bz.dll\0"
|
||||
VALUE "OriginalFilename", "bz2.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 12, 0, 0\0"
|
||||
VALUE "ProductVersion", "4, 19, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -122,6 +122,22 @@ SOURCE=.\StdAfx.h
|
||||
# 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
|
||||
@@ -319,6 +335,10 @@ SOURCE=..\..\Compress\LZ\LZOutWindow.h
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bitmap1.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cab.ico
|
||||
# End Source File
|
||||
# End Target
|
||||
|
||||
@@ -9,51 +9,57 @@
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
static const UINT32 kBufferSize = 1 << 17;
|
||||
static const UInt32 kBufferSize = 1 << 17;
|
||||
|
||||
/*
|
||||
void CCopyDecoder::ReleaseStreams()
|
||||
{
|
||||
m_InStream.ReleaseStream();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
|
||||
class CCopyDecoderFlusher
|
||||
{
|
||||
CCopyDecoder *m_Decoder;
|
||||
public:
|
||||
CCopyDecoderFlusher(CCopyDecoder *aDecoder): m_Decoder(aDecoder) {}
|
||||
CCopyDecoderFlusher(CCopyDecoder *decoder): m_Decoder(decoder) {}
|
||||
~CCopyDecoderFlusher()
|
||||
{
|
||||
m_Decoder->Flush();
|
||||
// m_Decoder->ReleaseStreams();
|
||||
m_Decoder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
STDMETHODIMP CCopyDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
UINT64 size = *outSize;
|
||||
UInt64 size = *outSize;
|
||||
|
||||
m_InStream.Init(inStream, m_ReservedSize, m_NumInDataBlocks);
|
||||
m_OutStream.Init(outStream);
|
||||
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;
|
||||
UInt64 nowPos64 = 0;
|
||||
while(nowPos64 < size)
|
||||
{
|
||||
UINT32 blockSize;
|
||||
UInt32 blockSize;
|
||||
bool dataAreCorrect;
|
||||
RINOK(m_InStream.ReadBlock(blockSize, dataAreCorrect));
|
||||
if (!dataAreCorrect)
|
||||
{
|
||||
throw 123456;
|
||||
}
|
||||
for (UINT32 i = 0; i < blockSize; i++)
|
||||
for (UInt32 i = 0; i < blockSize; i++)
|
||||
m_OutStream.WriteByte(m_InStream.ReadByte());
|
||||
nowPos64 += blockSize;
|
||||
if (progress != NULL)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef __ARCHIVE_CAB_COPY_DECODER_H
|
||||
#define __ARCHIVE_CAB_COPY_DECODER_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
@@ -19,18 +17,18 @@ class CCopyDecoder:
|
||||
{
|
||||
CInBuffer m_InStream;
|
||||
COutBuffer m_OutStream;
|
||||
BYTE m_ReservedSize;
|
||||
UINT32 m_NumInDataBlocks;
|
||||
Byte m_ReservedSize;
|
||||
UInt32 m_NumInDataBlocks;
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// void ReleaseStreams();
|
||||
void ReleaseStreams();
|
||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
||||
void SetParams(BYTE reservedSize, UINT32 numInDataBlocks)
|
||||
void SetParams(Byte reservedSize, UInt32 numInDataBlocks)
|
||||
{
|
||||
m_ReservedSize = reservedSize;
|
||||
m_NumInDataBlocks = numInDataBlocks;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
// Cab/Handler.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#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 "MSZipDecoder.h"
|
||||
|
||||
#include "CabHandler.h"
|
||||
|
||||
@@ -57,13 +58,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
@@ -75,19 +76,19 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
@@ -107,7 +108,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
propVariant = MultiByteToUnicodeString(fileInfo.Name, CP_ACP);
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
propVariant = fileInfo.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = fileInfo.UnPackSize;
|
||||
@@ -131,7 +132,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
|
||||
case kpidMethod:
|
||||
{
|
||||
UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
m_Folders.Size(), fileInfo.FolderIndex);
|
||||
const NHeader::CFolder &folder = m_Folders[realFolderIndex];
|
||||
UString method;
|
||||
@@ -144,14 +145,14 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
|
||||
{
|
||||
method += L":";
|
||||
wchar_t temp[32];
|
||||
_itow (folder.CompressionTypeMinor, temp, 10);
|
||||
ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
|
||||
method += temp;
|
||||
}
|
||||
propVariant = method;
|
||||
break;
|
||||
}
|
||||
case kpidBlock:
|
||||
propVariant = UINT32(fileInfo.FolderIndex);
|
||||
propVariant = UInt32(fileInfo.FolderIndex);
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
@@ -163,20 +164,20 @@ class CPropgressImp: public CProgressVirt
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
||||
public:
|
||||
STDMETHOD(SetTotal)(const UINT64 *numFiles);
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles);
|
||||
STDMETHOD(SetTotal)(const UInt64 *numFiles);
|
||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
||||
void Init(IArchiveOpenCallback *openArchiveCallback)
|
||||
{ m_OpenArchiveCallback = openArchiveCallback; }
|
||||
};
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetTotal(const UINT64 *numFiles)
|
||||
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallback)
|
||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles)
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
||||
{
|
||||
if (m_OpenArchiveCallback)
|
||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||
@@ -184,7 +185,7 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles)
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -222,8 +223,8 @@ class CCabFolderOutStream:
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
private:
|
||||
const CObjectVector<NHeader::CFolder> *m_Folders;
|
||||
const CObjectVector<CItem> *m_Files;
|
||||
@@ -232,17 +233,17 @@ private:
|
||||
int m_StartIndex;
|
||||
int m_CurrentIndex;
|
||||
int m_NumFiles;
|
||||
UINT64 m_CurrentDataPos;
|
||||
UInt64 m_CurrentDataPos;
|
||||
CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
|
||||
bool m_TestMode;
|
||||
|
||||
bool m_FileIsOpen;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
UINT64 m_FilePos;
|
||||
UInt64 m_FilePos;
|
||||
|
||||
HRESULT OpenFile(int indexIndex, ISequentialOutStream **realOutStream);
|
||||
HRESULT WriteEmptyFiles();
|
||||
UINT64 m_StartImportantTotalUnPacked;
|
||||
UInt64 m_StartImportantTotalUnPacked;
|
||||
public:
|
||||
void Init(
|
||||
const CObjectVector<NHeader::CFolder> *folders,
|
||||
@@ -252,7 +253,7 @@ public:
|
||||
int startIndex,
|
||||
int numFiles,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
UINT64 startImportantTotalUnPacked,
|
||||
UInt64 startImportantTotalUnPacked,
|
||||
bool testMode);
|
||||
HRESULT FlushCorrupted();
|
||||
HRESULT Unsupported();
|
||||
@@ -266,7 +267,7 @@ void CCabFolderOutStream::Init(
|
||||
int startIndex,
|
||||
int numFiles,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
UINT64 startImportantTotalUnPacked,
|
||||
UInt64 startImportantTotalUnPacked,
|
||||
bool testMode)
|
||||
{
|
||||
m_Folders = folders;
|
||||
@@ -289,7 +290,7 @@ HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **rea
|
||||
|
||||
int fullIndex = m_StartIndex + indexIndex;
|
||||
|
||||
INT32 askMode;
|
||||
Int32 askMode;
|
||||
if((*m_ExtractStatuses)[fullIndex])
|
||||
askMode = m_TestMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
@@ -299,12 +300,12 @@ HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **rea
|
||||
|
||||
int index = (*m_FileIndexes)[fullIndex];
|
||||
const CItem &fileInfo = (*m_Files)[index];
|
||||
UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
m_Folders->Size(), fileInfo.FolderIndex);
|
||||
|
||||
RINOK(m_ExtractCallback->GetStream(index, realOutStream, askMode));
|
||||
|
||||
UINT64 currentUnPackSize = fileInfo.UnPackSize;
|
||||
UInt64 currentUnPackSize = fileInfo.UnPackSize;
|
||||
|
||||
bool mustBeProcessedAnywhere = (indexIndex < m_NumFiles - 1);
|
||||
|
||||
@@ -345,28 +346,28 @@ HRESULT CCabFolderOutStream::WriteEmptyFiles()
|
||||
}
|
||||
|
||||
STDMETHODIMP CCabFolderOutStream::Write(const void *data,
|
||||
UINT32 size, UINT32 *processedSize)
|
||||
UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UINT32 processedSizeReal = 0;
|
||||
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;
|
||||
UInt64 fileSize = fileInfo.UnPackSize;
|
||||
|
||||
UINT32 numBytesToWrite = (UINT32)MyMin(fileSize - m_FilePos,
|
||||
UINT64(size - processedSizeReal));
|
||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - m_FilePos,
|
||||
UInt64(size - processedSizeReal));
|
||||
|
||||
UINT32 processedSizeLocal;
|
||||
UInt32 processedSizeLocal;
|
||||
if (!realOutStream)
|
||||
{
|
||||
processedSizeLocal = numBytesToWrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(realOutStream->Write((const BYTE *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal));
|
||||
RINOK(realOutStream->Write((const Byte *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal));
|
||||
}
|
||||
m_FilePos += processedSizeLocal;
|
||||
processedSizeReal += processedSizeLocal;
|
||||
@@ -401,14 +402,14 @@ STDMETHODIMP CCabFolderOutStream::Write(const void *data,
|
||||
|
||||
HRESULT CCabFolderOutStream::FlushCorrupted()
|
||||
{
|
||||
// UINT32 processedSizeReal = 0;
|
||||
// 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;
|
||||
UInt64 fileSize = fileInfo.UnPackSize;
|
||||
|
||||
realOutStream.Release();
|
||||
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError));
|
||||
@@ -441,29 +442,29 @@ HRESULT CCabFolderOutStream::Unsupported()
|
||||
}
|
||||
|
||||
STDMETHODIMP CCabFolderOutStream::WritePart(const void *data,
|
||||
UINT32 size, UINT32 *processedSize)
|
||||
UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return Write(data, size, processedSize);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == UINT32(-1));
|
||||
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;
|
||||
UInt64 censoredTotalUnPacked = 0, importantTotalUnPacked = 0;
|
||||
int lastIndex = 0;
|
||||
CRecordVector<int> folderIndexes;
|
||||
CRecordVector<int> importantIndices;
|
||||
CRecordVector<bool> extractStatuses;
|
||||
|
||||
UINT32 i;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
{
|
||||
int index = allFilesMode ? i : indices[i];
|
||||
@@ -479,7 +480,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
folderIndexes.Add(folderIndex);
|
||||
}
|
||||
|
||||
for(int j = index - 1; j >= lastIndex; j--)
|
||||
int j;
|
||||
for(j = index - 1; j >= lastIndex; j--)
|
||||
if(m_Files[j].FolderIndex != folderIndex)
|
||||
break;
|
||||
for(j++; j <= index; j++)
|
||||
@@ -493,8 +495,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
}
|
||||
|
||||
extractCallback->SetTotal(importantTotalUnPacked);
|
||||
UINT64 currentImportantTotalUnPacked = 0;
|
||||
UINT64 currentImportantTotalPacked = 0;
|
||||
UInt64 currentImportantTotalUnPacked = 0;
|
||||
UInt64 currentImportantTotalPacked = 0;
|
||||
|
||||
CCopyDecoder *storeDecoderSpec = NULL;
|
||||
CMyComPtr<ICompressCoder> storeDecoder;
|
||||
@@ -507,16 +509,17 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
|
||||
|
||||
int curImportantIndexIndex = 0;
|
||||
UINT64 totalFolderUnPacked;
|
||||
for(i = 0; i < (UINT32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked)
|
||||
UInt64 totalFolderUnPacked;
|
||||
for(i = 0; i < (UInt32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked)
|
||||
{
|
||||
int folderIndex = folderIndexes[i];
|
||||
UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
|
||||
m_Folders.Size(), folderIndex);
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked));
|
||||
totalFolderUnPacked = 0;
|
||||
for (int j = curImportantIndexIndex; j < importantIndices.Size(); j++)
|
||||
int j;
|
||||
for (j = curImportantIndexIndex; j < importantIndices.Size(); j++)
|
||||
{
|
||||
const CItem &fileInfo = m_Files[importantIndices[j]];
|
||||
if (fileInfo.FolderIndex != folderIndex)
|
||||
@@ -537,7 +540,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
|
||||
curImportantIndexIndex = j;
|
||||
|
||||
UINT64 pos = folder.DataStart; // test it (+ archiveStart)
|
||||
UInt64 pos = folder.DataStart; // test it (+ archiveStart)
|
||||
RINOK(m_Stream->Seek(pos, STREAM_SEEK_SET, NULL));
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
@@ -550,7 +553,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
localCompressProgressSpec->Init(progress,
|
||||
NULL, ¤tImportantTotalUnPacked);
|
||||
|
||||
BYTE reservedSize = m_ArchiveInfo.ReserveBlockPresent() ?
|
||||
Byte reservedSize = m_ArchiveInfo.ReserveBlockPresent() ?
|
||||
m_ArchiveInfo.PerDataSizes.PerDatablockAreaSize : 0;
|
||||
|
||||
switch(folder.GetCompressionMethod())
|
||||
@@ -625,7 +628,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*numItems = m_Files.Size();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// CabHandler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CAB_HANDLER_H
|
||||
#define __CAB_HANDLER_H
|
||||
|
||||
@@ -20,22 +18,22 @@ public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Open)(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
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(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,
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
private:
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace NHeader{
|
||||
|
||||
namespace NArchive {
|
||||
|
||||
UINT32 kSignature = 0x4643534d + 1;
|
||||
UInt32 kSignature = 0x4643534d + 1;
|
||||
static class CSignatureInitializer
|
||||
{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer;
|
||||
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
// Archive/Cab/Header.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_HEADER_H
|
||||
#define __ARCHIVE_CAB_HEADER_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
#pragma pack(push, PragmaCabHeaders)
|
||||
#pragma pack(push, 1)
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NHeader{
|
||||
|
||||
namespace NArchive {
|
||||
|
||||
extern UINT32 kSignature;
|
||||
extern UInt32 kSignature;
|
||||
|
||||
namespace NFlags
|
||||
{
|
||||
@@ -25,55 +20,61 @@ namespace NArchive {
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
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 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; }
|
||||
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;
|
||||
@@ -83,7 +84,7 @@ namespace NFolderIndex
|
||||
const int kContinuedFromPrev = 0xFFFD;
|
||||
const int kContinuedToNext = 0xFFFE;
|
||||
const int kContinuedPrevAndNext = 0xFFFF;
|
||||
inline UINT16 GetRealFolderIndex(UINT16 aNumFolders, UINT16 aFolderIndex)
|
||||
inline UInt16 GetRealFolderIndex(UInt16 aNumFolders, UInt16 aFolderIndex)
|
||||
{
|
||||
switch(aFolderIndex)
|
||||
{
|
||||
@@ -98,20 +99,19 @@ namespace NFolderIndex
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
UInt32 UnPackSize; // uncompressed size of this file in bytes
|
||||
UInt32 UnPackOffset; // uncompressed offset of this file in the folder
|
||||
UInt16 FolderIndex; // index into the CFFOLDER area
|
||||
UInt16 PureDate;
|
||||
UInt16 PureTime; // Time
|
||||
UInt16 Attributes; // attribute flags for this file
|
||||
Byte szName[]; // name of this file
|
||||
};
|
||||
|
||||
*/
|
||||
}}}
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, PragmaCabHeaders)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,38 +11,38 @@
|
||||
namespace NArchive{
|
||||
namespace NCab{
|
||||
|
||||
static HRESULT ReadBytes(IInStream *inStream, void *data, UINT32 size)
|
||||
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
UInt32 realProcessedSize;
|
||||
RINOK(inStream->Read(data, size, &realProcessedSize));
|
||||
if(realProcessedSize != size)
|
||||
return S_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT SafeRead(IInStream *inStream, void *data, UINT32 size)
|
||||
static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
UInt32 realProcessedSize;
|
||||
RINOK(inStream->Read(data, size, &realProcessedSize));
|
||||
if(realProcessedSize != size)
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void SafeInByteRead(CInBuffer &inBuffer, void *data, UINT32 size)
|
||||
static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
UInt32 realProcessedSize;
|
||||
inBuffer.ReadBytes(data, size, realProcessedSize);
|
||||
if(realProcessedSize != size)
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
}
|
||||
|
||||
static void SafeReadName(CInBuffer &inBuffer, AString &name)
|
||||
static void SafeReadName(::CInBuffer &inBuffer, AString &name)
|
||||
{
|
||||
name.Empty();
|
||||
while(true)
|
||||
{
|
||||
BYTE b;
|
||||
Byte b;
|
||||
if (!inBuffer.ReadByte(b))
|
||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||
if (b == 0)
|
||||
@@ -51,31 +51,63 @@ static void SafeReadName(CInBuffer &inBuffer, AString &name)
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CInArchiveInfo &inArchiveInfo,
|
||||
CObjectVector<NHeader::CFolder> &folders,
|
||||
CObjectVector<CItem> &files,
|
||||
CProgressVirt *progressVirt)
|
||||
{
|
||||
UINT64 startPosition;
|
||||
UInt64 startPosition;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition));
|
||||
|
||||
NHeader::NArchive::CBlock archiveHeader;
|
||||
// NHeader::NArchive::CBlock archiveHeader;
|
||||
|
||||
{
|
||||
CInBuffer inBuffer;
|
||||
inBuffer.Init(inStream);
|
||||
UINT64 value = 0;
|
||||
const int kSignatureSize = sizeof(value);
|
||||
UINT64 kSignature64 = NHeader::NArchive::kSignature;
|
||||
::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;
|
||||
Byte b;
|
||||
if (!inBuffer.ReadByte(b))
|
||||
return S_FALSE;
|
||||
value >>= 8;
|
||||
value |= ((UINT64)b) << ((kSignatureSize - 1) * 8);
|
||||
value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
|
||||
if (inBuffer.GetProcessedSize() >= kSignatureSize)
|
||||
{
|
||||
if (value == kSignature64)
|
||||
@@ -88,40 +120,59 @@ HRESULT CInArchive::Open(IInStream *inStream,
|
||||
startPosition += inBuffer.GetProcessedSize() - kSignatureSize;
|
||||
}
|
||||
RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL));
|
||||
RINOK(ReadBytes(inStream, &archiveHeader, sizeof(archiveHeader)));
|
||||
|
||||
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;
|
||||
|
||||
if (archiveHeader.Reserved1 != 0 ||
|
||||
archiveHeader.Reserved2 != 0 ||
|
||||
archiveHeader.Reserved3 != 0)
|
||||
throw CInArchiveException(CInArchiveException::kUnsupported);
|
||||
|
||||
inArchiveInfo.VersionMinor = archiveHeader.VersionMinor;
|
||||
inArchiveInfo.VersionMajor = archiveHeader.VersionMajor;
|
||||
inArchiveInfo.NumFolders = archiveHeader.NumFolders;
|
||||
inArchiveInfo.NumFiles = archiveHeader.NumFiles;
|
||||
inArchiveInfo.Flags = archiveHeader.Flags;
|
||||
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, &inArchiveInfo.PerDataSizes,
|
||||
sizeof(inArchiveInfo.PerDataSizes)));
|
||||
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;
|
||||
UInt64 foldersStartPosition;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition));
|
||||
CInBuffer inBuffer;
|
||||
inBuffer.Init(inStream);
|
||||
if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0)
|
||||
::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 ((archiveHeader.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0)
|
||||
if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0)
|
||||
{
|
||||
SafeReadName(inBuffer, inArchiveInfo.NextCabinetName);
|
||||
SafeReadName(inBuffer, inArchiveInfo.NextDiskName);
|
||||
@@ -132,54 +183,69 @@ HRESULT CInArchive::Open(IInStream *inStream,
|
||||
|
||||
if (progressVirt != NULL)
|
||||
{
|
||||
UINT64 numFiles = archiveHeader.NumFiles;
|
||||
UInt64 numFiles = inArchiveInfo.NumFiles;
|
||||
RINOK(progressVirt->SetTotal(&numFiles));
|
||||
}
|
||||
folders.Clear();
|
||||
for(int i = 0; i < archiveHeader.NumFolders; i++)
|
||||
int i;
|
||||
for(i = 0; i < inArchiveInfo.NumFolders; i++)
|
||||
{
|
||||
if (progressVirt != NULL)
|
||||
{
|
||||
UINT64 numFiles = 0;
|
||||
UInt64 numFiles = 0;
|
||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
||||
}
|
||||
NHeader::CFolder folder;
|
||||
RINOK(SafeRead(inStream, &folder, sizeof(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;
|
||||
folder.DataStart += (UInt32)startPosition;
|
||||
folders.Add(folder);
|
||||
}
|
||||
|
||||
RINOK(inStream->Seek(startPosition + archiveHeader.FileOffset,
|
||||
RINOK(inStream->Seek(startPosition + fileOffset,
|
||||
STREAM_SEEK_SET, NULL));
|
||||
|
||||
CInBuffer inBuffer;
|
||||
inBuffer.Init(inStream);
|
||||
::CInBuffer inBuffer;
|
||||
if (!inBuffer.Create(1 << 17))
|
||||
return E_OUTOFMEMORY;
|
||||
inBuffer.SetStream(inStream);
|
||||
inBuffer.Init();
|
||||
files.Clear();
|
||||
if (progressVirt != NULL)
|
||||
{
|
||||
UINT64 numFiles = files.Size();
|
||||
UInt64 numFiles = files.Size();
|
||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
||||
}
|
||||
for(i = 0; i < archiveHeader.NumFiles; i++)
|
||||
for(i = 0; i < inArchiveInfo.NumFiles; i++)
|
||||
{
|
||||
NHeader::CFile fileHeader;
|
||||
SafeInByteRead(inBuffer, &fileHeader, sizeof(fileHeader));
|
||||
SafeInByteRead(inBuffer, _block, NHeader::kFileHeaderSize);
|
||||
_blockSize = NHeader::kFileHeaderSize;
|
||||
_blockPos = 0;
|
||||
CItem item;
|
||||
item.UnPackSize = fileHeader.UnPackSize;
|
||||
item.UnPackOffset = fileHeader.UnPackOffset;
|
||||
item.FolderIndex = fileHeader.FolderIndex;
|
||||
item.Time = ((UINT32(fileHeader.PureDate) << 16)) | fileHeader.PureTime;
|
||||
item.Attributes = fileHeader.Attributes;
|
||||
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();
|
||||
UInt64 numFiles = files.Size();
|
||||
RINOK(progressVirt->SetCompleted(&numFiles));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Archive/CabIn.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_IN_H
|
||||
#define __ARCHIVE_CAB_IN_H
|
||||
|
||||
@@ -27,14 +25,14 @@ public:
|
||||
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 */
|
||||
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;
|
||||
@@ -48,19 +46,28 @@ public:
|
||||
class CProgressVirt
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetTotal)(const UINT64 *numFiles) PURE;
|
||||
STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE;
|
||||
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,
|
||||
const UInt64 *searchHeaderSizeLimit,
|
||||
CInArchiveInfo &inArchiveInfo,
|
||||
CObjectVector<NHeader::CFolder> &folders,
|
||||
CObjectVector<CItem> &aFiles,
|
||||
CProgressVirt *aProgressVirt);
|
||||
CObjectVector<CItem> &files,
|
||||
CProgressVirt *progressVirt);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,153 +1,175 @@
|
||||
// Archive/CabInBuffer.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Windows/Defs.h"
|
||||
#include "CabInBuffer.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
#pragma pack(push, PragmaCabDataHeader)
|
||||
#pragma pack(push, 1)
|
||||
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, PragmaCabDataHeader)
|
||||
|
||||
CInBuffer::CInBuffer(UINT32 bufferSize):
|
||||
m_BufferSize(bufferSize),
|
||||
m_Stream(0)
|
||||
bool CInBuffer::Create(UInt32 bufferSize)
|
||||
{
|
||||
m_Buffer = new BYTE[m_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);
|
||||
}
|
||||
|
||||
CInBuffer::~CInBuffer()
|
||||
void CInBuffer::Free()
|
||||
{
|
||||
delete []m_Buffer;
|
||||
// ReleaseStream();
|
||||
BigFree(m_Buffer);
|
||||
m_Buffer = 0;
|
||||
}
|
||||
|
||||
void CInBuffer::Init(ISequentialInStream *inStream, BYTE reservedSize, UINT32 numBlocks)
|
||||
void CInBuffer::Init(Byte reservedSize, UInt32 numBlocks)
|
||||
{
|
||||
m_ReservedSize = reservedSize;
|
||||
m_NumBlocks = numBlocks;
|
||||
m_CurrentBlockIndex = 0;
|
||||
// ReleaseStream();
|
||||
m_Stream = inStream;
|
||||
// m_Stream->AddRef();
|
||||
m_ProcessedSize = 0;
|
||||
m_Pos = 0;
|
||||
m_NumReadBytesInBuffer = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void CInBuffer::ReleaseStream()
|
||||
{
|
||||
if(m_Stream != 0)
|
||||
{
|
||||
m_Stream->Release();
|
||||
m_Stream = 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
class CCheckSum
|
||||
{
|
||||
UINT32 m_Value;
|
||||
UInt32 m_Value;
|
||||
public:
|
||||
CCheckSum(): m_Value(0){};
|
||||
void Init() { m_Value = 0; }
|
||||
void Update(const void *data, UINT32 size);
|
||||
UINT32 GetResult() const { return m_Value; }
|
||||
void 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)
|
||||
void CCheckSum::Update(const void *data, UInt32 size)
|
||||
{
|
||||
UINT32 checkSum = m_Value;
|
||||
const BYTE *aDataPointer = (const BYTE *)data;
|
||||
int numUINT32Words = size / 4; // Number of ULONGs
|
||||
UInt32 checkSum = m_Value;
|
||||
const Byte *dataPointer = (const Byte *)data;
|
||||
int numUINT32Words = size / 4; // Number of ULONGs
|
||||
|
||||
// dataPointer += numUINT32Words * 4;
|
||||
|
||||
UINT32 temp;
|
||||
const UINT32 *aDataPointer32 = (const UINT32 *)data;
|
||||
UInt32 temp;
|
||||
while (numUINT32Words-- > 0)
|
||||
{
|
||||
// temp ^= *aDataPointer32++;
|
||||
temp = *aDataPointer++; // Get low-order byte
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 8); // Add 2nd byte
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 16); // Add 3nd byte
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 24); // Add 4th byte
|
||||
checkSum ^= temp; // Update checksum
|
||||
temp = *dataPointer++;
|
||||
temp |= (((UInt32)(*dataPointer++)) << 8);
|
||||
temp |= (((UInt32)(*dataPointer++)) << 16);
|
||||
temp |= (((UInt32)(*dataPointer++)) << 24);
|
||||
checkSum ^= temp;
|
||||
}
|
||||
|
||||
temp = 0;
|
||||
switch (size % 4)
|
||||
{
|
||||
case 3:
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 16); // Add 3nd byte
|
||||
case 2:
|
||||
temp |= (((ULONG)(*aDataPointer++)) << 8); // Add 2nd byte
|
||||
case 1:
|
||||
temp |= *aDataPointer++; // Get low-order byte
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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)
|
||||
|
||||
HRESULT CInBuffer::ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
|
||||
{
|
||||
if (m_CurrentBlockIndex >= m_NumBlocks)
|
||||
throw "there is no more data blocks";
|
||||
|
||||
m_ProcessedSize += m_NumReadBytesInBuffer;
|
||||
|
||||
CDataBlockHeader dataBlockHeader;
|
||||
UINT32 numProcessedBytes;
|
||||
RINOK(m_Stream->Read(&dataBlockHeader, sizeof(dataBlockHeader), &numProcessedBytes));
|
||||
if (numProcessedBytes != sizeof(dataBlockHeader))
|
||||
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];
|
||||
Byte reservedArea[256];
|
||||
RINOK(m_Stream->Read(reservedArea, m_ReservedSize, &numProcessedBytes));
|
||||
if (numProcessedBytes != m_ReservedSize)
|
||||
throw "bad block";
|
||||
}
|
||||
|
||||
RINOK(m_Stream->Read(m_Buffer, dataBlockHeader.PackSize, &m_NumReadBytesInBuffer));
|
||||
if (m_NumReadBytesInBuffer != dataBlockHeader.PackSize)
|
||||
RINOK(m_Stream->Read(m_Buffer, packSize, &m_NumReadBytesInBuffer));
|
||||
if (m_NumReadBytesInBuffer != packSize)
|
||||
throw "bad block";
|
||||
|
||||
if (dataBlockHeader.CheckSum == 0)
|
||||
// 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 checkSum;
|
||||
checkSum.Update(m_Buffer, dataBlockHeader.PackSize);
|
||||
checkSum.Update(&dataBlockHeader.PackSize,
|
||||
sizeof(dataBlockHeader) - sizeof(dataBlockHeader.CheckSum));
|
||||
dataAreCorrect = (checkSum.GetResult() == dataBlockHeader.CheckSum);
|
||||
CCheckSum checkSumCalc;
|
||||
checkSumCalc.Update(m_Buffer, packSize);
|
||||
checkSumCalc.UpdateUInt32(packSize | (((UInt32)unPackSize) << 16));
|
||||
dataAreCorrect = (checkSumCalc.GetResult() == checkSum);
|
||||
}
|
||||
|
||||
m_Pos = 0;
|
||||
uncompressedSize = dataBlockHeader.UnPackSize;
|
||||
uncompressedSize = unPackSize;
|
||||
|
||||
m_CurrentBlockIndex++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,60 +1,64 @@
|
||||
// Archive/CabInBuffer.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#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;
|
||||
ISequentialInStream *m_Stream;
|
||||
UINT32 m_BufferSize;
|
||||
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;
|
||||
UInt32 m_NumBlocks;
|
||||
UInt32 m_CurrentBlockIndex;
|
||||
UInt32 m_ReservedSize;
|
||||
|
||||
public:
|
||||
CInBuffer(UINT32 bufferSize = 0x20000);
|
||||
~CInBuffer();
|
||||
CInBuffer(): m_Buffer(0) {}
|
||||
~CInBuffer() { Free(); }
|
||||
bool Create(UInt32 bufferSize);
|
||||
void Free();
|
||||
|
||||
void Init(ISequentialInStream *inStream, BYTE reservedSize, UINT32 numBlocks);
|
||||
// void ReleaseStream();
|
||||
void SetStream(ISequentialInStream *inStream) { m_Stream = inStream; }
|
||||
void ReleaseStream() { m_Stream.Release(); }
|
||||
|
||||
bool ReadByte(BYTE &b)
|
||||
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()
|
||||
Byte ReadByte()
|
||||
{
|
||||
if(m_Pos >= m_NumReadBytesInBuffer)
|
||||
return 0;
|
||||
return m_Buffer[m_Pos++];
|
||||
}
|
||||
/*
|
||||
void ReadBytes(void *data, UINT32 size, UINT32 &aProcessedSize)
|
||||
void ReadBytes(void *data, UInt32 size, UInt32 &aProcessedSize)
|
||||
{
|
||||
BYTE *aDataPointer = (BYTE *)data;
|
||||
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; }
|
||||
HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect);
|
||||
UInt64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Archive/Cab/ItemInfo.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_RAR_ITEMINFO_H
|
||||
#define __ARCHIVE_RAR_ITEMINFO_H
|
||||
|
||||
@@ -15,14 +13,15 @@ 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); }
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "CabHandler.h"
|
||||
@@ -60,6 +59,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
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;
|
||||
|
||||
@@ -19,21 +19,20 @@ class CDecoder
|
||||
{
|
||||
protected:
|
||||
CInBuffer m_Stream;
|
||||
UINT32 m_BitPos;
|
||||
UINT32 m_Value;
|
||||
UInt32 m_BitPos;
|
||||
UInt32 m_Value;
|
||||
public:
|
||||
void InitStream(ISequentialInStream *aStream, BYTE aReservedSize, UINT32 aNumBlocks)
|
||||
{
|
||||
m_Stream.Init(aStream, aReservedSize, aNumBlocks);
|
||||
}
|
||||
/*
|
||||
void ReleaseStream()
|
||||
{ m_Stream.ReleaseStream(); }
|
||||
*/
|
||||
UINT64 GetProcessedSize() const
|
||||
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)); }
|
||||
UInt32 GetBitPosition() const
|
||||
{ return UInt32(m_Stream.GetProcessedSize() * 8 - (kNumBigValueBits - m_BitPos)); }
|
||||
|
||||
void Init()
|
||||
{
|
||||
@@ -45,65 +44,65 @@ public:
|
||||
{
|
||||
for (;m_BitPos >= 16; m_BitPos -= 16)
|
||||
{
|
||||
BYTE aByte0 = m_Stream.ReadByte();
|
||||
BYTE aByte1 = m_Stream.ReadByte();
|
||||
m_Value = (m_Value << 8) | aByte1;
|
||||
m_Value = (m_Value << 8) | aByte0;
|
||||
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 aNumBits)
|
||||
UInt32 GetValue(UInt32 numBits)
|
||||
{
|
||||
return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >>
|
||||
(kNumValueBits - aNumBits);
|
||||
(kNumValueBits - numBits);
|
||||
}
|
||||
|
||||
void MovePos(UINT32 aNumBits)
|
||||
void MovePos(UInt32 numBits)
|
||||
{
|
||||
m_BitPos += aNumBits;
|
||||
m_BitPos += numBits;
|
||||
Normalize();
|
||||
}
|
||||
|
||||
UINT32 ReadBits(UINT32 aNumBits)
|
||||
UInt32 ReadBits(UInt32 numBits)
|
||||
{
|
||||
UINT32 aRes = GetValue(aNumBits);
|
||||
MovePos(aNumBits);
|
||||
return aRes;
|
||||
UInt32 res = GetValue(numBits);
|
||||
MovePos(numBits);
|
||||
return res;
|
||||
}
|
||||
UINT32 ReadBitsBig(UINT32 aNumBits)
|
||||
UInt32 ReadBitsBig(UInt32 numBits)
|
||||
{
|
||||
UINT32 aNumBits0 = aNumBits / 2;
|
||||
UINT32 aNumBits1 = aNumBits - aNumBits0;
|
||||
UINT32 aRes = ReadBits(aNumBits0) << aNumBits1;
|
||||
return aRes + ReadBits(aNumBits1);
|
||||
UInt32 numBits0 = numBits / 2;
|
||||
UInt32 numBits1 = numBits - numBits0;
|
||||
UInt32 res = ReadBits(numBits0) << numBits1;
|
||||
return res + ReadBits(numBits1);
|
||||
}
|
||||
|
||||
BYTE DirectReadByte()
|
||||
Byte DirectReadByte()
|
||||
{
|
||||
if (m_BitPos == kNumBigValueBits)
|
||||
return m_Stream.ReadByte();
|
||||
BYTE aRes;
|
||||
Byte res;
|
||||
switch(m_BitPos)
|
||||
{
|
||||
case 0:
|
||||
aRes = BYTE(m_Value >> 16);
|
||||
res = Byte(m_Value >> 16);
|
||||
break;
|
||||
case 8:
|
||||
aRes = BYTE(m_Value >> 24);
|
||||
res = Byte(m_Value >> 24);
|
||||
break;
|
||||
case 16:
|
||||
aRes = BYTE(m_Value);
|
||||
res = Byte(m_Value);
|
||||
break;
|
||||
case 24:
|
||||
aRes = BYTE(m_Value >> 8);
|
||||
res = Byte(m_Value >> 8);
|
||||
break;
|
||||
}
|
||||
m_BitPos += 8;
|
||||
return aRes;
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT ReadBlock(UINT32 &anUncompressedSize, bool &aDataAreCorrect)
|
||||
{ return m_Stream.ReadBlock(anUncompressedSize, aDataAreCorrect); }
|
||||
HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
|
||||
{ return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
|
||||
namespace NBlockType
|
||||
{
|
||||
const int kNumBits = 3;
|
||||
@@ -23,9 +22,9 @@ namespace NBlockType
|
||||
|
||||
const int kUncompressedBlockSizeNumBits = 24;
|
||||
|
||||
const UINT32 kLevelTableSize = 20;
|
||||
const UInt32 kLevelTableSize = 20;
|
||||
|
||||
const UINT32 kNumBitsForPreTreeLevel = 4;
|
||||
const UInt32 kNumBitsForPreTreeLevel = 4;
|
||||
|
||||
const int kLevelSymbolZeros = 17;
|
||||
const int kLevelSymbolZerosBig = 18;
|
||||
@@ -43,38 +42,38 @@ const int kNumBitsForAlignLevel = 3;
|
||||
const int kLevelSymbolSameNumBits = 1;
|
||||
const int kLevelSymbolSameStartValue = 4;
|
||||
|
||||
// const UINT32 kMainTableSize = 256 + kNumPosLenSlots + 1;
|
||||
// const UInt32 kMainTableSize = 256 + kNumPosLenSlots + 1;
|
||||
|
||||
/*
|
||||
const UINT32 kLenTableSize = 28;
|
||||
const UInt32 kLenTableSize = 28;
|
||||
|
||||
const UINT32 kLenTableStart = kMainTableSize;
|
||||
const UINT32 kAlignTableStart = kLenTableStart + kLenTableSize;
|
||||
const UInt32 kLenTableStart = kMainTableSize;
|
||||
const UInt32 kAlignTableStart = kLenTableStart + kLenTableSize;
|
||||
|
||||
const UINT32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize;
|
||||
const UInt32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize;
|
||||
|
||||
|
||||
const UINT32 kMaxTableSize = kHeapTablesSizesSum;
|
||||
const UInt32 kMaxTableSize = kHeapTablesSizesSum;
|
||||
|
||||
const UINT32 kTableDirectLevels = 16;
|
||||
const UINT32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
const UInt32 kTableDirectLevels = 16;
|
||||
const UInt32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
|
||||
const UINT32 kLevelMask = 0xF;
|
||||
const UInt32 kLevelMask = 0xF;
|
||||
|
||||
const UINT32 kPosLenNumber = 256;
|
||||
const UINT32 kReadTableNumber = 256 + kNumPosLenSlots;
|
||||
const UInt32 kPosLenNumber = 256;
|
||||
const UInt32 kReadTableNumber = 256 + kNumPosLenSlots;
|
||||
|
||||
//const UINT32 kMatchNumber = kReadTableNumber + 1;
|
||||
//const UInt32 kMatchNumber = kReadTableNumber + 1;
|
||||
|
||||
const BYTE kLenStart[kLenTableSize] =
|
||||
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] =
|
||||
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[] =
|
||||
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,
|
||||
@@ -93,7 +92,7 @@ const UINT32 kDistStart[] =
|
||||
0x1C0000,
|
||||
0x1E0000
|
||||
};
|
||||
const BYTE kDistDirectBits[] =
|
||||
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,
|
||||
@@ -101,12 +100,11 @@ const BYTE kDistDirectBits[] =
|
||||
};
|
||||
|
||||
/*
|
||||
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 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;
|
||||
const UInt32 kDistLimit2 = 0x101 - 1;
|
||||
*/
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "LZXDecoder.h"
|
||||
|
||||
#include "LZXConst.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
@@ -12,17 +11,10 @@ namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
static const UINT32 kHistorySize = (1 << 21);
|
||||
static const UInt32 kHistorySize = (1 << 21);
|
||||
|
||||
const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols;
|
||||
|
||||
CDecoder::CDecoder():
|
||||
m_MainDecoder(kMainTableSize),
|
||||
m_LenDecoder(kNumLenSymbols),
|
||||
m_AlignDecoder(kAlignTableSize),
|
||||
m_LevelDecoder(kLevelTableSize)
|
||||
CDecoder::CDecoder()
|
||||
{
|
||||
m_OutWindowStream.Create(kHistorySize);
|
||||
m_i86TranslationOutStreamSpec = new Ci86TranslationOutStream;
|
||||
m_i86TranslationOutStream = m_i86TranslationOutStreamSpec;
|
||||
}
|
||||
@@ -40,18 +32,18 @@ STDMETHODIMP CDecoder::Flush()
|
||||
return m_i86TranslationOutStreamSpec->Flush();
|
||||
}
|
||||
|
||||
void CDecoder::ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols)
|
||||
void CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols)
|
||||
{
|
||||
BYTE levelLevels[kLevelTableSize];
|
||||
UINT32 i;
|
||||
Byte levelLevels[kLevelTableSize];
|
||||
UInt32 i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
levelLevels[i] = BYTE(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel));
|
||||
levelLevels[i] = Byte(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel));
|
||||
m_LevelDecoder.SetCodeLengths(levelLevels);
|
||||
for (i = 0; i < numSymbols;)
|
||||
{
|
||||
UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number <= kNumHuffmanBits)
|
||||
newLevels[i++] = BYTE((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
|
||||
newLevels[i++] = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
|
||||
else if (number == kLevelSymbolZeros || number == kLevelSymbolZerosBig)
|
||||
{
|
||||
int num;
|
||||
@@ -67,10 +59,10 @@ void CDecoder::ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols)
|
||||
else if (number == kLevelSymbolSame)
|
||||
{
|
||||
int num = kLevelSymbolSameStartValue + m_InBitStream.ReadBits(kLevelSymbolSameNumBits);
|
||||
UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number > kNumHuffmanBits)
|
||||
throw "bad data";
|
||||
BYTE symbol = BYTE((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
|
||||
Byte symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
|
||||
for (; num > 0 && i < numSymbols; num--, i++)
|
||||
newLevels[i] = symbol;
|
||||
}
|
||||
@@ -94,7 +86,7 @@ void CDecoder::ReadTables(void)
|
||||
if (blockType == NBlockType::kUncompressed)
|
||||
{
|
||||
m_UncompressedBlock = true;
|
||||
UINT32 bitPos = m_InBitStream.GetBitPosition() % 16;
|
||||
UInt32 bitPos = m_InBitStream.GetBitPosition() % 16;
|
||||
m_InBitStream.ReadBits(16 - bitPos);
|
||||
for (int i = 0; i < kNumRepDistances; i++)
|
||||
{
|
||||
@@ -110,7 +102,7 @@ void CDecoder::ReadTables(void)
|
||||
|
||||
m_AlignIsUsed = (blockType == NBlockType::kAligned);
|
||||
|
||||
BYTE newLevels[kMaxTableSize];
|
||||
Byte newLevels[kMaxTableSize];
|
||||
|
||||
if (m_AlignIsUsed)
|
||||
{
|
||||
@@ -153,27 +145,34 @@ void CDecoder::ClearPrevLeveles()
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
UINT64 size = *outSize;
|
||||
UInt64 size = *outSize;
|
||||
|
||||
if (!m_OutWindowStream.Create(kHistorySize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_InBitStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_OutWindowStream.Init(m_i86TranslationOutStream);
|
||||
m_InBitStream.InitStream(inStream, m_ReservedSize, m_NumInDataBlocks);
|
||||
m_OutWindowStream.SetStream(m_i86TranslationOutStream);
|
||||
m_OutWindowStream.Init();
|
||||
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init(m_ReservedSize, m_NumInDataBlocks);
|
||||
|
||||
CDecoderFlusher flusher(this);
|
||||
|
||||
UINT32 uncompressedCFDataBlockSize;
|
||||
UInt32 uncompressedCFDataBlockSize;
|
||||
bool dataAreCorrect;
|
||||
RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
|
||||
if (!dataAreCorrect)
|
||||
{
|
||||
throw "Data Error";
|
||||
}
|
||||
UINT32 uncompressedCFDataCurrentValue = 0;
|
||||
UInt32 uncompressedCFDataCurrentValue = 0;
|
||||
m_InBitStream.Init();
|
||||
|
||||
ClearPrevLeveles();
|
||||
@@ -182,7 +181,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
m_i86TranslationOutStreamSpec->Init(outStream, false, 0);
|
||||
else
|
||||
{
|
||||
UINT32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16;
|
||||
UInt32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16;
|
||||
i86TranslationSize |= m_InBitStream.ReadBits(16);
|
||||
m_i86TranslationOutStreamSpec->Init(outStream, true , i86TranslationSize);
|
||||
}
|
||||
@@ -190,7 +189,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
for(int i = 0 ; i < kNumRepDistances; i++)
|
||||
m_RepDistances[i] = 0;
|
||||
|
||||
UINT64 nowPos64 = 0;
|
||||
UInt64 nowPos64 = 0;
|
||||
while(nowPos64 < size)
|
||||
{
|
||||
if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
|
||||
@@ -205,13 +204,13 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
uncompressedCFDataCurrentValue = 0;
|
||||
}
|
||||
ReadTables();
|
||||
UINT32 nowPos = 0;
|
||||
UINT32 next = (UINT32)MyMin((UINT64)m_UnCompressedBlockSize, size - nowPos64);
|
||||
UInt32 nowPos = 0;
|
||||
UInt32 next = (UInt32)MyMin((UInt64)m_UnCompressedBlockSize, size - nowPos64);
|
||||
if (m_UncompressedBlock)
|
||||
{
|
||||
while(nowPos < next)
|
||||
{
|
||||
m_OutWindowStream.PutOneByte(m_InBitStream.DirectReadByte());
|
||||
m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte());
|
||||
nowPos++;
|
||||
uncompressedCFDataCurrentValue++;
|
||||
if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
|
||||
@@ -245,27 +244,27 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
m_InBitStream.Init();
|
||||
uncompressedCFDataCurrentValue = 0;
|
||||
}
|
||||
UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < 256)
|
||||
{
|
||||
m_OutWindowStream.PutOneByte(BYTE(number));
|
||||
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;
|
||||
UInt32 posLenSlot = number - 256;
|
||||
UInt32 posSlot = posLenSlot / kNumLenSlots;
|
||||
UInt32 lenSlot = posLenSlot % kNumLenSlots;
|
||||
UInt32 length = 2 + lenSlot;
|
||||
if (lenSlot == kNumLenSlots - 1)
|
||||
length += m_LenDecoder.DecodeSymbol(&m_InBitStream);
|
||||
|
||||
if (posSlot < kNumRepDistances)
|
||||
{
|
||||
UINT32 distance = m_RepDistances[posSlot];
|
||||
m_OutWindowStream.CopyBackBlock(distance, length);
|
||||
UInt32 distance = m_RepDistances[posSlot];
|
||||
m_OutWindowStream.CopyBlock(distance, length);
|
||||
if (posSlot != 0)
|
||||
{
|
||||
m_RepDistances[posSlot] = m_RepDistances[0];
|
||||
@@ -274,8 +273,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 pos = kDistStart[posSlot];
|
||||
UINT32 posDirectBits = kDistDirectBits[posSlot];
|
||||
UInt32 pos = kDistStart[posSlot];
|
||||
UInt32 posDirectBits = kDistDirectBits[posSlot];
|
||||
if (m_AlignIsUsed && posDirectBits >= kNumAlignBits)
|
||||
{
|
||||
pos += (m_InBitStream.ReadBits(posDirectBits - kNumAlignBits) << kNumAlignBits);
|
||||
@@ -283,10 +282,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
}
|
||||
else
|
||||
pos += m_InBitStream.ReadBits(posDirectBits);
|
||||
UINT32 distance = pos - kNumRepDistances;
|
||||
UInt32 distance = pos - kNumRepDistances;
|
||||
if (distance >= nowPos64 + nowPos)
|
||||
throw 777123;
|
||||
m_OutWindowStream.CopyBackBlock(distance, length);
|
||||
m_OutWindowStream.CopyBlock(distance, length);
|
||||
m_RepDistances[2] = m_RepDistances[1];
|
||||
m_RepDistances[1] = m_RepDistances[0];
|
||||
m_RepDistances[0] = distance;
|
||||
@@ -299,8 +298,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
}
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 inSize = m_InBitStream.GetProcessedSize();
|
||||
UINT64 outSize = nowPos64 + nowPos;
|
||||
UInt64 inSize = m_InBitStream.GetProcessedSize();
|
||||
UInt64 outSize = nowPos64 + nowPos;
|
||||
RINOK(progress->SetRatioInfo(&inSize, &outSize));
|
||||
}
|
||||
nowPos64 += nowPos;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Archive/Cab/LZXDecoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_LZXDECODER_H
|
||||
#define __ARCHIVE_CAB_LZXDECODER_H
|
||||
|
||||
@@ -14,14 +12,13 @@
|
||||
#include "LZXBitDecoder.h"
|
||||
|
||||
#include "LZXi86Converter.h"
|
||||
|
||||
// #include "../../../Projects/CompressInterface/CompressInterface.h"
|
||||
#include "LZXConst.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CMSBFHuffmanDecoder;
|
||||
const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols;
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
@@ -30,36 +27,36 @@ class CDecoder :
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
NBitStream::CDecoder m_InBitStream;
|
||||
|
||||
CMSBFHuffmanDecoder m_MainDecoder;
|
||||
CMSBFHuffmanDecoder m_LenDecoder; // for matches with repeated offsets
|
||||
CMSBFHuffmanDecoder m_AlignDecoder; // for matches with repeated offsets
|
||||
CMSBFHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
|
||||
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];
|
||||
UInt32 m_RepDistances[kNumRepDistances];
|
||||
|
||||
BYTE m_LastByteLevels[256];
|
||||
BYTE m_LastPosLenLevels[kNumPosSlotLenSlotSymbols];
|
||||
BYTE m_LastLenLevels[kNumLenSymbols];
|
||||
Byte m_LastByteLevels[256];
|
||||
Byte m_LastPosLenLevels[kNumPosSlotLenSlotSymbols];
|
||||
Byte m_LastLenLevels[kNumLenSymbols];
|
||||
|
||||
UINT32 m_DictionarySizePowerOf2;
|
||||
UINT32 m_NumPosSlots;
|
||||
UINT32 m_NumPosLenSlots;
|
||||
UInt32 m_DictionarySizePowerOf2;
|
||||
UInt32 m_NumPosSlots;
|
||||
UInt32 m_NumPosLenSlots;
|
||||
|
||||
// bool m_i86PreprocessingUsed;
|
||||
// UINT32 m_i86TranslationSize;
|
||||
// UInt32 m_i86TranslationSize;
|
||||
|
||||
bool m_UncompressedBlock;
|
||||
bool m_AlignIsUsed;
|
||||
|
||||
UINT32 m_UnCompressedBlockSize;
|
||||
UInt32 m_UnCompressedBlockSize;
|
||||
|
||||
Ci86TranslationOutStream *m_i86TranslationOutStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> m_i86TranslationOutStream;
|
||||
|
||||
BYTE m_ReservedSize;
|
||||
UINT32 m_NumInDataBlocks;
|
||||
Byte m_ReservedSize;
|
||||
UInt32 m_NumInDataBlocks;
|
||||
|
||||
void ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols);
|
||||
void ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols);
|
||||
void ReadTables();
|
||||
void ClearPrevLeveles();
|
||||
|
||||
@@ -74,11 +71,11 @@ public:
|
||||
// ICompressCoder interface
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
void SetParams(BYTE reservedSize, UINT32 numInDataBlocks,
|
||||
UINT32 dictionarySizePowerOf2)
|
||||
void SetParams(Byte reservedSize, UInt32 numInDataBlocks,
|
||||
UInt32 dictionarySizePowerOf2)
|
||||
{
|
||||
m_ReservedSize = reservedSize;
|
||||
m_NumInDataBlocks = numInDataBlocks;
|
||||
|
||||
@@ -7,17 +7,17 @@ namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
const UINT32 kNumRepDistances = 3;
|
||||
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 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 Byte kNumAlignBits = 3;
|
||||
const UInt32 kAlignTableSize = 1 << kNumAlignBits;
|
||||
|
||||
const UINT32 kNumHuffmanBits = 16;
|
||||
const UInt32 kNumHuffmanBits = 16;
|
||||
|
||||
const int kNumPosSlotSymbols = 50;
|
||||
const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots;
|
||||
@@ -25,7 +25,6 @@ const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots;
|
||||
const int kMaxTableSize = 256 + kNumPosSlotLenSlotSymbols;
|
||||
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif;
|
||||
#endif
|
||||
|
||||
@@ -5,71 +5,42 @@
|
||||
#include "Common/Defs.h"
|
||||
|
||||
#include "LZXi86Converter.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
namespace NLZX {
|
||||
|
||||
Ci86TranslationOutStream::Ci86TranslationOutStream():
|
||||
m_Pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
Ci86TranslationOutStream::~Ci86TranslationOutStream()
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
||||
void Ci86TranslationOutStream::Init(ISequentialOutStream *aStream,
|
||||
bool aTranslationMode, UINT32 aTranslationSize)
|
||||
{
|
||||
m_Stream = aStream;
|
||||
m_TranslationMode = aTranslationMode;
|
||||
m_TranslationSize = aTranslationSize;
|
||||
m_ProcessedSize = 0;
|
||||
m_Pos = 0;
|
||||
}
|
||||
|
||||
void Ci86TranslationOutStream::ReleaseStream()
|
||||
{
|
||||
m_Stream.Release();
|
||||
}
|
||||
|
||||
inline INT32 Ci86TranslationOutStream::ConvertAbsoluteToOffset(INT32 aPos, INT32 anAbsoluteValue)
|
||||
{
|
||||
}
|
||||
|
||||
static const int kResidue = 6 + 4;
|
||||
|
||||
void Ci86TranslationOutStream::MakeTranslation()
|
||||
{
|
||||
if (m_Pos <= kResidue)
|
||||
return;
|
||||
UINT32 aNumBytes = m_Pos - kResidue;
|
||||
for (UINT32 i = 0; i < aNumBytes;)
|
||||
UInt32 numBytes = m_Pos - kResidue;
|
||||
for (UInt32 i = 0; i < numBytes;)
|
||||
{
|
||||
if (m_Buffer[i] == 0xE8)
|
||||
{
|
||||
i++;
|
||||
INT32 anAbsoluteValue = 0;
|
||||
for(int j = 0; j < 4; j++)
|
||||
anAbsoluteValue += UINT32(m_Buffer[i + j]) << (j * 8);
|
||||
Int32 absValue = 0;
|
||||
int j;
|
||||
for(j = 0; j < 4; j++)
|
||||
absValue += UInt32(m_Buffer[i + j]) << (j * 8);
|
||||
|
||||
INT32 aPos = m_ProcessedSize + i - 1;
|
||||
UINT32 anOffset;
|
||||
if (anAbsoluteValue < -aPos || anAbsoluteValue >= INT32(m_TranslationSize))
|
||||
Int32 pos = m_ProcessedSize + i - 1;
|
||||
UInt32 offset;
|
||||
if (absValue < -pos || absValue >= Int32(m_TranslationSize))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
anOffset = (anAbsoluteValue >= 0) ?
|
||||
anAbsoluteValue - aPos :
|
||||
anAbsoluteValue + m_TranslationSize;
|
||||
offset = (absValue >= 0) ?
|
||||
absValue - pos :
|
||||
absValue + m_TranslationSize;
|
||||
for(j = 0; j < 4; j++)
|
||||
{
|
||||
m_Buffer[i + j] = BYTE(anOffset & 0xFF);
|
||||
anOffset >>= 8;
|
||||
m_Buffer[i + j] = Byte(offset & 0xFF);
|
||||
offset >>= 8;
|
||||
}
|
||||
}
|
||||
i += 4;
|
||||
@@ -79,32 +50,32 @@ void Ci86TranslationOutStream::MakeTranslation()
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP Ci86TranslationOutStream::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
|
||||
STDMETHODIMP Ci86TranslationOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if (!m_TranslationMode)
|
||||
return m_Stream->Write(aData, aSize, aProcessedSize);
|
||||
return m_Stream->Write(data, size, processedSize);
|
||||
|
||||
UINT32 aProcessedSizeReal = 0;
|
||||
UInt32 realProcessedSize = 0;
|
||||
|
||||
while (aProcessedSizeReal < aSize)
|
||||
while (realProcessedSize < size)
|
||||
{
|
||||
UINT32 aWriteSize = MyMin(aSize - aProcessedSizeReal, kUncompressedBlockSize - m_Pos);
|
||||
memmove(m_Buffer + m_Pos, (const BYTE *)aData + aProcessedSizeReal, aWriteSize);
|
||||
m_Pos += aWriteSize;
|
||||
aProcessedSizeReal += aWriteSize;
|
||||
UInt32 writeSize = MyMin(size - realProcessedSize, kUncompressedBlockSize - m_Pos);
|
||||
memmove(m_Buffer + m_Pos, (const Byte *)data + realProcessedSize, writeSize);
|
||||
m_Pos += writeSize;
|
||||
realProcessedSize += writeSize;
|
||||
if (m_Pos == kUncompressedBlockSize)
|
||||
{
|
||||
RINOK(Flush());
|
||||
}
|
||||
}
|
||||
if (aProcessedSize != NULL)
|
||||
*aProcessedSize = aProcessedSizeReal;
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP Ci86TranslationOutStream::WritePart(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
|
||||
STDMETHODIMP Ci86TranslationOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return Write(aData, aSize, aProcessedSize);
|
||||
return Write(data, size, processedSize);
|
||||
}
|
||||
|
||||
HRESULT Ci86TranslationOutStream::Flush()
|
||||
@@ -119,6 +90,4 @@ HRESULT Ci86TranslationOutStream::Flush()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Archive/Cab/LZXi86Converter.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CAB_LZXI86CONVERTER_H
|
||||
#define __ARCHIVE_CAB_LZXI86CONVERTER_H
|
||||
|
||||
@@ -20,27 +18,33 @@ class Ci86TranslationOutStream:
|
||||
{
|
||||
bool m_TranslationMode;
|
||||
CMyComPtr<ISequentialOutStream> m_Stream;
|
||||
UINT32 m_ProcessedSize;
|
||||
BYTE m_Buffer[kUncompressedBlockSize];
|
||||
UINT32 m_Pos;
|
||||
UINT32 m_TranslationSize;
|
||||
UInt32 m_ProcessedSize;
|
||||
Byte m_Buffer[kUncompressedBlockSize];
|
||||
UInt32 m_Pos;
|
||||
UInt32 m_TranslationSize;
|
||||
|
||||
INT32 ConvertAbsoluteToOffset(INT32 aPos, INT32 anAbsoluteValue);
|
||||
void MakeTranslation();
|
||||
public:
|
||||
Ci86TranslationOutStream();
|
||||
~Ci86TranslationOutStream();
|
||||
Ci86TranslationOutStream(): m_Pos(0) {}
|
||||
~Ci86TranslationOutStream() { Flush(); }
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Write)(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
|
||||
STDMETHOD(WritePart)(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
public:
|
||||
void Init(ISequentialOutStream *aStream, bool aTranslationMode, UINT32 aTranslationSize);
|
||||
void Init(ISequentialOutStream *outStream, bool translationMode, UInt32 translationSize)
|
||||
{
|
||||
m_Stream = outStream;
|
||||
m_TranslationMode = translationMode;
|
||||
m_TranslationSize = translationSize;
|
||||
m_ProcessedSize = 0;
|
||||
m_Pos = 0;
|
||||
}
|
||||
void ReleaseStream() { m_Stream.Release(); }
|
||||
HRESULT Flush();
|
||||
void ReleaseStream();
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user