Compare commits

...

21 Commits
3.13 ... 4.42

Author SHA1 Message Date
Igor Pavlov
0ec42ff829 4.42 2016-05-28 00:15:49 +01:00
Igor Pavlov
631462beb2 4.41 beta 2016-05-28 00:15:48 +01:00
Igor Pavlov
bd9a40b0ed 4.40 beta 2016-05-28 00:15:48 +01:00
Igor Pavlov
3415684502 4.39 beta 2016-05-28 00:15:48 +01:00
Igor Pavlov
83911c8529 4.38 beta 2016-05-28 00:15:47 +01:00
Igor Pavlov
cb9eea7264 4.37 beta 2016-05-28 00:15:47 +01:00
Igor Pavlov
8304895f29 4.36 beta 2016-05-28 00:15:47 +01:00
Igor Pavlov
191cf6781a 4.35 beta 2016-05-28 00:15:46 +01:00
Igor Pavlov
0f60a4933b 4.34 beta 2016-05-28 00:15:46 +01:00
Igor Pavlov
02516d3fce 4.33 beta 2016-05-28 00:15:46 +01:00
Igor Pavlov
e8d0636d7a 4.32 2016-05-28 00:15:45 +01:00
Igor Pavlov
acac987575 4.31 2016-05-28 00:15:45 +01:00
Igor Pavlov
e18587ba51 4.30 beta 2016-05-28 00:15:45 +01:00
Igor Pavlov
bcd1db2f5a 4.29 beta 2016-05-28 00:15:44 +01:00
Igor Pavlov
32c73adef4 4.28 beta 2016-05-28 00:15:44 +01:00
Igor Pavlov
d66cf2fcf3 4.27 beta 2016-05-28 00:15:44 +01:00
Igor Pavlov
31e7b924e8 4.26 beta 2016-05-28 00:15:43 +01:00
Igor Pavlov
af1fe52701 4.25 beta 2016-05-28 00:15:43 +01:00
Igor Pavlov
47f4915611 4.24 beta 2016-05-28 00:15:42 +01:00
Igor Pavlov
ac2b563958 4.23 2016-05-28 00:15:42 +01:00
Igor Pavlov
3c510ba80b 4.20 2016-05-28 00:15:41 +01:00
1314 changed files with 79314 additions and 40657 deletions

View File

@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1 # PROP Ignore_Export_Lib 1
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /c # ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD BASE RSC /l 0x419 /d "NDEBUG"
@@ -70,7 +70,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 1 # PROP Ignore_Export_Lib 1
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c # ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD BASE RSC /l 0x419 /d "_DEBUG"
@@ -93,7 +93,7 @@ LINK32=link.exe
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=.\7z.def SOURCE=..\Archive.def
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -254,10 +254,6 @@ SOURCE=..\..\ICoder.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\ICoderProperties.h
# End Source File
# Begin Source File
SOURCE=..\..\IMyUnknown.h SOURCE=..\..\IMyUnknown.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -282,6 +278,14 @@ SOURCE=..\..\PropID.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\Alloc.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Buffer.h SOURCE=..\..\..\Common\Buffer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -294,6 +298,10 @@ SOURCE=..\..\..\Common\CRC.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\DynamicBuffer.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.cpp SOURCE=..\..\..\Common\IntToString.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -302,6 +310,14 @@ SOURCE=..\..\..\Common\IntToString.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\Common\String.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -346,6 +362,10 @@ SOURCE=..\Common\CodecsPath.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\Common\CoderLoader.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CoderLoader.h SOURCE=..\Common\CoderLoader.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -358,6 +378,14 @@ SOURCE=..\Common\CoderMixer2.h
# End Source File # End Source File
# Begin 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 SOURCE=..\Common\CrossThreadProgress.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -366,6 +394,14 @@ SOURCE=..\Common\CrossThreadProgress.h
# End Source File # End Source File
# Begin 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 SOURCE=..\Common\InStreamWithCRC.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -382,12 +418,28 @@ SOURCE=..\Common\ItemNameUtils.h
# End Source File # End Source File
# Begin 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 SOURCE=..\Common\OutStreamWithCRC.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\Common\OutStreamWithCRC.h SOURCE=..\Common\OutStreamWithCRC.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\Common\ParseProperties.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\ParseProperties.h
# End Source File
# End Group # End Group
# Begin Group "7-Zip Common" # Begin Group "7-Zip Common"
@@ -410,11 +462,11 @@ SOURCE=..\..\Common\LimitedStreams.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\MultiStream.cpp SOURCE=..\..\Common\LockedStream.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\MultiStream.h SOURCE=..\..\Common\LockedStream.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -448,6 +500,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
SOURCE=..\..\Common\StreamObjects.h SOURCE=..\..\Common\StreamObjects.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.h
# End Source File
# End Group # End Group
# Begin Group "Windows" # Begin Group "Windows"

View File

@@ -1,7 +1,5 @@
// 7zCompressionMode.h // 7zCompressionMode.h
#pragma once
#ifndef __7Z_COMPRESSION_MODE_H #ifndef __7Z_COMPRESSION_MODE_H
#define __7Z_COMPRESSION_MODE_H #define __7Z_COMPRESSION_MODE_H
@@ -21,8 +19,8 @@ struct CProperty
struct CMethodFull struct CMethodFull
{ {
CMethodID MethodID; CMethodID MethodID;
UINT32 NumInStreams; UInt32 NumInStreams;
UINT32 NumOutStreams; UInt32 NumOutStreams;
bool IsSimpleCoder() const bool IsSimpleCoder() const
{ return (NumInStreams == 1) && (NumOutStreams == 1); } { return (NumInStreams == 1) && (NumOutStreams == 1); }
@@ -37,22 +35,28 @@ struct CMethodFull
struct CBind struct CBind
{ {
UINT32 InCoder; UInt32 InCoder;
UINT32 InStream; UInt32 InStream;
UINT32 OutCoder; UInt32 OutCoder;
UINT32 OutStream; UInt32 OutStream;
}; };
struct CCompressionMethodMode struct CCompressionMethodMode
{ {
CObjectVector<CMethodFull> Methods; CObjectVector<CMethodFull> Methods;
CRecordVector<CBind> Binds; CRecordVector<CBind> Binds;
bool MultiThread; #ifdef COMPRESS_MT
UInt32 NumThreads;
#endif
bool PasswordIsDefined; bool PasswordIsDefined;
UString Password; UString Password;
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); } bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
CCompressionMethodMode(): PasswordIsDefined(false), MultiThread(false) {} CCompressionMethodMode(): PasswordIsDefined(false)
#ifdef COMPRESS_MT
, NumThreads(1)
#endif
{}
}; };
}} }}

View File

@@ -1,19 +1,18 @@
// Decode.cpp // 7zDecode.cpp
#include "StdAfx.h" #include "StdAfx.h"
#include "7zDecode.h" #include "7zDecode.h"
#include "../../Common/MultiStream.h" #include "../../IPassword.h"
#include "../../Common/LockedStream.h"
#include "../../Common/StreamObjects.h" #include "../../Common/StreamObjects.h"
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h" #include "../../Common/LimitedStreams.h"
#include "../Common/FilterCoder.h"
#include "7zMethods.h" #include "7zMethods.h"
#include "../../IPassword.h"
#ifdef COMPRESS_LZMA #ifdef COMPRESS_LZMA
#include "../../Compress/LZMA/LZMADecoder.h" #include "../../Compress/LZMA/LZMADecoder.h"
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; 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 #endif
#ifdef COMPRESS_DEFLATE #ifdef COMPRESS_DEFLATE
#ifndef COMPRESS_DEFLATE_DECODER
#define COMPRESS_DEFLATE_DECODER
#endif
#endif
#ifdef COMPRESS_DEFLATE_DECODER
#include "../../Compress/Deflate/DeflateDecoder.h" #include "../../Compress/Deflate/DeflateDecoder.h"
static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
#endif #endif
#ifdef COMPRESS_BZIP2 #ifdef COMPRESS_BZIP2
#ifndef COMPRESS_BZIP2_DECODER
#define COMPRESS_BZIP2_DECODER
#endif
#endif
#ifdef COMPRESS_BZIP2_DECODER
#include "../../Compress/BZip2/BZip2Decoder.h" #include "../../Compress/BZip2/BZip2Decoder.h"
static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
#endif #endif
@@ -60,35 +71,31 @@ namespace N7z {
static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
CBindInfoEx &bindInfo) CBindInfoEx &bindInfo)
{ {
bindInfo.Coders.Clear(); bindInfo.Clear();
bindInfo.CoderMethodIDs.Clear();
bindInfo.OutStreams.Clear();
bindInfo.InStreams.Clear();
bindInfo.BindPairs.Clear();
int i; int i;
for (i = 0; i < folder.BindPairs.Size(); i++) for (i = 0; i < folder.BindPairs.Size(); i++)
{ {
NCoderMixer2::CBindPair bindPair; NCoderMixer2::CBindPair bindPair;
bindPair.InIndex = (UINT32)folder.BindPairs[i].InIndex; bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
bindPair.OutIndex = (UINT32)folder.BindPairs[i].OutIndex; bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
bindInfo.BindPairs.Add(bindPair); bindInfo.BindPairs.Add(bindPair);
} }
UINT32 outStreamIndex = 0; UInt32 outStreamIndex = 0;
for (i = 0; i < folder.Coders.Size(); i++) for (i = 0; i < folder.Coders.Size(); i++)
{ {
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
const CCoderInfo &coderInfo = folder.Coders[i]; const CCoderInfo &coderInfo = folder.Coders[i];
coderStreamsInfo.NumInStreams = (UINT32)coderInfo.NumInStreams; coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
coderStreamsInfo.NumOutStreams = (UINT32)coderInfo.NumOutStreams; coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
bindInfo.Coders.Add(coderStreamsInfo); bindInfo.Coders.Add(coderStreamsInfo);
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
bindInfo.CoderMethodIDs.Add(altCoderInfo.MethodID); 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) if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
bindInfo.OutStreams.Add(outStreamIndex); bindInfo.OutStreams.Add(outStreamIndex);
} }
for (i = 0; i < folder.PackStreams.Size(); i++) 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, static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1,
@@ -127,8 +134,12 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
return true; return true;
} }
CDecoder::CDecoder() CDecoder::CDecoder(bool multiThread)
{ {
#ifndef _ST_MODE
multiThread = true;
#endif
_multiThread = multiThread;
_bindInfoExPrevIsDefinded = false; _bindInfoExPrevIsDefinded = false;
#ifndef EXCLUDE_COM #ifndef EXCLUDE_COM
LoadMethodMap(); LoadMethodMap();
@@ -136,14 +147,17 @@ CDecoder::CDecoder()
} }
HRESULT CDecoder::Decode(IInStream *inStream, HRESULT CDecoder::Decode(IInStream *inStream,
UINT64 startPos, UInt64 startPos,
const UINT64 *packSizes, const UInt64 *packSizes,
const CFolder &folderInfo, const CFolder &folderInfo,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
ICompressProgressInfo *compressProgress ICompressProgressInfo *compressProgress
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword , ICryptoGetTextPassword *getTextPassword
#endif #endif
#ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads
#endif
) )
{ {
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
@@ -182,11 +196,23 @@ HRESULT CDecoder::Decode(IInStream *inStream,
// _decoders2.Clear(); // _decoders2.Clear();
_mixerCoder.Release(); _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++) for (i = 0; i < numCoders; i++)
{ {
const CCoderInfo &coderInfo = folderInfo.Coders[i]; const CCoderInfo &coderInfo = folderInfo.Coders[i];
@@ -200,6 +226,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
if (coderInfo.IsSimpleCoder()) if (coderInfo.IsSimpleCoder())
{ {
CMyComPtr<ICompressCoder> decoder; CMyComPtr<ICompressCoder> decoder;
CMyComPtr<ICompressFilter> filter;
#ifdef COMPRESS_LZMA #ifdef COMPRESS_LZMA
if (altCoderInfo.MethodID == k_LZMA) if (altCoderInfo.MethodID == k_LZMA)
@@ -213,15 +240,15 @@ HRESULT CDecoder::Decode(IInStream *inStream,
#ifdef COMPRESS_BCJ_X86 #ifdef COMPRESS_BCJ_X86
if (altCoderInfo.MethodID == k_BCJ_X86) if (altCoderInfo.MethodID == k_BCJ_X86)
decoder = new CBCJ_x86_Decoder; filter = new CBCJ_x86_Decoder;
#endif #endif
#ifdef COMPRESS_DEFLATE #ifdef COMPRESS_DEFLATE_DECODER
if (altCoderInfo.MethodID == k_Deflate) if (altCoderInfo.MethodID == k_Deflate)
decoder = new NCompress::NDeflate::NDecoder::CCOMCoder; decoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
#endif #endif
#ifdef COMPRESS_BZIP2 #ifdef COMPRESS_BZIP2_DECODER
if (altCoderInfo.MethodID == k_BZip2) if (altCoderInfo.MethodID == k_BZip2)
decoder = new NCompress::NBZip2::CDecoder; decoder = new NCompress::NBZip2::CDecoder;
#endif #endif
@@ -233,13 +260,19 @@ HRESULT CDecoder::Decode(IInStream *inStream,
#ifdef CRYPTO_7ZAES #ifdef CRYPTO_7ZAES
if (altCoderInfo.MethodID == k_7zAES) if (altCoderInfo.MethodID == k_7zAES)
decoder = new NCrypto::NSevenZ::CDecoder; filter = new NCrypto::NSevenZ::CDecoder;
#endif #endif
if (filter)
{
CFilterCoder *coderSpec = new CFilterCoder;
decoder = coderSpec;
coderSpec->Filter = filter;
}
#ifndef EXCLUDE_COM #ifndef EXCLUDE_COM
if (decoder == 0) if (decoder == 0)
{ {
RINOK(_libraries.CreateCoder(methodInfo.FilePath, RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath,
methodInfo.Decoder, &decoder)); methodInfo.Decoder, &decoder));
} }
#endif #endif
@@ -249,7 +282,12 @@ HRESULT CDecoder::Decode(IInStream *inStream,
_decoders.Add((IUnknown *)decoder); _decoders.Add((IUnknown *)decoder);
_mixerCoderSpec->AddCoder(decoder); if (_multiThread)
_mixerCoderMTSpec->AddCoder(decoder);
#ifdef _ST_MODE
else
_mixerCoderSTSpec->AddCoder(decoder, false);
#endif
} }
else else
{ {
@@ -272,71 +310,93 @@ HRESULT CDecoder::Decode(IInStream *inStream,
return E_NOTIMPL; return E_NOTIMPL;
_decoders.Add((IUnknown *)decoder); _decoders.Add((IUnknown *)decoder);
_mixerCoderSpec->AddCoder2(decoder); if (_multiThread)
_mixerCoderMTSpec->AddCoder2(decoder);
#ifdef _ST_MODE
else
_mixerCoderSTSpec->AddCoder2(decoder, false);
#endif
} }
} }
_bindInfoExPrev = bindInfo; _bindInfoExPrev = bindInfo;
_bindInfoExPrevIsDefinded = true; _bindInfoExPrevIsDefinded = true;
} }
int i; int i;
_mixerCoderSpec->ReInit(); _mixerCoderCommon->ReInit();
UINT32 packStreamIndex = 0, unPackStreamIndex = 0; UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
UINT32 coderIndex = 0; UInt32 coderIndex = 0;
// UINT32 coder2Index = 0; // UInt32 coder2Index = 0;
for (i = 0; i < numCoders; i++) for (i = 0; i < numCoders; i++)
{ {
const CCoderInfo &coderInfo = folderInfo.Coders[i]; const CCoderInfo &coderInfo = folderInfo.Coders[i];
const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties; CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
HRESULT result = _decoders[coderIndex].QueryInterface(
IID_ICompressSetDecoderProperties, &compressSetDecoderProperties);
if (result == S_OK)
{ {
const CByteBuffer &properties = altCoderInfo.Properties; CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
UINT32 size = properties.GetCapacity(); HRESULT result = decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
if (size > 0) if (setDecoderProperties)
{ {
CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp; const CByteBuffer &properties = altCoderInfo.Properties;
CMyComPtr<ISequentialInStream> inStream(inStreamSpec); size_t size = properties.GetCapacity();
inStreamSpec->Init((const BYTE *)properties, size); if (size > 0xFFFFFFFF)
RINOK(compressSetDecoderProperties->SetDecoderProperties(inStream)); return E_NOTIMPL;
if (size > 0)
{
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
}
} }
} }
else if (result != E_NOINTERFACE)
return result; #ifdef COMPRESS_MT
if (mtMode)
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
}
}
#endif
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
result = _decoders[coderIndex].QueryInterface(
IID_ICryptoSetPassword, &cryptoSetPassword);
if (result == S_OK)
{ {
if (getTextPassword == 0) CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
return E_FAIL; HRESULT result = decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
CMyComBSTR password; if (cryptoSetPassword)
RINOK(getTextPassword->CryptoGetTextPassword(&password)); {
UString unicodePassword(password); if (getTextPassword == 0)
RINOK(cryptoSetPassword->CryptoSetPassword( return E_FAIL;
(const BYTE *)(const wchar_t *)unicodePassword, CMyComBSTR password;
unicodePassword.Length() * sizeof(wchar_t))); RINOK(getTextPassword->CryptoGetTextPassword(&password));
CByteBuffer buffer;
UString unicodePassword(password);
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
buffer.SetCapacity(sizeInBytes);
for (int i = 0; i < unicodePassword.Length(); i++)
{
wchar_t c = unicodePassword[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
RINOK(cryptoSetPassword->CryptoSetPassword(
(const Byte *)buffer, sizeInBytes));
}
} }
else if (result != E_NOINTERFACE)
return result;
#endif #endif
coderIndex++; coderIndex++;
UINT32 numInStreams = (UINT32)coderInfo.NumInStreams; UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
UINT32 numOutStreams = (UINT32)coderInfo.NumOutStreams; UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
CRecordVector<const UINT64 *> packSizesPointers; CRecordVector<const UInt64 *> packSizesPointers;
CRecordVector<const UINT64 *> unPackSizesPointers; CRecordVector<const UInt64 *> unPackSizesPointers;
packSizesPointers.Reserve(numInStreams); packSizesPointers.Reserve(numInStreams);
unPackSizesPointers.Reserve(numOutStreams); unPackSizesPointers.Reserve(numOutStreams);
UINT32 j; UInt32 j;
for (j = 0; j < numOutStreams; j++, unPackStreamIndex++) for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]); unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
@@ -345,7 +405,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
if (bindPairIndex >= 0) if (bindPairIndex >= 0)
packSizesPointers.Add( packSizesPointers.Add(
&folderInfo.UnPackSizes[(UINT32)folderInfo.BindPairs[bindPairIndex].OutIndex]); &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
else else
{ {
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
@@ -355,13 +415,19 @@ HRESULT CDecoder::Decode(IInStream *inStream,
} }
} }
_mixerCoderSpec->SetCoderInfo(i, _mixerCoderCommon->SetCoderInfo(i,
&packSizesPointers.Front(), &packSizesPointers.Front(),
&unPackSizesPointers.Front()); &unPackSizesPointers.Front());
} }
UINT32 mainCoder, temp; UInt32 mainCoder, temp;
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
_mixerCoderSpec->SetProgressCoderIndex(mainCoder);
if (_multiThread)
_mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
/*
else
_mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
*/
if (numCoders == 0) if (numCoders == 0)
return 0; return 0;
@@ -370,7 +436,7 @@ HRESULT CDecoder::Decode(IInStream *inStream,
for (i = 0; i < inStreams.Size(); i++) for (i = 0; i < inStreams.Size(); i++)
inStreamPointers.Add(inStreams[i]); inStreamPointers.Add(inStreams[i]);
ISequentialOutStream *outStreamPointer = outStream; ISequentialOutStream *outStreamPointer = outStream;
return _mixerCoderSpec->Code(&inStreamPointers.Front(), NULL, return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
} }

View File

@@ -1,7 +1,5 @@
// 7zDecode.h // 7zDecode.h
#pragma once
#ifndef __7Z_DECODE_H #ifndef __7Z_DECODE_H
#define __7Z_DECODE_H #define __7Z_DECODE_H
@@ -9,6 +7,10 @@
#include "../../IPassword.h" #include "../../IPassword.h"
#include "../Common/CoderMixer2.h" #include "../Common/CoderMixer2.h"
#include "../Common/CoderMixer2MT.h"
#ifdef _ST_MODE
#include "../Common/CoderMixer2ST.h"
#endif
#ifndef EXCLUDE_COM #ifndef EXCLUDE_COM
#include "../Common/CoderLoader.h" #include "../Common/CoderLoader.h"
#endif #endif
@@ -21,6 +23,11 @@ namespace N7z {
struct CBindInfoEx: public NCoderMixer2::CBindInfo struct CBindInfoEx: public NCoderMixer2::CBindInfo
{ {
CRecordVector<CMethodID> CoderMethodIDs; CRecordVector<CMethodID> CoderMethodIDs;
void Clear()
{
CBindInfo::Clear();
CoderMethodIDs.Clear();
}
}; };
class CDecoder class CDecoder
@@ -31,21 +38,31 @@ class CDecoder
bool _bindInfoExPrevIsDefinded; bool _bindInfoExPrevIsDefinded;
CBindInfoEx _bindInfoExPrev; CBindInfoEx _bindInfoExPrev;
NCoderMixer2::CCoderMixer2 *_mixerCoderSpec;
bool _multiThread;
#ifdef _ST_MODE
NCoderMixer2::CCoderMixer2ST *_mixerCoderSTSpec;
#endif
NCoderMixer2::CCoderMixer2MT *_mixerCoderMTSpec;
NCoderMixer2::CCoderMixer2 *_mixerCoderCommon;
CMyComPtr<ICompressCoder2> _mixerCoder; CMyComPtr<ICompressCoder2> _mixerCoder;
CObjectVector<CMyComPtr<IUnknown> > _decoders; CObjectVector<CMyComPtr<IUnknown> > _decoders;
// CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2; // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
public: public:
CDecoder(); CDecoder(bool multiThread);
HRESULT Decode(IInStream *inStream, HRESULT Decode(IInStream *inStream,
UINT64 startPos, UInt64 startPos,
const UINT64 *packSizes, const UInt64 *packSizes,
const CFolder &folder, const CFolder &folder,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
ICompressProgressInfo *compressProgress ICompressProgressInfo *compressProgress
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPasswordSpec , ICryptoGetTextPassword *getTextPasswordSpec
#endif #endif
#ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads
#endif
); );
}; };

View File

@@ -11,15 +11,17 @@
#include "../../Common/LimitedStreams.h" #include "../../Common/LimitedStreams.h"
#include "../../Common/InOutTempBuffer.h" #include "../../Common/InOutTempBuffer.h"
#include "../../Common/StreamObjects.h" #include "../../Common/StreamObjects.h"
#include "../Common/FilterCoder.h"
#ifdef COMPRESS_COPY #ifdef COMPRESS_COPY
static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 }; static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
#include "../../Compress/Copy/CopyCoder.h" #include "../../Compress/Copy/CopyCoder.h"
#endif #endif
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
#ifdef COMPRESS_LZMA #ifdef COMPRESS_LZMA
#include "../../Compress/LZMA/LZMAEncoder.h" #include "../../Compress/LZMA/LZMAEncoder.h"
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
#endif #endif
#ifdef COMPRESS_PPMD #ifdef COMPRESS_PPMD
@@ -38,11 +40,23 @@ static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
#endif #endif
#ifdef COMPRESS_DEFLATE #ifdef COMPRESS_DEFLATE
#ifndef COMPRESS_DEFLATE_ENCODER
#define COMPRESS_DEFLATE_ENCODER
#endif
#endif
#ifdef COMPRESS_DEFLATE_ENCODER
#include "../../Compress/Deflate/DeflateEncoder.h" #include "../../Compress/Deflate/DeflateEncoder.h"
static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
#endif #endif
#ifdef COMPRESS_BZIP2 #ifdef COMPRESS_BZIP2
#ifndef COMPRESS_BZIP2_ENCODER
#define COMPRESS_BZIP2_ENCODER
#endif
#endif
#ifdef COMPRESS_BZIP2_ENCODER
#include "../../Compress/BZip2/BZip2Encoder.h" #include "../../Compress/BZip2/BZip2Encoder.h"
static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
#endif #endif
@@ -98,16 +112,12 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindI
folder.Coders.Add(coderInfo); folder.Coders.Add(coderInfo);
} }
for (i = 0; i < bindInfo.InStreams.Size(); i++) for (i = 0; i < bindInfo.InStreams.Size(); i++)
{ folder.PackStreams.Add(bindInfo.InStreams[i]);
CPackStreamInfo packStreamInfo;
packStreamInfo.Index = bindInfo.InStreams[i];
folder.PackStreams.Add(packStreamInfo);
}
} }
HRESULT CEncoder::CreateMixerCoder() HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
{ {
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2; _mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT;
_mixerCoder = _mixerCoderSpec; _mixerCoder = _mixerCoderSpec;
_mixerCoderSpec->SetBindInfo(_bindInfo); _mixerCoderSpec->SetBindInfo(_bindInfo);
for (int i = 0; i < _options.Methods.Size(); i++) for (int i = 0; i < _options.Methods.Size(); i++)
@@ -116,6 +126,7 @@ HRESULT CEncoder::CreateMixerCoder()
_codersInfo.Add(CCoderInfo()); _codersInfo.Add(CCoderInfo());
CCoderInfo &encodingInfo = _codersInfo.Back(); CCoderInfo &encodingInfo = _codersInfo.Back();
CMyComPtr<ICompressCoder> encoder; CMyComPtr<ICompressCoder> encoder;
CMyComPtr<ICompressFilter> filter;
CMyComPtr<ICompressCoder2> encoder2; CMyComPtr<ICompressCoder2> encoder2;
if (methodFull.IsSimpleCoder()) if (methodFull.IsSimpleCoder())
@@ -132,7 +143,7 @@ HRESULT CEncoder::CreateMixerCoder()
#ifdef COMPRESS_BCJ_X86 #ifdef COMPRESS_BCJ_X86
if (methodFull.MethodID == k_BCJ_X86) if (methodFull.MethodID == k_BCJ_X86)
encoder = new CBCJ_x86_Encoder; filter = new CBCJ_x86_Encoder;
#endif #endif
#ifdef COMPRESS_COPY #ifdef COMPRESS_COPY
@@ -140,25 +151,32 @@ HRESULT CEncoder::CreateMixerCoder()
encoder = new NCompress::CCopyCoder; encoder = new NCompress::CCopyCoder;
#endif #endif
#ifdef COMPRESS_BZIP2 #ifdef COMPRESS_BZIP2_ENCODER
if (methodFull.MethodID == k_BZip2) if (methodFull.MethodID == k_BZip2)
encoder = new NCompress::NBZip2::CEncoder; encoder = new NCompress::NBZip2::CEncoder;
#endif #endif
#ifdef COMPRESS_DEFLATE #ifdef COMPRESS_DEFLATE_ENCODER
if (methodFull.MethodID == k_Deflate) if (methodFull.MethodID == k_Deflate)
encoder = new NCompress::NDeflate::NEncoder::CCOMCoder; encoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
#endif #endif
#ifdef CRYPTO_7ZAES #ifdef CRYPTO_7ZAES
if (methodFull.MethodID == k_AES) if (methodFull.MethodID == k_AES)
encoder = new NCrypto::NSevenZ::CEncoder; filter = new NCrypto::NSevenZ::CEncoder;
#endif #endif
if (filter)
{
CFilterCoder *coderSpec = new CFilterCoder;
encoder = coderSpec;
coderSpec->Filter = filter;
}
#ifndef EXCLUDE_COM #ifndef EXCLUDE_COM
if (encoder == 0) if (encoder == 0)
{ {
RINOK(_libraries.CreateCoder(methodFull.FilePath, RINOK(_libraries.CreateCoderSpec(methodFull.FilePath,
methodFull.EncoderClassID, &encoder)); methodFull.EncoderClassID, &encoder));
} }
#endif #endif
@@ -186,46 +204,75 @@ HRESULT CEncoder::CreateMixerCoder()
return E_FAIL; return E_FAIL;
#endif #endif
} }
bool tryReduce = false;
UInt32 reducedDictionarySize = 1 << 10;
if (inSizeForReduce != 0 && methodFull.MethodID == k_LZMA)
{
while (true)
{
const UInt32 step = (reducedDictionarySize >> 1);
if (reducedDictionarySize >= *inSizeForReduce)
{
tryReduce = true;
break;
}
reducedDictionarySize += step;
if (reducedDictionarySize >= *inSizeForReduce)
{
tryReduce = true;
break;
}
if (reducedDictionarySize >= ((UInt32)11 << 30))
break;
reducedDictionarySize += step;
}
}
CMyComPtr<IUnknown> encoderCommon = methodFull.IsSimpleCoder() ? (IUnknown *)encoder : (IUnknown *)encoder2;
#ifdef COMPRESS_MT
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
}
}
#endif
if (methodFull.CoderProperties.Size() > 0) if (methodFull.CoderProperties.Size() > 0)
{ {
std::vector<NWindows::NCOM::CPropVariant> properties; CRecordVector<PROPID> propIDs;
std::vector<PROPID> propIDs; int numProperties = methodFull.CoderProperties.Size();
INT32 numProperties = methodFull.CoderProperties.Size(); NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties];
for (int i = 0; i < numProperties; i++) try
{ {
const CProperty &property = methodFull.CoderProperties[i]; for (int i = 0; i < numProperties; i++)
propIDs.push_back(property.PropID); {
properties.push_back(property.Value); const CProperty &property = methodFull.CoderProperties[i];
propIDs.Add(property.PropID);
NWindows::NCOM::CPropVariant value = property.Value;
if (tryReduce && property.PropID == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
value.ulVal = reducedDictionarySize;
values[i] = value;
}
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
RINOK(encoderCommon.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
} }
CMyComPtr<ICompressSetCoderProperties> setCoderProperties; catch(...)
if (methodFull.IsSimpleCoder())
{ {
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, delete []values;
&setCoderProperties)); throw;
} }
else delete []values;
{
RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
&setCoderProperties));
}
RINOK(setCoderProperties->SetCoderProperties(&propIDs.front(),
&properties.front(), numProperties));
} }
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties; CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
if (methodFull.IsSimpleCoder()) encoderCommon.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
{
encoder.QueryInterface(IID_ICompressWriteCoderProperties,
&writeCoderProperties);
}
else
{
encoder2.QueryInterface(IID_ICompressWriteCoderProperties,
&writeCoderProperties);
}
if (writeCoderProperties != NULL) if (writeCoderProperties != NULL)
{ {
@@ -234,7 +281,7 @@ HRESULT CEncoder::CreateMixerCoder()
outStreamSpec->Init(); outStreamSpec->Init();
writeCoderProperties->WriteCoderProperties(outStream); writeCoderProperties->WriteCoderProperties(outStream);
UINT32 size = outStreamSpec->GetSize(); size_t size = outStreamSpec->GetSize();
// encodingInfo.Properties.SetCapacity(size); // encodingInfo.Properties.SetCapacity(size);
if (encodingInfo.AltCoders.Size() == 0) if (encodingInfo.AltCoders.Size() == 0)
@@ -246,45 +293,40 @@ HRESULT CEncoder::CreateMixerCoder()
} }
CMyComPtr<ICryptoSetPassword> cryptoSetPassword; CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
if (methodFull.IsSimpleCoder()) encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
{
encoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
}
else
{
encoder2.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
}
if (cryptoSetPassword) if (cryptoSetPassword)
{ {
RINOK(cryptoSetPassword->CryptoSetPassword( CByteBuffer buffer;
(const BYTE *)(const wchar_t *)_options.Password, const UInt32 sizeInBytes = _options.Password.Length() * 2;
_options.Password.Length() * sizeof(wchar_t))); buffer.SetCapacity(sizeInBytes);
for (int i = 0; i < _options.Password.Length(); i++)
{
wchar_t c = _options.Password[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
} }
// public ICompressWriteCoderProperties,
if (methodFull.IsSimpleCoder()) if (methodFull.IsSimpleCoder())
{
_mixerCoderSpec->AddCoder(encoder); _mixerCoderSpec->AddCoder(encoder);
}
else else
{
_mixerCoderSpec->AddCoder2(encoder2); _mixerCoderSpec->AddCoder2(encoder2);
}
} }
return S_OK; return S_OK;
} }
HRESULT CEncoder::Encode(ISequentialInStream *inStream, HRESULT CEncoder::Encode(ISequentialInStream *inStream,
const UINT64 *inStreamSize, const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
CFolder &folderItem, CFolder &folderItem,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
CRecordVector<UINT64> &packSizes, CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress) ICompressProgressInfo *compressProgress)
{ {
if (_mixerCoderSpec == NULL) if (_mixerCoderSpec == NULL)
{ {
RINOK(CreateMixerCoder()); RINOK(CreateMixerCoder(inSizeForReduce));
} }
_mixerCoderSpec->ReInit(); _mixerCoderSpec->ReInit();
// _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress); // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
@@ -315,13 +357,13 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
if (_bindInfo.InStreams.IsEmpty()) if (_bindInfo.InStreams.IsEmpty())
return E_FAIL; return E_FAIL;
UINT32 mainCoderIndex, mainStreamIndex; UInt32 mainCoderIndex, mainStreamIndex;
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex); _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
_mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex); _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
if (inStreamSize != NULL) if (inStreamSize != NULL)
{ {
CRecordVector<const UINT64 *> sizePointers; CRecordVector<const UInt64 *> sizePointers;
for (int i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++) for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
if (i == mainStreamIndex) if (i == mainStreamIndex)
sizePointers.Add(inStreamSize); sizePointers.Add(inStreamSize);
else else
@@ -330,7 +372,7 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
} }
// UINT64 outStreamStartPos; // UInt64 outStreamStartPos;
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos)); // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
@@ -367,11 +409,11 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
packSizes.Add(inOutTempBuffer.GetDataSize()); packSizes.Add(inOutTempBuffer.GetDataSize());
} }
for (i = 0; i < _bindReverseConverter->NumSrcInStreams; i++) for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
{ {
int binder = _bindInfo.FindBinderForInStream( int binder = _bindInfo.FindBinderForInStream(
_bindReverseConverter->DestOutToSrcInMap[i]); _bindReverseConverter->DestOutToSrcInMap[i]);
UINT64 streamSize; UInt64 streamSize;
if (binder < 0) if (binder < 0)
streamSize = inStreamSizeCountSpec->GetSize(); streamSize = inStreamSizeCountSpec->GetSize();
else else
@@ -433,7 +475,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
else else
{ {
UINT32 numInStreams = 0, numOutStreams = 0; UInt32 numInStreams = 0, numOutStreams = 0;
int i; int i;
for (i = 0; i < options.Methods.Size(); i++) for (i = 0; i < options.Methods.Size(); i++)
{ {
@@ -452,7 +494,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
} }
else else
_bindInfo.OutStreams.Insert(0, numOutStreams); _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); _bindInfo.OutStreams.Add(numOutStreams + j);
} }
@@ -464,7 +506,7 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
if (!options.Binds.IsEmpty()) if (!options.Binds.IsEmpty())
{ {
for (int i = 0; i < options.Binds.Size(); i++) for (i = 0; i < options.Binds.Size(); i++)
{ {
NCoderMixer2::CBindPair bindPair; NCoderMixer2::CBindPair bindPair;
const CBind &bind = options.Binds[i]; const CBind &bind = options.Binds[i];
@@ -472,12 +514,12 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream; bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
_bindInfo.BindPairs.Add(bindPair); _bindInfo.BindPairs.Add(bindPair);
} }
for (i = 0; i < numOutStreams; i++) for (i = 0; i < (int)numOutStreams; i++)
if (_bindInfo.FindBinderForOutStream(i) == -1) if (_bindInfo.FindBinderForOutStream(i) == -1)
_bindInfo.OutStreams.Add(i); _bindInfo.OutStreams.Add(i);
} }
for (i = 0; i < numInStreams; i++) for (i = 0; i < (int)numInStreams; i++)
if (_bindInfo.FindBinderForInStream(i) == -1) if (_bindInfo.FindBinderForInStream(i) == -1)
_bindInfo.InStreams.Add(i); _bindInfo.InStreams.Add(i);
@@ -488,9 +530,9 @@ CEncoder::CEncoder(const CCompressionMethodMode &options):
int inIndex = _bindInfo.InStreams[0]; int inIndex = _bindInfo.InStreams[0];
while (true) while (true)
{ {
UINT32 coderIndex, coderStreamIndex; UInt32 coderIndex, coderStreamIndex;
_bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex); _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
UINT32 outIndex = _bindInfo.GetCoderStartOutStream(coderIndex); UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
int binder = _bindInfo.FindBinderForOutStream(outIndex); int binder = _bindInfo.FindBinderForOutStream(outIndex);
if (binder >= 0) if (binder >= 0)
{ {

View File

@@ -1,7 +1,5 @@
// 7zEncode.h // 7zEncode.h
#pragma once
#ifndef __7Z_ENCODE_H #ifndef __7Z_ENCODE_H
#define __7Z_ENCODE_H #define __7Z_ENCODE_H
@@ -10,6 +8,8 @@
#include "7zCompressionMode.h" #include "7zCompressionMode.h"
#include "../Common/CoderMixer2.h" #include "../Common/CoderMixer2.h"
#include "../Common/CoderMixer2MT.h"
#include "../Common/CoderMixer2ST.h"
#ifndef EXCLUDE_COM #ifndef EXCLUDE_COM
#include "../Common/CoderLoader.h" #include "../Common/CoderLoader.h"
#endif #endif
@@ -27,7 +27,7 @@ class CEncoder
CCoderLibraries _libraries; CCoderLibraries _libraries;
#endif #endif
NCoderMixer2::CCoderMixer2 *_mixerCoderSpec; NCoderMixer2::CCoderMixer2MT *_mixerCoderSpec;
CMyComPtr<ICompressCoder2> _mixerCoder; CMyComPtr<ICompressCoder2> _mixerCoder;
CObjectVector<CCoderInfo> _codersInfo; CObjectVector<CCoderInfo> _codersInfo;
@@ -38,16 +38,16 @@ class CEncoder
NCoderMixer2::CBindReverseConverter *_bindReverseConverter; NCoderMixer2::CBindReverseConverter *_bindReverseConverter;
CRecordVector<CMethodID> _decompressionMethods; CRecordVector<CMethodID> _decompressionMethods;
HRESULT CreateMixerCoder(); HRESULT CreateMixerCoder(const UInt64 *inSizeForReduce);
public: public:
CEncoder(const CCompressionMethodMode &options); CEncoder(const CCompressionMethodMode &options);
~CEncoder(); ~CEncoder();
HRESULT Encode(ISequentialInStream *inStream, HRESULT Encode(ISequentialInStream *inStream,
const UINT64 *inStreamSize, const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
CFolder &folderItem, CFolder &folderItem,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
CRecordVector<UINT64> &packSizes, CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress); ICompressProgressInfo *compressProgress);
}; };

View File

@@ -6,9 +6,9 @@
#include "7zFolderOutStream.h" #include "7zFolderOutStream.h"
#include "7zMethods.h" #include "7zMethods.h"
#include "7zDecode.h" #include "7zDecode.h"
// #include "7z1Decode.h"
#include "../../../Common/ComTry.h" #include "../../../Common/ComTry.h"
#include "../../Common/MultiStream.h"
#include "../../Common/StreamObjects.h" #include "../../Common/StreamObjects.h"
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h" #include "../../Common/LimitedStreams.h"
@@ -18,16 +18,26 @@ namespace N7z {
struct CExtractFolderInfo struct CExtractFolderInfo
{ {
int FileIndex; #ifdef _7Z_VOL
int FolderIndex; int VolumeIndex;
#endif
CNum FileIndex;
CNum FolderIndex;
CBoolVector ExtractStatuses; CBoolVector ExtractStatuses;
UINT64 UnPackSize; UInt64 UnPackSize;
CExtractFolderInfo(int fileIndex, int folderIndex): CExtractFolderInfo(
#ifdef _7Z_VOL
int volumeIndex,
#endif
CNum fileIndex, CNum folderIndex):
#ifdef _7Z_VOL
VolumeIndex(volumeIndex),
#endif
FileIndex(fileIndex), FileIndex(fileIndex),
FolderIndex(folderIndex), FolderIndex(folderIndex),
UnPackSize(0) UnPackSize(0)
{ {
if (fileIndex >= 0) if (fileIndex != kNumNoIndex)
{ {
ExtractStatuses.Reserve(1); ExtractStatuses.Reserve(1);
ExtractStatuses.Add(true); ExtractStatuses.Add(true);
@@ -35,116 +45,155 @@ struct CExtractFolderInfo
}; };
}; };
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
INT32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
bool testMode = (testModeSpec != 0); bool testMode = (testModeSpec != 0);
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
UINT64 importantTotalUnPacked = 0; UInt64 importantTotalUnPacked = 0;
UINT64 censoredTotalUnPacked = 0, censoredTotalPacked = 0;
bool allFilesMode = (numItems == UINT32(-1)); bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode) if (allFilesMode)
numItems = _database.Files.Size(); numItems =
#ifdef _7Z_VOL
_refs.Size();
#else
_database.Files.Size();
#endif
if(numItems == 0) if(numItems == 0)
return S_OK; 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; CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
for(UINT32 indexIndex = 0; indexIndex < numItems; indexIndex++) for(UInt32 ii = 0; ii < numItems; ii++)
{ {
int fileIndex = allFilesMode ? indexIndex : indices[indexIndex]; // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
int folderIndex = _database.FileIndexToFolderIndexMap[fileIndex]; UInt32 ref2Index = allFilesMode ? ii : indices[ii];
if (folderIndex < 0) // const CRef2 &ref2 = _refs[ref2Index];
{
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;
}
CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector.Back(); // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
UINT32 startIndex = (UINT32)_database.FolderStartFileIndex[folderIndex];
for (UINT32 index = extractFolderInfo.ExtractStatuses.Size();
index <= fileIndex - startIndex; index++)
{ {
UINT64 unPackSize = _database.Files[startIndex + index].UnPackSize; #ifdef _7Z_VOL
// Count partial_folder_size // const CRef &ref = ref2.Refs[ri];
// extractFolderInfo.UnPackSize += unPackSize; const CRef &ref = _refs[ref2Index];
// importantTotalUnPacked += unPackSize;
extractFolderInfo.ExtractStatuses.Add(index == fileIndex - startIndex); 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); extractCallback->SetTotal(importantTotalUnPacked);
CDecoder decoder; CDecoder decoder(
#ifdef _ST_MODE
false
#else
true
#endif
);
// CDecoder1 decoder;
UINT64 currentImportantTotalUnPacked = 0; UInt64 currentImportantTotalUnPacked = 0;
UINT64 totalFolderUnPacked; UInt64 totalFolderUnPacked;
for(int i = 0; i < extractFolderInfoVector.Size(); i++, for(int i = 0; i < extractFolderInfoVector.Size(); i++,
currentImportantTotalUnPacked += totalFolderUnPacked) currentImportantTotalUnPacked += totalFolderUnPacked)
{ {
CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector[i]; const CExtractFolderInfo &efi = extractFolderInfoVector[i];
totalFolderUnPacked = extractFolderInfo.UnPackSize; totalFolderUnPacked = efi.UnPackSize;
RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked)); RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked));
CFolderOutStream *folderOutStream = new CFolderOutStream; CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream); CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
UINT32 startIndex; #ifdef _7Z_VOL
if (extractFolderInfo.FileIndex >= 0) const CVolume &volume = _volumes[efi.VolumeIndex];
startIndex = extractFolderInfo.FileIndex; const CArchiveDatabaseEx &database = volume.Database;
#else
const CArchiveDatabaseEx &database = _database;
#endif
CNum startIndex;
if (efi.FileIndex != kNumNoIndex)
startIndex = efi.FileIndex;
else else
startIndex = (UINT32)_database.FolderStartFileIndex[extractFolderInfo.FolderIndex]; startIndex = database.FolderStartFileIndex[efi.FolderIndex];
RINOK(folderOutStream->Init(&_database, startIndex, HRESULT result = folderOutStream->Init(&database,
&extractFolderInfo.ExtractStatuses, extractCallback, testMode)); #ifdef _7Z_VOL
volume.StartRef2Index,
#else
0,
#endif
startIndex,
&efi.ExtractStatuses, extractCallback, testMode);
if (extractFolderInfo.FileIndex >= 0) RINOK(result);
if (efi.FileIndex != kNumNoIndex)
continue; continue;
UINT32 folderIndex = extractFolderInfo.FolderIndex; CNum folderIndex = efi.FolderIndex;
const CFolder &folderInfo = _database.Folders[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);
}
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
@@ -155,8 +204,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress, NULL, &currentImportantTotalUnPacked); localCompressProgressSpec->Init(progress, NULL, &currentImportantTotalUnPacked);
UINT32 packStreamIndex = _database.FolderStartPackStreamIndex[folderIndex]; CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
UINT64 folderStartPackPos = _database.GetFolderStreamPos(folderIndex, 0); UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword; CMyComPtr<ICryptoGetTextPassword> getTextPassword;
@@ -166,15 +215,23 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
try try
{ {
HRESULT result = decoder.Decode(_inStream, HRESULT result = decoder.Decode(
#ifdef _7Z_VOL
volume.Stream,
#else
_inStream,
#endif
folderStartPackPos, folderStartPackPos,
&_database.PackSizes[packStreamIndex], &database.PackSizes[packStreamIndex],
folderInfo, folderInfo,
outStream, outStream,
compressProgress compressProgress
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword
#endif #endif
#ifdef COMPRESS_MT
, true, _numThreads
#endif
); );
if (result == S_FALSE) if (result == S_FALSE)
@@ -189,7 +246,11 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
} }
if (result != S_OK) if (result != S_OK)
return result; return result;
RINOK(folderOutStream->WasWritingFinished()); if (folderOutStream->WasWritingFinished() != S_OK)
{
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
continue;
}
} }
catch(...) catch(...)
{ {

View File

@@ -9,17 +9,18 @@ namespace N7z {
CFolderInStream::CFolderInStream() CFolderInStream::CFolderInStream()
{ {
_inStreamWithHashSpec = new CInStreamWithCRC; _inStreamWithHashSpec = new CSequentialInStreamWithCRC;
_inStreamWithHash = _inStreamWithHashSpec; _inStreamWithHash = _inStreamWithHashSpec;
} }
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
const UINT32 *fileIndices, UINT32 numFiles) const UInt32 *fileIndices, UInt32 numFiles)
{ {
_updateCallback = updateCallback; _updateCallback = updateCallback;
_numFiles = numFiles; _numFiles = numFiles;
_fileIndex = 0; _fileIndex = 0;
_fileIndices = fileIndices; _fileIndices = fileIndices;
Processed.Clear();
CRCs.Clear(); CRCs.Clear();
Sizes.Clear(); Sizes.Clear();
_fileIsOpen = false; _fileIsOpen = false;
@@ -32,14 +33,17 @@ HRESULT CFolderInStream::OpenStream()
while (_fileIndex < _numFiles) while (_fileIndex < _numFiles)
{ {
_currentSizeIsDefined = false; _currentSizeIsDefined = false;
CMyComPtr<IInStream> stream; CMyComPtr<ISequentialInStream> stream;
RINOK(_updateCallback->GetStream(_fileIndices[_fileIndex], &stream)); HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
if (result != S_OK && result != S_FALSE)
return result;
_fileIndex++; _fileIndex++;
_inStreamWithHashSpec->Init(stream); _inStreamWithHashSpec->Init(stream);
if (!stream) if (!stream)
{ {
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
Sizes.Add(0); Sizes.Add(0);
Processed.Add(result == S_OK);
AddDigest(); AddDigest();
continue; continue;
} }
@@ -69,21 +73,22 @@ HRESULT CFolderInStream::CloseStream()
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
_inStreamWithHashSpec->ReleaseStream(); _inStreamWithHashSpec->ReleaseStream();
_fileIsOpen = false; _fileIsOpen = false;
Processed.Add(true);
Sizes.Add(_filePos); Sizes.Add(_filePos);
AddDigest(); AddDigest();
return S_OK; return S_OK;
} }
STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize) STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{ {
UINT32 realProcessedSize = 0; UInt32 realProcessedSize = 0;
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0) while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
{ {
if (_fileIsOpen) if (_fileIsOpen)
{ {
UINT32 localProcessedSize; UInt32 localProcessedSize;
RINOK(_inStreamWithHash->Read( RINOK(_inStreamWithHash->Read(
((BYTE *)data) + realProcessedSize, size, &localProcessedSize)); ((Byte *)data) + realProcessedSize, size, &localProcessedSize));
if (localProcessedSize == 0) if (localProcessedSize == 0)
{ {
RINOK(CloseStream()); RINOK(CloseStream());
@@ -104,30 +109,12 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processe
return S_OK; return S_OK;
} }
STDMETHODIMP CFolderInStream::Read(void *data, UINT32 size, UINT32 *processedSize) STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
UINT32 realProcessedSize = 0;
while (size > 0)
{
UINT32 localProcessedSize;
RINOK(ReadPart(((BYTE *)data) + realProcessedSize, size, &localProcessedSize));
if (localProcessedSize == 0)
break;
size -= localProcessedSize;
realProcessedSize += localProcessedSize;
}
if (processedSize != 0)
*processedSize = realProcessedSize;
return S_OK;
}
STDMETHODIMP CFolderInStream::GetSubStreamSize(UINT64 subStream, UINT64 *value)
{ {
*value = 0; *value = 0;
if (subStream < Sizes.Size()) if (subStream < Sizes.Size())
{ {
*value= Sizes[subStream]; *value= Sizes[(int)(size_t)subStream];
return S_OK; return S_OK;
} }
if (subStream > Sizes.Size()) if (subStream > Sizes.Size())

View File

@@ -1,7 +1,5 @@
// 7z/FolderInStream.h // 7z/FolderInStream.h
#pragma once
#ifndef __7Z_FOLDERINSTREAM_H #ifndef __7Z_FOLDERINSTREAM_H
#define __7Z_FOLDERINSTREAM_H #define __7Z_FOLDERINSTREAM_H
@@ -27,36 +25,36 @@ public:
CFolderInStream(); CFolderInStream();
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value); STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
private: private:
CInStreamWithCRC *_inStreamWithHashSpec; CSequentialInStreamWithCRC *_inStreamWithHashSpec;
CMyComPtr<ISequentialInStream> _inStreamWithHash; CMyComPtr<ISequentialInStream> _inStreamWithHash;
CMyComPtr<IArchiveUpdateCallback> _updateCallback; CMyComPtr<IArchiveUpdateCallback> _updateCallback;
bool _currentSizeIsDefined; bool _currentSizeIsDefined;
UINT64 _currentSize; UInt64 _currentSize;
bool _fileIsOpen; bool _fileIsOpen;
UINT64 _filePos; UInt64 _filePos;
const UINT32 *_fileIndices; const UInt32 *_fileIndices;
UINT32 _numFiles; UInt32 _numFiles;
UINT32 _fileIndex; UInt32 _fileIndex;
HRESULT OpenStream(); HRESULT OpenStream();
HRESULT CloseStream(); HRESULT CloseStream();
void AddDigest(); void AddDigest();
public: public:
void Init(IArchiveUpdateCallback *updateCallback, void Init(IArchiveUpdateCallback *updateCallback,
const UINT32 *fileIndices, UINT32 numFiles); const UInt32 *fileIndices, UInt32 numFiles);
CRecordVector<UINT32> CRCs; CRecordVector<bool> Processed;
CRecordVector<UINT64> Sizes; CRecordVector<UInt32> CRCs;
UINT64 GetFullSize() const CRecordVector<UInt64> Sizes;
UInt64 GetFullSize() const
{ {
UINT64 size = 0; UInt64 size = 0;
for (int i = 0; i < Sizes.Size(); i++) for (int i = 0; i < Sizes.Size(); i++)
size += Sizes[i]; size += Sizes[i];
return size; return size;

View File

@@ -14,13 +14,15 @@ CFolderOutStream::CFolderOutStream()
} }
HRESULT CFolderOutStream::Init( HRESULT CFolderOutStream::Init(
CArchiveDatabaseEx *archiveDatabase, const CArchiveDatabaseEx *archiveDatabase,
UINT32 startIndex, UInt32 ref2Offset,
UInt32 startIndex,
const CBoolVector *extractStatuses, const CBoolVector *extractStatuses,
IArchiveExtractCallback *extractCallback, IArchiveExtractCallback *extractCallback,
bool testMode) bool testMode)
{ {
_archiveDatabase = archiveDatabase; _archiveDatabase = archiveDatabase;
_ref2Offset = ref2Offset;
_startIndex = startIndex; _startIndex = startIndex;
_extractStatuses = extractStatuses; _extractStatuses = extractStatuses;
@@ -34,7 +36,7 @@ HRESULT CFolderOutStream::Init(
HRESULT CFolderOutStream::OpenFile() HRESULT CFolderOutStream::OpenFile()
{ {
INT32 askMode; Int32 askMode;
if((*_extractStatuses)[_currentIndex]) if((*_extractStatuses)[_currentIndex])
askMode = _testMode ? askMode = _testMode ?
NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
@@ -43,14 +45,13 @@ HRESULT CFolderOutStream::OpenFile()
askMode = NArchive::NExtract::NAskMode::kSkip; askMode = NArchive::NExtract::NAskMode::kSkip;
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
UINT32 index = _startIndex + _currentIndex; UInt32 index = _startIndex + _currentIndex;
RINOK(_extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
_outStreamWithHashSpec->Init(realOutStream); _outStreamWithHashSpec->Init(realOutStream);
if (askMode == NArchive::NExtract::NAskMode::kExtract && if (askMode == NArchive::NExtract::NAskMode::kExtract &&
(!realOutStream)) (!realOutStream))
{ {
UINT32 index = _startIndex + _currentIndex;
const CFileItem &fileInfo = _archiveDatabase->Files[index]; const CFileItem &fileInfo = _archiveDatabase->Files[index];
if (!fileInfo.IsAnti && !fileInfo.IsDirectory) if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
askMode = NArchive::NExtract::NAskMode::kSkip; askMode = NArchive::NExtract::NAskMode::kSkip;
@@ -62,7 +63,7 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
{ {
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++) for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
{ {
UINT32 index = _startIndex + _currentIndex; UInt32 index = _startIndex + _currentIndex;
const CFileItem &fileInfo = _archiveDatabase->Files[index]; const CFileItem &fileInfo = _archiveDatabase->Files[index];
if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0) if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
return S_OK; return S_OK;
@@ -75,29 +76,30 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
} }
STDMETHODIMP CFolderOutStream::Write(const void *data, STDMETHODIMP CFolderOutStream::Write(const void *data,
UINT32 size, UINT32 *processedSize) UInt32 size, UInt32 *processedSize)
{ {
UINT32 realProcessedSize = 0; UInt32 realProcessedSize = 0;
while(_currentIndex < _extractStatuses->Size()) while(_currentIndex < _extractStatuses->Size())
{ {
if (_fileIsOpen) if (_fileIsOpen)
{ {
UINT32 index = _startIndex + _currentIndex; UInt32 index = _startIndex + _currentIndex;
const CFileItem &fileInfo = _archiveDatabase->Files[index]; const CFileItem &fileInfo = _archiveDatabase->Files[index];
UINT64 fileSize = fileInfo.UnPackSize; UInt64 fileSize = fileInfo.UnPackSize;
UINT32 numBytesToWrite = (UINT32)MyMin(fileSize - _filePos, UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
UINT64(size - realProcessedSize)); UInt64(size - realProcessedSize));
UINT32 processedSizeLocal; UInt32 processedSizeLocal;
RINOK(_outStreamWithHash->Write((const BYTE *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal)); RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
numBytesToWrite, &processedSizeLocal));
_filePos += processedSizeLocal; _filePos += processedSizeLocal;
realProcessedSize += processedSizeLocal; realProcessedSize += processedSizeLocal;
if (_filePos == fileSize) if (_filePos == fileSize)
{ {
bool digestsAreEqual; bool digestsAreEqual;
if (fileInfo.FileCRCIsDefined) if (fileInfo.IsFileCRCDefined)
digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC(); digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
else else
digestsAreEqual = true; digestsAreEqual = true;
@@ -129,13 +131,7 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
return S_OK; return S_OK;
} }
STDMETHODIMP CFolderOutStream::WritePart(const void *data, HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
UINT32 size, UINT32 *processedSize)
{
return Write(data, size, processedSize);
}
HRESULT CFolderOutStream::FlushCorrupted(INT32 resultEOperationResult)
{ {
while(_currentIndex < _extractStatuses->Size()) while(_currentIndex < _extractStatuses->Size())
{ {

View File

@@ -1,7 +1,5 @@
// 7zFolderOutStream.h // 7zFolderOutStream.h
#pragma once
#ifndef __7Z_FOLDEROUTSTREAM_H #ifndef __7Z_FOLDEROUTSTREAM_H
#define __7Z_FOLDEROUTSTREAM_H #define __7Z_FOLDEROUTSTREAM_H
@@ -23,33 +21,34 @@ public:
CFolderOutStream(); CFolderOutStream();
STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
private: private:
COutStreamWithCRC *_outStreamWithHashSpec; COutStreamWithCRC *_outStreamWithHashSpec;
CMyComPtr<ISequentialOutStream> _outStreamWithHash; CMyComPtr<ISequentialOutStream> _outStreamWithHash;
CArchiveDatabaseEx *_archiveDatabase; const CArchiveDatabaseEx *_archiveDatabase;
const CBoolVector *_extractStatuses; const CBoolVector *_extractStatuses;
UINT32 _startIndex; UInt32 _startIndex;
UInt32 _ref2Offset;
int _currentIndex; int _currentIndex;
// UINT64 _currentDataPos; // UInt64 _currentDataPos;
CMyComPtr<IArchiveExtractCallback> _extractCallback; CMyComPtr<IArchiveExtractCallback> _extractCallback;
bool _testMode; bool _testMode;
bool _fileIsOpen; bool _fileIsOpen;
UINT64 _filePos; UInt64 _filePos;
HRESULT OpenFile(); HRESULT OpenFile();
HRESULT WriteEmptyFiles(); HRESULT WriteEmptyFiles();
public: public:
HRESULT Init( HRESULT Init(
CArchiveDatabaseEx *archiveDatabase, const CArchiveDatabaseEx *archiveDatabase,
UINT32 startIndex, UInt32 ref2Offset,
UInt32 startIndex,
const CBoolVector *extractStatuses, const CBoolVector *extractStatuses,
IArchiveExtractCallback *extractCallback, IArchiveExtractCallback *extractCallback,
bool testMode); bool testMode);
HRESULT FlushCorrupted(INT32 resultEOperationResult); HRESULT FlushCorrupted(Int32 resultEOperationResult);
HRESULT WasWritingFinished(); HRESULT WasWritingFinished();
}; };

View File

@@ -1,4 +1,4 @@
// 7z/Handler.cpp // 7zHandler.cpp
#include "StdAfx.h" #include "StdAfx.h"
@@ -6,20 +6,30 @@
#include "7zProperties.h" #include "7zProperties.h"
#include "../../../Common/IntToString.h" #include "../../../Common/IntToString.h"
// #include "../../../Common/StringConvert.h"
#include "../../../Common/ComTry.h" #include "../../../Common/ComTry.h"
#include "../../../Windows/Defs.h" #include "../../../Windows/Defs.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
#ifdef _7Z_VOL
#include "../Common/MultiStream.h"
#endif
// #include "7zMethods.h" #ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
#include "../Common/ParseProperties.h"
#endif
#endif
using namespace NWindows;
namespace NArchive { namespace NArchive {
namespace N7z { namespace N7z {
CHandler::CHandler() CHandler::CHandler()
{ {
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
#endif
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
Init(); Init();
#endif #endif
@@ -28,31 +38,15 @@ CHandler::CHandler()
#endif #endif
} }
/* STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::EnumProperties(IEnumSTATPROPSTG **enumerator)
{ {
#ifndef _SFX
COM_TRY_BEGIN COM_TRY_BEGIN
CComObjectNoLock<CEnumArchiveItemProperty> *enumeratorSpec = *numItems =
new CComObjectNoLock<CEnumArchiveItemProperty>; #ifdef _7Z_VOL
if (enumeratorSpec == NULL) _refs.Size();
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
#else #else
return E_NOTIMPL;
#endif
}
*/
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
{
COM_TRY_BEGIN
*numItems = _database.Files.Size(); *numItems = _database.Files.Size();
#endif
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -65,12 +59,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
#ifdef _SFX #ifdef _SFX
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
{ {
return E_NOTIMPL; return E_NOTIMPL;
} }
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType) BSTR *name, PROPID *propID, VARTYPE *varType)
{ {
return E_NOTIMPL; return E_NOTIMPL;
@@ -79,13 +73,13 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
#endif #endif
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{ {
*numProperties = 0; *numProperties = 0;
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType) BSTR *name, PROPID *propID, VARTYPE *varType)
{ {
return E_NOTIMPL; return E_NOTIMPL;
@@ -95,30 +89,22 @@ STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
static void MySetFileTime(bool timeDefined, FILETIME unixTime, static void MySetFileTime(bool timeDefined, FILETIME unixTime,
NWindows::NCOM::CPropVariant &propVariant) NWindows::NCOM::CPropVariant &propVariant)
{ {
// FILETIME fileTime;
if (timeDefined) if (timeDefined)
propVariant = unixTime; 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)); 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; 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 >> 4);
result += GetHex(b & 0xF); result += GetHex(b & 0xF);
} }
@@ -129,32 +115,32 @@ static UString ConvertBytesToHexString(const BYTE *data, UINT32 size)
#ifndef _SFX #ifndef _SFX
static UString ConvertUINT32ToString(UINT32 value) static UString ConvertUInt32ToString(UInt32 value)
{ {
wchar_t buffer[32]; wchar_t buffer[32];
ConvertUINT64ToString(value, buffer); ConvertUInt64ToString(value, buffer);
return buffer; return buffer;
} }
static UString GetStringForSizeValue(UINT32 value) static UString GetStringForSizeValue(UInt32 value)
{ {
for (int i = 31; i >= 0; i--) for (int i = 31; i >= 0; i--)
if ((UINT32(1) << i) == value) if ((UInt32(1) << i) == value)
return ConvertUINT32ToString(i); return ConvertUInt32ToString(i);
UString result; UString result;
if (value % (1 << 20) == 0) if (value % (1 << 20) == 0)
{ {
result += ConvertUINT32ToString(value >> 20); result += ConvertUInt32ToString(value >> 20);
result += L"m"; result += L"m";
} }
else if (value % (1 << 10) == 0) else if (value % (1 << 10) == 0)
{ {
result += ConvertUINT32ToString(value >> 10); result += ConvertUInt32ToString(value >> 10);
result += L"k"; result += L"k";
} }
else else
{ {
result += ConvertUINT32ToString(value); result += ConvertUInt32ToString(value);
result += L"b"; result += L"b";
} }
return result; return result;
@@ -168,11 +154,11 @@ static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 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)); return (value < 10) ? ('0' + value) : ('A' + (value - 10));
} }
static inline UString GetHex2(BYTE value) static inline UString GetHex2(Byte value)
{ {
UString result; UString result;
result += GetHex(value >> 4); result += GetHex(value >> 4);
@@ -182,39 +168,78 @@ static inline UString GetHex2(BYTE value)
#endif #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 COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; 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]; const CFileItem &item = _database.Files[index];
UInt32 index2 = index;
#endif
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
{ {
propVariant = NArchive::NItemName::GetOSName(item.Name); if (!item.Name.IsEmpty())
propVariant = NItemName::GetOSName(item.Name);
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory; propVariant = item.IsDirectory;
break; break;
case kpidSize: case kpidSize:
{
propVariant = item.UnPackSize; propVariant = item.UnPackSize;
// propVariant = ref2.UnPackSize;
break; break;
}
case kpidPosition:
{
/*
if (ref2.Refs.Size() > 1)
propVariant = ref2.StartPos;
else
*/
if (item.IsStartPosDefined)
propVariant = item.StartPos;
break;
}
case kpidPackedSize: case kpidPackedSize:
{ {
// propVariant = ref2.PackSize;
{ {
int folderIndex = _database.FileIndexToFolderIndexMap[index]; CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex >= 0) if (folderIndex != kNumNoIndex)
{ {
const CFolder &folderInfo = _database.Folders[folderIndex]; if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
if (_database.FolderStartFileIndex[folderIndex] == index)
propVariant = _database.GetFolderFullPackSize(folderIndex); propVariant = _database.GetFolderFullPackSize(folderIndex);
/*
else else
propVariant = UINT64(0); propVariant = UInt64(0);
*/
} }
else else
propVariant = UINT64(0); propVariant = UInt64(0);
} }
break; break;
} }
@@ -232,14 +257,14 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
propVariant = item.Attributes; propVariant = item.Attributes;
break; break;
case kpidCRC: case kpidCRC:
if (item.FileCRCIsDefined) if (item.IsFileCRCDefined)
propVariant = item.FileCRC; propVariant = item.FileCRC;
break; break;
#ifndef _SFX #ifndef _SFX
case kpidMethod: case kpidMethod:
{ {
int folderIndex = _database.FileIndexToFolderIndexMap[index]; CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex >= 0) if (folderIndex != kNumNoIndex)
{ {
const CFolder &folderInfo = _database.Folders[folderIndex]; const CFolder &folderInfo = _database.Folders[folderIndex];
UString methodsString; UString methodsString;
@@ -292,24 +317,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
methodsString += methodName; methodsString += methodName;
if (altCoderInfo.MethodID == k_LZMA) if (altCoderInfo.MethodID == k_LZMA)
{ {
if (altCoderInfo.Properties.GetCapacity() == 5) if (altCoderInfo.Properties.GetCapacity() >= 5)
{ {
methodsString += L":"; methodsString += L":";
UINT32 dicSize = *(const UINT32 *) UInt32 dicSize = GetUInt32FromMemLE(
((const BYTE *)altCoderInfo.Properties + 1); ((const Byte *)altCoderInfo.Properties + 1));
methodsString += GetStringForSizeValue(dicSize); methodsString += GetStringForSizeValue(dicSize);
} }
} }
else if (altCoderInfo.MethodID == k_PPMD) 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 += L":o";
methodsString += ConvertUINT32ToString(order); methodsString += ConvertUInt32ToString(order);
methodsString += L":mem"; methodsString += L":mem";
UINT32 dicSize = *(const UINT32 *) UInt32 dicSize = GetUInt32FromMemLE(
((const BYTE *)altCoderInfo.Properties + 1); ((const Byte *)altCoderInfo.Properties + 1));
methodsString += GetStringForSizeValue(dicSize); methodsString += GetStringForSizeValue(dicSize);
} }
} }
@@ -318,7 +343,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
if (altCoderInfo.Properties.GetCapacity() > 0) if (altCoderInfo.Properties.GetCapacity() > 0)
{ {
methodsString += L":["; 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()) if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())
{ {
@@ -344,9 +369,9 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
break; break;
case kpidBlock: case kpidBlock:
{ {
int folderIndex = _database.FileIndexToFolderIndexMap[index]; CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex >= 0) if (folderIndex != kNumNoIndex)
propVariant = (UINT32)folderIndex; propVariant = (UInt32)folderIndex;
} }
break; break;
case kpidPackedSize0: case kpidPackedSize0:
@@ -355,20 +380,20 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
case kpidPackedSize3: case kpidPackedSize3:
case kpidPackedSize4: case kpidPackedSize4:
{ {
int folderIndex = _database.FileIndexToFolderIndexMap[index]; CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex >= 0) if (folderIndex != kNumNoIndex)
{ {
const CFolder &folderInfo = _database.Folders[folderIndex]; const CFolder &folderInfo = _database.Folders[folderIndex];
if (_database.FolderStartFileIndex[folderIndex] == index && if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
folderInfo.PackStreams.Size() > propID - kpidPackedSize0) folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
{ {
propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
} }
else else
propVariant = UINT64(0); propVariant = UInt64(0);
} }
else else
propVariant = UINT64(0); propVariant = UInt64(0);
} }
break; break;
#endif #endif
@@ -381,49 +406,238 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
COM_TRY_END 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, STDMETHODIMP CHandler::Open(IInStream *stream,
const UINT64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback *openArchiveCallback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
_inStream.Release(); Close();
_database.Clear();
#ifndef _SFX #ifndef _SFX
_fileInfoPopIDs.Clear(); _fileInfoPopIDs.Clear();
#endif #endif
try try
{ {
CInArchive archive; CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
RINOK(archive.Open(stream, maxCheckStartPosition)); #ifdef _7Z_VOL
CVolumeName seqName;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
#endif
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword; CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (openArchiveCallback) if (openArchiveCallback)
{ {
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
openArchiveCallbackTemp.QueryInterface( openArchiveCallbackTemp.QueryInterface(
IID_ICryptoGetTextPassword, &getTextPassword); IID_ICryptoGetTextPassword, &getTextPassword);
} }
#endif #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 HRESULT result = archive.ReadDatabase(_database
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword
#endif #endif
); );
RINOK(result); RINOK(result);
result = archive.CheckIntegrity(); _database.Fill();
if (result != S_OK) _inStream = stream;
return E_FAIL; #endif
_database.FillFolderStartPackStream();
_database.FillStartPos();
_database.FillFolderStartFileIndex();
} }
catch(...) catch(...)
{ {
Close();
return S_FALSE; return S_FALSE;
} }
_inStream = stream; // _inStream = stream;
#ifndef _SFX #ifndef _SFX
FillPopIDs(); FillPopIDs();
#endif #endif
@@ -434,9 +648,110 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
STDMETHODIMP CHandler::Close() STDMETHODIMP CHandler::Close()
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
#ifdef _7Z_VOL
_volumes.Clear();
_refs.Clear();
#else
_inStream.Release(); _inStream.Release();
_database.Clear();
#endif
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
#ifdef _7Z_VOL
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
if (index != 0)
return E_INVALIDARG;
*stream = 0;
CMultiStream *streamSpec = new CMultiStream;
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
UInt64 pos = 0;
const UString *fileName;
for (int i = 0; i < _refs.Size(); i++)
{
const CRef &ref = _refs[i];
const CVolume &volume = _volumes[ref.VolumeIndex];
const CArchiveDatabaseEx &database = volume.Database;
const CFileItem &file = database.Files[ref.ItemIndex];
if (i == 0)
fileName = &file.Name;
else
if (fileName->Compare(file.Name) != 0)
return S_FALSE;
if (!file.IsStartPosDefined)
return S_FALSE;
if (file.StartPos != pos)
return S_FALSE;
CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
if (folderIndex == kNumNoIndex)
{
if (file.UnPackSize != 0)
return E_FAIL;
continue;
}
if (database.NumUnPackStreamsVector[folderIndex] != 1)
return S_FALSE;
const CFolder &folder = database.Folders[folderIndex];
if (folder.Coders.Size() != 1)
return S_FALSE;
const CCoderInfo &coder = folder.Coders.Front();
if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
return S_FALSE;
const CAltCoderInfo &altCoder = coder.AltCoders.Front();
if (altCoder.MethodID.IDSize != 1 || altCoder.MethodID.ID[0] != 0)
return S_FALSE;
pos += file.UnPackSize;
CMultiStream::CSubStreamInfo subStreamInfo;
subStreamInfo.Stream = volume.Stream;
subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
subStreamInfo.Size = file.UnPackSize;
streamSpec->Streams.Add(subStreamInfo);
}
streamSpec->Init();
*stream = streamTemp.Detach();
return S_OK;
}
#endif
#ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{
COM_TRY_BEGIN
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
for (int i = 0; i < numProperties; i++)
{
UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
UInt32 number;
int index = ParseStringToUInt32(name, number);
if (index == 0)
{
if(name.Left(2).CompareNoCase(L"MT") == 0)
{
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
continue;
}
else
return E_INVALIDARG;
}
}
return S_OK;
COM_TRY_END
}
#endif
#endif
}} }}

View File

@@ -1,12 +1,9 @@
// 7z/Handler.h // 7z/Handler.h
#pragma once
#ifndef __7Z_HANDLER_H #ifndef __7Z_HANDLER_H
#define __7Z_HANDLER_H #define __7Z_HANDLER_H
#include "../IArchive.h" #include "../IArchive.h"
// #include "../../../Compress/Interface/CompressInterface.h"
#include "7zIn.h" #include "7zIn.h"
#include "7zCompressionMode.h" #include "7zCompressionMode.h"
@@ -15,9 +12,39 @@
#include "7zMethods.h" #include "7zMethods.h"
#endif #endif
#ifdef COMPRESS_MT
#include "../../../Windows/System.h"
#endif
namespace NArchive { namespace NArchive {
namespace N7z { 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 #ifndef EXTRACT_ONLY
struct COneMethodInfo struct COneMethodInfo
@@ -27,59 +54,86 @@ struct COneMethodInfo
}; };
#endif #endif
// {23170F69-40C1-278A-1000-000110050000} // {23170F69-40C1-278A-1000-000110070000}
DEFINE_GUID(CLSID_CFormat7z, DEFINE_GUID(CLSID_CFormat7z,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00); 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
#ifdef COMPRESS_MT
#define __7Z_SET_PROPERTIES
#endif
#else
#define __7Z_SET_PROPERTIES
#endif
#endif
class CHandler: class CHandler:
public IInArchive, public IInArchive,
#ifdef _7Z_VOL
public IInArchiveGetStream,
#endif
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
public IOutArchive, public IOutArchive,
public ISetProperties,
#endif #endif
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
#ifdef EXTRACT_ONLY MY_QUERYINTERFACE_BEGIN
MY_UNKNOWN_IMP #ifdef _7Z_VOL
#else MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
MY_UNKNOWN_IMP3(
IInArchive,
IOutArchive,
ISetProperties
)
#endif #endif
#ifdef __7Z_SET_PROPERTIES
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
#ifndef EXTRACT_ONLY
MY_QUERYINTERFACE_ENTRY(IOutArchive)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
STDMETHOD(Open)(IInStream *stream, STDMETHOD(Open)(IInStream *stream,
const UINT64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback); IArchiveOpenCallback *openArchiveCallback);
STDMETHOD(Close)(); STDMETHOD(Close)();
STDMETHOD(GetNumberOfItems)(UINT32 *numItems); STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
INT32 testMode, IArchiveExtractCallback *extractCallback); Int32 testMode, IArchiveExtractCallback *extractCallback);
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
STDMETHOD(GetPropertyInfo)(UINT32 index, STDMETHOD(GetPropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType); BSTR *name, PROPID *propID, VARTYPE *varType);
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
STDMETHOD(GetArchivePropertyInfo)(UINT32 index, STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType); BSTR *name, PROPID *propID, VARTYPE *varType);
#ifdef _7Z_VOL
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
#endif
#ifdef __7Z_SET_PROPERTIES
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
#endif
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
// IOutArchiveHandler // IOutArchiveHandler
STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback); IArchiveUpdateCallback *updateCallback);
STDMETHOD(GetFileTimeType)(UINT32 *type); STDMETHOD(GetFileTimeType)(UInt32 *type);
// ISetProperties // ISetProperties
STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties);
HRESULT SetSolidSettings(const UString &s); HRESULT SetSolidSettings(const UString &s);
HRESULT SetSolidSettings(const PROPVARIANT &value); HRESULT SetSolidSettings(const PROPVARIANT &value);
@@ -88,16 +142,24 @@ public:
CHandler(); CHandler();
private: private:
#ifdef _7Z_VOL
CObjectVector<CVolume> _volumes;
CObjectVector<CRef> _refs;
#else
CMyComPtr<IInStream> _inStream; CMyComPtr<IInStream> _inStream;
NArchive::N7z::CArchiveDatabaseEx _database; NArchive::N7z::CArchiveDatabaseEx _database;
#endif
#ifdef COMPRESS_MT
UInt32 _numThreads;
#endif
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
CObjectVector<COneMethodInfo> _methods; CObjectVector<COneMethodInfo> _methods;
CRecordVector<CBind> _binds; CRecordVector<CBind> _binds;
bool _removeSfxBlock; bool _removeSfxBlock;
UINT64 _numSolidFiles; UInt64 _numSolidFiles;
UINT64 _numSolidBytes; UInt64 _numSolidBytes;
bool _numSolidBytesDefined; bool _numSolidBytesDefined;
bool _solidExtension; bool _solidExtension;
@@ -105,14 +167,11 @@ private:
bool _compressHeadersFull; bool _compressHeadersFull;
bool _encryptHeaders; bool _encryptHeaders;
bool _copyMode;
UINT32 _defaultDicSize;
UINT32 _defaultAlgorithm;
UINT32 _defaultFastBytes;
UString _defaultMatchFinder;
bool _autoFilter; bool _autoFilter;
bool _multiThread; UInt32 _level;
UINT32 _level;
bool _volumeMode;
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value); HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString); HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
@@ -121,8 +180,11 @@ private:
IArchiveUpdateCallback *updateCallback); IArchiveUpdateCallback *updateCallback);
HRESULT SetCompressionMethod(CCompressionMethodMode &method, HRESULT SetCompressionMethod(CCompressionMethodMode &method,
CObjectVector<COneMethodInfo> &methodsInfo, CObjectVector<COneMethodInfo> &methodsInfo
bool multiThread); #ifdef COMPRESS_MT
, UInt32 numThreads
#endif
);
HRESULT SetCompressionMethod( HRESULT SetCompressionMethod(
CCompressionMethodMode &method, CCompressionMethodMode &method,
@@ -132,25 +194,15 @@ private:
#ifndef _SFX #ifndef _SFX
CRecordVector<UINT64> _fileInfoPopIDs; CRecordVector<UInt64> _fileInfoPopIDs;
void FillPopIDs(); void FillPopIDs();
#endif #endif
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
UINT64 GetUINT64MAX() const void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); }
{ void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); }
return
#if (__GNUC__)
0xFFFFFFFFFFFFFFFFLL
#else
0xFFFFFFFFFFFFFFFF
#endif
;
}
void InitSolidFiles() { _numSolidFiles = GetUINT64MAX(); }
void InitSolidSize() { _numSolidBytes = GetUINT64MAX(); }
void InitSolid() void InitSolid()
{ {
InitSolidFiles(); InitSolidFiles();
@@ -158,30 +210,6 @@ private:
_solidExtension = false; _solidExtension = false;
_numSolidBytesDefined = false; _numSolidBytesDefined = false;
} }
/*
void InitSolidPart()
{
if (_numSolidFiles <= 1)
InitSolidFiles();
}
*/
void SetSolidBytesLimit()
{
_numSolidBytes = ((UINT64)_defaultDicSize) << 7;
const UINT64 kMinSize = (1<<24);
if (_numSolidBytes < kMinSize)
_numSolidBytes = kMinSize;
}
void CheckAndSetSolidBytesLimit()
{
if (!_numSolidBytesDefined)
{
if (_copyMode)
_numSolidBytes = 0;
else
SetSolidBytesLimit();
}
}
void Init() void Init()
{ {
@@ -189,16 +217,14 @@ private:
_compressHeaders = true; _compressHeaders = true;
_compressHeadersFull = true; _compressHeadersFull = true;
_encryptHeaders = false; _encryptHeaders = false;
_multiThread = false; #ifdef COMPRESS_MT
_copyMode = false; _numThreads = NWindows::NSystem::GetNumberOfProcessors();
_defaultDicSize = (1 << 21); #endif
_defaultAlgorithm = 1;
_defaultFastBytes = 32;
_defaultMatchFinder = L"BT4";
_level = 5; _level = 5;
_autoFilter = true; _autoFilter = true;
_volumeMode = false;
InitSolid(); InitSolid();
SetSolidBytesLimit();
} }
#endif #endif
}; };

View File

@@ -8,12 +8,14 @@
#include "7zMethods.h" #include "7zMethods.h"
#include "../../../Windows/PropVariant.h" #include "../../../Windows/PropVariant.h"
#include "../../../Common/ComTry.h" #include "../../../Common/ComTry.h"
#include "../../../Common/StringToInt.h" #include "../../../Common/StringToInt.h"
#include "../../IPassword.h" #include "../../IPassword.h"
#include "../../ICoder.h" #include "../../ICoder.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"
using namespace NWindows; using namespace NWindows;
@@ -41,41 +43,99 @@ static CMethodID k_Copy = { { 0x0 }, 1 };
#endif #endif
#ifdef COMPRESS_DEFLATE #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 }; static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
#endif #endif
#ifdef COMPRESS_BZIP2 #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 }; static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
#endif #endif
const wchar_t *kCopyMethod = L"Copy"; const wchar_t *kCopyMethod = L"Copy";
const wchar_t *kLZMAMethodName = L"LZMA"; const wchar_t *kLZMAMethodName = L"LZMA";
const wchar_t *kBZip2MethodName = L"BZip2";
const wchar_t *kPpmdMethodName = L"PPMd";
const wchar_t *kDeflateMethodName = L"Deflate";
const wchar_t *kDeflate64MethodName = L"Deflate64";
const UINT32 kAlgorithmForX7 = 2; static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
const UINT32 kDicSizeForX7 = 1 << 23; static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
const UINT32 kFastBytesForX7 = 64;
const UINT32 kAlgorithmForX9 = 2; static const UInt32 kLzmaAlgorithmX1 = 0;
const UINT32 kDicSizeForX9 = 1 << 25; static const UInt32 kLzmaAlgorithmX5 = 1;
const UINT32 kFastBytesForX9 = 64;
static const wchar_t *kMatchFinderForX9 = L"BT4b";
const UINT32 kAlgorithmForFast = 0; static const UInt32 kLzmaDicSizeX1 = 1 << 16;
const UINT32 kDicSizeForFast = 1 << 15; static const UInt32 kLzmaDicSizeX3 = 1 << 20;
static const wchar_t *kMatchFinderForFast = L"HC3"; static const UInt32 kLzmaDicSizeX5 = 1 << 22;
static const UInt32 kLzmaDicSizeX7 = 1 << 24;
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
static const UInt32 kLzmaFastBytesX1 = 32;
static const UInt32 kLzmaFastBytesX7 = 64;
static const UInt32 kPpmdMemSizeX1 = (1 << 22);
static const UInt32 kPpmdMemSizeX5 = (1 << 24);
static const UInt32 kPpmdMemSizeX7 = (1 << 26);
static const UInt32 kPpmdMemSizeX9 = (192 << 20);
static const UInt32 kPpmdOrderX1 = 4;
static const UInt32 kPpmdOrderX5 = 6;
static const UInt32 kPpmdOrderX7 = 16;
static const UInt32 kPpmdOrderX9 = 32;
static const UInt32 kDeflateFastBytesX1 = 32;
static const UInt32 kDeflateFastBytesX7 = 64;
static const UInt32 kDeflateFastBytesX9 = 128;
static const UInt32 kDeflatePassesX1 = 1;
static const UInt32 kDeflatePassesX7 = 3;
static const UInt32 kDeflatePassesX9 = 10;
static const UInt32 kBZip2NumPassesX1 = 1;
static const UInt32 kBZip2NumPassesX7 = 2;
static const UInt32 kBZip2NumPassesX9 = 7;
static const UInt32 kBZip2DicSizeX1 = 100000;
static const UInt32 kBZip2DicSizeX3 = 500000;
static const UInt32 kBZip2DicSizeX5 = 900000;
const wchar_t *kDefaultMethodName = kLZMAMethodName; const wchar_t *kDefaultMethodName = kLZMAMethodName;
static const wchar_t *kMatchFinderForHeaders = L"BT2"; static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
static const UINT32 kDictionaryForHeaders = 1 << 20; static const UInt32 kDictionaryForHeaders = 1 << 20;
static const UINT32 kNumFastBytesForHeaders = 254; static const UInt32 kNumFastBytesForHeaders = 273;
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
static bool IsCopyMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kCopyMethod) == 0); }
static bool IsLZMAMethod(const UString &methodName) static bool IsLZMAMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); } { return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
static bool IsLZMethod(const UString &methodName) static bool IsLZMethod(const UString &methodName)
{ return IsLZMAMethod(methodName); } { return IsLZMAMethod(methodName); }
STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type) static bool IsBZip2Method(const UString &methodName)
{ return (methodName.CompareNoCase(kBZip2MethodName) == 0); }
static bool IsPpmdMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kPpmdMethodName) == 0); }
static bool IsDeflateMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kDeflateMethodName) == 0) ||
(methodName.CompareNoCase(kDeflate64MethodName) == 0); }
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{ {
*type = NFileTimeType::kWindows; *type = NFileTimeType::kWindows;
return S_OK; return S_OK;
@@ -94,7 +154,7 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
if (getTextPassword) if (getTextPassword)
{ {
CMyComBSTR password; CMyComBSTR password;
INT32 passwordIsDefined; Int32 passwordIsDefined;
RINOK(getTextPassword->CryptoGetTextPassword2( RINOK(getTextPassword->CryptoGetTextPassword2(
&passwordIsDefined, &password)); &passwordIsDefined, &password));
if (methodMode.PasswordIsDefined = IntToBool(passwordIsDefined)) if (methodMode.PasswordIsDefined = IntToBool(passwordIsDefined))
@@ -105,52 +165,6 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
return S_OK; 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 struct CNameToPropID
{ {
PROPID PropID; PROPID PropID;
@@ -167,9 +181,10 @@ CNameToPropID g_NameToPropID[] =
{ NCoderPropID::kNumPasses, VT_UI4, L"Pass" }, { NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" }, { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
{ NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" }, { NCoderPropID::kAlgorithm, VT_UI4, L"a" },
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" }, { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
{ NCoderPropID::kMultiThread, VT_BOOL, L"mt" } { NCoderPropID::kNumThreads, VT_UI4, L"mt" }
}; };
bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
@@ -184,10 +199,10 @@ bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
{ {
if(srcProp.vt == VT_UI4) if(srcProp.vt == VT_UI4)
{ {
UINT32 value = srcProp.ulVal; UInt32 value = srcProp.ulVal;
if (value > 0xFF) if (value > 0xFF)
return false; return false;
destProp = BYTE(value); destProp = Byte(value);
return true; return true;
} }
} }
@@ -208,7 +223,12 @@ HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode, CCompressionMethodMode &methodMode,
CCompressionMethodMode &headerMethod) CCompressionMethodMode &headerMethod)
{ {
RINOK(SetCompressionMethod(methodMode, _methods, _multiThread)); HRESULT res = SetCompressionMethod(methodMode, _methods
#ifdef COMPRESS_MT
, _numThreads
#endif
);
RINOK(res);
methodMode.Binds = _binds; methodMode.Binds = _binds;
if (_compressHeadersFull) if (_compressHeadersFull)
_compressHeaders = true; _compressHeaders = true;
@@ -223,29 +243,34 @@ HRESULT CHandler::SetCompressionMethod(
{ {
CProperty property; CProperty property;
property.PropID = NCoderPropID::kMatchFinder; property.PropID = NCoderPropID::kMatchFinder;
property.Value = kMatchFinderForHeaders; property.Value = kLzmaMatchFinderForHeaders;
oneMethodInfo.CoderProperties.Add(property); oneMethodInfo.CoderProperties.Add(property);
} }
{ {
CProperty property; CProperty property;
property.PropID = NCoderPropID::kAlgorithm; property.PropID = NCoderPropID::kAlgorithm;
property.Value = kAlgorithmForX9; property.Value = kAlgorithmForHeaders;
oneMethodInfo.CoderProperties.Add(property); oneMethodInfo.CoderProperties.Add(property);
} }
{ {
CProperty property; CProperty property;
property.PropID = NCoderPropID::kNumFastBytes; property.PropID = NCoderPropID::kNumFastBytes;
property.Value = UINT32(kNumFastBytesForHeaders); property.Value = UInt32(kNumFastBytesForHeaders);
oneMethodInfo.CoderProperties.Add(property); oneMethodInfo.CoderProperties.Add(property);
} }
{ {
CProperty property; CProperty property;
property.PropID = NCoderPropID::kDictionarySize; property.PropID = NCoderPropID::kDictionarySize;
property.Value = UINT32(kDictionaryForHeaders); property.Value = UInt32(kDictionaryForHeaders);
oneMethodInfo.CoderProperties.Add(property); oneMethodInfo.CoderProperties.Add(property);
} }
headerMethodInfoVector.Add(oneMethodInfo); headerMethodInfoVector.Add(oneMethodInfo);
RINOK(SetCompressionMethod(headerMethod, headerMethodInfoVector, false)); HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
#ifdef COMPRESS_MT
,1
#endif
);
RINOK(res);
} }
return S_OK; return S_OK;
} }
@@ -267,8 +292,11 @@ static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
HRESULT CHandler::SetCompressionMethod( HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode, CCompressionMethodMode &methodMode,
CObjectVector<COneMethodInfo> &methodsInfo, CObjectVector<COneMethodInfo> &methodsInfo
bool multiThread) #ifdef COMPRESS_MT
, UInt32 numThreads
#endif
)
{ {
#ifndef EXCLUDE_COM #ifndef EXCLUDE_COM
/* /*
@@ -279,36 +307,106 @@ HRESULT CHandler::SetCompressionMethod(
#endif #endif
UInt32 level = _level;
if (methodsInfo.IsEmpty()) if (methodsInfo.IsEmpty())
{ {
COneMethodInfo oneMethodInfo; COneMethodInfo oneMethodInfo;
oneMethodInfo.MethodName = _copyMode ? kCopyMethod : kDefaultMethodName; oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
methodsInfo.Add(oneMethodInfo); methodsInfo.Add(oneMethodInfo);
} }
bool needSolid = false;
for(int i = 0; i < methodsInfo.Size(); i++) for(int i = 0; i < methodsInfo.Size(); i++)
{ {
COneMethodInfo &oneMethodInfo = methodsInfo[i]; COneMethodInfo &oneMethodInfo = methodsInfo[i];
if (oneMethodInfo.MethodName.IsEmpty()) if (oneMethodInfo.MethodName.IsEmpty())
oneMethodInfo.MethodName = kDefaultMethodName; oneMethodInfo.MethodName = kDefaultMethodName;
if (IsLZMethod(oneMethodInfo.MethodName)) if (!IsCopyMethod(oneMethodInfo.MethodName))
needSolid = true;
if (IsLZMAMethod(oneMethodInfo.MethodName))
{ {
if (IsLZMAMethod(oneMethodInfo.MethodName)) UInt32 dicSize =
{ (level >= 9 ? kLzmaDicSizeX9 :
SetOneMethodProp(oneMethodInfo, (level >= 7 ? kLzmaDicSizeX7 :
NCoderPropID::kDictionarySize, _defaultDicSize); (level >= 5 ? kLzmaDicSizeX5 :
SetOneMethodProp(oneMethodInfo, (level >= 3 ? kLzmaDicSizeX3 :
NCoderPropID::kAlgorithm, _defaultAlgorithm); kLzmaDicSizeX1))));
SetOneMethodProp(oneMethodInfo,
NCoderPropID::kNumFastBytes, _defaultFastBytes); UInt32 algorithm =
SetOneMethodProp(oneMethodInfo, (level >= 5 ? kLzmaAlgorithmX5 :
NCoderPropID::kMatchFinder, (const wchar_t *)_defaultMatchFinder); kLzmaAlgorithmX1);
if (multiThread)
SetOneMethodProp(oneMethodInfo, UInt32 fastBytes =
NCoderPropID::kMultiThread, true); (level >= 7 ? kLzmaFastBytesX7 :
} kLzmaFastBytesX1);
const wchar_t *matchFinder =
(level >= 5 ? kLzmaMatchFinderX5 :
kLzmaMatchFinderX1);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algorithm);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
#ifdef COMPRESS_MT
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
} }
else if (IsDeflateMethod(oneMethodInfo.MethodName))
{
UInt32 fastBytes =
(level >= 9 ? kDeflateFastBytesX9 :
(level >= 7 ? kDeflateFastBytesX7 :
kDeflateFastBytesX1));
UInt32 numPasses =
(level >= 9 ? kDeflatePassesX9 :
(level >= 7 ? kDeflatePassesX7 :
kDeflatePassesX1));
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
}
else if (IsBZip2Method(oneMethodInfo.MethodName))
{
UInt32 numPasses =
(level >= 9 ? kBZip2NumPassesX9 :
(level >= 7 ? kBZip2NumPassesX7 :
kBZip2NumPassesX1));
UInt32 dicSize =
(level >= 5 ? kBZip2DicSizeX5 :
(level >= 3 ? kBZip2DicSizeX3 :
kBZip2DicSizeX1));
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
#ifdef COMPRESS_MT
SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
}
else if (IsPpmdMethod(oneMethodInfo.MethodName))
{
UInt32 useMemSize =
(level >= 9 ? kPpmdMemSizeX9 :
(level >= 7 ? kPpmdMemSizeX7 :
(level >= 5 ? kPpmdMemSizeX5 :
kPpmdMemSizeX1)));
UInt32 order =
(level >= 9 ? kPpmdOrderX9 :
(level >= 7 ? kPpmdOrderX7 :
(level >= 5 ? kPpmdOrderX5 :
kPpmdOrderX1)));
SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
}
CMethodFull methodFull; CMethodFull methodFull;
methodFull.NumInStreams = 1; methodFull.NumInStreams = 1;
methodFull.NumOutStreams = 1; methodFull.NumOutStreams = 1;
@@ -349,7 +447,7 @@ HRESULT CHandler::SetCompressionMethod(
} }
#endif #endif
#ifdef COMPRESS_DEFLATE #ifdef COMPRESS_DEFLATE_ENCODER
if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0) if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0)
{ {
defined = true; defined = true;
@@ -357,7 +455,7 @@ HRESULT CHandler::SetCompressionMethod(
} }
#endif #endif
#ifdef COMPRESS_BZIP2 #ifdef COMPRESS_BZIP2_ENCODER
if (oneMethodInfo.MethodName.CompareNoCase(L"BZip2") == 0) if (oneMethodInfo.MethodName.CompareNoCase(L"BZip2") == 0)
{ {
defined = true; defined = true;
@@ -406,28 +504,66 @@ HRESULT CHandler::SetCompressionMethod(
return E_FAIL; return E_FAIL;
methodMode.Methods.Add(methodFull); methodMode.Methods.Add(methodFull);
if (!_numSolidBytesDefined)
{
for (int j = 0; j < methodFull.CoderProperties.Size(); j++)
{
const CProperty &prop = methodFull.CoderProperties[j];
if ((prop.PropID == NCoderPropID::kDictionarySize ||
prop.PropID == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
{
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
const UInt64 kMinSize = (1 << 24);
if (_numSolidBytes < kMinSize)
_numSolidBytes = kMinSize;
_numSolidBytesDefined = true;
break;
}
}
}
}
if (!needSolid && !_numSolidBytesDefined)
{
_numSolidBytesDefined = true;
_numSolidBytes = 0;
} }
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback) IArchiveUpdateCallback *updateCallback)
{ {
COM_TRY_BEGIN 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; // CRecordVector<bool> compressStatuses;
CObjectVector<CUpdateItem> updateItems; CObjectVector<CUpdateItem> updateItems;
// CRecordVector<UINT32> copyIndices; // CRecordVector<UInt32> copyIndices;
// CMyComPtr<IUpdateCallback2> updateCallback2; // CMyComPtr<IUpdateCallback2> updateCallback2;
// updateCallback->QueryInterface(&updateCallback2); // updateCallback->QueryInterface(&updateCallback2);
int index = 0; for(UInt32 i = 0; i < numItems; i++)
for(int i = 0; i < numItems; i++)
{ {
INT32 newData; Int32 newData;
INT32 newProperties; Int32 newProperties;
UINT32 indexInArchive; UInt32 indexInArchive;
if (!updateCallback) if (!updateCallback)
return E_FAIL; return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(i, RINOK(updateCallback->GetUpdateItemInfo(i,
@@ -442,7 +578,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
if (updateItem.IndexInArchive != -1) if (updateItem.IndexInArchive != -1)
{ {
const CFileItem &fileItem = _database.Files[updateItem.IndexInArchive]; const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
updateItem.Name = fileItem.Name; updateItem.Name = fileItem.Name;
updateItem.IsDirectory = fileItem.IsDirectory; updateItem.IsDirectory = fileItem.IsDirectory;
updateItem.Size = fileItem.UnPackSize; updateItem.Size = fileItem.UnPackSize;
@@ -550,39 +686,19 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
if (propVariant.vt != VT_UI8) if (propVariant.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
updateItem.Size = *(const UINT64 *)(&propVariant.uhVal); updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
if (updateItem.Size != 0 && updateItem.IsAnti) if (updateItem.Size != 0 && updateItem.IsAnti)
return E_INVALIDARG; return E_INVALIDARG;
} }
/*
else
thereIsCopyData = true;
*/
updateItems.Add(updateItem); updateItems.Add(updateItem);
} }
/*
if (thereIsCopyData)
{
for(int i = 0; i < _database.NumUnPackStreamsVector.Size(); i++)
if (_database.NumUnPackStreamsVector[i] != 1)
return E_NOTIMPL;
if (!_solidIsSpecified)
_solid = false;
if (_solid)
return E_NOTIMPL;
}
*/
CCompressionMethodMode methodMode, headerMethod; CCompressionMethodMode methodMode, headerMethod;
RINOK(SetCompressionMethod(methodMode, headerMethod)); RINOK(SetCompressionMethod(methodMode, headerMethod));
methodMode.MultiThread = _multiThread; #ifdef COMPRESS_MT
// methodMode.MultiThreadMult = _multiThreadMult; methodMode.NumThreads = _numThreads;
headerMethod.NumThreads = 1;
headerMethod.MultiThread = false; #endif
// headerMethod.MultiThreadMult = _multiThreadMult;
RINOK(SetPassword(methodMode, updateCallback)); RINOK(SetPassword(methodMode, updateCallback));
@@ -605,158 +721,43 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
if (numItems < 2) if (numItems < 2)
compressMainHeader = false; compressMainHeader = false;
CInArchiveInfo *inArchiveInfo; CUpdateOptions options;
if (!_inStream) options.Method = &methodMode;
inArchiveInfo = 0; options.HeaderMethod = (_compressHeaders ||
else (methodMode.PasswordIsDefined && _encryptHeaders)) ?
inArchiveInfo = &_database.ArchiveInfo; &headerMethod : 0;
options.UseFilters = _level != 0 && _autoFilter;
return Update(_database, options.MaxFilter = _level >= 8;
// compressStatuses, options.UseAdditionalHeaderStreams = useAdditionalHeaderStreams;
updateItems, options.CompressMainHeader = compressMainHeader;
// copyIndices, options.NumSolidFiles = _numSolidFiles;
outStream, _inStream, inArchiveInfo, options.NumSolidBytes = _numSolidBytes;
methodMode, options.SolidExtension = _solidExtension;
(_compressHeaders || options.RemoveSfxBlock = _removeSfxBlock;
(methodMode.PasswordIsDefined && _encryptHeaders)) ? options.VolumeMode = _volumeMode;
&headerMethod : 0, return Update(
_level != 0 && _autoFilter, // useFilters #ifdef _7Z_VOL
_level >= 8, // maxFilter volume ? volume->Stream: 0,
useAdditionalHeaderStreams, compressMainHeader, volume ? database: 0,
updateCallback, _numSolidFiles, _numSolidBytes, _solidExtension, #else
_removeSfxBlock); _inStream,
database,
#endif
updateItems, outStream, updateCallback, options);
COM_TRY_END COM_TRY_END
} }
static int ParseStringToUINT32(const UString &srcString, UINT32 &number) static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
{
const wchar_t *start = srcString;
const wchar_t *end;
UINT64 number64 = ConvertStringToUINT64(start, &end);
if (number64 >= (UINT64(1) << 32))
{
number = 0;
return 0;
}
number = number64;
return end - start;
}
static const int kLogarithmicSizeLimit = 32;
static const char kByteSymbol = 'B';
static const char kKiloByteSymbol = 'K';
static const char kMegaByteSymbol = 'M';
HRESULT ParseDictionaryValues(const UString &srcStringSpec, UINT32 &dicSize)
{
UString srcString = srcStringSpec;
srcString.MakeUpper();
const wchar_t *start = srcString;
const wchar_t *end;
UINT64 number = ConvertStringToUINT64(start, &end);
int numDigits = end - start;
if (numDigits == 0 || srcString.Length() > numDigits + 1)
return E_INVALIDARG;
if (srcString.Length() == numDigits)
{
if (number >= kLogarithmicSizeLimit)
return E_INVALIDARG;
dicSize = (UINT32)1 << number;
return S_OK;
}
switch (srcString[numDigits])
{
case kByteSymbol:
if (number >= ((UINT64)1 << kLogarithmicSizeLimit))
return E_INVALIDARG;
dicSize = (UINT32)number;
break;
case kKiloByteSymbol:
if (number >= ((UINT64)1 << (kLogarithmicSizeLimit - 10)))
return E_INVALIDARG;
dicSize = UINT32(number << 10);
break;
case kMegaByteSymbol:
if (number >= ((UINT64)1 << (kLogarithmicSizeLimit - 20)))
return E_INVALIDARG;
dicSize = UINT32(number << 20);
break;
default:
return E_INVALIDARG;
}
return S_OK;
}
static inline UINT GetCurrentFileCodePage()
{
return AreFileApisANSI() ? CP_ACP : CP_OEMCP;
}
static HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
{
switch(value.vt)
{
case VT_EMPTY:
dest = true;
break;
/*
case VT_UI4:
dest = (value.ulVal != 0);
break;
*/
case VT_BSTR:
{
UString valueString = value.bstrVal;
valueString.MakeUpper();
if (valueString.Compare(L"ON") == 0)
dest = true;
else if (valueString.Compare(L"OFF") == 0)
dest = false;
else
return E_INVALIDARG;
break;
}
default:
return E_INVALIDARG;
}
return S_OK;
}
/*
static HRESULT SetComplexProperty(bool &boolStatus, UINT32 &number,
const PROPVARIANT &value)
{
switch(value.vt)
{
case VT_EMPTY:
case VT_BSTR:
{
RINOK(SetBoolProperty(boolStatus, value));
return S_OK;
}
case VT_UI4:
boolStatus = true;
number = (value.ulVal);
break;
default:
return E_INVALIDARG;
}
return S_OK;
}
*/
static HRESULT GetBindInfoPart(UString &srcString, UINT32 &coder, UINT32 &stream)
{ {
stream = 0; stream = 0;
int index = ParseStringToUINT32(srcString, coder); int index = ParseStringToUInt32(srcString, coder);
if (index == 0) if (index == 0)
return E_INVALIDARG; return E_INVALIDARG;
srcString.Delete(0, index); srcString.Delete(0, index);
if (srcString[0] == 'S') if (srcString[0] == 'S')
{ {
srcString.Delete(0); srcString.Delete(0);
int index = ParseStringToUINT32(srcString, stream); int index = ParseStringToUInt32(srcString, stream);
if (index == 0) if (index == 0)
return E_INVALIDARG; return E_INVALIDARG;
srcString.Delete(0, index); srcString.Delete(0, index);
@@ -824,8 +825,8 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
CProperty property; CProperty property;
if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0) if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
{ {
UINT32 dicSize; UInt32 dicSize;
RINOK(ParseDictionaryValues(value, dicSize)); RINOK(ParsePropDictionaryValue(value, dicSize));
if (name.CompareNoCase(L"D") == 0) if (name.CompareNoCase(L"D") == 0)
property.PropID = NCoderPropID::kDictionarySize; property.PropID = NCoderPropID::kDictionarySize;
else else
@@ -849,8 +850,8 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
propValue = value; propValue = value;
else else
{ {
UINT32 number; UInt32 number;
if (ParseStringToUINT32(value, number) == value.Length()) if (ParseStringToUInt32(value, number) == value.Length())
propValue = number; propValue = number;
else else
propValue = value; propValue = value;
@@ -898,7 +899,7 @@ HRESULT CHandler::SetSolidSettings(const UString &s)
{ {
const wchar_t *start = ((const wchar_t *)s2) + i; const wchar_t *start = ((const wchar_t *)s2) + i;
const wchar_t *end; const wchar_t *end;
UINT64 v = ConvertStringToUINT64(start, &end); UInt64 v = ConvertStringToUInt64(start, &end);
if (start == end) if (start == end)
{ {
if (s2[i++] != 'E') if (s2[i++] != 'E')
@@ -906,7 +907,7 @@ HRESULT CHandler::SetSolidSettings(const UString &s)
_solidExtension = true; _solidExtension = true;
continue; continue;
} }
i += end - start; i += (int)(end - start);
if (i == s2.Length()) if (i == s2.Length())
return E_INVALIDARG; return E_INVALIDARG;
wchar_t c = s2[i++]; wchar_t c = s2[i++];
@@ -954,14 +955,20 @@ 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 COM_TRY_BEGIN
_methods.Clear(); _methods.Clear();
_binds.Clear(); _binds.Clear();
Init(); Init();
int minNumber = 0; #ifdef COMPRESS_MT
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
#endif
UInt32 mainDicSize = 0xFFFFFFFF;
UInt32 mainDicMethodIndex = 0xFFFFFFFF;
UInt32 minNumber = 0;
for (int i = 0; i < numProperties; i++) for (int i = 0; i < numProperties; i++)
{ {
@@ -976,50 +983,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
{ {
name.Delete(0); name.Delete(0);
_level = 9; _level = 9;
if (value.vt == VT_UI4) RINOK(ParsePropValue(name, value, _level));
{
if (!name.IsEmpty())
return E_INVALIDARG;
_level = value.ulVal;
}
else if (value.vt == VT_EMPTY)
{
if(!name.IsEmpty())
{
int index = ParseStringToUINT32(name, _level);
if (index != name.Length())
return E_INVALIDARG;
}
}
else
return E_INVALIDARG;
if (_level == 0)
{
_copyMode = true;
}
else if (_level < 5)
{
_defaultAlgorithm = kAlgorithmForFast;
_defaultDicSize = kDicSizeForFast;
_defaultMatchFinder = kMatchFinderForFast;
}
else if (_level < 7)
{
// normal;
}
else if(_level < 9)
{
_defaultAlgorithm = kAlgorithmForX7;
_defaultDicSize = kDicSizeForX7;
_defaultFastBytes = kFastBytesForX7;
}
else
{
_defaultAlgorithm = kAlgorithmForX9;
_defaultDicSize = kDicSizeForX9;
_defaultFastBytes = kFastBytesForX9;
_defaultMatchFinder = kMatchFinderForX9;
}
continue; continue;
} }
@@ -1047,17 +1011,24 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
} }
UINT32 number; UInt32 number;
int index = ParseStringToUINT32(name, number); int index = ParseStringToUInt32(name, number);
UString realName = name.Mid(index); UString realName = name.Mid(index);
if (index == 0) if (index == 0)
{ {
if (name.CompareNoCase(L"RSFX") == 0) if(name.Left(2).CompareNoCase(L"MT") == 0)
{
#ifdef COMPRESS_MT
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
#endif
continue;
}
else if (name.CompareNoCase(L"RSFX") == 0)
{ {
RINOK(SetBoolProperty(_removeSfxBlock, value)); RINOK(SetBoolProperty(_removeSfxBlock, value));
continue; continue;
} }
if (name.CompareNoCase(L"F") == 0) else if (name.CompareNoCase(L"F") == 0)
{ {
RINOK(SetBoolProperty(_autoFilter, value)); RINOK(SetBoolProperty(_autoFilter, value));
continue; continue;
@@ -1077,23 +1048,19 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
RINOK(SetBoolProperty(_encryptHeaders, value)); RINOK(SetBoolProperty(_encryptHeaders, value));
continue; continue;
} }
else if (name.CompareNoCase(L"MT") == 0) else if (name.CompareNoCase(L"V") == 0)
{ {
// _multiThreadMult = 200; RINOK(SetBoolProperty(_volumeMode, value));
RINOK(SetBoolProperty(_multiThread, value));
// RINOK(SetComplexProperty(MultiThread, _multiThreadMult, value));
continue; continue;
} }
number = 0; number = 0;
} }
if (number > 100) if (number > 10000)
return E_FAIL; return E_FAIL;
if (number < minNumber) if (number < minNumber)
{
return E_INVALIDARG; return E_INVALIDARG;
}
number -= minNumber; number -= minNumber;
for(int j = _methods.Size(); j <= number; j++) for(int j = _methods.Size(); j <= (int)number; j++)
{ {
COneMethodInfo oneMethodInfo; COneMethodInfo oneMethodInfo;
_methods.Add(oneMethodInfo); _methods.Add(oneMethodInfo);
@@ -1112,28 +1079,25 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
else else
{ {
CProperty property; CProperty property;
if (realName.CompareNoCase(L"D") == 0 || realName.CompareNoCase(L"MEM") == 0) if (realName.Left(1).CompareNoCase(L"D") == 0)
{ {
UINT32 dicSize; UInt32 dicSize;
if (value.vt == VT_UI4) RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
{ property.PropID = NCoderPropID::kDictionarySize;
UINT32 logDicSize = value.ulVal;
if (logDicSize >= 32)
return E_INVALIDARG;
dicSize = (UINT32)1 << logDicSize;
}
else if (value.vt == VT_BSTR)
{
RINOK(ParseDictionaryValues(value.bstrVal, dicSize));
}
else
return E_FAIL;
if (realName.CompareNoCase(L"D") == 0)
property.PropID = NCoderPropID::kDictionarySize;
else
property.PropID = NCoderPropID::kUsedMemorySize;
property.Value = dicSize; property.Value = dicSize;
oneMethodInfo.CoderProperties.Add(property); oneMethodInfo.CoderProperties.Add(property);
if (number <= mainDicMethodIndex)
mainDicSize = dicSize;
}
else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
{
UInt32 dicSize;
RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
property.PropID = NCoderPropID::kUsedMemorySize;
property.Value = dicSize;
oneMethodInfo.CoderProperties.Add(property);
if (number <= mainDicMethodIndex)
mainDicSize = dicSize;
} }
else else
{ {
@@ -1151,7 +1115,6 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
} }
} }
} }
CheckAndSetSolidBytesLimit();
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END

View File

@@ -6,12 +6,13 @@
namespace NArchive { namespace NArchive {
namespace N7z { 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 class SignatureInitializer
{ {
public: public:
SignatureInitializer() { kSignature[0]--; }; SignatureInitializer() { kSignature[0]--; kFinishSignature[0]--;};
} g_SignatureInitializer; } g_SignatureInitializer;
}} }}

View File

@@ -1,37 +1,53 @@
// 7z/Header.h // 7z/7zHeader.h
#pragma once
#ifndef __7Z_HEADER_H #ifndef __7Z_HEADER_H
#define __7Z_HEADER_H #define __7Z_HEADER_H
// #include "Common/Types.h"
// #include "../../../Common/CRC.h"
#include "7zMethodID.h" #include "7zMethodID.h"
namespace NArchive { namespace NArchive {
namespace N7z { namespace N7z {
#pragma pack( push, Pragma7zHeaders)
#pragma pack( push, 1)
const int kSignatureSize = 6; 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 struct CArchiveVersion
{ {
BYTE Major; Byte Major;
BYTE Minor; Byte Minor;
}; };
const Byte kMajorVersion = 0;
struct CStartHeader struct CStartHeader
{ {
UINT64 NextHeaderOffset; UInt64 NextHeaderOffset;
UINT64 NextHeaderSize; UInt64 NextHeaderSize;
UINT32 NextHeaderCRC; 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 namespace NID
{ {
enum EEnum enum EEnum
@@ -70,16 +86,11 @@ namespace NID
kComment, kComment,
kEncodedHeader, kEncodedHeader,
kStartPos
}; };
} }
#pragma pack(pop)
#pragma pack(pop, Pragma7zHeaders)
const BYTE kMajorVersion = 0;
}} }}
#endif #endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,5 @@
// 7zIn.h // 7zIn.h
#pragma once
#ifndef __7Z_IN_H #ifndef __7Z_IN_H
#define __7Z_IN_H #define __7Z_IN_H
@@ -31,11 +29,11 @@ public:
struct CInArchiveInfo struct CInArchiveInfo
{ {
CArchiveVersion Version; CArchiveVersion Version;
UINT64 StartPosition; UInt64 StartPosition;
UINT64 StartPositionAfterHeader; UInt64 StartPositionAfterHeader;
UINT64 DataStartPosition; UInt64 DataStartPosition;
UINT64 DataStartPosition2; UInt64 DataStartPosition2;
CRecordVector<UINT64> FileInfoPopIDs; CRecordVector<UInt64> FileInfoPopIDs;
void Clear() void Clear()
{ {
FileInfoPopIDs.Clear(); FileInfoPopIDs.Clear();
@@ -46,10 +44,10 @@ struct CInArchiveInfo
struct CArchiveDatabaseEx: public CArchiveDatabase struct CArchiveDatabaseEx: public CArchiveDatabase
{ {
CInArchiveInfo ArchiveInfo; CInArchiveInfo ArchiveInfo;
CRecordVector<UINT64> PackStreamStartPositions; CRecordVector<UInt64> PackStreamStartPositions;
CRecordVector<UINT32> FolderStartPackStreamIndex; CRecordVector<CNum> FolderStartPackStreamIndex;
CRecordVector<UINT64> FolderStartFileIndex; CRecordVector<CNum> FolderStartFileIndex;
CRecordVector<int> FileIndexToFolderIndexMap; CRecordVector<CNum> FileIndexToFolderIndexMap;
void Clear() void Clear()
{ {
@@ -58,69 +56,87 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
PackStreamStartPositions.Clear(); PackStreamStartPositions.Clear();
FolderStartPackStreamIndex.Clear(); FolderStartPackStreamIndex.Clear();
FolderStartFileIndex.Clear(); FolderStartFileIndex.Clear();
FolderStartFileIndex.Clear(); FileIndexToFolderIndexMap.Clear();
} }
void FillFolderStartPackStream(); void FillFolderStartPackStream();
void FillStartPos(); void FillStartPos();
void FillFolderStartFileIndex(); void FillFolderStartFileIndex();
void Fill()
{
FillFolderStartPackStream();
FillStartPos();
FillFolderStartFileIndex();
}
UINT64 GetFolderStreamPos(int folderIndex, int indexInFolder) const UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
{ {
return ArchiveInfo.DataStartPosition + return ArchiveInfo.DataStartPosition +
PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] +
indexInFolder]; indexInFolder];
} }
UINT64 GetFolderFullPackSize(int folderIndex) const UInt64 GetFolderFullPackSize(int folderIndex) const
{ {
UINT32 packStreamIndex = FolderStartPackStreamIndex[folderIndex]; CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
const CFolder &folder = Folders[folderIndex]; const CFolder &folder = Folders[folderIndex];
UINT64 size = 0; UInt64 size = 0;
for (int i = 0; i < folder.PackStreams.Size(); i++) for (int i = 0; i < folder.PackStreams.Size(); i++)
size += PackSizes[packStreamIndex + i]; size += PackSizes[packStreamIndex + i];
return size; return size;
} }
UINT64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
{ {
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
} }
UInt64 GetFilePackSize(CNum fileIndex) const
{
CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
if (folderIndex >= 0)
{
if (FolderStartFileIndex[folderIndex] == fileIndex)
return GetFolderFullPackSize(folderIndex);
}
return 0;
}
}; };
class CInByte2 class CInByte2
{ {
const BYTE *_buffer; const Byte *_buffer;
UINT32 _size; size_t _size;
UINT32 _pos; size_t _pos;
public: public:
void Init(const BYTE *buffer, UINT32 size) void Init(const Byte *buffer, size_t size)
{ {
_buffer = buffer; _buffer = buffer;
_size = size; _size = size;
_pos = 0; _pos = 0;
} }
bool ReadByte(BYTE &b) bool ReadByte(Byte &b)
{ {
if(_pos >= _size) if(_pos >= _size)
return false; return false;
b = _buffer[_pos++]; b = _buffer[_pos++];
return true; 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++) 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); ReadBytes(data, size, processedSize);
return (processedSize == size); return (processedSize == size);
} }
UINT32 GetProcessedSize() const { return _pos; } size_t GetProcessedSize() const { return _pos; }
}; };
class CStreamSwitch; class CStreamSwitch;
@@ -129,14 +145,17 @@ class CInArchive
friend class CStreamSwitch; friend class CStreamSwitch;
CMyComPtr<IInStream> _stream; CMyComPtr<IInStream> _stream;
#ifdef _7Z_VOL
bool _finishSignature;
#endif
CObjectVector<CInByte2> _inByteVector; CObjectVector<CInByte2> _inByteVector;
CInByte2 *_inByteBack; CInByte2 *_inByteBack;
UINT64 _arhiveBeginStreamPosition; UInt64 _arhiveBeginStreamPosition;
UINT64 _position; UInt64 _position;
void AddByteStream(const BYTE *buffer, UINT32 size) void AddByteStream(const Byte *buffer, size_t size)
{ {
_inByteVector.Add(CInByte2()); _inByteVector.Add(CInByte2());
_inByteBack = &_inByteVector.Back(); _inByteBack = &_inByteVector.Back();
@@ -151,62 +170,67 @@ class CInArchive
} }
private: 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 ReadFileNames(CObjectVector<CFileItem> &files);
HRESULT ReadBytes(IInStream *stream, void *data, UINT32 size, HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size,
UINT32 *processedSize); UInt32 *processedSize);
HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize); HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize);
HRESULT SafeReadBytes(void *data, UINT32 size); 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)) if (!_inByteBack->ReadBytes(data, size))
return E_FAIL; return E_FAIL;
return S_OK; return S_OK;
} }
HRESULT SafeReadByte2(BYTE &b) HRESULT ReadByte(Byte &b)
{ {
if (!_inByteBack->ReadByte(b)) if (!_inByteBack->ReadByte(b))
return E_FAIL; return E_FAIL;
return S_OK; return S_OK;
} }
HRESULT SafeReadWideCharLE(wchar_t &c) HRESULT ReadWideCharLE(wchar_t &c)
{ {
BYTE b1; Byte b1;
if (!_inByteBack->ReadByte(b1)) if (!_inByteBack->ReadByte(b1))
return E_FAIL; return E_FAIL;
BYTE b2; Byte b2;
if (!_inByteBack->ReadByte(b2)) if (!_inByteBack->ReadByte(b2))
return E_FAIL; return E_FAIL;
c = (int(b2) << 8) + b1; c = (wchar_t(b2) << 8) + b1;
return S_OK; return S_OK;
} }
HRESULT ReadNumber(UINT64 &value); HRESULT ReadNumber(UInt64 &value);
HRESULT ReadNum(CNum &value);
HRESULT ReadID(UINT64 &value) HRESULT ReadID(UInt64 &value) { return ReadNumber(value); }
{ HRESULT ReadUInt32(UInt32 &value);
return ReadNumber(value); HRESULT ReadUInt64(UInt64 &value);
}
HRESULT SkeepData(UINT64 size); HRESULT SkeepData(UInt64 size);
HRESULT SkeepData(); HRESULT SkeepData();
HRESULT WaitAttribute(UINT64 attribute); HRESULT WaitAttribute(UInt64 attribute);
HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo); HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo);
HRESULT GetNextFolderItem(CFolder &itemInfo); HRESULT GetNextFolderItem(CFolder &itemInfo);
HRESULT ReadHashDigests(int numItems, HRESULT ReadHashDigests(int numItems,
CRecordVector<bool> &digestsDefined, CRecordVector<UINT32> &digests); CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
HRESULT ReadPackInfo( HRESULT ReadPackInfo(
UINT64 &dataOffset, UInt64 &dataOffset,
CRecordVector<UINT64> &packSizes, CRecordVector<UInt64> &packSizes,
CRecordVector<bool> &packCRCsDefined, CRecordVector<bool> &packCRCsDefined,
CRecordVector<UINT32> &packCRCs); CRecordVector<UInt32> &packCRCs);
HRESULT ReadUnPackInfo( HRESULT ReadUnPackInfo(
const CObjectVector<CByteBuffer> *dataVector, const CObjectVector<CByteBuffer> *dataVector,
@@ -214,31 +238,30 @@ private:
HRESULT ReadSubStreamsInfo( HRESULT ReadSubStreamsInfo(
const CObjectVector<CFolder> &folders, const CObjectVector<CFolder> &folders,
CRecordVector<UINT64> &numUnPackStreamsInFolders, CRecordVector<CNum> &numUnPackStreamsInFolders,
CRecordVector<UINT64> &unPackSizes, CRecordVector<UInt64> &unPackSizes,
CRecordVector<bool> &digestsDefined, CRecordVector<bool> &digestsDefined,
CRecordVector<UINT32> &digests); CRecordVector<UInt32> &digests);
HRESULT CInArchive::ReadStreamsInfo( HRESULT ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector, const CObjectVector<CByteBuffer> *dataVector,
UINT64 &dataOffset, UInt64 &dataOffset,
CRecordVector<UINT64> &packSizes, CRecordVector<UInt64> &packSizes,
CRecordVector<bool> &packCRCsDefined, CRecordVector<bool> &packCRCsDefined,
CRecordVector<UINT32> &packCRCs, CRecordVector<UInt32> &packCRCs,
CObjectVector<CFolder> &folders, CObjectVector<CFolder> &folders,
CRecordVector<UINT64> &numUnPackStreamsInFolders, CRecordVector<CNum> &numUnPackStreamsInFolders,
CRecordVector<UINT64> &unPackSizes, CRecordVector<UInt64> &unPackSizes,
CRecordVector<bool> &digestsDefined, CRecordVector<bool> &digestsDefined,
CRecordVector<UINT32> &digests); CRecordVector<UInt32> &digests);
HRESULT GetNextFileItem(CFileItem &itemInfo); HRESULT GetNextFileItem(CFileItem &itemInfo);
HRESULT ReadBoolVector(UINT32 numItems, CBoolVector &vector); HRESULT ReadBoolVector(int numItems, CBoolVector &v);
HRESULT ReadBoolVector2(UINT32 numItems, CBoolVector &vector); HRESULT ReadBoolVector2(int numItems, CBoolVector &v);
HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector, HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector,
CObjectVector<CFileItem> &files, UINT64 type); CObjectVector<CFileItem> &files, UInt64 type);
HRESULT ReadAndDecodePackedStreams(UINT64 baseOffset, UINT64 &dataOffset, HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset,
CObjectVector<CByteBuffer> &dataVector CObjectVector<CByteBuffer> &dataVector
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword , ICryptoGetTextPassword *getTextPassword
@@ -250,7 +273,7 @@ private:
#endif #endif
); );
public: 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(); void Close();
HRESULT ReadDatabase(CArchiveDatabaseEx &database HRESULT ReadDatabase(CArchiveDatabaseEx &database
@@ -258,7 +281,6 @@ public:
,ICryptoGetTextPassword *getTextPassword ,ICryptoGetTextPassword *getTextPassword
#endif #endif
); );
HRESULT CheckIntegrity();
}; };
}} }}

View File

@@ -1,7 +1,5 @@
// 7zItem.h // 7zItem.h
#pragma once
#ifndef __7Z_ITEM_H #ifndef __7Z_ITEM_H
#define __7Z_ITEM_H #define __7Z_ITEM_H
@@ -18,38 +16,36 @@ struct CAltCoderInfo
CByteBuffer Properties; CByteBuffer Properties;
}; };
typedef UInt32 CNum;
const CNum kNumMax = 0x7FFFFFFF;
const CNum kNumNoIndex = 0xFFFFFFFF;
struct CCoderInfo struct CCoderInfo
{ {
UINT64 NumInStreams; CNum NumInStreams;
UINT64 NumOutStreams; CNum NumOutStreams;
CObjectVector<CAltCoderInfo> AltCoders; CObjectVector<CAltCoderInfo> AltCoders;
bool IsSimpleCoder() const bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
{ return (NumInStreams == 1) && (NumOutStreams == 1); }
};
struct CPackStreamInfo
{
UINT64 Index;
}; };
struct CBindPair struct CBindPair
{ {
UINT64 InIndex; CNum InIndex;
UINT64 OutIndex; CNum OutIndex;
}; };
struct CFolder struct CFolder
{ {
CObjectVector<CCoderInfo> Coders; CObjectVector<CCoderInfo> Coders;
CRecordVector<CBindPair> BindPairs; CRecordVector<CBindPair> BindPairs;
CRecordVector<CPackStreamInfo> PackStreams; CRecordVector<CNum> PackStreams;
CRecordVector<UINT64> UnPackSizes; CRecordVector<UInt64> UnPackSizes;
UInt32 UnPackCRC;
bool UnPackCRCDefined; bool UnPackCRCDefined;
UINT32 UnPackCRC;
CFolder(): UnPackCRCDefined(false) {} CFolder(): UnPackCRCDefined(false) {}
UINT64 GetUnPackSize() const // test it UInt64 GetUnPackSize() const // test it
{ {
if (UnPackSizes.IsEmpty()) if (UnPackSizes.IsEmpty())
return 0; return 0;
@@ -58,33 +54,33 @@ struct CFolder
return UnPackSizes[i]; return UnPackSizes[i];
throw 1; throw 1;
} }
UINT64 GetNumOutStreams() const
CNum GetNumOutStreams() const
{ {
UINT64 result = 0; CNum result = 0;
for (int i = 0; i < Coders.Size(); i++) for (int i = 0; i < Coders.Size(); i++)
result += Coders[i].NumOutStreams; result += Coders[i].NumOutStreams;
return result; return result;
} }
int FindBindPairForInStream(CNum inStreamIndex) const
int FindBindPairForInStream(int inStreamIndex) const
{ {
for(int i = 0; i < BindPairs.Size(); i++) for(int i = 0; i < BindPairs.Size(); i++)
if (BindPairs[i].InIndex == inStreamIndex) if (BindPairs[i].InIndex == inStreamIndex)
return i; return i;
return -1; return -1;
} }
int FindBindPairForOutStream(int outStreamIndex) const int FindBindPairForOutStream(CNum outStreamIndex) const
{ {
for(int i = 0; i < BindPairs.Size(); i++) for(int i = 0; i < BindPairs.Size(); i++)
if (BindPairs[i].OutIndex == outStreamIndex) if (BindPairs[i].OutIndex == outStreamIndex)
return i; return i;
return -1; return -1;
} }
int FindPackStreamArrayIndex(int inStreamIndex) const int FindPackStreamArrayIndex(CNum inStreamIndex) const
{ {
for(int i = 0; i < PackStreams.Size(); i++) for(int i = 0; i < PackStreams.Size(); i++)
if (PackStreams[i].Index == inStreamIndex) if (PackStreams[i] == inStreamIndex)
return i; return i;
return -1; return -1;
} }
@@ -98,51 +94,54 @@ public:
CArchiveFileTime CreationTime; CArchiveFileTime CreationTime;
CArchiveFileTime LastWriteTime; CArchiveFileTime LastWriteTime;
CArchiveFileTime LastAccessTime; CArchiveFileTime LastAccessTime;
UINT64 UnPackSize; UInt64 UnPackSize;
UINT32 Attributes; UInt64 StartPos;
UINT32 FileCRC; UInt32 Attributes;
UInt32 FileCRC;
UString Name; UString Name;
bool HasStream; // Test it !!! it means that there is bool HasStream; // Test it !!! it means that there is
// stream in some folder. It can be empty stream // stream in some folder. It can be empty stream
bool IsDirectory; bool IsDirectory;
bool IsAnti; bool IsAnti;
bool FileCRCIsDefined; bool IsFileCRCDefined;
bool AreAttributesDefined; bool AreAttributesDefined;
bool IsCreationTimeDefined; bool IsCreationTimeDefined;
bool IsLastWriteTimeDefined; bool IsLastWriteTimeDefined;
bool IsLastAccessTimeDefined; bool IsLastAccessTimeDefined;
bool IsStartPosDefined;
/* /*
const bool HasStream() const { const bool HasStream() const {
return !IsDirectory && !IsAnti && UnPackSize != 0; } return !IsDirectory && !IsAnti && UnPackSize != 0; }
*/ */
CFileItem(): CFileItem():
HasStream(true),
IsDirectory(false),
IsAnti(false),
IsFileCRCDefined(false),
AreAttributesDefined(false), AreAttributesDefined(false),
IsCreationTimeDefined(false), IsCreationTimeDefined(false),
IsLastWriteTimeDefined(false), IsLastWriteTimeDefined(false),
IsLastAccessTimeDefined(false), IsLastAccessTimeDefined(false),
IsDirectory(false), IsStartPosDefined(false)
FileCRCIsDefined(false),
IsAnti(false),
HasStream(true)
{} {}
void SetAttributes(UINT32 attributes) void SetAttributes(UInt32 attributes)
{ {
AreAttributesDefined = true; AreAttributesDefined = true;
Attributes = attributes; Attributes = attributes;
} }
void SetCreationTime(CArchiveFileTime creationTime) void SetCreationTime(const CArchiveFileTime &creationTime)
{ {
IsCreationTimeDefined = true; IsCreationTimeDefined = true;
CreationTime = creationTime; CreationTime = creationTime;
} }
void SetLastWriteTime(CArchiveFileTime lastWriteTime) void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
{ {
IsLastWriteTimeDefined = true; IsLastWriteTimeDefined = true;
LastWriteTime = lastWriteTime; LastWriteTime = lastWriteTime;
} }
void SetLastAccessTime(CArchiveFileTime lastAccessTime) void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
{ {
IsLastAccessTimeDefined = true; IsLastAccessTimeDefined = true;
LastAccessTime = lastAccessTime; LastAccessTime = lastAccessTime;
@@ -151,11 +150,11 @@ public:
struct CArchiveDatabase struct CArchiveDatabase
{ {
CRecordVector<UINT64> PackSizes; CRecordVector<UInt64> PackSizes;
CRecordVector<bool> PackCRCsDefined; CRecordVector<bool> PackCRCsDefined;
CRecordVector<UINT32> PackCRCs; CRecordVector<UInt32> PackCRCs;
CObjectVector<CFolder> Folders; CObjectVector<CFolder> Folders;
CRecordVector<UINT64> NumUnPackStreamsVector; CRecordVector<CNum> NumUnPackStreamsVector;
CObjectVector<CFileItem> Files; CObjectVector<CFileItem> Files;
void Clear() 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 #endif

View File

@@ -7,12 +7,12 @@
namespace NArchive { namespace NArchive {
namespace N7z { namespace N7z {
static inline wchar_t GetHex(BYTE value) static wchar_t GetHex(Byte value)
{ {
return (value < 10) ? ('0' + value) : ('A' + (value - 10)); 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') if (value >= '0' && value <= '9')
result = value - '0'; result = value - '0';
@@ -25,9 +25,9 @@ static bool HexCharToInt(wchar_t value, BYTE &result)
return true; 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)) if (!HexCharToInt(valueHigh, resultHigh))
return false; return false;
if (!HexCharToInt(valueLow, resultLow)) if (!HexCharToInt(valueLow, resultLow))
@@ -41,7 +41,7 @@ UString CMethodID::ConvertToString() const
UString result; UString result;
for (int i = 0; i < IDSize; i++) for (int i = 0; i < IDSize; i++)
{ {
BYTE b = ID[i]; Byte b = ID[i];
result += GetHex(b >> 4); result += GetHex(b >> 4);
result += GetHex(b & 0xF); result += GetHex(b & 0xF);
} }
@@ -51,18 +51,26 @@ UString CMethodID::ConvertToString() const
bool CMethodID::ConvertFromString(const UString &srcString) bool CMethodID::ConvertFromString(const UString &srcString)
{ {
int length = srcString.Length(); int length = srcString.Length();
if ((length & 1) != 0) if ((length & 1) != 0 || (length >> 1) > kMethodIDSize)
return false; return false;
IDSize = length / 2; IDSize = length / 2;
if (IDSize > kMethodIDSize) UInt32 i;
return false;
UINT32 i;
for(i = 0; i < IDSize; i++) for(i = 0; i < IDSize; i++)
if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i])) if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i]))
return false; return false;
for(i = IDSize; i < kMethodIDSize; i++) for(; i < kMethodIDSize; i++)
ID[i] = 0; ID[i] = 0;
return true; 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;
}
}} }}

View File

@@ -1,34 +1,25 @@
// 7zMethodID.h // 7zMethodID.h
#pragma once
#ifndef __7Z_METHOD_ID_H #ifndef __7Z_METHOD_ID_H
#define __7Z_METHOD_ID_H #define __7Z_METHOD_ID_H
#include "../../../Common/String.h" #include "../../../Common/String.h"
#include "../../../Common/Types.h"
namespace NArchive { namespace NArchive {
namespace N7z { namespace N7z {
const int kMethodIDSize = 16; const int kMethodIDSize = 15;
struct CMethodID struct CMethodID
{ {
BYTE ID[kMethodIDSize]; Byte ID[kMethodIDSize];
UINT32 IDSize; Byte IDSize;
UString ConvertToString() const; UString ConvertToString() const;
bool ConvertFromString(const UString &srcString); bool ConvertFromString(const UString &srcString);
}; };
inline bool operator==(const CMethodID &a1, const CMethodID &a2) 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;
}
inline bool operator!=(const CMethodID &a1, const CMethodID &a2) inline bool operator!=(const CMethodID &a1, const CMethodID &a2)
{ return !(a1 == a2); } { return !(a1 == a2); }

View File

@@ -20,10 +20,10 @@ namespace N7z {
static CObjectVector<CMethodInfo2> g_Methods; static CObjectVector<CMethodInfo2> g_Methods;
static bool g_Loaded = false; static bool g_Loaded = false;
typedef UINT32 (WINAPI *GetNumberOfMethodsFunc)(UINT32 *numMethods); typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
typedef UINT32 (WINAPI *GetMethodPropertyFunc)( typedef UInt32 (WINAPI *GetMethodPropertyFunc)(
UINT32 index, PROPID propID, PROPVARIANT *value); UInt32 index, PROPID propID, PROPVARIANT *value);
static void Load(const CSysString &folderPrefix) static void Load(const CSysString &folderPrefix)
{ {
@@ -47,14 +47,14 @@ static void Load(const CSysString &folderPrefix)
if (getMethodProperty == NULL) if (getMethodProperty == NULL)
continue; continue;
UINT32 numMethods = 1; UInt32 numMethods = 1;
GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc) GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)
library.GetProcAddress("GetNumberOfMethods"); library.GetProcAddress("GetNumberOfMethods");
if (getNumberOfMethodsFunc != NULL) if (getNumberOfMethodsFunc != NULL)
if (getNumberOfMethodsFunc(&numMethods) != S_OK) if (getNumberOfMethodsFunc(&numMethods) != S_OK)
continue; continue;
for(UINT32 i = 0; i < numMethods; i++) for(UInt32 i = 0; i < numMethods; i++)
{ {
CMethodInfo2 info; CMethodInfo2 info;
info.FilePath = filePath; info.FilePath = filePath;
@@ -160,7 +160,7 @@ bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
for(int i = 0; i < g_Methods.Size(); i++) for(int i = 0; i < g_Methods.Size(); i++)
{ {
const CMethodInfo2 &method = g_Methods[i]; const CMethodInfo2 &method = g_Methods[i];
if (method.Name.CollateNoCase(name) == 0) if (method.Name.CompareNoCase(name) == 0)
{ {
methodInfo = method; methodInfo = method;
return true; return true;

View File

@@ -13,8 +13,8 @@ struct CMethodInfo
UString Name; UString Name;
bool EncoderIsAssigned; bool EncoderIsAssigned;
bool DecoderIsAssigned; bool DecoderIsAssigned;
UINT32 NumInStreams; UInt32 NumInStreams;
UINT32 NumOutStreams; UInt32 NumOutStreams;
CLSID Encoder; CLSID Encoder;
CLSID Decoder; CLSID Decoder;
// UString Description; // UString Description;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,5 @@
// 7z/Out.h // 7z/Out.h
#pragma once
#ifndef __7Z_OUT_H #ifndef __7Z_OUT_H
#define __7Z_OUT_H #define __7Z_OUT_H
@@ -19,18 +17,18 @@ namespace N7z {
class CWriteBufferLoc class CWriteBufferLoc
{ {
BYTE *_data; Byte *_data;
UINT32 _size; size_t _size;
UINT32 _pos; size_t _pos;
public: public:
CWriteBufferLoc(): _size(0), _pos(0) {} CWriteBufferLoc(): _size(0), _pos(0) {}
void Init(BYTE *data, UINT32 size) void Init(Byte *data, size_t size)
{ {
_pos = 0; _pos = 0;
_data = data; _data = data;
_size = size; _size = size;
} }
HRESULT Write(const void *data, UINT32 size) HRESULT Write(const void *data, size_t size)
{ {
if (_pos + size > _size) if (_pos + size > _size)
return E_FAIL; return E_FAIL;
@@ -43,110 +41,135 @@ public:
class CWriteDynamicBuffer class CWriteDynamicBuffer
{ {
CByteDynamicBuffer _buffer; CByteDynamicBuffer _buffer;
UINT32 _pos; size_t _pos;
public: public:
CWriteDynamicBuffer(): _pos(0) {} CWriteDynamicBuffer(): _pos(0) {}
void Init() void Init()
{ {
_pos = 0; _pos = 0;
} }
void Write(const void *data, UINT32 size) void Write(const void *data, size_t size)
{ {
if (_pos + size > _buffer.GetCapacity()) if (_pos + size > _buffer.GetCapacity())
_buffer.EnsureCapacity(_pos + size); _buffer.EnsureCapacity(_pos + size);
memmove(((BYTE *)_buffer) +_pos, data, size); memmove(((Byte *)_buffer) +_pos, data, size);
_pos += size; _pos += size;
} }
operator BYTE *() { return (BYTE *)_buffer; }; operator Byte *() { return (Byte *)_buffer; };
operator const BYTE *() const { return (const BYTE *)_buffer; }; operator const Byte *() const { return (const Byte *)_buffer; };
UINT32 GetSize() const { return _pos; } size_t GetSize() const { return _pos; }
}; };
class COutArchive class COutArchive
{ {
UINT64 _prefixHeaderPos; UInt64 _prefixHeaderPos;
HRESULT WriteBytes(const void *data, UINT32 size); HRESULT WriteDirect(const void *data, UInt32 size);
HRESULT WriteBytes2(const void *data, UINT32 size); HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
HRESULT WriteBytes2(const CByteBuffer &data); HRESULT WriteDirectUInt32(UInt32 value);
HRESULT WriteByte2(BYTE b); HRESULT WriteDirectUInt64(UInt64 value);
HRESULT WriteNumber(UINT64 value);
HRESULT WriteID(UINT64 value) HRESULT WriteBytes(const void *data, size_t size);
{ HRESULT WriteBytes(const CByteBuffer &data);
return WriteNumber(value); 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 WriteFileHeader(const CFileItem &itemInfo);
HRESULT WriteBoolVector(const CBoolVector &boolVector); HRESULT WriteBoolVector(const CBoolVector &boolVector);
HRESULT WriteHashDigests( HRESULT WriteHashDigests(
const CRecordVector<bool> &digestsDefined, const CRecordVector<bool> &digestsDefined,
const CRecordVector<UINT32> &hashDigests); const CRecordVector<UInt32> &hashDigests);
HRESULT WritePackInfo( HRESULT WritePackInfo(
UINT64 dataOffset, UInt64 dataOffset,
const CRecordVector<UINT64> &packSizes, const CRecordVector<UInt64> &packSizes,
const CRecordVector<bool> &packCRCsDefined, const CRecordVector<bool> &packCRCsDefined,
const CRecordVector<UINT32> &packCRCs); const CRecordVector<UInt32> &packCRCs);
HRESULT WriteUnPackInfo( HRESULT WriteUnPackInfo(
bool externalFolders, bool externalFolders,
UINT64 externalFoldersStreamIndex, CNum externalFoldersStreamIndex,
const CObjectVector<CFolder> &folders); const CObjectVector<CFolder> &folders);
HRESULT WriteSubStreamsInfo( HRESULT WriteSubStreamsInfo(
const CObjectVector<CFolder> &folders, const CObjectVector<CFolder> &folders,
const CRecordVector<UINT64> &numUnPackStreamsInFolders, const CRecordVector<CNum> &numUnPackStreamsInFolders,
const CRecordVector<UINT64> &unPackSizes, const CRecordVector<UInt64> &unPackSizes,
const CRecordVector<bool> &digestsDefined, const CRecordVector<bool> &digestsDefined,
const CRecordVector<UINT32> &hashDigests); const CRecordVector<UInt32> &hashDigests);
/*
HRESULT WriteStreamsInfo( HRESULT WriteStreamsInfo(
UINT64 dataOffset, UInt64 dataOffset,
const CRecordVector<UINT64> &packSizes, const CRecordVector<UInt64> &packSizes,
const CRecordVector<bool> &packCRCsDefined, const CRecordVector<bool> &packCRCsDefined,
const CRecordVector<UINT32> &packCRCs, const CRecordVector<UInt32> &packCRCs,
bool externalFolders, bool externalFolders,
UINT64 externalFoldersStreamIndex, UInt64 externalFoldersStreamIndex,
const CObjectVector<CFolder> &folders, const CObjectVector<CFolder> &folders,
const CRecordVector<UINT64> &numUnPackStreamsInFolders, const CRecordVector<CNum> &numUnPackStreamsInFolders,
const CRecordVector<UINT64> &unPackSizes, const CRecordVector<UInt64> &unPackSizes,
const CRecordVector<bool> &digestsDefined, const CRecordVector<bool> &digestsDefined,
const CRecordVector<UINT32> &hashDigests); const CRecordVector<UInt32> &hashDigests);
*/
HRESULT WriteTime(const CObjectVector<CFileItem> &files, BYTE type, HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type,
bool isExternal, int externalDataIndex); bool isExternal, CNum externalDataIndex);
HRESULT EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 dataSize, HRESULT EncodeStream(CEncoder &encoder, const Byte *data, size_t dataSize,
CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders); CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
HRESULT EncodeStream(CEncoder &encoder, const CByteBuffer &data, HRESULT EncodeStream(CEncoder &encoder, const CByteBuffer &data,
CRecordVector<UINT64> &packSizes, CObjectVector<CFolder> &folders); CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
HRESULT WriteHeader(const CArchiveDatabase &database, HRESULT WriteHeader(const CArchiveDatabase &database,
const CCompressionMethodMode *options, const CCompressionMethodMode *options,
UINT64 &headerOffset); UInt64 &headerOffset);
bool _mainMode; bool _mainMode;
bool _dynamicMode; bool _dynamicMode;
bool _countMode; bool _countMode;
UINT32 _countSize; size_t _countSize;
COutBuffer _outByte; COutBuffer _outByte;
CWriteBufferLoc _outByte2; CWriteBufferLoc _outByte2;
CWriteDynamicBuffer _dynamicBuffer; CWriteDynamicBuffer _dynamicBuffer;
CCRC _crc; 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; CMyComPtr<IOutStream> Stream;
HRESULT Create(IOutStream *stream); public:
COutArchive() { _outByte.Create(1 << 16); }
CMyComPtr<ISequentialOutStream> SeqStream;
HRESULT Create(ISequentialOutStream *stream, bool endMarker);
void Close(); void Close();
HRESULT SkeepPrefixArchiveHeader(); HRESULT SkeepPrefixArchiveHeader();
HRESULT WriteDatabase(const CArchiveDatabase &database, HRESULT WriteDatabase(const CArchiveDatabase &database,
const CCompressionMethodMode *options, const CCompressionMethodMode *options,
bool useAdditionalHeaderStreams, bool useAdditionalHeaderStreams,
bool compressMainHeader); 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
}; };
}} }}

View File

@@ -13,7 +13,7 @@ namespace N7z {
struct CPropMap struct CPropMap
{ {
UINT64 FilePropID; UInt64 FilePropID;
STATPROPSTG StatPROPSTG; STATPROPSTG StatPROPSTG;
}; };
@@ -35,6 +35,7 @@ CPropMap kPropMap[] =
{ NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME}, { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
{ NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME}, { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4}, { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
{ NID::kCRC, NULL, kpidCRC, VT_UI4}, { NID::kCRC, NULL, kpidCRC, VT_UI4},
@@ -52,7 +53,7 @@ CPropMap kPropMap[] =
static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); 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++) for (int i = 0; i < kPropMapSize; i++)
if (kPropMap[i].FilePropID == filePropID) if (kPropMap[i].FilePropID == filePropID)
@@ -60,8 +61,8 @@ static int FindPropInMap(UINT64 filePropID)
return -1; return -1;
} }
static void CopyOneItem(CRecordVector<UINT64> &src, static void CopyOneItem(CRecordVector<UInt64> &src,
CRecordVector<UINT64> &dest, UINT32 item) CRecordVector<UInt64> &dest, UInt32 item)
{ {
for (int i = 0; i < src.Size(); i++) for (int i = 0; i < src.Size(); i++)
if (src[i] == item) 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++) for (int i = 0; i < src.Size(); i++)
if (src[i] == item) 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++) for (int i = 0; i < dest.Size(); i++)
if (dest[i] == item) if (dest[i] == item)
@@ -96,7 +97,15 @@ static void InsertToHead(CRecordVector<UINT64> &dest, UINT32 item)
void CHandler::FillPopIDs() void CHandler::FillPopIDs()
{ {
_fileInfoPopIDs.Clear(); _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::kEmptyStream);
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
@@ -133,16 +142,16 @@ void CHandler::FillPopIDs()
#endif #endif
} }
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
{ {
*numProperties = _fileInfoPopIDs.Size(); *numProperties = _fileInfoPopIDs.Size();
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType) BSTR *name, PROPID *propID, VARTYPE *varType)
{ {
if(index >= _fileInfoPopIDs.Size()) if((int)index >= _fileInfoPopIDs.Size())
return E_INVALIDARG; return E_INVALIDARG;
int indexInMap = FindPropInMap(_fileInfoPopIDs[index]); int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
if (indexInMap == -1) if (indexInMap == -1)

View File

@@ -1,7 +1,5 @@
// 7zProperties.h // 7zProperties.h
#pragma once
#ifndef __7Z_PROPERTIES_H #ifndef __7Z_PROPERTIES_H
#define __7Z_PROPERTIES_H #define __7Z_PROPERTIES_H
@@ -19,33 +17,6 @@ enum // PropID
kpidPackedSize4, 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 #endif

View File

@@ -4,9 +4,9 @@
#include "7zSpecStream.h" #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); HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize; _size += realProcessedSize;
if (processedSize != 0) if (processedSize != 0)
@@ -14,18 +14,8 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UINT32 size, UINT32
return result; return result;
} }
STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
{
UINT32 realProcessedSize;
HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize != 0)
*processedSize = realProcessedSize;
return result;
}
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize( STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
UINT64 subStream, UINT64 *value) UInt64 subStream, UInt64 *value)
{ {
if (_getSubStreamSize == NULL) if (_getSubStreamSize == NULL)
return E_NOTIMPL; return E_NOTIMPL;

View File

@@ -1,7 +1,5 @@
// 7zSpecStream.h // 7zSpecStream.h
#pragma once
#ifndef __7Z_SPEC_STREAM_H #ifndef __7Z_SPEC_STREAM_H
#define __7Z_SPEC_STREAM_H #define __7Z_SPEC_STREAM_H
@@ -16,7 +14,7 @@ class CSequentialInStreamSizeCount2:
{ {
CMyComPtr<ISequentialInStream> _stream; CMyComPtr<ISequentialInStream> _stream;
CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize; CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
UINT64 _size; UInt64 _size;
public: public:
void Init(ISequentialInStream *stream) void Init(ISequentialInStream *stream)
{ {
@@ -25,14 +23,13 @@ public:
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize); _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
_size = 0; _size = 0;
} }
UINT64 GetSize() const { return _size; } UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize) MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize); STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value); STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
}; };
#endif #endif

View File

@@ -22,9 +22,9 @@ namespace NArchive {
namespace N7z { namespace N7z {
static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2"; static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
static const UINT32 kDictionaryForBCJ2_LZMA = 1 << 20; static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
const UINT32 kAlgorithmForBCJ2_LZMA = 2; static const UInt32 kAlgorithmForBCJ2_LZMA = 2;
const UINT32 kNumFastBytesForBCJ2_LZMA = 64; static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
static HRESULT CopyBlock(ISequentialInStream *inStream, static HRESULT CopyBlock(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ICompressProgressInfo *progress) ISequentialOutStream *outStream, ICompressProgressInfo *progress)
@@ -33,19 +33,17 @@ static HRESULT CopyBlock(ISequentialInStream *inStream,
return copyCoder->Code(inStream, outStream, NULL, NULL, progress); return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
} }
static HRESULT WriteRange(IInStream *inStream, static HRESULT WriteRange(
ISequentialInStream *inStream,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
const CUpdateRange &range, UInt64 size,
IProgress *progress, IProgress *progress,
UINT64 &currentComplexity) UInt64 &currentComplexity)
{ {
UINT64 position;
inStream->Seek(range.Position, STREAM_SEEK_SET, &position);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream *streamSpec = new
CLimitedSequentialInStream; CLimitedSequentialInStream;
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec); CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
streamSpec->Init(inStream, range.Size); streamSpec->Init(inStream, size);
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec; CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
@@ -58,15 +56,36 @@ static HRESULT WriteRange(IInStream *inStream,
localCompressProgressSpec->Init(localProgress, &currentComplexity, &currentComplexity); localCompressProgressSpec->Init(localProgress, &currentComplexity, &currentComplexity);
HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress); HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress);
currentComplexity += range.Size; currentComplexity += size;
return result; return result;
} }
static HRESULT WriteRange(IInStream *inStream,
ISequentialOutStream *outStream,
UInt64 position,
UInt64 size,
IProgress *progress,
UInt64 &currentComplexity)
{
inStream->Seek(position, STREAM_SEEK_SET, 0);
return WriteRange(inStream, outStream,
size, progress, currentComplexity);
}
static int GetReverseSlashPos(const UString &name)
{
int slashPos = name.ReverseFind(L'/');
#ifdef _WIN32
int slash1Pos = name.ReverseFind(L'\\');
slashPos = MyMax(slashPos, slash1Pos);
#endif
return slashPos;
}
int CUpdateItem::GetExtensionPos() const int CUpdateItem::GetExtensionPos() const
{ {
int slash1Pos = Name.ReverseFind(L'\\'); int slashPos = GetReverseSlashPos(Name);
int slash2Pos = Name.ReverseFind(L'/');
int slashPos = MyMax(slash1Pos, slash2Pos);
int dotPos = Name.ReverseFind(L'.'); int dotPos = Name.ReverseFind(L'.');
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0)) if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
return Name.Length(); return Name.Length();
@@ -78,11 +97,13 @@ UString CUpdateItem::GetExtension() const
return Name.Mid(GetExtensionPos()); return Name.Mid(GetExtensionPos());
} }
/*
struct CFolderRef struct CFolderRef
{ {
const CArchiveDatabaseEx *Database; const CArchiveDatabaseEx *Database;
int FolderIndex; int FolderIndex;
}; };
*/
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } #define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
@@ -95,10 +116,10 @@ static int CompareMethodIDs(const CMethodID &a1, const CMethodID &a2)
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
{ {
int c1 = a1.GetCapacity(); size_t c1 = a1.GetCapacity();
int c2 = a2.GetCapacity(); size_t c2 = a2.GetCapacity();
RINOZ(MyCompare(c1, c2)); RINOZ(MyCompare(c1, c2));
for (int i = 0; i < c1; i++) for (size_t i = 0; i < c1; i++)
RINOZ(MyCompare(a1[i], a2[i])); RINOZ(MyCompare(a1[i], a2[i]));
return 0; return 0;
} }
@@ -145,34 +166,34 @@ static int CompareFolders(const CFolder &f1, const CFolder &f2)
static int CompareFiles(const CFileItem &f1, const CFileItem &f2) static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
{ {
return MyStringCollateNoCase(f1.Name, f2.Name); return MyStringCompareNoCase(f1.Name, f2.Name);
} }
static int __cdecl CompareFolderRefs(const void *p1, const void *p2) static int CompareFolderRefs(const int *p1, const int *p2, void *param)
{ {
const CFolderRef &a1 = *((const CFolderRef *)p1); int i1 = *p1;
const CFolderRef &a2 = *((const CFolderRef *)p2); int i2 = *p2;
const CArchiveDatabaseEx &d1 = *a1.Database; const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
const CArchiveDatabaseEx &d2 = *a2.Database;
RINOZ(CompareFolders( RINOZ(CompareFolders(
d1.Folders[a1.FolderIndex], db.Folders[i1],
d2.Folders[a2.FolderIndex])); db.Folders[i2]));
RINOZ(MyCompare( RINOZ(MyCompare(
d1.NumUnPackStreamsVector[a1.FolderIndex], db.NumUnPackStreamsVector[i1],
d2.NumUnPackStreamsVector[a2.FolderIndex])); db.NumUnPackStreamsVector[i2]));
if (d1.NumUnPackStreamsVector[a1.FolderIndex] == 0) if (db.NumUnPackStreamsVector[i1] == 0)
return 0; return 0;
return CompareFiles( return CompareFiles(
d1.Files[d1.FolderStartFileIndex[a1.FolderIndex]], db.Files[db.FolderStartFileIndex[i1]],
d2.Files[d2.FolderStartFileIndex[a2.FolderIndex]]); db.Files[db.FolderStartFileIndex[i2]]);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static int __cdecl CompareEmptyItems(const void *p1, const void *p2) static int CompareEmptyItems(const int *p1, const int *p2, void *param)
{ {
const CUpdateItem &u1 = **((CUpdateItem **)p1); const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
const CUpdateItem &u2 = **((CUpdateItem **)p2); const CUpdateItem &u1 = updateItems[*p1];
const CUpdateItem &u2 = updateItems[*p2];
if (u1.IsDirectory != u2.IsDirectory) if (u1.IsDirectory != u2.IsDirectory)
{ {
if (u1.IsDirectory) if (u1.IsDirectory)
@@ -183,22 +204,22 @@ static int __cdecl CompareEmptyItems(const void *p1, const void *p2)
{ {
if (u1.IsAnti != u2.IsAnti) if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1); return (u1.IsAnti ? 1 : -1);
int n = MyStringCollateNoCase(u1.Name, u2.Name); int n = MyStringCompareNoCase(u1.Name, u2.Name);
return (u1.IsAnti ? (-n) : n); return (u1.IsAnti ? (-n) : n);
} }
if (u1.IsAnti != u2.IsAnti) if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1); return (u1.IsAnti ? 1 : -1);
return MyStringCollateNoCase(u1.Name, u2.Name); return MyStringCompareNoCase(u1.Name, u2.Name);
} }
struct CRefItem struct CRefItem
{ {
UINT32 Index; UInt32 Index;
const CUpdateItem *UpdateItem; const CUpdateItem *UpdateItem;
UINT32 ExtensionPos; UInt32 ExtensionPos;
UINT32 NamePos; UInt32 NamePos;
bool SortByType; bool SortByType;
CRefItem(UINT32 index, const CUpdateItem &updateItem, bool sortByType): CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
SortByType(sortByType), SortByType(sortByType),
Index(index), Index(index),
UpdateItem(&updateItem), UpdateItem(&updateItem),
@@ -207,9 +228,7 @@ struct CRefItem
{ {
if (sortByType) if (sortByType)
{ {
int slash1Pos = updateItem.Name.ReverseFind(L'\\'); int slashPos = GetReverseSlashPos(updateItem.Name);
int slash2Pos = updateItem.Name.ReverseFind(L'/');
int slashPos = MyMax(slash1Pos, slash2Pos);
if (slashPos >= 0) if (slashPos >= 0)
NamePos = slashPos + 1; NamePos = slashPos + 1;
else else
@@ -223,10 +242,10 @@ struct CRefItem
} }
}; };
static int __cdecl CompareUpdateItems(const void *p1, const void *p2) static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
{ {
const CRefItem &a1 = *((CRefItem *)p1); const CRefItem &a1 = *p1;
const CRefItem &a2 = *((CRefItem *)p2); const CRefItem &a2 = *p2;
const CUpdateItem &u1 = *a1.UpdateItem; const CUpdateItem &u1 = *a1.UpdateItem;
const CUpdateItem &u2 = *a2.UpdateItem; const CUpdateItem &u2 = *a2.UpdateItem;
int n; int n;
@@ -240,24 +259,24 @@ static int __cdecl CompareUpdateItems(const void *p1, const void *p2)
{ {
if (u1.IsAnti != u2.IsAnti) if (u1.IsAnti != u2.IsAnti)
return (u1.IsAnti ? 1 : -1); return (u1.IsAnti ? 1 : -1);
n = MyStringCollateNoCase(u1.Name, u2.Name); n = MyStringCompareNoCase(u1.Name, u2.Name);
return (u1.IsAnti ? (-n) : n); return (u1.IsAnti ? (-n) : n);
} }
if (a1.SortByType) if (a1.SortByType)
{ {
RINOZ(MyStringCollateNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos)); RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
RINOZ(MyStringCollateNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos)); RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
if (u1.LastWriteTimeIsDefined && u2.LastWriteTimeIsDefined) if (u1.LastWriteTimeIsDefined && u2.LastWriteTimeIsDefined)
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime)); RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
RINOZ(MyCompare(u1.Size, u2.Size)) RINOZ(MyCompare(u1.Size, u2.Size))
} }
return MyStringCollateNoCase(u1.Name, u2.Name); return MyStringCompareNoCase(u1.Name, u2.Name);
} }
struct CSolidGroup struct CSolidGroup
{ {
CCompressionMethodMode Method; CCompressionMethodMode Method;
CRecordVector<UINT32> Indices; CRecordVector<UInt32> Indices;
}; };
static wchar_t *g_ExeExts[] = static wchar_t *g_ExeExts[] =
@@ -282,7 +301,7 @@ static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
static bool GetMethodFull(const CMethodID &methodID, static bool GetMethodFull(const CMethodID &methodID,
UINT32 numInStreams, CMethodFull &methodResult) UInt32 numInStreams, CMethodFull &methodResult)
{ {
methodResult.MethodID = methodID; methodResult.MethodID = methodID;
methodResult.NumInStreams = numInStreams; methodResult.NumInStreams = numInStreams;
@@ -441,40 +460,43 @@ static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
file.HasStream = updateItem.HasStream(); file.HasStream = updateItem.HasStream();
} }
HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, static HRESULT Update2(
CObjectVector<CUpdateItem> &updateItems,
IOutStream *outStream,
IInStream *inStream, IInStream *inStream,
NArchive::N7z::CInArchiveInfo *inArchiveInfo, const CArchiveDatabaseEx *database,
const CCompressionMethodMode &method, const CObjectVector<CUpdateItem> &updateItems,
const CCompressionMethodMode *headerMethod, ISequentialOutStream *seqOutStream,
bool useFilters,
bool maxFilter,
bool useAdditionalHeaderStreams,
bool compressMainHeader,
IArchiveUpdateCallback *updateCallback, IArchiveUpdateCallback *updateCallback,
UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension, const CUpdateOptions &options)
bool removeSfxBlock)
{ {
UInt64 numSolidFiles = options.NumSolidFiles;
if (numSolidFiles == 0) if (numSolidFiles == 0)
numSolidFiles = 1; numSolidFiles = 1;
/*
CMyComPtr<IOutStream> outStream;
RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
if (!outStream)
return E_NOTIMPL;
*/
UINT64 startBlockSize = inArchiveInfo != 0 ? UInt64 startBlockSize = database != 0 ?
inArchiveInfo->StartPosition: 0; database->ArchiveInfo.StartPosition: 0;
if (startBlockSize > 0 && !removeSfxBlock) if (startBlockSize > 0 && !options.RemoveSfxBlock)
{ {
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> limitedStream(streamSpec); CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
streamSpec->Init(inStream, startBlockSize); streamSpec->Init(inStream, startBlockSize);
RINOK(CopyBlock(limitedStream, outStream, NULL)); RINOK(CopyBlock(limitedStream, seqOutStream, NULL));
} }
CRecordVector<int> fileIndexToUpdateIndexMap; 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; int i;
for (i = 0; i < database.Files.Size(); i++)
fileIndexToUpdateIndexMap.Add(-1);
for(i = 0; i < updateItems.Size(); i++) for(i = 0; i < updateItems.Size(); i++)
{ {
int index = updateItems[i].IndexInArchive; int index = updateItems[i].IndexInArchive;
@@ -482,43 +504,40 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
fileIndexToUpdateIndexMap[index] = i; fileIndexToUpdateIndexMap[index] = i;
} }
CRecordVector<CFolderRef> folderRefs; CRecordVector<int> folderRefs;
for(i = 0; i < database.Folders.Size(); i++) if (database != 0)
{ {
UINT64 indexInFolder = 0; for(i = 0; i < database->Folders.Size(); i++)
UINT64 numCopyItems = 0;
UINT64 numUnPackStreams = database.NumUnPackStreamsVector[i];
for (int fileIndex = database.FolderStartFileIndex[i];
indexInFolder < numUnPackStreams; fileIndex++)
{ {
if (database.Files[fileIndex].HasStream) CNum indexInFolder = 0;
CNum numCopyItems = 0;
CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
for (CNum fileIndex = database->FolderStartFileIndex[i];
indexInFolder < numUnPackStreams; fileIndex++)
{ {
indexInFolder++; if (database->Files[fileIndex].HasStream)
int updateIndex = fileIndexToUpdateIndexMap[fileIndex]; {
if (updateIndex >= 0) indexInFolder++;
if (!updateItems[updateIndex].NewData) int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
numCopyItems++; if (updateIndex >= 0)
if (!updateItems[updateIndex].NewData)
numCopyItems++;
}
} }
if (numCopyItems != numUnPackStreams && numCopyItems != 0)
return E_NOTIMPL; // It needs repacking !!!
if (numCopyItems > 0)
folderRefs.Add(i);
} }
if (numCopyItems != numUnPackStreams && numCopyItems != 0) folderRefs.Sort(CompareFolderRefs, (void *)database);
return E_NOTIMPL; // It needs repacking !!!
if (numCopyItems > 0)
{
CFolderRef folderRef;
folderRef.Database = &database;
folderRef.FolderIndex = i;
folderRefs.Add(folderRef);
}
} }
qsort(&folderRefs.Front(), folderRefs.Size(), sizeof(folderRefs[0]),
CompareFolderRefs);
CArchiveDatabase newDatabase; CArchiveDatabase newDatabase;
///////////////////////////////////////// /////////////////////////////////////////
// Write Empty Files & Folders // Write Empty Files & Folders
CRecordVector<const CUpdateItem *> emptyRefs; CRecordVector<int> emptyRefs;
for(i = 0; i < updateItems.Size(); i++) for(i = 0; i < updateItems.Size(); i++)
{ {
const CUpdateItem &updateItem = updateItems[i]; const CUpdateItem &updateItem = updateItems[i];
@@ -529,36 +548,45 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
} }
else else
if (updateItem.IndexInArchive != -1) if (updateItem.IndexInArchive != -1)
if (database.Files[updateItem.IndexInArchive].HasStream) if (database->Files[updateItem.IndexInArchive].HasStream)
continue; continue;
emptyRefs.Add(&updateItem); emptyRefs.Add(i);
} }
qsort(&emptyRefs.Front(), emptyRefs.Size(), sizeof(emptyRefs[0]), emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
CompareEmptyItems);
for(i = 0; i < emptyRefs.Size(); i++) for(i = 0; i < emptyRefs.Size(); i++)
{ {
const CUpdateItem &updateItem = *emptyRefs[i]; const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
CFileItem file; CFileItem file;
if (updateItem.NewProperties) if (updateItem.NewProperties)
FromUpdateItemToFileItem(updateItem, file); FromUpdateItemToFileItem(updateItem, file);
else else
file = database.Files[updateItem.IndexInArchive]; file = database->Files[updateItem.IndexInArchive];
newDatabase.Files.Add(file); newDatabase.Files.Add(file);
} }
//////////////////////////// ////////////////////////////
COutArchive archive; COutArchive archive;
archive.Create(outStream); RINOK(archive.Create(seqOutStream, false));
RINOK(archive.SkeepPrefixArchiveHeader()); RINOK(archive.SkeepPrefixArchiveHeader());
UINT64 complexity = 0; UInt64 complexity = 0;
for(i = 0; i < folderRefs.Size(); i++) for(i = 0; i < folderRefs.Size(); i++)
complexity += database.GetFolderFullPackSize(folderRefs[i].FolderIndex); complexity += database->GetFolderFullPackSize(folderRefs[i]);
UInt64 inSizeForReduce = 0;
for(i = 0; i < updateItems.Size(); i++) for(i = 0; i < updateItems.Size(); i++)
{ {
const CUpdateItem &updateItem = updateItems[i]; const CUpdateItem &updateItem = updateItems[i];
if (updateItem.NewData) if (updateItem.NewData)
{
complexity += updateItem.Size; complexity += updateItem.Size;
if (numSolidFiles == 1)
{
if (updateItem.Size > inSizeForReduce)
inSizeForReduce = updateItem.Size;
}
else
inSizeForReduce += updateItem.Size;
}
} }
RINOK(updateCallback->SetTotal(complexity)); RINOK(updateCallback->SetTotal(complexity));
complexity = 0; complexity = 0;
@@ -569,36 +597,35 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
for(i = 0; i < folderRefs.Size(); i++) for(i = 0; i < folderRefs.Size(); i++)
{ {
int folderIndex = folderRefs[i].FolderIndex; int folderIndex = folderRefs[i];
RINOK(WriteRange(inStream, archive.Stream, RINOK(WriteRange(inStream, archive.SeqStream,
CUpdateRange(database.GetFolderStreamPos(folderIndex, 0), database->GetFolderStreamPos(folderIndex, 0),
database.GetFolderFullPackSize(folderIndex)), database->GetFolderFullPackSize(folderIndex),
updateCallback, complexity)); updateCallback, complexity));
const CFolder &folder = database.Folders[folderIndex]; const CFolder &folder = database->Folders[folderIndex];
UINT32 startIndex = database.FolderStartPackStreamIndex[folderIndex]; CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
int j; for (int j = 0; j < folder.PackStreams.Size(); j++)
for (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.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
// newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]); // newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
} }
newDatabase.Folders.Add(folder); newDatabase.Folders.Add(folder);
UINT64 numUnPackStreams = database.NumUnPackStreamsVector[folderIndex]; CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex];
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
UINT64 indexInFolder = 0; CNum indexInFolder = 0;
for (j = database.FolderStartFileIndex[folderIndex]; for (CNum fi = database->FolderStartFileIndex[folderIndex];
indexInFolder < numUnPackStreams; j++) indexInFolder < numUnPackStreams; fi++)
{ {
CFileItem file = database.Files[j]; CFileItem file = database->Files[fi];
if (file.HasStream) if (file.HasStream)
{ {
indexInFolder++; indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[j]; int updateIndex = fileIndexToUpdateIndexMap[fi];
if (updateIndex >= 0) if (updateIndex >= 0)
{ {
const CUpdateItem &updateItem = updateItems[updateIndex]; const CUpdateItem &updateItem = updateItems[updateIndex];
@@ -608,7 +635,7 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
FromUpdateItemToFileItem(updateItem, file2); FromUpdateItemToFileItem(updateItem, file2);
file2.UnPackSize = file.UnPackSize; file2.UnPackSize = file.UnPackSize;
file2.FileCRC = file.FileCRC; file2.FileCRC = file.FileCRC;
file2.FileCRCIsDefined = file.FileCRCIsDefined; file2.IsFileCRCDefined = file.IsFileCRCDefined;
file2.HasStream = file.HasStream; file2.HasStream = file.HasStream;
file = file2; file = file2;
} }
@@ -622,7 +649,12 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
// Compress New Files // Compress New Files
CObjectVector<CSolidGroup> groups; CObjectVector<CSolidGroup> groups;
SplitFilesToGroups(method, useFilters, maxFilter, updateItems, groups); SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
updateItems, groups);
const UInt32 kMinReduceSize = (1 << 16);
if (inSizeForReduce < kMinReduceSize)
inSizeForReduce = kMinReduceSize;
for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++) for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++)
{ {
@@ -635,16 +667,16 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
for (i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
refItems.Add(CRefItem(group.Indices[i], refItems.Add(CRefItem(group.Indices[i],
updateItems[group.Indices[i]], numSolidFiles > 1)); updateItems[group.Indices[i]], numSolidFiles > 1));
qsort(&refItems.Front(), refItems.Size(), sizeof(refItems[0]), CompareUpdateItems); refItems.Sort(CompareUpdateItems, 0);
CRecordVector<UINT32> indices; CRecordVector<UInt32> indices;
indices.Reserve(numFiles); indices.Reserve(numFiles);
int startFileIndexInDatabase = newDatabase.Files.Size();
for (i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
{ {
UINT32 index = refItems[i].Index; UInt32 index = refItems[i].Index;
indices.Add(index); indices.Add(index);
/*
const CUpdateItem &updateItem = updateItems[index]; const CUpdateItem &updateItem = updateItems[index];
CFileItem file; CFileItem file;
if (updateItem.NewProperties) if (updateItem.NewProperties)
@@ -654,13 +686,14 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
if (file.IsAnti || file.IsDirectory) if (file.IsAnti || file.IsDirectory)
return E_FAIL; return E_FAIL;
newDatabase.Files.Add(file); newDatabase.Files.Add(file);
*/
} }
CEncoder encoder(group.Method); CEncoder encoder(group.Method);
for (i = 0; i < numFiles;) for (i = 0; i < numFiles;)
{ {
UINT64 totalSize = 0; UInt64 totalSize = 0;
int numSubFiles; int numSubFiles;
UString prevExtension; UString prevExtension;
for (numSubFiles = 0; i + numSubFiles < numFiles && for (numSubFiles = 0; i + numSubFiles < numFiles &&
@@ -668,15 +701,15 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
{ {
const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]]; const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
totalSize += updateItem.Size; totalSize += updateItem.Size;
if (totalSize > numSolidBytes) if (totalSize > options.NumSolidBytes)
break; break;
if (solidExtension) if (options.SolidExtension)
{ {
UString ext = updateItem.GetExtension(); UString ext = updateItem.GetExtension();
if (numSubFiles == 0) if (numSubFiles == 0)
prevExtension = ext; prevExtension = ext;
else else
if (ext.CollateNoCase(prevExtension) != 0) if (ext.CompareNoCase(prevExtension) != 0)
break; break;
} }
} }
@@ -695,43 +728,292 @@ HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(localProgress, &complexity, NULL); localCompressProgressSpec->Init(localProgress, &complexity, NULL);
RINOK(encoder.Encode(solidInStream, NULL, folderItem, RINOK(encoder.Encode(solidInStream, NULL, &inSizeForReduce, folderItem,
archive.Stream, newDatabase.PackSizes, compressProgress)); archive.SeqStream, newDatabase.PackSizes, compressProgress));
// for() // for()
// newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCsDefined.Add(false);
// newDatabase.PackCRCs.Add(0); // newDatabase.PackCRCs.Add(0);
newDatabase.Folders.Add(folderItem); newDatabase.Folders.Add(folderItem);
UINT32 numUnPackStreams = 0; CNum numUnPackStreams = 0;
for (int subIndex = 0; subIndex < numSubFiles; subIndex++) 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[ 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.FileCRC = inStreamSpec->CRCs[subIndex];
file.UnPackSize = inStreamSpec->Sizes[subIndex]; file.UnPackSize = inStreamSpec->Sizes[subIndex];
if (file.UnPackSize != 0) if (file.UnPackSize != 0)
{ {
file.FileCRCIsDefined = true; file.IsFileCRCDefined = true;
file.HasStream = true; file.HasStream = true;
numUnPackStreams++; numUnPackStreams++;
complexity += file.UnPackSize; complexity += file.UnPackSize;
} }
else else
{ {
file.FileCRCIsDefined = false; file.IsFileCRCDefined = false;
file.HasStream = 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); newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
i += numSubFiles; i += numSubFiles;
} }
} }
/*
if (newDatabase.Files.Size() != updateItems.Size()) if (newDatabase.Files.Size() != updateItems.Size())
return E_FAIL; return E_FAIL;
*/
return archive.WriteDatabase(newDatabase, headerMethod, return archive.WriteDatabase(newDatabase, options.HeaderMethod,
useAdditionalHeaderStreams, compressMainHeader); 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;
RINOK(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);
};
HRESULT COutVolumeStream::Flush()
{
if (_volumeStream)
{
_file.UnPackSize = _curPos;
_file.FileCRC = _crc.GetDigest();
RINOK(WriteVolumeHeader(_archive, _file, _options));
_archive.Close();
_volumeStream.Release();
_file.StartPos += _file.UnPackSize;
}
return S_OK;
}
STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if(processedSize != NULL)
*processedSize = 0;
while(size > 0)
{
if (!_volumeStream)
{
RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
_volIndex++;
_curPos = 0;
RINOK(_archive.Create(_volumeStream, true));
RINOK(_archive.SkeepPrefixArchiveHeader());
_crc.Init();
continue;
}
UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);
_crc.Update(data, curSize);
UInt32 realProcessed;
RINOK(_volumeStream->Write(data, curSize, &realProcessed))
data = (void *)((Byte *)data + realProcessed);
size -= realProcessed;
if(processedSize != NULL)
*processedSize += realProcessed;
_curPos += realProcessed;
if (realProcessed != curSize && realProcessed == 0)
return E_FAIL;
if (_curPos == pureSize)
{
RINOK(Flush());
}
}
return S_OK;
}
#endif
HRESULT Update(
IInStream *inStream,
const CArchiveDatabaseEx *database,
const CObjectVector<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
} }
}} }}

View File

@@ -1,7 +1,5 @@
// 7zUpdate.h // 7zUpdate.h
#pragma once
#ifndef __7Z_UPDATE_H #ifndef __7Z_UPDATE_H
#define __7Z_UPDATE_H #define __7Z_UPDATE_H
@@ -13,14 +11,6 @@
namespace NArchive { namespace NArchive {
namespace N7z { namespace N7z {
struct CUpdateRange
{
UINT64 Position;
UINT64 Size;
CUpdateRange() {};
CUpdateRange(UINT64 position, UINT64 size): Position(position), Size(size) {};
};
struct CUpdateItem struct CUpdateItem
{ {
bool NewData; bool NewData;
@@ -28,11 +18,11 @@ struct CUpdateItem
int IndexInArchive; int IndexInArchive;
int IndexInClient; int IndexInClient;
UINT32 Attributes; UInt32 Attributes;
FILETIME CreationTime; FILETIME CreationTime;
FILETIME LastWriteTime; FILETIME LastWriteTime;
UINT64 Size; UInt64 Size;
UString Name; UString Name;
bool IsAnti; bool IsAnti;
@@ -52,21 +42,28 @@ struct CUpdateItem
UString GetExtension() const; UString GetExtension() const;
}; };
HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database, struct CUpdateOptions
CObjectVector<CUpdateItem> &updateItems, {
IOutStream *outStream, const CCompressionMethodMode *Method;
IInStream *inStream, const CCompressionMethodMode *HeaderMethod;
CInArchiveInfo *inArchiveInfo, bool UseFilters;
const CCompressionMethodMode &method, bool MaxFilter;
const CCompressionMethodMode *headerMethod, bool UseAdditionalHeaderStreams;
bool useFilters, bool CompressMainHeader;
bool maxFilter, UInt64 NumSolidFiles;
bool useAdditionalHeaderStreams, UInt64 NumSolidBytes;
bool compressMainHeader, bool SolidExtension;
IArchiveUpdateCallback *updateCallback, bool RemoveSfxBlock;
UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension, bool VolumeMode;
bool removeSfxBlock); };
HRESULT Update(
IInStream *inStream,
const CArchiveDatabaseEx *database,
const CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options);
}} }}
#endif #endif

View File

@@ -2,13 +2,15 @@
#include "StdAfx.h" #include "StdAfx.h"
#include <initguid.h> #include "../../../Common/MyInitGuid.h"
#include "../../../Common/ComTry.h"
#ifdef _WIN32
#include "../../../Common/Alloc.h"
#endif
#include "../../ICoder.h"
#include "7zHandler.h" #include "7zHandler.h"
#include "../../ICoder.h"
#include "../../IPassword.h"
#include "../../../Common/NewHandler.h"
#include "../../../Common/ComTry.h"
#ifndef EXCLUDE_COM #ifndef EXCLUDE_COM
// {23170F69-40C1-278B-06F1-070100000100} // {23170F69-40C1-278B-06F1-070100000100}
@@ -19,12 +21,32 @@ DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
#endif #endif
HINSTANCE g_hInstance; HINSTANCE g_hInstance;
#ifndef _UNICODE
bool g_IsNT = false;
static bool IsItWindowsNT()
{
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!::GetVersionEx(&versionInfo))
return false;
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
#endif
extern "C" extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{ {
if (dwReason == DLL_PROCESS_ATTACH) if (dwReason == DLL_PROCESS_ATTACH)
{
g_hInstance = hInstance; g_hInstance = hInstance;
#ifndef _UNICODE
g_IsNT = IsItWindowsNT();
#endif
#ifdef _WIN32
SetLargePageSize();
#endif
}
return TRUE; return TRUE;
} }
@@ -38,22 +60,18 @@ STDAPI CreateObject(
*outObject = 0; *outObject = 0;
if (*classID != NArchive::N7z::CLSID_CFormat7z) if (*classID != NArchive::N7z::CLSID_CFormat7z)
return CLASS_E_CLASSNOTAVAILABLE; return CLASS_E_CLASSNOTAVAILABLE;
int needIn = *interfaceID == IID_IInArchive; if (*interfaceID == IID_IInArchive)
int needOut = *interfaceID == IID_IOutArchive;
if (needIn || needOut)
{ {
NArchive::N7z::CHandler *temp = new NArchive::N7z::CHandler; CMyComPtr<IInArchive> inArchive = new NArchive::N7z::CHandler;
if (needIn) *outObject = inArchive.Detach();
{
CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
*outObject = inArchive.Detach();
}
else
{
CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
*outObject = outArchive.Detach();
}
} }
#ifndef EXTRACT_ONLY
else if (*interfaceID == IID_IOutArchive)
{
CMyComPtr<IOutArchive> outArchive = new NArchive::N7z::CHandler;
*outObject = outArchive.Detach();
}
#endif
else else
return E_NOINTERFACE; return E_NOINTERFACE;
COM_TRY_END COM_TRY_END
@@ -84,6 +102,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
case NArchive::kKeepName: case NArchive::kKeepName:
propVariant = false; propVariant = false;
break; 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); propVariant.Detach(value);
return S_OK; return S_OK;

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp // StdAfx.cpp
#include "stdafx.h" #include "StdAfx.h"

View File

@@ -1,23 +1,9 @@
// stdafx.h // StdAfx.h
#ifndef __STDAFX_H #ifndef __STDAFX_H
#define __STDAFX_H #define __STDAFX_H
#include <windows.h> #include "../../../Common/MyWindows.h"
#include "../../../Common/NewHandler.h"
/* #endif
#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

89
7zip/Archive/7z/makefile Executable file
View File

@@ -0,0 +1,89 @@
PROG = 7z.dll
DEF_FILE = ../Archive.def
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
LIBS = $(LIBS) oleaut32.lib user32.lib
7Z_OBJS = \
$O\7zCompressionMode.obj \
$O\7zDecode.obj \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
$O\7zMethodID.obj \
$O\7zMethods.obj \
$O\7zOut.obj \
$O\7zProperties.obj \
$O\7zSpecStream.obj \
$O\7zUpdate.obj \
$O\DllExports.obj \
COMMON_OBJS = \
$O\Alloc.obj \
$O\CRC.obj \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\String.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\Vector.obj \
WIN_OBJS = \
$O\DLL.obj \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
$O\PropVariant.obj \
$O\Synchronization.obj
7ZIP_COMMON_OBJS = \
$O\InOutTempBuffer.obj \
$O\LimitedStreams.obj \
$O\LockedStream.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CodecsPath.obj \
$O\CoderLoader.obj \
$O\CoderMixer2.obj \
$O\CoderMixer2MT.obj \
$O\CrossThreadProgress.obj \
$O\FilterCoder.obj \
$O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \
$O\MultiStream.obj \
$O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \
OBJS = \
$O\StdAfx.obj \
$(7Z_OBJS) \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(AR_COMMON_OBJS) \
$O\CopyCoder.obj \
$O\resource.res
!include "../../../Build.mak"
$(7Z_OBJS): $(*B).cpp
$(COMPL)
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
$(WIN_OBJS): ../../../Windows/$(*B).cpp
$(COMPL)
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL)
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
$(COMPL)
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
$(COMPL)

View File

@@ -1,16 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by resource.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -1,130 +1,5 @@
//Microsoft Developer Studio generated resource script. #include "../../MyVersionInfo.rc"
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS MY_VERSION_INFO_DLL("7z Plugin", "7z")
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Russian resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Russian resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "7z.ico"
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,12,0,0
PRODUCTVERSION 3,12,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "7z Plugin for 7-Zip\0"
VALUE "FileVersion", "3, 12, 0, 0\0"
VALUE "InternalName", "7z\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2003 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 "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
101 ICON "7z.ico"

70
7zip/Archive/7z_C/7zAlloc.c Executable file
View File

@@ -0,0 +1,70 @@
/* 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
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountTemp = 0;
#endif
void *SzAlloc(size_t size)
{
if (size == 0)
return 0;
#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)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
g_allocCountTemp++;
#ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size);
#endif
#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);
}
#ifdef _WIN32
HeapFree(GetProcessHeap(), 0, address);
return;
#endif
#endif
free(address);
}

20
7zip/Archive/7z_C/7zAlloc.h Executable file
View 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

29
7zip/Archive/7z_C/7zBuffer.c Executable file
View File

@@ -0,0 +1,29 @@
/* 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;
if (newCapacity == 0)
{
buffer->Items = 0;
return 1;
}
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
View 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
View 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
View 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

150
7zip/Archive/7z_C/7zDecode.c Executable file
View File

@@ -0,0 +1,150 @@
/* 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, const unsigned char **buffer, SizeT *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 = (SizeT)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(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
ISzInStream *inStream,
#else
const 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;
#else
SizeT inProcessed;
#endif
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
int result;
SizeT outSizeProcessedLoc;
#ifdef _LZMA_IN_CB
lzmaCallback.Size = inSize;
lzmaCallback.InStream = inStream;
lzmaCallback.InCallback.Read = LzmaReadImp;
#endif
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
coder->Properties.Capacity) != LZMA_RESULT_OK)
return SZE_FAIL;
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (state.Probs == 0)
return SZE_OUTOFMEMORY;
#ifdef _LZMA_OUT_READ
if (state.Properties.DictionarySize == 0)
state.Dictionary = 0;
else
{
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
if (state.Dictionary == 0)
{
allocMain->Free(state.Probs);
return SZE_OUTOFMEMORY;
}
}
LzmaDecoderInit(&state);
#endif
result = LzmaDecode(&state,
#ifdef _LZMA_IN_CB
&lzmaCallback.InCallback,
#else
inBuffer, (SizeT)inSize, &inProcessed,
#endif
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
*outSizeProcessed = (size_t)outSizeProcessedLoc;
allocMain->Free(state.Probs);
#ifdef _LZMA_OUT_READ
allocMain->Free(state.Dictionary);
#endif
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
View 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(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
ISzInStream *stream,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize,
size_t *outSizeProcessed, ISzAlloc *allocMain);
#endif

116
7zip/Archive/7z_C/7zExtract.c Executable file
View File

@@ -0,0 +1,116 @@
/* 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
if (packSize != 0)
{
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)
{
*outBufferSize = (size_t)unPackSize;
if (unPackSize != 0)
{
*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
if (*outBuffer == 0)
res = SZE_OUTOFMEMORY;
}
if (res == SZ_OK)
{
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;
}
}
}
#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;
}

40
7zip/Archive/7z_C/7zExtract.h Executable file
View File

@@ -0,0 +1,40 @@
/* 7zExtract.h */
#ifndef __7Z_EXTRACT_H
#define __7Z_EXTRACT_H
#include "7zIn.h"
/*
SzExtract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
SZ_RESULT SzExtract(
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
View 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
View 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

1292
7zip/Archive/7z_C/7zIn.c Executable file
View File

File diff suppressed because it is too large Load Diff

55
7zip/Archive/7z_C/7zIn.h Executable file
View 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
View 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
View 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;
Byte *PackCRCsDefined;
UInt32 *PackCRCs;
UInt32 NumFolders;
CFolder *Folders;
UInt32 NumFiles;
CFileItem *Files;
}CArchiveDatabase;
void SzArchiveDatabaseInit(CArchiveDatabase *db);
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
#endif

223
7zip/Archive/7z_C/7zMain.c Executable file
View File

@@ -0,0 +1,223 @@
/*
7zMain.c
Test application for 7z Decoder
LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02)
*/
#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.30 Copyright (c) 1999-2005 Igor Pavlov 2005-11-20\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;
// if you need cache, use these 3 variables.
// if you use external function, you can make these variable as static.
UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0)
Byte *outBuffer = 0; // it must be 0 before first call for each new archive.
size_t outBufferSize = 0; // it can have any value before first call (if outBuffer = 0)
printf("\n");
for (i = 0; i < db.Database.NumFiles; i++)
{
size_t offset;
size_t outSizeProcessed;
CFileItem *f = db.Database.Files + i;
if (f->IsDirectory)
printf("Directory ");
else
printf(testCommand ?
"Testing ":
"Extracting");
printf(" %s", f->Name);
if (f->IsDirectory)
{
printf("\n");
continue;
}
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
View 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
View 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
View 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
View 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

View File

@@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
############################################################################### ###############################################################################
Project: "Implode"=.\Implode.dsp - Package Owner=<4> Project: "7z_C"=.\7z_C.dsp - Package Owner=<4>
Package=<5> Package=<5>
{{{ {{{

55
7zip/Archive/7z_C/makefile Executable file
View File

@@ -0,0 +1,55 @@
PROG = 7zDec.exe
!IFNDEF O
!IFDEF CPU
O=$(CPU)
!ELSE
O=O
!ENDIF
!ENDIF
CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS-
CFLAGS_O1 = $(CFLAGS) -O1
CFLAGS_O2 = $(CFLAGS) -O2
LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98
PROGPATH = $O\$(PROG)
COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
COMPL = $(CPP) $(CFLAGS_O1) $**
7Z_OBJS = \
$O\7zAlloc.obj \
$O\7zBuffer.obj \
$O\7zCrc.obj \
$O\7zDecode.obj \
$O\7zExtract.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
$O\7zItem.obj \
$O\7zMain.obj \
$O\7zMethodID.obj \
OBJS = \
$(7Z_OBJS) \
$O\LzmaDecode.obj \
all: $(PROGPATH)
clean:
-del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
$O:
if not exist "$O" mkdir "$O"
$(PROGPATH): $O $(OBJS)
link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
$(7Z_OBJS): $(*B).c
$(COMPL)
$O\LzmaDecode.obj: ../../Compress/LZMA_C/$(*B).c
$(COMPL_O2)

50
7zip/Archive/7z_C/makefile.gcc Executable file
View File

@@ -0,0 +1,50 @@
PROG = 7zDec
CXX = g++
LIB =
RM = rm -f
CFLAGS = -c -O2 -Wall
OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o
all: $(PROG)
$(PROG): $(OBJS)
$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
7zAlloc.o: 7zAlloc.c
$(CXX) $(CFLAGS) 7zAlloc.c
7zBuffer.o: 7zBuffer.c
$(CXX) $(CFLAGS) 7zBuffer.c
7zCrc.o: 7zCrc.c
$(CXX) $(CFLAGS) 7zCrc.c
7zDecode.o: 7zDecode.c
$(CXX) $(CFLAGS) 7zDecode.c
7zExtract.o: 7zExtract.c
$(CXX) $(CFLAGS) 7zExtract.c
7zHeader.o: 7zHeader.c
$(CXX) $(CFLAGS) 7zHeader.c
7zIn.o: 7zIn.c
$(CXX) $(CFLAGS) 7zIn.c
7zItem.o: 7zItem.c
$(CXX) $(CFLAGS) 7zItem.c
7zMain.o: 7zMain.c
$(CXX) $(CFLAGS) 7zMain.c
7zMethodID.o: 7zMethodID.c
$(CXX) $(CFLAGS) 7zMethodID.c
LzmaDecode.o: ../../Compress/LZMA_C/LzmaDecode.c
$(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c
clean:
-$(RM) $(PROG) $(OBJS)

View File

@@ -1,4 +1,3 @@
EXPORTS EXPORTS
CreateObject PRIVATE CreateObject PRIVATE
GetHandlerProperty PRIVATE GetHandlerProperty PRIVATE

View File

@@ -93,7 +93,7 @@ LINK32=link.exe
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=.\arj.def SOURCE=..\Archive.def
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -101,10 +101,6 @@ SOURCE=.\DllExports.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=.\resource.rc SOURCE=.\resource.rc
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -122,6 +118,14 @@ SOURCE=.\StdAfx.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\Alloc.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\CRC.cpp SOURCE=..\..\..\Common\CRC.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -201,10 +205,6 @@ SOURCE=.\ArjIn.h
SOURCE=.\ArjItem.h SOURCE=.\ArjItem.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Compression"
# PROP Default_Filter ""
# End Group
# Begin Group "Compress" # Begin Group "Compress"
# PROP Default_Filter "" # PROP Default_Filter ""
@@ -213,19 +213,19 @@ SOURCE=.\ArjItem.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\Compress\Arj\Decoder1.cpp SOURCE=..\..\Compress\Arj\ArjDecoder1.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Compress\Arj\Decoder1.h SOURCE=..\..\Compress\Arj\ArjDecoder1.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Compress\Arj\Decoder2.cpp SOURCE=..\..\Compress\Arj\ArjDecoder2.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Compress\Arj\Decoder2.h SOURCE=..\..\Compress\Arj\ArjDecoder2.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "LZ" # Begin Group "LZ"
@@ -274,12 +274,32 @@ SOURCE=..\..\Common\LimitedStreams.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\MSBFDecoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\OutBuffer.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\OutBuffer.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\ProgressUtils.h SOURCE=..\..\Common\ProgressUtils.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.h
# End Source File
# End Group # End Group
# Begin Group "Archive Common" # Begin Group "Archive Common"

View File

@@ -19,8 +19,8 @@
#include "../../Common/LimitedStreams.h" #include "../../Common/LimitedStreams.h"
#include "../../Compress/Copy/CopyCoder.h" #include "../../Compress/Copy/CopyCoder.h"
#include "../../Compress/Arj/Decoder1.h" #include "../../Compress/Arj/ArjDecoder1.h"
#include "../../Compress/Arj/Decoder2.h" #include "../../Compress/Arj/ArjDecoder2.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
#include "../Common/OutStreamWithCRC.h" #include "../Common/OutStreamWithCRC.h"
@@ -93,13 +93,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
{ {
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]); *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType) BSTR *name, PROPID *propID, VARTYPE *varType)
{ {
if(index >= sizeof(kProperties) / sizeof(kProperties[0])) if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
@@ -111,25 +111,25 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{ {
*numProperties = 0; *numProperties = 0;
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType) BSTR *name, PROPID *propID, VARTYPE *varType)
{ {
return E_NOTIMPL; return E_NOTIMPL;
} }
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
*numItems = _items.Size(); *numItems = _items.Size();
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant propVariant;
@@ -193,24 +193,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
COM_TRY_END COM_TRY_END
} }
/*
class CPropgressImp: public CProgressVirt class CPropgressImp: public CProgressVirt
{ {
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallBack;
public: public:
STDMETHOD(SetCompleted)(const UINT64 *numFiles); CMyComPtr<IArchiveOpenCallback> Callback;
void Init(IArchiveOpenCallback *openArchiveCallback) STDMETHOD(SetCompleted)(const UInt64 *numFiles);
{ m_OpenArchiveCallBack = openArchiveCallback; }
}; };
STDMETHODIMP CPropgressImp::SetCompleted(const UINT64 *numFiles) STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
{ {
if (m_OpenArchiveCallBack) if (Callback)
return m_OpenArchiveCallBack->SetCompleted(numFiles, NULL); return Callback->SetCompleted(numFiles, NULL);
return S_OK; return S_OK;
} }
*/
STDMETHODIMP CHandler::Open(IInStream *inStream, STDMETHODIMP CHandler::Open(IInStream *inStream,
const UINT64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
try try
@@ -219,11 +219,11 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
CInArchive archive; CInArchive archive;
if(!archive.Open(inStream, maxCheckStartPosition)) if(!archive.Open(inStream, maxCheckStartPosition))
return S_FALSE; return S_FALSE;
if (openArchiveCallback != NULL) if (callback != NULL)
{ {
RINOK(openArchiveCallback->SetTotal(NULL, NULL)); RINOK(callback->SetTotal(NULL, NULL));
UINT64 numFiles = _items.Size(); UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); RINOK(callback->SetCompleted(&numFiles, NULL));
} }
while(true) while(true)
{ {
@@ -238,10 +238,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
break; break;
_items.Add(itemInfo); _items.Add(itemInfo);
archive.IncreaseRealPosition(itemInfo.PackSize); archive.IncreaseRealPosition(itemInfo.PackSize);
if (openArchiveCallback != NULL) if (callback != NULL)
{ {
UINT64 numFiles = _items.Size(); UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); RINOK(callback->SetCompleted(&numFiles, NULL));
} }
} }
_stream = inStream; _stream = inStream;
@@ -256,6 +256,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
STDMETHODIMP CHandler::Close() STDMETHODIMP CHandler::Close()
{ {
_items.Clear();
_stream.Release(); _stream.Release();
return S_OK; return S_OK;
} }
@@ -265,18 +266,18 @@ STDMETHODIMP CHandler::Close()
////////////////////////////////////// //////////////////////////////////////
// CHandler::DecompressItems // CHandler::DecompressItems
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
INT32 testModeSpec, IArchiveExtractCallback *extractCallback) Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
bool testMode = (testModeSpec != 0); bool testMode = (testModeSpec != 0);
UINT64 totalUnPacked = 0, totalPacked = 0; UInt64 totalUnPacked = 0, totalPacked = 0;
bool allFilesMode = (numItems == UINT32(-1)); bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode) if (allFilesMode)
numItems = _items.Size(); numItems = _items.Size();
if(numItems == 0) if(numItems == 0)
return S_OK; return S_OK;
UINT32 i; UInt32 i;
for(i = 0; i < numItems; i++) for(i = 0; i < numItems; i++)
{ {
const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]];
@@ -285,8 +286,8 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
} }
extractCallback->SetTotal(totalUnPacked); extractCallback->SetTotal(totalUnPacked);
UINT64 currentTotalUnPacked = 0, currentTotalPacked = 0; UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
UINT64 currentItemUnPacked, currentItemPacked; UInt64 currentItemUnPacked, currentItemPacked;
CMyComPtr<ICompressCoder> arj1Decoder; CMyComPtr<ICompressCoder> arj1Decoder;
CMyComPtr<ICompressCoder> arj2Decoder; CMyComPtr<ICompressCoder> arj2Decoder;
@@ -300,10 +301,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
RINOK(extractCallback->SetCompleted(&currentTotalUnPacked)); RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
INT32 askMode; Int32 askMode;
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
INT32 index = allFilesMode ? i : indices[i]; Int32 index = allFilesMode ? i : indices[i];
const CItemEx &itemInfo = _items[index]; const CItemEx &itemInfo = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -333,7 +334,7 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec); CMyComPtr<ISequentialInStream> inStream(streamSpec);
UINT64 pos; UInt64 pos;
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
streamSpec->Init(_stream, itemInfo.PackSize); streamSpec->Init(_stream, itemInfo.PackSize);

View File

@@ -1,7 +1,5 @@
// ArjHandler.h // ArjHandler.h
#pragma once
#ifndef __ARJ_HANDLER_H #ifndef __ARJ_HANDLER_H
#define __ARJ_HANDLER_H #define __ARJ_HANDLER_H
@@ -19,23 +17,23 @@ class CHandler:
public: public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(Open)(IInStream *aStream, STDMETHOD(Open)(IInStream *inStream,
const UINT64 *aMaxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *anOpenArchiveCallback); IArchiveOpenCallback *callback);
STDMETHOD(Close)(); STDMETHOD(Close)();
STDMETHOD(GetNumberOfItems)(UINT32 *numItems); STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
INT32 testMode, IArchiveExtractCallback *anExtractCallback); Int32 testMode, IArchiveExtractCallback *anExtractCallback);
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
STDMETHOD(GetPropertyInfo)(UINT32 index, STDMETHOD(GetPropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType); BSTR *name, PROPID *propID, VARTYPE *varType);
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
STDMETHOD(GetArchivePropertyInfo)(UINT32 index, STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType); BSTR *name, PROPID *propID, VARTYPE *varType);
CHandler(); CHandler();
@@ -46,4 +44,4 @@ private:
}} }}
#endif #endif

View File

@@ -1,7 +1,5 @@
// Archive/Arj/Header.h // Archive/Arj/Header.h
#pragma once
#ifndef __ARCHIVE_ARJ_HEADER_H #ifndef __ARCHIVE_ARJ_HEADER_H
#define __ARCHIVE_ARJ_HEADER_H #define __ARCHIVE_ARJ_HEADER_H
@@ -14,33 +12,32 @@ const int kMaxBlockSize = 2600;
namespace NSignature namespace NSignature
{ {
const BYTE kSig0 = 0x60; const Byte kSig0 = 0x60;
const BYTE kSig1 = 0xEA; const Byte kSig1 = 0xEA;
} }
#pragma pack( push, Pragma_Arj_Headers) /*
#pragma pack( push, 1)
struct CArchiveHeader struct CArchiveHeader
{ {
// UINT16 BasicHeaderSize; // UInt16 BasicHeaderSize;
BYTE FirstHeaderSize; Byte FirstHeaderSize;
BYTE Version; Byte Version;
BYTE ExtractVersion; Byte ExtractVersion;
BYTE HostOS; Byte HostOS;
BYTE Flags; Byte Flags;
BYTE SecuryVersion; Byte SecuryVersion;
BYTE FileType; Byte FileType;
BYTE Reserved; Byte Reserved;
UINT32 CreatedTime; UInt32 CreatedTime;
UINT32 ModifiedTime; UInt32 ModifiedTime;
UINT32 ArchiveSize; UInt32 ArchiveSize;
UINT32 SecurityEnvelopeFilePosition; UInt32 SecurityEnvelopeFilePosition;
UINT16 FilespecPositionInFilename; UInt16 FilespecPositionInFilename;
UINT16 LengthOfSecurityEnvelopeSata; UInt16 LengthOfSecurityEnvelopeSata;
BYTE EncryptionVersion; Byte EncryptionVersion;
BYTE LastChapter; Byte LastChapter;
}; };
*/
namespace NFileHeader namespace NFileHeader
{ {
@@ -70,32 +67,35 @@ namespace NFileHeader
} }
namespace NFlags namespace NFlags
{ {
const BYTE kGarbled = 1; const Byte kGarbled = 1;
const BYTE kVolume = 4; const Byte kVolume = 4;
const BYTE kExtFile = 8; const Byte kExtFile = 8;
const BYTE kPathSym = 0x10; const Byte kPathSym = 0x10;
const BYTE kBackup= 0x20; const Byte kBackup= 0x20;
} }
/*
struct CHeader struct CHeader
{ {
BYTE FirstHeaderSize; Byte FirstHeaderSize;
BYTE Version; Byte Version;
BYTE ExtractVersion; Byte ExtractVersion;
BYTE HostOS; Byte HostOS;
BYTE Flags; Byte Flags;
BYTE Method; Byte Method;
BYTE FileType; Byte FileType;
BYTE Reserved; Byte Reserved;
UINT32 ModifiedTime; UInt32 ModifiedTime;
UINT32 PackSize; UInt32 PackSize;
UINT32 Size; UInt32 Size;
UINT32 FileCRC; UInt32 FileCRC;
UINT16 FilespecPositionInFilename; UInt16 FilespecPositionInFilename;
UINT16 FileAccessMode; UInt16 FileAccessMode;
BYTE FirstChapter; Byte FirstChapter;
BYTE LastChapter; Byte LastChapter;
}; };
*/
namespace NHostOS namespace NHostOS
{ {
enum EEnum enum EEnum
@@ -116,9 +116,6 @@ namespace NFileHeader
} }
} }
#pragma pack(pop)
#pragma pack(pop, Pragma_Arj_Headers)
}} }}
#endif #endif

View File

@@ -6,60 +6,66 @@
#include "Common/Buffer.h" #include "Common/Buffer.h"
#include "Common/CRC.h" #include "Common/CRC.h"
#include "Windows/Defs.h" #include "../../Common/StreamUtils.h"
#include "ArjIn.h" #include "ArjIn.h"
namespace NArchive { namespace NArchive {
namespace NArj { namespace NArj {
CInArchiveException::CInArchiveException(CCauseType cause): HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
Cause(cause)
{}
HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
{ {
UINT32 realProcessedSize; UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize); HRESULT result = ReadStream(_stream, data, size, &realProcessedSize);
if(processedSize != NULL) if(processedSize != NULL)
*processedSize = realProcessedSize; *processedSize = realProcessedSize;
IncreasePositionValue(realProcessedSize); IncreasePositionValue(realProcessedSize);
return result; 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) if (maxSize < 2 + 2 + 4)
return false; return false;
const BYTE *block = ((const BYTE *)(testBytes)); const Byte *block = ((const Byte *)(testBytes));
if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1) if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1)
return false; return false;
UINT32 blockSize = *((const UINT16 *)(block + 2)); UInt32 blockSize = GetUInt16FromMemLE(block + 2);
if (maxSize < 2 + 2 + blockSize + 4) if (maxSize < 2 + 2 + blockSize + 4)
return false; return false;
block += 4; block += 4;
if (blockSize == 0 || blockSize > 2600) if (blockSize == 0 || blockSize > 2600)
return false; return false;
UINT32 crcFromFile = *(const UINT32 *)(block + blockSize); UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize);
return (CCRC::VerifyDigest(crcFromFile, block, blockSize)); return (CCRC::VerifyDigest(crcFromFile, block, blockSize));
} }
bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit) bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
{ {
// _archiveInfo.StartPosition = 0; // _archiveInfo.StartPosition = 0;
_position = _streamStartPosition; _position = _streamStartPosition;
if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK) if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
return false; return false;
const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + sizeof(UINT32); const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4;
CByteBuffer byteBuffer; CByteBuffer byteBuffer;
static const UINT32 kSearchMarkerBufferSize = 0x10000; static const UInt32 kSearchMarkerBufferSize = 0x10000;
byteBuffer.SetCapacity(kSearchMarkerBufferSize); byteBuffer.SetCapacity(kSearchMarkerBufferSize);
BYTE *buffer = byteBuffer; Byte *buffer = byteBuffer;
UINT32 processedSize; UInt32 processedSize;
ReadBytes(buffer, 2 + 2 + kMaxBlockSize + sizeof(UINT32), &processedSize); ReadBytes(buffer, kMarkerSizeMax, &processedSize);
if (processedSize == 0) if (processedSize == 0)
return false; return false;
if (TestMarkerCandidate(buffer, processedSize)) if (TestMarkerCandidate(buffer, processedSize))
@@ -70,21 +76,21 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit)
return true; return true;
} }
UINT32 numBytesPrev = processedSize - 1; UInt32 numBytesPrev = processedSize - 1;
memmove(buffer, buffer + 1, numBytesPrev); memmove(buffer, buffer + 1, numBytesPrev);
UINT64 curTestPos = _streamStartPosition + 1; UInt64 curTestPos = _streamStartPosition + 1;
while(true) while(true)
{ {
if (searchHeaderSizeLimit != NULL) if (searchHeaderSizeLimit != NULL)
if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit) if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit)
return false; return false;
UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
UINT32 numBytesInBuffer = numBytesPrev + processedSize; UInt32 numBytesInBuffer = numBytesPrev + processedSize;
if (numBytesInBuffer < 1) if (numBytesInBuffer < 1)
return false; return false;
UINT32 numTests = numBytesInBuffer; UInt32 numTests = numBytesInBuffer;
for(UINT32 pos = 0; pos < numTests; pos++, curTestPos++) for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
{ {
if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos)) if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos))
{ {
@@ -100,39 +106,68 @@ bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit)
} }
} }
void CInArchive::IncreasePositionValue(UINT64 addValue) void CInArchive::IncreasePositionValue(UInt64 addValue)
{ {
_position += addValue; _position += addValue;
} }
void CInArchive::IncreaseRealPosition(UINT64 addValue) void CInArchive::IncreaseRealPosition(UInt64 addValue)
{ {
if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK) if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK)
throw CInArchiveException(CInArchiveException::kSeekStreamError); 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) if(ReadBytes(data, size, &realProcessedSize) != S_OK)
throw CInArchiveException(CInArchiveException::kReadStreamError); throw CInArchiveException(CInArchiveException::kReadStreamError);
return (realProcessedSize == size); return (realProcessedSize == size);
} }
void CInArchive::SafeReadBytes(void *data, UINT32 size) void CInArchive::SafeReadBytes(void *data, UInt32 size)
{ {
if(!ReadBytesAndTestSize(data, size)) if(!ReadBytesAndTestSize(data, size))
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); 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() bool CInArchive::ReadBlock()
{ {
SafeReadBytes(&_blockSize, sizeof(_blockSize)); _blockPos = 0;
if (_blockSize == 0) _blockSize = SafeReadUInt16();
if (_blockSize == 0 || _blockSize > kMaxBlockSize)
return false; return false;
SafeReadBytes(_block, _blockSize); SafeReadBytes(_block, _blockSize);
UINT32 crcFromFile; UInt32 crcFromFile = SafeReadUInt32();
ReadBytesAndTestSize(&crcFromFile, sizeof(crcFromFile));
if (!CCRC::VerifyDigest(crcFromFile, _block, _blockSize)) if (!CCRC::VerifyDigest(crcFromFile, _block, _blockSize))
throw CInArchiveException(CInArchiveException::kCRCError); throw CInArchiveException(CInArchiveException::kCRCError);
return true; return true;
@@ -140,14 +175,14 @@ bool CInArchive::ReadBlock()
bool CInArchive::ReadBlock2() bool CInArchive::ReadBlock2()
{ {
BYTE id[2]; Byte id[2];
ReadBytesAndTestSize(id, 2); ReadBytesAndTestSize(id, 2);
if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1) if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
throw CInArchiveException(CInArchiveException::kIncorrectArchive); throw CInArchiveException(CInArchiveException::kIncorrectArchive);
return ReadBlock(); return ReadBlock();
} }
bool CInArchive::Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit) bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
{ {
_stream = inStream; _stream = inStream;
if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK) if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK)
@@ -173,40 +208,67 @@ void CInArchive::ThrowIncorrectArchiveException()
throw CInArchiveException(CInArchiveException::kIncorrectArchive); 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) HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
{ {
filled = false; filled = false;
if (!ReadBlock2()) if (!ReadBlock2())
return S_OK; return S_OK;
const NFileHeader::CHeader &header = *(const NFileHeader::CHeader *)_block; Byte firstHeaderSize = ReadByte();
item.Version = ReadByte();
item.Version = header.Version; item.ExtractVersion = ReadByte();
item.ExtractVersion = header.ExtractVersion; item.HostOS = ReadByte();
item.HostOS = header.HostOS; item.Flags = ReadByte();
item.Flags = header.Flags; item.Method = ReadByte();
item.Method = header.Method; item.FileType = ReadByte();
item.FileType = header.FileType; ReadByte(); // Reserved
item.ModifiedTime = header.ModifiedTime; item.ModifiedTime = ReadUInt32();
item.PackSize = header.PackSize; item.PackSize = ReadUInt32();
item.Size = header.Size; item.Size = ReadUInt32();
item.FileCRC = header.FileCRC; item.FileCRC = ReadUInt32();
item.FileAccessMode = header.FileAccessMode; ReadUInt16(); // FilespecPositionInFilename
item.FileAccessMode = ReadUInt16();
ReadByte(); // FirstChapter
ReadByte(); // LastChapter
/* /*
UINT32 extraData; UInt32 extraData;
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0) 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++) for (; _blockPos < _blockSize;)
{ item.Name += (char)ReadByte();
char aByte = _block[pos];
if (aByte == 0)
break;
item.Name += aByte;
}
while(true) while(true)
if (!ReadBlock()) if (!ReadBlock())

View File

@@ -1,15 +1,11 @@
// Archive/ArjIn.h // Archive/ArjIn.h
#pragma once
#ifndef __ARCHIVE_ARJIN_H #ifndef __ARCHIVE_ARJIN_H
#define __ARCHIVE_ARJIN_H #define __ARCHIVE_ARJIN_H
#include "Common/Exception.h"
#include "Common/MyCom.h" #include "Common/MyCom.h"
#include "../../IStream.h" #include "../../IStream.h"
#include "Header.h"
#include "ArjItem.h" #include "ArjItem.h"
namespace NArchive { namespace NArchive {
@@ -27,42 +23,51 @@ public:
kSeekStreamError kSeekStreamError
} }
Cause; Cause;
CInArchiveException(CCauseType cause); CInArchiveException(CCauseType cause): Cause(cause) {};
}; };
class CProgressVirt class CProgressVirt
{ {
public: public:
STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE; STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
}; };
class CInArchive class CInArchive
{ {
CMyComPtr<IInStream> _stream; CMyComPtr<IInStream> _stream;
UINT64 _streamStartPosition; UInt64 _streamStartPosition;
UINT64 _position; UInt64 _position;
UINT16 _blockSize; UInt16 _blockSize;
BYTE _block[kMaxBlockSize]; Byte _block[kMaxBlockSize];
UInt32 _blockPos;
bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit); bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
bool ReadBlock(); bool ReadBlock();
bool ReadBlock2(); bool ReadBlock2();
HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize); Byte ReadByte();
bool ReadBytesAndTestSize(void *data, UINT32 size); UInt16 ReadUInt16();
void SafeReadBytes(void *data, UINT32 size); UInt32 ReadUInt32();
void IncreasePositionValue(UINT64 addValue); 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(); void ThrowIncorrectArchiveException();
public: public:
HRESULT GetNextItem(bool &filled, CItemEx &item); HRESULT GetNextItem(bool &filled, CItemEx &item);
bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit); bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
void Close(); void Close();
void IncreaseRealPosition(UINT64 addValue); void IncreaseRealPosition(UInt64 addValue);
}; };
}} }}

View File

@@ -1,9 +1,7 @@
// Archive/Arj/ItemInfo.h // Archive/ArjItem.h
#pragma once #ifndef __ARCHIVE_ARJ_ITEM_H
#define __ARCHIVE_ARJ_ITEM_H
#ifndef __ARCHIVE_ARJ_ITEMINFO_H
#define __ARCHIVE_ARJ_ITEMINFO_H
#include "Common/Types.h" #include "Common/Types.h"
#include "Common/String.h" #include "Common/String.h"
@@ -14,8 +12,8 @@ namespace NArj {
struct CVersion struct CVersion
{ {
BYTE Version; Byte Version;
BYTE HostOS; Byte HostOS;
}; };
inline bool operator==(const CVersion &v1, const CVersion &v2) inline bool operator==(const CVersion &v1, const CVersion &v2)
@@ -26,29 +24,29 @@ inline bool operator!=(const CVersion &v1, const CVersion &v2)
class CItem class CItem
{ {
public: public:
BYTE Version; Byte Version;
BYTE ExtractVersion; Byte ExtractVersion;
BYTE HostOS; Byte HostOS;
BYTE Flags; Byte Flags;
BYTE Method; Byte Method;
BYTE FileType; Byte FileType;
UINT32 ModifiedTime; UInt32 ModifiedTime;
UINT32 PackSize; UInt32 PackSize;
UINT32 Size; UInt32 Size;
UINT32 FileCRC; UInt32 FileCRC;
// UINT16 FilespecPositionInFilename; // UInt16 FilespecPositionInFilename;
UINT16 FileAccessMode; UInt16 FileAccessMode;
// BYTE FirstChapter; // Byte FirstChapter;
// BYTE LastChapter; // Byte LastChapter;
AString Name; AString Name;
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; } bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); } bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); }
UINT32 GetWinAttributes() const UInt32 GetWinAttributes() const
{ {
DWORD winAtrributes; UInt32 winAtrributes;
switch(HostOS) switch(HostOS)
{ {
case NFileHeader::NHostOS::kMSDOS: case NFileHeader::NHostOS::kMSDOS:
@@ -67,7 +65,7 @@ public:
class CItemEx: public CItem class CItemEx: public CItem
{ {
public: public:
UINT64 DataPosition; UInt64 DataPosition;
}; };
}} }}

View File

@@ -2,16 +2,15 @@
#include "StdAfx.h" #include "StdAfx.h"
#include <initguid.h> #include "Common/MyInitGuid.h"
#include "Common/ComTry.h" #include "Common/ComTry.h"
#include "Windows/PropVariant.h" #include "Windows/PropVariant.h"
#include "../../ICoder.h" #include "../../ICoder.h"
#include "ArjHandler.h" #include "ArjHandler.h"
// {23170F69-40C1-278A-1000-0001100A0000} // {23170F69-40C1-278A-1000-000110040000}
DEFINE_GUID(CLSID_CArjHandler, DEFINE_GUID(CLSID_CArjHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0A, 0x00, 0x00); 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00);
extern "C" extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
@@ -63,6 +62,13 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
case NArchive::kKeepName: case NArchive::kKeepName:
propVariant = false; propVariant = false;
break; 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); propVariant.Detach(value);
return S_OK; return S_OK;

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp // StdAfx.cpp
#include "stdafx.h" #include "StdAfx.h"

View File

@@ -1,9 +1,8 @@
// stdafx.h // StdAfx.h
#ifndef __STDAFX_H #ifndef __STDAFX_H
#define __STDAFX_H #define __STDAFX_H
#include <windows.h> #include "../../../Common/MyWindows.h"
#include <limits.h>
#endif #endif

66
7zip/Archive/Arj/makefile Executable file
View File

@@ -0,0 +1,66 @@
PROG = arj.dll
DEF_FILE = ../Archive.def
CFLAGS = $(CFLAGS) -I ../../../
LIBS = $(LIBS) oleaut32.lib user32.lib
ARJ_OBJS = \
$O\DllExports.obj \
$O\ArjHandler.obj \
$O\ArjIn.obj \
COMMON_OBJS = \
$O\Alloc.obj \
$O\CRC.obj \
$O\NewHandler.obj \
$O\String.obj \
$O\StringConvert.obj \
$O\Vector.obj \
WIN_OBJS = \
$O\PropVariant.obj \
7ZIP_COMMON_OBJS = \
$O\InBuffer.obj \
$O\LimitedStreams.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
$O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \
COMPRESS_ARJ_OBJS = \
$O\ArjDecoder1.obj \
$O\ArjDecoder2.obj \
OBJS = \
$O\StdAfx.obj \
$(ARJ_OBJS) \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(AR_COMMON_OBJS) \
$(COMPRESS_ARJ_OBJS) \
$O\CopyCoder.obj \
$O\LZOutWindow.obj \
$O\resource.res
!include "../../../Build.mak"
$(ARJ_OBJS): $(*B).cpp
$(COMPL)
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
$(WIN_OBJS): ../../../Windows/$(*B).cpp
$(COMPL)
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL)
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
$(COMPL)
$(COMPRESS_ARJ_OBJS): ../../Compress/Arj/$(*B).cpp
$(COMPL)
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
$(COMPL)
$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
$(COMPL)

View File

@@ -1,16 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by resource.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -1,130 +1,5 @@
//Microsoft Developer Studio generated resource script. #include "../../MyVersionInfo.rc"
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS MY_VERSION_INFO_DLL("Arj Plugin", "arj")
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Russian resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Russian resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "arj.ico"
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,9,2,0
PRODUCTVERSION 3,9,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "Arj Plugin for 7-Zip\0"
VALUE "FileVersion", "3, 9, 2, 0\0"
VALUE "InternalName", "arj\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2003 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 "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
101 ICON "arj.ico"

View File

@@ -1,8 +0,0 @@
; BZip2.def
LIBRARY bz2.dll
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE

View File

@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1 # PROP Ignore_Export_Lib 1
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /c # ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD BASE RSC /l 0x419 /d "NDEBUG"
@@ -70,7 +70,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 1 # PROP Ignore_Export_Lib 1
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c # ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD BASE RSC /l 0x419 /d "_DEBUG"
@@ -93,7 +93,7 @@ LINK32=link.exe
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=.\BZip2.def SOURCE=..\Archive.def
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -105,10 +105,6 @@ SOURCE=.\DllExports.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=.\resource.rc SOURCE=.\resource.rc
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -126,6 +122,14 @@ SOURCE=.\StdAfx.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\Alloc.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.cpp SOURCE=..\..\..\Common\NewHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -134,12 +138,28 @@ SOURCE=..\..\..\Common\NewHandler.h
# End Source File # End Source File
# Begin 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 SOURCE=..\..\..\Common\StringConvert.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\StringConvert.h SOURCE=..\..\..\Common\StringConvert.h
# End Source File # 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 # End Group
# Begin Group "Windows" # Begin Group "Windows"
@@ -186,12 +206,24 @@ SOURCE=..\Common\CodecsPath.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\Common\CoderLoader.h
# End Source File
# Begin Source File
SOURCE=..\Common\DummyOutStream.cpp SOURCE=..\Common\DummyOutStream.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\Common\DummyOutStream.h SOURCE=..\Common\DummyOutStream.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\Common\ParseProperties.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\ParseProperties.h
# End Source File
# End Group # End Group
# Begin Group "Engine" # Begin Group "Engine"
@@ -232,6 +264,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.h SOURCE=..\..\Common\ProgressUtils.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.h
# End Source File
# End Group # End Group
# Begin Source File # Begin Source File

View File

@@ -7,7 +7,7 @@
#include "Common/Defs.h" #include "Common/Defs.h"
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
// #include "Interface/EnumStatProp.h" #include "../../Common/StreamUtils.h"
#include "Windows/PropVariant.h" #include "Windows/PropVariant.h"
#include "Windows/Defs.h" #include "Windows/Defs.h"
@@ -44,13 +44,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties) STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
{ {
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]); *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index, STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType) BSTR *name, PROPID *propID, VARTYPE *varType)
{ {
if(index >= sizeof(kProperties) / sizeof(kProperties[0])) if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
@@ -62,25 +62,25 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties) STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{ {
*numProperties = 0; *numProperties = 0;
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index, STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType) BSTR *name, PROPID *propID, VARTYPE *varType)
{ {
return E_INVALIDARG; return E_INVALIDARG;
} }
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
*numItems = 1; *numItems = 1;
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant propVariant;
@@ -101,7 +101,7 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *va
} }
STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream,
const UINT64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback *openArchiveCallback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
@@ -109,15 +109,15 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
{ {
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition));
const int kSignatureSize = 3; const int kSignatureSize = 3;
BYTE buffer[kSignatureSize]; Byte buffer[kSignatureSize];
UINT32 processedSize; UInt32 processedSize;
RINOK(stream->Read(buffer, kSignatureSize, &processedSize)); RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize));
if (processedSize != kSignatureSize) if (processedSize != kSignatureSize)
return S_FALSE; return S_FALSE;
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
return S_FALSE; return S_FALSE;
UINT64 endPosition; UInt64 endPosition;
RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition)); RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition));
_item.PackSize = endPosition - _streamStartPosition; _item.PackSize = endPosition - _streamStartPosition;
@@ -138,11 +138,11 @@ STDMETHODIMP CHandler::Close()
} }
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems, STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
INT32 testModeSpec, IArchiveExtractCallback *extractCallback) Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
bool allFilesMode = (numItems == UINT32(-1)); bool allFilesMode = (numItems == UInt32(-1));
if (!allFilesMode) if (!allFilesMode)
{ {
if (numItems == 0) if (numItems == 0)
@@ -157,12 +157,12 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
extractCallback->SetTotal(_item.PackSize); extractCallback->SetTotal(_item.PackSize);
UINT64 currentTotalPacked = 0; UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalPacked)); RINOK(extractCallback->SetCompleted(&currentTotalPacked));
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
INT32 askMode; Int32 askMode;
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
@@ -171,8 +171,37 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
if(!testMode && !realOutStream) if(!testMode && !realOutStream)
return S_OK; return S_OK;
extractCallback->PrepareOperation(askMode); 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
#ifdef COMPRESS_MT
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(_numThreads));
}
}
#endif
CDummyOutStream *outStreamSpec = new CDummyOutStream; CDummyOutStream *outStreamSpec = new CDummyOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream); outStreamSpec->Init(realOutStream);
@@ -182,31 +211,72 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, true); localProgressSpec->Init(extractCallback, true);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); 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,
&currentTotalPacked,
&currentTotalUnPacked);
const int kSignatureSize = 3;
Byte buffer[kSignatureSize];
UInt32 processedSize;
RINOK(ReadStream(_stream, buffer, kSignatureSize, &processedSize));
if (processedSize < kSignatureSize)
{
if (firstItem)
return E_FAIL;
break;
}
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
{
if (firstItem)
return E_FAIL;
outStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
return S_OK;
}
firstItem = false;
UInt64 dataStartPos;
RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos));
result = decoder->Code(_stream, outStream, NULL, NULL, compressProgress);
if (result != S_OK)
break;
CMyComPtr<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(); outStream.Release();
if (result == S_FALSE)
RINOK(extractCallback->SetOperationResult( int retResult;
NArchive::NExtract::NOperationResult::kDataError)) if (result == S_OK)
else if (result == S_OK) retResult = NArchive::NExtract::NOperationResult::kOK;
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kOK))
else else
return result; retResult = NArchive::NExtract::NOperationResult::kDataError;
RINOK(extractCallback->SetOperationResult(retResult));
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END

View File

@@ -1,7 +1,5 @@
// BZip2/Handler.h // BZip2/Handler.h
#pragma once
#ifndef __BZIP2_HANDLER_H #ifndef __BZIP2_HANDLER_H
#define __BZIP2_HANDLER_H #define __BZIP2_HANDLER_H
@@ -9,51 +7,75 @@
#include "../IArchive.h" #include "../IArchive.h"
#include "BZip2Item.h" #include "BZip2Item.h"
#ifdef COMPRESS_MT
#include "../../../Windows/System.h"
#endif
namespace NArchive { namespace NArchive {
namespace NBZip2 { namespace NBZip2 {
class CHandler: class CHandler:
public IInArchive, public IInArchive,
public IOutArchive, public IOutArchive,
public ISetProperties,
public CMyUnknownImp public CMyUnknownImp
{ {
CMyComPtr<IInStream> _stream;
NArchive::NBZip2::CItem _item;
UInt64 _streamStartPosition;
UInt32 _level;
UInt32 _dicSize;
UInt32 _numPasses;
#ifdef COMPRESS_MT
UInt32 _numThreads;
#endif
void InitMethodProperties()
{
_level = 5;
_dicSize =
_numPasses = 0xFFFFFFFF;
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
#endif
}
public: public:
MY_UNKNOWN_IMP2( MY_UNKNOWN_IMP3(
IInArchive, IInArchive,
IOutArchive IOutArchive,
ISetProperties
) )
STDMETHOD(Open)(IInStream *stream, STDMETHOD(Open)(IInStream *stream,
const UINT64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback); IArchiveOpenCallback *openArchiveCallback);
STDMETHOD(Close)(); STDMETHOD(Close)();
STDMETHOD(GetNumberOfItems)(UINT32 *numItems); STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
INT32 testMode, IArchiveExtractCallback *extractCallback); Int32 testMode, IArchiveExtractCallback *extractCallback);
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
STDMETHOD(GetPropertyInfo)(UINT32 index, STDMETHOD(GetPropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType); BSTR *name, PROPID *propID, VARTYPE *varType);
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
STDMETHOD(GetArchivePropertyInfo)(UINT32 index, STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType); BSTR *name, PROPID *propID, VARTYPE *varType);
// IOutArchiveHandler // IOutArchiveHandler
STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems, STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback); IArchiveUpdateCallback *updateCallback);
STDMETHOD(GetFileTimeType)(UInt32 *type);
STDMETHOD(GetFileTimeType)(UINT32 *type); // ISetProperties
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
private: CHandler() { InitMethodProperties(); }
CMyComPtr<IInStream> _stream;
NArchive::NBZip2::CItem _item;
UINT64 _streamStartPosition;
}; };
}} }}

View File

@@ -1,45 +1,54 @@
// BZip2/OutHandler.cpp // BZip2HandlerOut.cpp
#include "StdAfx.h" #include "StdAfx.h"
#include "BZip2Handler.h" #include "BZip2Handler.h"
#include "BZip2Update.h" #include "BZip2Update.h"
#include "Windows/FileFind.h" #include "Common/Defs.h"
#include "Windows/Defs.h" #include "Common/String.h"
#include "Windows/PropVariant.h" #include "Windows/PropVariant.h"
#include "../../Compress/Copy/CopyCoder.h" #include "../../Compress/Copy/CopyCoder.h"
#include "../Common/ParseProperties.h"
using namespace NWindows; using namespace NWindows;
static const int kNumItemInArchive = 1; static const UInt32 kNumPassesX1 = 1;
static const UInt32 kNumPassesX7 = 2;
static const UInt32 kNumPassesX9 = 7;
static const UInt32 kDicSizeX1 = 100000;
static const UInt32 kDicSizeX3 = 500000;
static const UInt32 kDicSizeX5 = 900000;
namespace NArchive { namespace NArchive {
namespace NBZip2 { namespace NBZip2 {
STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type) STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{ {
*type = NFileTimeType::kUnix; *type = NFileTimeType::kUnix;
return S_OK; return S_OK;
} }
static HRESULT CopyStreams(IInStream *inStream, IOutStream *outStream, static HRESULT CopyStreams(ISequentialInStream *inStream,
IArchiveUpdateCallback *updateCallback) ISequentialOutStream *outStream, IArchiveUpdateCallback *updateCallback)
{ {
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
} }
STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems, STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback) IArchiveUpdateCallback *updateCallback)
{ {
if (numItems != 1) if (numItems != 1)
return E_INVALIDARG; return E_INVALIDARG;
INT32 newData; Int32 newData;
INT32 newProperties; Int32 newProperties;
UINT32 indexInArchive; UInt32 indexInArchive;
if (!updateCallback) if (!updateCallback)
return E_FAIL; return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0, RINOK(updateCallback->GetUpdateItemInfo(0,
@@ -47,17 +56,6 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
if (IntToBool(newProperties)) 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; NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant)); RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant));
@@ -73,15 +71,32 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
if (IntToBool(newData)) if (IntToBool(newData))
{ {
UINT64 size; UInt64 size;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant)); RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant));
if (propVariant.vt != VT_UI8) if (propVariant.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = *(UINT64 *)(&propVariant.uhVal); size = propVariant.uhVal.QuadPart;
} }
return UpdateArchive(size, outStream, 0, updateCallback);
UInt32 dicSize = _dicSize;
if (dicSize == 0xFFFFFFFF)
dicSize = (_level >= 5 ? kDicSizeX5 :
(_level >= 3 ? kDicSizeX3 :
kDicSizeX1));
UInt32 numPasses = _numPasses;
if (numPasses == 0xFFFFFFFF)
numPasses = (_level >= 9 ? kNumPassesX9 :
(_level >= 7 ? kNumPassesX7 :
kNumPassesX1));
return UpdateArchive(size, outStream, 0, dicSize, numPasses,
#ifdef COMPRESS_MT
_numThreads,
#endif
updateCallback);
} }
if (indexInArchive != 0) if (indexInArchive != 0)
return E_INVALIDARG; return E_INVALIDARG;
@@ -89,4 +104,54 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
return CopyStreams(_stream, outStream, updateCallback); return CopyStreams(_stream, outStream, updateCallback);
} }
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{
InitMethodProperties();
#ifdef COMPRESS_MT
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
#endif
for (int i = 0; i < numProperties; i++)
{
UString name = UString(names[i]);
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &prop = values[i];
if (name[0] == 'X')
{
UInt32 level = 9;
RINOK(ParsePropValue(name.Mid(1), prop, level));
_level = level;
continue;
}
if (name[0] == 'D')
{
UInt32 dicSize = kDicSizeX5;
RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
_dicSize = dicSize;
continue;
}
if (name.Left(4) == L"PASS")
{
UInt32 num = kNumPassesX9;
RINOK(ParsePropValue(name.Mid(4), prop, num));
_numPasses = num;
continue;
}
if (name.Left(2) == L"MT")
{
#ifdef COMPRESS_MT
RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
#endif
continue;
}
return E_INVALIDARG;
}
return S_OK;
}
}} }}

View File

@@ -1,7 +1,5 @@
// Archive/BZip2Item.h // Archive/BZip2Item.h
#pragma once
#ifndef __ARCHIVE_BZIP2_ITEM_H #ifndef __ARCHIVE_BZIP2_ITEM_H
#define __ARCHIVE_BZIP2_ITEM_H #define __ARCHIVE_BZIP2_ITEM_H
@@ -10,8 +8,8 @@ namespace NBZip2 {
struct CItem struct CItem
{ {
UINT64 PackSize; UInt64 PackSize;
UINT64 UnPackSize; UInt64 UnPackSize;
}; };
}} }}

View File

@@ -2,9 +2,8 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "Common/Defs.h"
#include "Windows/Defs.h"
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
#include "Windows/PropVariant.h"
#include "BZip2Update.h" #include "BZip2Update.h"
@@ -21,17 +20,21 @@ extern CSysString GetBZip2CodecPath();
namespace NArchive { namespace NArchive {
namespace NBZip2 { namespace NBZip2 {
HRESULT UpdateArchive(UINT64 unpackSize, HRESULT UpdateArchive(UInt64 unpackSize,
IOutStream *outStream, ISequentialOutStream *outStream,
int indexInClient, int indexInClient,
UInt32 dictionary,
UInt32 numPasses,
#ifdef COMPRESS_MT
UInt32 numThreads,
#endif
IArchiveUpdateCallback *updateCallback) IArchiveUpdateCallback *updateCallback)
{ {
RINOK(updateCallback->SetTotal(unpackSize)); RINOK(updateCallback->SetTotal(unpackSize));
UInt64 complexity = 0;
UINT64 complexity = 0;
RINOK(updateCallback->SetCompleted(&complexity)); RINOK(updateCallback->SetCompleted(&complexity));
CMyComPtr<IInStream> fileInStream; CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(indexInClient, &fileInStream)); RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
@@ -49,6 +52,29 @@ HRESULT UpdateArchive(UINT64 unpackSize,
RINOK(lib.LoadAndCreateCoder(GetBZip2CodecPath(), RINOK(lib.LoadAndCreateCoder(GetBZip2CodecPath(),
CLSID_CCompressBZip2Encoder, &encoder)); CLSID_CCompressBZip2Encoder, &encoder));
#endif #endif
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
if (setCoderProperties)
{
NWindows::NCOM::CPropVariant properties[] =
{
dictionary,
numPasses
#ifdef COMPRESS_MT
, numThreads
#endif
};
PROPID propIDs[] =
{
NCoderPropID::kDictionarySize,
NCoderPropID::kNumPasses
#ifdef COMPRESS_MT
, NCoderPropID::kNumThreads
#endif
};
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
}
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress)); RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));

View File

@@ -1,21 +1,22 @@
// BZip2Update.h // BZip2Update.h
#pragma once
#ifndef __BZIP2_UPDATE_H #ifndef __BZIP2_UPDATE_H
#define __BZIP2_UPDATE_H #define __BZIP2_UPDATE_H
#include "Common/Types.h"
#include "../IArchive.h" #include "../IArchive.h"
namespace NArchive { namespace NArchive {
namespace NBZip2 { namespace NBZip2 {
HRESULT UpdateArchive( HRESULT UpdateArchive(
UINT64 unpackSize, UInt64 unpackSize,
IOutStream *outStream, ISequentialOutStream *outStream,
int indexInClient, int indexInClient,
UInt32 dictionary,
UInt32 numPasses,
#ifdef COMPRESS_MT
UInt32 numThreads,
#endif
IArchiveUpdateCallback *updateCallback); IArchiveUpdateCallback *updateCallback);
}} }}

View File

@@ -2,10 +2,8 @@
#include "StdAfx.h" #include "StdAfx.h"
#define INITGUID #include "Common/MyInitGuid.h"
#include "Common/ComTry.h" #include "Common/ComTry.h"
#include "Common/String.h"
#include "Windows/PropVariant.h" #include "Windows/PropVariant.h"
#include "BZip2Handler.h" #include "BZip2Handler.h"
#include "../../ICoder.h" #include "../../ICoder.h"
@@ -18,11 +16,22 @@ DEFINE_GUID(CLSID_CCompressBZip2Encoder,
DEFINE_GUID(CLSID_CCompressBZip2Decoder, DEFINE_GUID(CLSID_CCompressBZip2Decoder,
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); 0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
// {23170F69-40C1-278A-1000-000110070000} // {23170F69-40C1-278A-1000-000110020000}
DEFINE_GUID(CLSID_CBZip2Handler, DEFINE_GUID(CLSID_CBZip2Handler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
HINSTANCE g_hInstance; HINSTANCE g_hInstance;
#ifndef _UNICODE
bool g_IsNT = false;
static bool IsItWindowsNT()
{
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!::GetVersionEx(&versionInfo))
return false;
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
#endif
#ifndef COMPRESS_BZIP2 #ifndef COMPRESS_BZIP2
#include "../Common/CodecsPath.h" #include "../Common/CodecsPath.h"
@@ -36,7 +45,12 @@ extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{ {
if (dwReason == DLL_PROCESS_ATTACH) if (dwReason == DLL_PROCESS_ATTACH)
{
g_hInstance = hInstance; g_hInstance = hInstance;
#ifndef _UNICODE
g_IsNT = IsItWindowsNT();
#endif
}
return TRUE; return TRUE;
} }
@@ -88,10 +102,10 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
return S_OK; return S_OK;
} }
case NArchive::kExtension: case NArchive::kExtension:
propVariant = L"bz2 tbz2"; propVariant = L"bz2 bzip2 tbz2 tbz";
break; break;
case NArchive::kAddExtension: case NArchive::kAddExtension:
propVariant = L"* .tar"; propVariant = L"* * .tar .tar";
break; break;
case NArchive::kUpdate: case NArchive::kUpdate:
propVariant = true; propVariant = true;
@@ -99,6 +113,14 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
case NArchive::kKeepName: case NArchive::kKeepName:
propVariant = true; propVariant = true;
break; 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); propVariant.Detach(value);
return S_OK; return S_OK;

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp // StdAfx.cpp
#include "stdafx.h" #include "StdAfx.h"

View File

@@ -1,8 +1,8 @@
// stdafx.h // StdAfx.h
#ifndef __STDAFX_H #ifndef __STDAFX_H
#define __STDAFX_H #define __STDAFX_H
#include <windows.h> #include "../../../Common/MyWindows.h"
#endif #endif

55
7zip/Archive/BZip2/makefile Executable file
View File

@@ -0,0 +1,55 @@
PROG = bz2.dll
DEF_FILE = ../Archive.def
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
LIBS = $(LIBS) oleaut32.lib user32.lib
BZ2_OBJS = \
$O\BZip2Handler.obj \
$O\BZip2HandlerOut.obj \
$O\BZip2Update.obj \
$O\DllExports.obj \
COMMON_OBJS = \
$O\Alloc.obj \
$O\NewHandler.obj \
$O\String.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
WIN_OBJS = \
$O\DLL.obj \
$O\PropVariant.obj \
7ZIP_COMMON_OBJS = \
$O\ProgressUtils.obj \
$O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CodecsPath.obj \
$O\DummyOutStream.obj \
$O\ParseProperties.obj \
OBJS = \
$O\StdAfx.obj \
$(BZ2_OBJS) \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(AR_COMMON_OBJS) \
$O\CopyCoder.obj \
$O\resource.res
!include "../../../Build.mak"
$(BZ2_OBJS): $(*B).cpp
$(COMPL)
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
$(WIN_OBJS): ../../../Windows/$(*B).cpp
$(COMPL)
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL)
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
$(COMPL)
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
$(COMPL)

View File

@@ -1,16 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by resource.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -1,130 +1,5 @@
//Microsoft Developer Studio generated resource script. #include "../../MyVersionInfo.rc"
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS MY_VERSION_INFO_DLL("BZip2 Plugin", "bz2")
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Russian resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Russian resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "bz2.ico"
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,12,0,0
PRODUCTVERSION 3,12,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "BZip2 Plugin for 7-Zip\0"
VALUE "FileVersion", "3, 12, 0, 0\0"
VALUE "InternalName", "bz2\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "bz.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "3, 12, 0, 0\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
101 ICON "bz2.ico"

View File

@@ -1,7 +0,0 @@
; Cab.def
LIBRARY cab.dll
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE

View File

@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1 # PROP Ignore_Export_Lib 1
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /c
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /c # ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAs /Yu"StdAfx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD BASE RSC /l 0x419 /d "NDEBUG"
@@ -70,7 +70,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 1 # PROP Ignore_Export_Lib 1
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /GZ /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c # ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAcs /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD BASE RSC /l 0x419 /d "_DEBUG"
@@ -93,7 +93,7 @@ LINK32=link.exe
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=.\Cab.def SOURCE=..\Archive.def
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -101,10 +101,6 @@ SOURCE=.\DllExports.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=.\resource.rc SOURCE=.\resource.rc
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -122,6 +118,22 @@ SOURCE=.\StdAfx.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\Alloc.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.cpp SOURCE=..\..\..\Common\NewHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -178,11 +190,11 @@ SOURCE=..\..\..\Windows\PropVariant.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=.\CabCopyDecoder.cpp SOURCE=.\CabBlockInStream.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\CabCopyDecoder.h SOURCE=.\CabBlockInStream.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -210,60 +222,8 @@ SOURCE=.\CabIn.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\CabInBuffer.cpp
# End Source File
# Begin Source File
SOURCE=.\CabInBuffer.h
# End Source File
# Begin Source File
SOURCE=.\CabItem.h SOURCE=.\CabItem.h
# End Source File # End Source File
# Begin Source File
SOURCE=.\LZXBitDecoder.h
# End Source File
# Begin Source File
SOURCE=.\LZXConst.h
# End Source File
# Begin Source File
SOURCE=.\LZXDecoder.cpp
# End Source File
# Begin Source File
SOURCE=.\LZXDecoder.h
# End Source File
# Begin Source File
SOURCE=.\LZXExtConst.h
# End Source File
# Begin Source File
SOURCE=.\LZXi86Converter.cpp
# End Source File
# Begin Source File
SOURCE=.\LZXi86Converter.h
# End Source File
# Begin Source File
SOURCE=.\MSZipConst.h
# End Source File
# Begin Source File
SOURCE=.\MSZipDecoder.cpp
# End Source File
# Begin Source File
SOURCE=.\MSZipDecoder.h
# End Source File
# Begin Source File
SOURCE=.\MSZipExtConst.h
# End Source File
# End Group # End Group
# Begin Group "7zip Common" # Begin Group "7zip Common"
@@ -286,6 +246,10 @@ SOURCE=..\..\Common\LSBFDecoder.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\MSBFDecoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\OutBuffer.cpp SOURCE=..\..\Common\OutBuffer.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -294,11 +258,11 @@ SOURCE=..\..\Common\OutBuffer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\StreamUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\ProgressUtils.h SOURCE=..\..\Common\StreamUtils.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Compress" # Begin Group "Compress"
@@ -316,6 +280,112 @@ SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
SOURCE=..\..\Compress\LZ\LZOutWindow.h SOURCE=..\..\Compress\LZ\LZOutWindow.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Lzx"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\Lzx\Lzx.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp
!IF "$(CFG)" == "Cab - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Lzx\Lzx86Converter.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp
!IF "$(CFG)" == "Cab - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Lzx\LzxDecoder.h
# End Source File
# End Group
# Begin Group "Deflate"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\Deflate\DeflateConst.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp
!IF "$(CFG)" == "Cab - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Deflate\DeflateDecoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Deflate\DeflateExtConst.h
# End Source File
# End Group
# Begin Group "Copy"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Copy\CopyCoder.h
# End Source File
# End Group
# Begin Group "Quantum"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\Quantum\QuantumDecoder.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Quantum\QuantumDecoder.h
# End Source File
# End Group
# Begin Group "Huffman"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h
# End Source File
# End Group
# End Group # End Group
# Begin Source File # Begin Source File

View File

@@ -0,0 +1,194 @@
// CabBlockInStream.cpp
#include "StdAfx.h"
#include "Common/Alloc.h"
#include "Common/Defs.h"
#include "../../Common/StreamUtils.h"
#include "CabBlockInStream.h"
namespace NArchive {
namespace NCab {
static const UInt32 kBlockSize = (1 << 16);
bool CCabBlockInStream::Create()
{
if (!_buffer)
_buffer = (Byte *)::MyAlloc(kBlockSize);
return (_buffer != 0);
}
CCabBlockInStream::~CCabBlockInStream()
{
MyFree(_buffer);
}
class CCheckSum2
{
UInt32 m_Value;
int m_Pos;
Byte m_Hist[4];
public:
CCheckSum2(): m_Value(0){};
void Init() { m_Value = 0; m_Pos = 0; }
void Update(const void *data, UInt32 size);
void FinishDataUpdate()
{
for (int i = 0; i < m_Pos; i++)
m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1));
}
void UpdateUInt32(UInt32 v) { m_Value ^= v; }
UInt32 GetResult() const { return m_Value; }
};
void CCheckSum2::Update(const void *data, UInt32 size)
{
UInt32 checkSum = m_Value;
const Byte *dataPointer = (const Byte *)data;
while (size != 0 && m_Pos != 0)
{
m_Hist[m_Pos] = *dataPointer++;
m_Pos = (m_Pos + 1) & 3;
size--;
if (m_Pos == 0)
for (int i = 0; i < 4; i++)
checkSum ^= ((UInt32)m_Hist[i]) << (8 * i);
}
int numWords = size / 4;
while (numWords-- != 0)
{
UInt32 temp = *dataPointer++;
temp |= ((UInt32)(*dataPointer++)) << 8;
temp |= ((UInt32)(*dataPointer++)) << 16;
temp |= ((UInt32)(*dataPointer++)) << 24;
checkSum ^= temp;
}
m_Value = checkSum;
size &= 3;
while (size != 0)
{
m_Hist[m_Pos] = *dataPointer++;
m_Pos = (m_Pos + 1) & 3;
size--;
}
}
static const UInt32 kDataBlockHeaderSize = 8;
class CTempCabInBuffer2
{
public:
Byte Buffer[kDataBlockHeaderSize];
UInt32 Pos;
Byte ReadByte()
{
return Buffer[Pos++];
}
UInt32 ReadUInt32()
{
UInt32 value = 0;
for (int i = 0; i < 4; i++)
value |= (((UInt32)ReadByte()) << (8 * i));
return value;
}
UInt16 ReadUInt16()
{
UInt16 value = 0;
for (int i = 0; i < 2; i++)
value |= (((UInt16)ReadByte()) << (8 * i));
return value;
}
};
HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize)
{
CTempCabInBuffer2 inBuffer;
inBuffer.Pos = 0;
UInt32 processedSizeLoc;
RINOK(ReadStream(_stream, inBuffer.Buffer, kDataBlockHeaderSize, &processedSizeLoc))
if (processedSizeLoc != kDataBlockHeaderSize)
return S_FALSE; // bad block
UInt32 checkSum = inBuffer.ReadUInt32();
packSize = inBuffer.ReadUInt16();
unpackSize = inBuffer.ReadUInt16();
if (ReservedSize != 0)
{
RINOK(ReadStream(_stream, _buffer, ReservedSize, &processedSizeLoc));
if(ReservedSize != processedSizeLoc)
return S_FALSE; // bad block;
}
_pos = 0;
CCheckSum2 checkSumCalc;
checkSumCalc.Init();
UInt32 packSize2 = packSize;
if (MsZip && _size == 0)
{
if (packSize < 2)
return S_FALSE; // bad block;
Byte sig[2];
RINOK(ReadStream(_stream, sig, 2, &processedSizeLoc));
if(processedSizeLoc != 2)
return S_FALSE;
if (sig[0] != 0x43 || sig[1] != 0x4B)
return S_FALSE;
packSize2 -= 2;
checkSumCalc.Update(sig, 2);
}
if (kBlockSize - _size < packSize2)
return S_FALSE;
UInt32 curSize = packSize2;
if (curSize != 0)
{
RINOK(ReadStream(_stream, _buffer + _size, curSize, &processedSizeLoc));
checkSumCalc.Update(_buffer + _size, processedSizeLoc);
_size += processedSizeLoc;
if (processedSizeLoc != curSize)
return S_FALSE;
}
TotalPackSize = _size;
checkSumCalc.FinishDataUpdate();
bool dataError;
if (checkSum == 0)
dataError = false;
else
{
checkSumCalc.UpdateUInt32(packSize | (((UInt32)unpackSize) << 16));
dataError = (checkSumCalc.GetResult() != checkSum);
}
DataError |= dataError;
return dataError ? S_FALSE : S_OK;
}
STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize != 0)
*processedSize = 0;
if (size == 0)
return S_OK;
if (_size != 0)
{
size = MyMin(_size, size);
memmove(data, _buffer + _pos, size);
_pos += size;
_size -= size;
if (processedSize != 0)
*processedSize = size;
return S_OK;
}
return S_OK; // no blocks data
}
}}

View File

@@ -0,0 +1,56 @@
// CabBlockInStream.cpp
#ifndef __CABBLOCKINSTREAM_H
#define __CABBLOCKINSTREAM_H
#include "Common/MyCom.h"
#include "../../IStream.h"
namespace NArchive {
namespace NCab {
class CCabBlockInStream:
public ISequentialInStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _stream;
Byte *_buffer;
UInt32 _pos;
UInt32 _size;
int _align;
public:
UInt32 TotalPackSize;
UInt32 ReservedSize;
bool DataError;
bool MsZip;
CCabBlockInStream(): _buffer(0), ReservedSize(0), MsZip(false), DataError(false), _align(0), TotalPackSize(0) {}
~CCabBlockInStream();
bool Create();
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void InitForNewFolder()
{
_align = 0;
TotalPackSize = 0;
}
void InitForNewBlock()
{
_size = 0;
_align = (_align + (int)TotalPackSize) & 1;
}
int GetAlign() const { return _align; }
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
HRESULT PreRead(UInt32 &packSize, UInt32 &unpackSize);
};
}}
#endif

View File

@@ -1,67 +0,0 @@
// CabCopyDecoder.cpp
#include "StdAfx.h"
#include "CabCopyDecoder.h"
#include "Common/Defs.h"
#include "Windows/Defs.h"
namespace NArchive {
namespace NCab {
static const UINT32 kBufferSize = 1 << 17;
/*
void CCopyDecoder::ReleaseStreams()
{
m_InStream.ReleaseStream();
m_OutStream.ReleaseStream();
}
*/
class CCopyDecoderFlusher
{
CCopyDecoder *m_Decoder;
public:
CCopyDecoderFlusher(CCopyDecoder *aDecoder): m_Decoder(aDecoder) {}
~CCopyDecoderFlusher()
{
m_Decoder->Flush();
// m_Decoder->ReleaseStreams();
}
};
STDMETHODIMP CCopyDecoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress)
{
if (outSize == NULL)
return E_INVALIDARG;
UINT64 size = *outSize;
m_InStream.Init(inStream, m_ReservedSize, m_NumInDataBlocks);
m_OutStream.Init(outStream);
CCopyDecoderFlusher decoderFlusher(this);
UINT64 nowPos64 = 0;
while(nowPos64 < size)
{
UINT32 blockSize;
bool dataAreCorrect;
RINOK(m_InStream.ReadBlock(blockSize, dataAreCorrect));
if (!dataAreCorrect)
{
throw 123456;
}
for (UINT32 i = 0; i < blockSize; i++)
m_OutStream.WriteByte(m_InStream.ReadByte());
nowPos64 += blockSize;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
}
}
return S_OK;
}
}}

View File

@@ -1,43 +0,0 @@
// CabCopyDecoder.h
#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"
#include "CabInBuffer.h"
namespace NArchive {
namespace NCab {
class CCopyDecoder:
public ICompressCoder,
public CMyUnknownImp
{
CInBuffer m_InStream;
COutBuffer m_OutStream;
BYTE m_ReservedSize;
UINT32 m_NumInDataBlocks;
public:
MY_UNKNOWN_IMP
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress);
// void ReleaseStreams();
HRESULT Flush() { return m_OutStream.Flush(); }
void SetParams(BYTE reservedSize, UINT32 numInDataBlocks)
{
m_ReservedSize = reservedSize;
m_NumInDataBlocks = numInDataBlocks;
}
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,5 @@
// CabHandler.h // CabHandler.h
#pragma once
#ifndef __CAB_HANDLER_H #ifndef __CAB_HANDLER_H
#define __CAB_HANDLER_H #define __CAB_HANDLER_H
@@ -20,31 +18,28 @@ public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(Open)(IInStream *stream, STDMETHOD(Open)(IInStream *stream,
const UINT64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback); IArchiveOpenCallback *openArchiveCallback);
STDMETHOD(Close)(); STDMETHOD(Close)();
STDMETHOD(GetNumberOfItems)(UINT32 *numItems); STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value); STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
INT32 testMode, IArchiveExtractCallback *extractCallback); Int32 testMode, IArchiveExtractCallback *extractCallback);
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
STDMETHOD(GetPropertyInfo)(UINT32 index, STDMETHOD(GetPropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType); BSTR *name, PROPID *propID, VARTYPE *varType);
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
STDMETHOD(GetArchivePropertyInfo)(UINT32 index, STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType); BSTR *name, PROPID *propID, VARTYPE *varType);
private: private:
CObjectVector<NHeader::CFolder> m_Folders; CMvDatabaseEx m_Database;
CObjectVector<CItem> m_Files;
CInArchiveInfo m_ArchiveInfo;
CMyComPtr<IInStream> m_Stream;
}; };
}} }}
#endif #endif

View File

@@ -10,10 +10,10 @@ namespace NHeader{
namespace NArchive { namespace NArchive {
UINT32 kSignature = 0x4643534d + 1; UInt32 kSignature = 0x4643534d + 1;
static class CSignatureInitializer static class CSignatureInitializer
{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer; { public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer;
} }
}}} }}}

View File

@@ -1,81 +1,33 @@
// Archive/Cab/Header.h // Archive/Cab/Header.h
#pragma once
#ifndef __ARCHIVE_CAB_HEADER_H #ifndef __ARCHIVE_CAB_HEADER_H
#define __ARCHIVE_CAB_HEADER_H #define __ARCHIVE_CAB_HEADER_H
#include "Common/Types.h" #include "Common/Types.h"
#pragma pack(push, PragmaCabHeaders)
#pragma pack(push, 1)
namespace NArchive { namespace NArchive {
namespace NCab { namespace NCab {
namespace NHeader{ namespace NHeader{
namespace NArchive { namespace NArchive
{
extern UINT32 kSignature; extern UInt32 kSignature;
namespace NFlags namespace NFlags
{ {
const int kPrevCabinet = 0x0001; const int kPrevCabinet = 0x0001;
const int kNextCabinet = 0x0002; const int kNextCabinet = 0x0002;
const int kReservePresent = 0x0004; const int kReservePresent = 0x0004;
} }
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 */
};
struct CPerDataSizes
{
UINT16 PerCabinetAreaSize; /* (optional) size of per-cabinet reserved area */
BYTE PerFolderAreaSize; /* (optional) size of per-folder reserved area */
BYTE PerDatablockAreaSize; /* (optional) size of per-datablock reserved area */
};
/*
BYTE abReserve[]; // (optional) per-cabinet reserved area
BYTE szCabinetPrev[]; // (optional) name of previous cabinet file
BYTE szDiskPrev[]; // (optional) name of previous disk
BYTE szCabinetNext[]; // (optional) name of next cabinet file
BYTE szDiskNext[]; // (optional) name of next disk
*/
} }
namespace NCompressionMethodMajor namespace NCompressionMethodMajor
{ {
const BYTE kNone = 0; const Byte kNone = 0;
const BYTE kMSZip = 1; const Byte kMSZip = 1;
const BYTE kQuantum = 2; const Byte kQuantum = 2;
const BYTE kLZX = 3; const Byte kLZX = 3;
} }
struct CFolder
{
UINT32 DataStart; // offset of the first CFDATA block in this folder
UINT16 NumDataBlocks; // number of CFDATA blocks in this folder
BYTE CompressionTypeMajor;
BYTE CompressionTypeMinor;
// BYTE abReserve[]; // (optional) per-folder reserved area
BYTE GetCompressionMethod() const { return CompressionTypeMajor & 0xF; }
};
const int kFileNameIsUTFAttributeMask = 0x80; const int kFileNameIsUTFAttributeMask = 0x80;
namespace NFolderIndex namespace NFolderIndex
@@ -83,35 +35,8 @@ namespace NFolderIndex
const int kContinuedFromPrev = 0xFFFD; const int kContinuedFromPrev = 0xFFFD;
const int kContinuedToNext = 0xFFFE; const int kContinuedToNext = 0xFFFE;
const int kContinuedPrevAndNext = 0xFFFF; const int kContinuedPrevAndNext = 0xFFFF;
inline UINT16 GetRealFolderIndex(UINT16 aNumFolders, UINT16 aFolderIndex)
{
switch(aFolderIndex)
{
case kContinuedFromPrev:
return 0;
case kContinuedToNext:
case kContinuedPrevAndNext:
return aNumFolders - 1;
default:
return aFolderIndex;
}
}
} }
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 */
};
}}} }}}
#pragma pack(pop)
#pragma pack(pop, PragmaCabHeaders)
#endif #endif

View File

@@ -6,76 +6,114 @@
#include "Common/MyCom.h" #include "Common/MyCom.h"
#include "CabIn.h" #include "CabIn.h"
#include "Windows/Defs.h" #include "Windows/Defs.h"
#include "../../Common/InBuffer.h"
#include "../../Common/StreamUtils.h"
namespace NArchive{ namespace NArchive{
namespace NCab{ namespace NCab{
static HRESULT ReadBytes(IInStream *inStream, void *data, UINT32 size) static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
{ {
UINT32 realProcessedSize; UInt32 realProcessedSize;
RINOK(inStream->Read(data, size, &realProcessedSize)); RINOK(ReadStream(inStream, data, size, &realProcessedSize));
if(realProcessedSize != size) if(realProcessedSize != size)
return S_FALSE; return S_FALSE;
return S_OK; return S_OK;
} }
static HRESULT SafeRead(IInStream *inStream, void *data, UINT32 size) static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size)
{ {
UINT32 realProcessedSize; UInt32 realProcessedSize;
RINOK(inStream->Read(data, size, &realProcessedSize)); RINOK(ReadStream(inStream, data, size, &realProcessedSize));
if(realProcessedSize != size) if(realProcessedSize != size)
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
return S_OK; return S_OK;
} }
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); inBuffer.ReadBytes(data, size, realProcessedSize);
if(realProcessedSize != size) if(realProcessedSize != size)
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
} }
static void SafeReadName(CInBuffer &inBuffer, AString &name) Byte CInArchive::ReadByte()
{ {
name.Empty(); Byte b;
if (!inBuffer.ReadByte(b))
throw CInArchiveException(CInArchiveException::kUnsupported);
return b;
}
UInt16 CInArchive::ReadUInt16()
{
UInt16 value = 0;
for (int i = 0; i < 2; i++)
{
Byte b = ReadByte();
value |= (UInt16(b) << (8 * i));
}
return value;
}
UInt32 CInArchive::ReadUInt32()
{
UInt32 value = 0;
for (int i = 0; i < 4; i++)
{
Byte b = ReadByte();
value |= (UInt32(b) << (8 * i));
}
return value;
}
AString CInArchive::SafeReadName()
{
AString name;
while(true) while(true)
{ {
BYTE b; Byte b = ReadByte();
if (!inBuffer.ReadByte(b))
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
if (b == 0) if (b == 0)
return; return name;
name += char(b); name += (char)b;
} }
} }
HRESULT CInArchive::Open(IInStream *inStream, void CInArchive::ReadOtherArchive(COtherArchive &oa)
const UINT64 *searchHeaderSizeLimit,
CInArchiveInfo &inArchiveInfo,
CObjectVector<NHeader::CFolder> &folders,
CObjectVector<CItem> &files,
CProgressVirt *progressVirt)
{ {
UINT64 startPosition; oa.FileName = SafeReadName();
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition)); oa.DiskName = SafeReadName();
}
NHeader::NArchive::CBlock archiveHeader; void CInArchive::Skeep(size_t size)
{
while (size-- != 0)
ReadByte();
}
HRESULT CInArchive::Open2(IInStream *inStream,
const UInt64 *searchHeaderSizeLimit,
CDatabase &database)
{
database.Clear();
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition));
{ {
CInBuffer inBuffer; if (!inBuffer.Create(1 << 17))
inBuffer.Init(inStream); return E_OUTOFMEMORY;
UINT64 value = 0; inBuffer.SetStream(inStream);
const int kSignatureSize = sizeof(value); inBuffer.Init();
UINT64 kSignature64 = NHeader::NArchive::kSignature; UInt64 value = 0;
const int kSignatureSize = 8;
UInt64 kSignature64 = NHeader::NArchive::kSignature;
while(true) while(true)
{ {
BYTE b; Byte b;
if (!inBuffer.ReadByte(b)) if (!inBuffer.ReadByte(b))
return S_FALSE; return S_FALSE;
value >>= 8; value >>= 8;
value |= ((UINT64)b) << ((kSignatureSize - 1) * 8); value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
if (inBuffer.GetProcessedSize() >= kSignatureSize) if (inBuffer.GetProcessedSize() >= kSignatureSize)
{ {
if (value == kSignature64) if (value == kSignature64)
@@ -85,105 +123,219 @@ HRESULT CInArchive::Open(IInStream *inStream,
return S_FALSE; return S_FALSE;
} }
} }
startPosition += inBuffer.GetProcessedSize() - kSignatureSize; database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize;
} }
RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL));
RINOK(ReadBytes(inStream, &archiveHeader, sizeof(archiveHeader)));
// 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; CInArchiveInfo &archiveInfo = database.ArchiveInfo;
inArchiveInfo.VersionMajor = archiveHeader.VersionMajor;
inArchiveInfo.NumFolders = archiveHeader.NumFolders;
inArchiveInfo.NumFiles = archiveHeader.NumFiles;
inArchiveInfo.Flags = archiveHeader.Flags;
if (inArchiveInfo.ReserveBlockPresent()) archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes
if (ReadUInt32() != 0)
return S_FALSE;
archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry
if (ReadUInt32() != 0)
return S_FALSE;
archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor
archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet
archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
if (archiveInfo.ReserveBlockPresent())
{ {
RINOK(SafeRead(inStream, &inArchiveInfo.PerDataSizes, archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area
sizeof(inArchiveInfo.PerDataSizes))); archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area
RINOK(inStream->Seek(inArchiveInfo.PerDataSizes.PerCabinetAreaSize, archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area
STREAM_SEEK_CUR, NULL));
Skeep(archiveInfo.PerCabinetAreaSize);
} }
{ {
UINT64 foldersStartPosition; if (archiveInfo.IsTherePrev())
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition)); ReadOtherArchive(archiveInfo.PreviousArchive);
CInBuffer inBuffer; if (archiveInfo.IsThereNext())
inBuffer.Init(inStream); ReadOtherArchive(archiveInfo.NextArchive);
if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0)
{
SafeReadName(inBuffer, inArchiveInfo.PreviousCabinetName);
SafeReadName(inBuffer, inArchiveInfo.PreviousDiskName);
}
if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0)
{
SafeReadName(inBuffer, inArchiveInfo.NextCabinetName);
SafeReadName(inBuffer, inArchiveInfo.NextDiskName);
}
foldersStartPosition += inBuffer.GetProcessedSize();
RINOK(inStream->Seek(foldersStartPosition, STREAM_SEEK_SET, NULL));
} }
if (progressVirt != NULL) int i;
for(i = 0; i < archiveInfo.NumFolders; i++)
{ {
UINT64 numFiles = archiveHeader.NumFiles; CFolder folder;
RINOK(progressVirt->SetTotal(&numFiles));
} folder.DataStart = ReadUInt32();
folders.Clear(); folder.NumDataBlocks = ReadUInt16();
for(int i = 0; i < archiveHeader.NumFolders; i++) folder.CompressionTypeMajor = ReadByte();
{ folder.CompressionTypeMinor = ReadByte();
if (progressVirt != NULL)
{ Skeep(archiveInfo.PerFolderAreaSize);
UINT64 numFiles = 0; database.Folders.Add(folder);
RINOK(progressVirt->SetCompleted(&numFiles));
}
NHeader::CFolder folder;
RINOK(SafeRead(inStream, &folder, sizeof(folder)));
if (inArchiveInfo.ReserveBlockPresent())
{
RINOK(inStream->Seek(
inArchiveInfo.PerDataSizes.PerFolderAreaSize, STREAM_SEEK_CUR, NULL));
}
folder.DataStart += (UINT32)startPosition;
folders.Add(folder);
} }
RINOK(inStream->Seek(startPosition + archiveHeader.FileOffset, RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
STREAM_SEEK_SET, NULL));
CInBuffer inBuffer; inBuffer.SetStream(inStream);
inBuffer.Init(inStream); inBuffer.Init();
files.Clear(); for(i = 0; i < archiveInfo.NumFiles; i++)
if (progressVirt != NULL)
{ {
UINT64 numFiles = files.Size();
RINOK(progressVirt->SetCompleted(&numFiles));
}
for(i = 0; i < archiveHeader.NumFiles; i++)
{
NHeader::CFile fileHeader;
SafeInByteRead(inBuffer, &fileHeader, sizeof(fileHeader));
CItem item; CItem item;
item.UnPackSize = fileHeader.UnPackSize; item.Size = ReadUInt32();
item.UnPackOffset = fileHeader.UnPackOffset; item.Offset = ReadUInt32();
item.FolderIndex = fileHeader.FolderIndex; item.FolderIndex = ReadUInt16();
item.Time = ((UINT32(fileHeader.PureDate) << 16)) | fileHeader.PureTime; UInt16 pureDate = ReadUInt16();
item.Attributes = fileHeader.Attributes; UInt16 pureTime = ReadUInt16();
SafeReadName(inBuffer, item.Name); item.Time = ((UInt32(pureDate) << 16)) | pureTime;
files.Add(item); item.Attributes = ReadUInt16();
if (progressVirt != NULL) item.Name = SafeReadName();
{ int folderIndex = item.GetFolderIndex(database.Folders.Size());
UINT64 numFiles = files.Size(); if (folderIndex >= database.Folders.Size())
RINOK(progressVirt->SetCompleted(&numFiles)); return S_FALSE;
} database.Items.Add(item);
} }
return S_OK; return S_OK;
} }
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
HRESULT CInArchive::Open(
const UInt64 *searchHeaderSizeLimit,
CDatabaseEx &database)
{
return Open2(database.Stream, searchHeaderSizeLimit, database);
}
static int CompareMvItems2(const CMvItem *p1, const CMvItem *p2)
{
RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex));
return MyCompare(p1->ItemIndex, p2->ItemIndex);
}
static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
{
const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param;
const CDatabaseEx &db1 = mvDb.Volumes[p1->VolumeIndex];
const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex];
const CItem &item1 = db1.Items[p1->ItemIndex];
const CItem &item2 = db2.Items[p2->ItemIndex];;
bool isDir1 = item1.IsDirectory();
bool isDir2 = item2.IsDirectory();
if (isDir1 && !isDir2)
return -1;
if (isDir2 && !isDir1)
return 1;
int f1 = mvDb.GetFolderIndex(p1);
int f2 = mvDb.GetFolderIndex(p2);
RINOZ(MyCompare(f1, f2));
RINOZ(MyCompare(item1.Offset, item2.Offset));
RINOZ(MyCompare(item1.Size, item2.Size));
return CompareMvItems2(p1, p2);
}
bool CMvDatabaseEx::AreItemsEqual(int i1, int i2)
{
const CMvItem *p1 = &Items[i1];
const CMvItem *p2 = &Items[i2];
const CDatabaseEx &db1 = Volumes[p1->VolumeIndex];
const CDatabaseEx &db2 = Volumes[p2->VolumeIndex];
const CItem &item1 = db1.Items[p1->ItemIndex];
const CItem &item2 = db2.Items[p2->ItemIndex];;
int f1 = GetFolderIndex(p1);
int f2 = GetFolderIndex(p2);
if (f1 != f2)
return false;
if (item1.Offset != item2.Offset)
return false;
if (item1.Size != item2.Size)
return false;
return true;
}
void CMvDatabaseEx::FillSortAndShrink()
{
Items.Clear();
StartFolderOfVol.Clear();
FolderStartFileIndex.Clear();
int offset = 0;
for (int v = 0; v < Volumes.Size(); v++)
{
const CDatabaseEx &db = Volumes[v];
int curOffset = offset;
if (db.IsTherePrevFolder())
curOffset--;
StartFolderOfVol.Add(curOffset);
offset += db.GetNumberOfNewFolders();
CMvItem mvItem;
mvItem.VolumeIndex = v;
for (int i = 0 ; i < db.Items.Size(); i++)
{
mvItem.ItemIndex = i;
Items.Add(mvItem);
}
}
Items.Sort(CompareMvItems, (void *)this);
int j = 1;
int i;
for (i = 1; i < Items.Size(); i++)
if (!AreItemsEqual(i, i -1))
Items[j++] = Items[i];
Items.DeleteFrom(j);
for (i = 0; i < Items.Size(); i++)
{
const CMvItem &mvItem = Items[i];
int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex >= FolderStartFileIndex.Size())
FolderStartFileIndex.Add(i);
}
}
bool CMvDatabaseEx::Check()
{
for (int v = 1; v < Volumes.Size(); v++)
{
const CDatabaseEx &db1 = Volumes[v];
if (db1.IsTherePrevFolder())
{
const CDatabaseEx &db0 = Volumes[v - 1];
if (db0.Folders.IsEmpty() || db1.Folders.IsEmpty())
return false;
const CFolder &f0 = db0.Folders.Back();
const CFolder &f1 = db1.Folders.Front();
if (f0.CompressionTypeMajor != f1.CompressionTypeMajor ||
f0.CompressionTypeMinor != f1.CompressionTypeMinor)
return false;
}
}
UInt64 maxPos = 0;
int prevFolder = -2;
for(int i = 0; i < Items.Size(); i++)
{
const CMvItem &mvItem = Items[i];
int fIndex = GetFolderIndex(&mvItem);
if (fIndex >= FolderStartFileIndex.Size())
return false;
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDirectory())
continue;
int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder)
{
prevFolder = folderIndex;
maxPos = 0;
continue;
}
if (item.Offset < maxPos)
return false;
maxPos = item.GetEndOffset();
if (maxPos < item.Offset)
return false;
}
return true;
}
}} }}

Some files were not shown because too many files have changed in this diff Show More