Normalize all the line endings

This commit is contained in:
Tino Reichardt
2020-05-31 13:08:03 +02:00
parent d8345ee3b3
commit 9c3c277ad7
1156 changed files with 292304 additions and 292304 deletions

View File

@@ -1,305 +1,305 @@
OBJS = \
$O\StdAfx.obj \
$(CURRENT_OBJS) \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(WIN_CTRL_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(AR_OBJS) \
$(AR_COMMON_OBJS) \
$(UI_COMMON_OBJS) \
$(AGENT_OBJS) \
$(CONSOLE_OBJS) \
$(EXPLORER_OBJS) \
$(FM_OBJS) \
$(GUI_OBJS) \
$(7Z_OBJS) \
$(CAB_OBJS) \
$(CHM_OBJS) \
$(COM_OBJS) \
$(ISO_OBJS) \
$(NSIS_OBJS) \
$(RAR_OBJS) \
$(TAR_OBJS) \
$(UDF_OBJS) \
$(WIM_OBJS) \
$(ZIP_OBJS) \
$(COMPRESS_OBJS) \
$(CRYPTO_OBJS) \
$(C_OBJS) \
$(BROTLI_OBJS) \
$(HASHES_OBJS) \
$(LIZARD_OBJS) \
$(LZ4_OBJS) \
$(LZ5_OBJS) \
$(ZSTD_OBJS) \
$(ZSTDMT_OBJS) \
$(FASTLZMA2_OBJS) \
$(ASM_OBJS) \
$O\resource.res \
!include "../../../Build.mak"
# MAK_SINGLE_FILE = 1
!IFDEF MAK_SINGLE_FILE
!IFDEF CURRENT_OBJS
$(CURRENT_OBJS): ./$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF COMMON_OBJS
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF WIN_OBJS
$(WIN_OBJS): ../../../Windows/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF WIN_CTRL_OBJS
$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF 7ZIP_COMMON_OBJS
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF AR_OBJS
$(AR_OBJS): ../../Archive/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF AR_COMMON_OBJS
$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF 7Z_OBJS
$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF CAB_OBJS
$(CAB_OBJS): ../../Archive/Cab/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF CHM_OBJS
$(CHM_OBJS): ../../Archive/Chm/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF COM_OBJS
$(COM_OBJS): ../../Archive/Com/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF ISO_OBJS
$(ISO_OBJS): ../../Archive/Iso/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF NSIS_OBJS
$(NSIS_OBJS): ../../Archive/Nsis/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF RAR_OBJS
$(RAR_OBJS): ../../Archive/Rar/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF TAR_OBJS
$(TAR_OBJS): ../../Archive/Tar/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF UDF_OBJS
$(UDF_OBJS): ../../Archive/Udf/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF WIM_OBJS
$(WIM_OBJS): ../../Archive/Wim/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF ZIP_OBJS
$(ZIP_OBJS): ../../Archive/Zip/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF COMPRESS_OBJS
$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
$(COMPL_O2)
!ENDIF
!IFDEF CRYPTO_OBJS
$(CRYPTO_OBJS): ../../Crypto/$(*B).cpp
$(COMPL_O2)
!ENDIF
!IFDEF UI_COMMON_OBJS
$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF AGENT_OBJS
$(AGENT_OBJS): ../../UI/Agent/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF CONSOLE_OBJS
$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF EXPLORER_OBJS
$(EXPLORER_OBJS): ../../UI/Explorer/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF FM_OBJS
$(FM_OBJS): ../../UI/FileManager/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF GUI_OBJS
$(GUI_OBJS): ../../UI/GUI/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF C_OBJS
$(C_OBJS): ../../../../C/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF BROTLI_OBJS
$(BROTLI_OBJS): ../../../../C/brotli/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF LIZARD_OBJS
$(LIZARD_OBJS): ../../../../C/lizard/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF LZ4_OBJS
$(LZ4_OBJS): ../../../../C/lz4/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF LZ5_OBJS
$(LZ5_OBJS): ../../../../C/lz5/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF ZSTD_OBJS
$(ZSTD_OBJS): ../../../../C/zstd/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF ZSTDMT_OBJS
$(ZSTDMT_OBJS): ../../../../C/zstdmt/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF FASTLZMA2_OBJS
$(FASTLZMA2_OBJS): ../../../../C/fast-lzma2/$(*B).c
$(COMPL_O2) -DNO_XXHASH -DFL2_7ZIP_BUILD
!ENDIF
!ELSE
{.}.cpp{$O}.obj::
$(COMPLB)
{../../../Common}.cpp{$O}.obj::
$(COMPLB)
{../../../Windows}.cpp{$O}.obj::
$(COMPLB)
{../../../Windows/Control}.cpp{$O}.obj::
$(COMPLB)
{../../Common}.cpp{$O}.obj::
$(COMPLB)
{../../UI/Common}.cpp{$O}.obj::
$(COMPLB)
{../../UI/Agent}.cpp{$O}.obj::
$(COMPLB)
{../../UI/Console}.cpp{$O}.obj::
$(COMPLB)
{../../UI/Explorer}.cpp{$O}.obj::
$(COMPLB)
{../../UI/FileManager}.cpp{$O}.obj::
$(COMPLB)
{../../UI/GUI}.cpp{$O}.obj::
$(COMPLB)
{../../Archive}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Common}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/7z}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Cab}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Chm}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Com}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Iso}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Nsis}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Rar}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Tar}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Udf}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Wim}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Zip}.cpp{$O}.obj::
$(COMPLB)
{../../Compress}.cpp{$O}.obj::
$(COMPLB_O2)
{../../Crypto}.cpp{$O}.obj::
$(COMPLB_O2)
{../../../../C}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/brotli}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/hashes}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/lizard}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/lz4}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/lz5}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/zstd}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/zstdmt}.c{$O}.obj::
$(COMPLB_O2) \
-I ../../../../C/brotli \
-I ../../../../C/hashes \
-I ../../../../C/lizard \
-I ../../../../C/lz4 \
-I ../../../../C/lz5 \
-I ../../../../C/zstd
{../../../../C/fast-lzma2}.c{$O}.obj::
$(COMPLB_O2) -DNO_XXHASH -DFL2_7ZIP_BUILD
!ENDIF
!include "Asm.mak"
OBJS = \
$O\StdAfx.obj \
$(CURRENT_OBJS) \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(WIN_CTRL_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(AR_OBJS) \
$(AR_COMMON_OBJS) \
$(UI_COMMON_OBJS) \
$(AGENT_OBJS) \
$(CONSOLE_OBJS) \
$(EXPLORER_OBJS) \
$(FM_OBJS) \
$(GUI_OBJS) \
$(7Z_OBJS) \
$(CAB_OBJS) \
$(CHM_OBJS) \
$(COM_OBJS) \
$(ISO_OBJS) \
$(NSIS_OBJS) \
$(RAR_OBJS) \
$(TAR_OBJS) \
$(UDF_OBJS) \
$(WIM_OBJS) \
$(ZIP_OBJS) \
$(COMPRESS_OBJS) \
$(CRYPTO_OBJS) \
$(C_OBJS) \
$(BROTLI_OBJS) \
$(HASHES_OBJS) \
$(LIZARD_OBJS) \
$(LZ4_OBJS) \
$(LZ5_OBJS) \
$(ZSTD_OBJS) \
$(ZSTDMT_OBJS) \
$(FASTLZMA2_OBJS) \
$(ASM_OBJS) \
$O\resource.res \
!include "../../../Build.mak"
# MAK_SINGLE_FILE = 1
!IFDEF MAK_SINGLE_FILE
!IFDEF CURRENT_OBJS
$(CURRENT_OBJS): ./$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF COMMON_OBJS
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF WIN_OBJS
$(WIN_OBJS): ../../../Windows/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF WIN_CTRL_OBJS
$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF 7ZIP_COMMON_OBJS
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF AR_OBJS
$(AR_OBJS): ../../Archive/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF AR_COMMON_OBJS
$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF 7Z_OBJS
$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF CAB_OBJS
$(CAB_OBJS): ../../Archive/Cab/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF CHM_OBJS
$(CHM_OBJS): ../../Archive/Chm/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF COM_OBJS
$(COM_OBJS): ../../Archive/Com/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF ISO_OBJS
$(ISO_OBJS): ../../Archive/Iso/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF NSIS_OBJS
$(NSIS_OBJS): ../../Archive/Nsis/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF RAR_OBJS
$(RAR_OBJS): ../../Archive/Rar/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF TAR_OBJS
$(TAR_OBJS): ../../Archive/Tar/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF UDF_OBJS
$(UDF_OBJS): ../../Archive/Udf/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF WIM_OBJS
$(WIM_OBJS): ../../Archive/Wim/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF ZIP_OBJS
$(ZIP_OBJS): ../../Archive/Zip/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF COMPRESS_OBJS
$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
$(COMPL_O2)
!ENDIF
!IFDEF CRYPTO_OBJS
$(CRYPTO_OBJS): ../../Crypto/$(*B).cpp
$(COMPL_O2)
!ENDIF
!IFDEF UI_COMMON_OBJS
$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF AGENT_OBJS
$(AGENT_OBJS): ../../UI/Agent/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF CONSOLE_OBJS
$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF EXPLORER_OBJS
$(EXPLORER_OBJS): ../../UI/Explorer/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF FM_OBJS
$(FM_OBJS): ../../UI/FileManager/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF GUI_OBJS
$(GUI_OBJS): ../../UI/GUI/$(*B).cpp
$(COMPL)
!ENDIF
!IFDEF C_OBJS
$(C_OBJS): ../../../../C/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF BROTLI_OBJS
$(BROTLI_OBJS): ../../../../C/brotli/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF LIZARD_OBJS
$(LIZARD_OBJS): ../../../../C/lizard/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF LZ4_OBJS
$(LZ4_OBJS): ../../../../C/lz4/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF LZ5_OBJS
$(LZ5_OBJS): ../../../../C/lz5/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF ZSTD_OBJS
$(ZSTD_OBJS): ../../../../C/zstd/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF ZSTDMT_OBJS
$(ZSTDMT_OBJS): ../../../../C/zstdmt/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF FASTLZMA2_OBJS
$(FASTLZMA2_OBJS): ../../../../C/fast-lzma2/$(*B).c
$(COMPL_O2) -DNO_XXHASH -DFL2_7ZIP_BUILD
!ENDIF
!ELSE
{.}.cpp{$O}.obj::
$(COMPLB)
{../../../Common}.cpp{$O}.obj::
$(COMPLB)
{../../../Windows}.cpp{$O}.obj::
$(COMPLB)
{../../../Windows/Control}.cpp{$O}.obj::
$(COMPLB)
{../../Common}.cpp{$O}.obj::
$(COMPLB)
{../../UI/Common}.cpp{$O}.obj::
$(COMPLB)
{../../UI/Agent}.cpp{$O}.obj::
$(COMPLB)
{../../UI/Console}.cpp{$O}.obj::
$(COMPLB)
{../../UI/Explorer}.cpp{$O}.obj::
$(COMPLB)
{../../UI/FileManager}.cpp{$O}.obj::
$(COMPLB)
{../../UI/GUI}.cpp{$O}.obj::
$(COMPLB)
{../../Archive}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Common}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/7z}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Cab}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Chm}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Com}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Iso}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Nsis}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Rar}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Tar}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Udf}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Wim}.cpp{$O}.obj::
$(COMPLB)
{../../Archive/Zip}.cpp{$O}.obj::
$(COMPLB)
{../../Compress}.cpp{$O}.obj::
$(COMPLB_O2)
{../../Crypto}.cpp{$O}.obj::
$(COMPLB_O2)
{../../../../C}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/brotli}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/hashes}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/lizard}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/lz4}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/lz5}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/zstd}.c{$O}.obj::
$(COMPLB_O2)
{../../../../C/zstdmt}.c{$O}.obj::
$(COMPLB_O2) \
-I ../../../../C/brotli \
-I ../../../../C/hashes \
-I ../../../../C/lizard \
-I ../../../../C/lz4 \
-I ../../../../C/lz5 \
-I ../../../../C/zstd
{../../../../C/fast-lzma2}.c{$O}.obj::
$(COMPLB_O2) -DNO_XXHASH -DFL2_7ZIP_BUILD
!ENDIF
!include "Asm.mak"

View File

@@ -1,7 +1,7 @@
C_OBJS = $(C_OBJS) \
$O\Aes.obj
!IF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64"
ASM_OBJS = $(ASM_OBJS) \
$O\AesOpt.obj
!ENDIF
C_OBJS = $(C_OBJS) \
$O\Aes.obj
!IF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64"
ASM_OBJS = $(ASM_OBJS) \
$O\AesOpt.obj
!ENDIF

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "7z"=".\7z.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "7z"=".\7z.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

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

View File

@@ -1,76 +1,76 @@
// 7zCompressionMode.h
#ifndef __7Z_COMPRESSION_MODE_H
#define __7Z_COMPRESSION_MODE_H
#include "../../Common/MethodId.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
namespace N7z {
struct CMethodFull: public CMethodProps
{
CMethodId Id;
UInt32 NumStreams;
int CodecIndex;
CMethodFull(): CodecIndex(-1) {}
bool IsSimpleCoder() const { return NumStreams == 1; }
};
struct CBond2
{
UInt32 OutCoder;
UInt32 OutStream;
UInt32 InCoder;
};
struct CCompressionMethodMode
{
/*
if (Bonds.Empty()), then default bonds must be created
if (Filter_was_Inserted)
{
Methods[0] is filter method
Bonds don't contain bonds for filter (these bonds must be created)
}
*/
CObjectVector<CMethodFull> Methods;
CRecordVector<CBond2> Bonds;
bool IsThereBond_to_Coder(unsigned coderIndex) const
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].InCoder == coderIndex)
return true;
return false;
}
bool DefaultMethod_was_Inserted;
bool Filter_was_Inserted;
#ifndef _7ZIP_ST
UInt32 NumThreads;
bool MultiThreadMixer;
#endif
bool PasswordIsDefined;
UString Password;
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
CCompressionMethodMode():
DefaultMethod_was_Inserted(false),
Filter_was_Inserted(false),
PasswordIsDefined(false)
#ifndef _7ZIP_ST
, NumThreads(1)
, MultiThreadMixer(true)
#endif
{}
};
}}
#endif
// 7zCompressionMode.h
#ifndef __7Z_COMPRESSION_MODE_H
#define __7Z_COMPRESSION_MODE_H
#include "../../Common/MethodId.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
namespace N7z {
struct CMethodFull: public CMethodProps
{
CMethodId Id;
UInt32 NumStreams;
int CodecIndex;
CMethodFull(): CodecIndex(-1) {}
bool IsSimpleCoder() const { return NumStreams == 1; }
};
struct CBond2
{
UInt32 OutCoder;
UInt32 OutStream;
UInt32 InCoder;
};
struct CCompressionMethodMode
{
/*
if (Bonds.Empty()), then default bonds must be created
if (Filter_was_Inserted)
{
Methods[0] is filter method
Bonds don't contain bonds for filter (these bonds must be created)
}
*/
CObjectVector<CMethodFull> Methods;
CRecordVector<CBond2> Bonds;
bool IsThereBond_to_Coder(unsigned coderIndex) const
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].InCoder == coderIndex)
return true;
return false;
}
bool DefaultMethod_was_Inserted;
bool Filter_was_Inserted;
#ifndef _7ZIP_ST
UInt32 NumThreads;
bool MultiThreadMixer;
#endif
bool PasswordIsDefined;
UString Password;
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
CCompressionMethodMode():
DefaultMethod_was_Inserted(false),
Filter_was_Inserted(false),
PasswordIsDefined(false)
#ifndef _7ZIP_ST
, NumThreads(1)
, MultiThreadMixer(true)
#endif
{}
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,70 +1,70 @@
// 7zDecode.h
#ifndef __7Z_DECODE_H
#define __7Z_DECODE_H
#include "../Common/CoderMixer2.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
struct CBindInfoEx: public NCoderMixer2::CBindInfo
{
CRecordVector<CMethodId> CoderMethodIDs;
void Clear()
{
CBindInfo::Clear();
CoderMethodIDs.Clear();
}
};
class CDecoder
{
bool _bindInfoPrev_Defined;
CBindInfoEx _bindInfoPrev;
bool _useMixerMT;
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
#endif
#ifdef USE_MIXER_MT
NCoderMixer2::CMixerMT *_mixerMT;
#endif
NCoderMixer2::CMixer *_mixer;
CMyComPtr<IUnknown> _mixerRef;
public:
CDecoder(bool useMixerMT);
HRESULT Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
UInt64 startPos,
const CFolders &folders, unsigned folderIndex,
const UInt64 *unpackSize // if (!unpackSize), then full folder is required
// if (unpackSize), then only *unpackSize bytes from folder are required
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
, ISequentialInStream **inStreamMainRes
, bool &dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST)
, bool mtMode, UInt32 numThreads, UInt64 memUsage
#endif
);
};
}}
#endif
// 7zDecode.h
#ifndef __7Z_DECODE_H
#define __7Z_DECODE_H
#include "../Common/CoderMixer2.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
struct CBindInfoEx: public NCoderMixer2::CBindInfo
{
CRecordVector<CMethodId> CoderMethodIDs;
void Clear()
{
CBindInfo::Clear();
CoderMethodIDs.Clear();
}
};
class CDecoder
{
bool _bindInfoPrev_Defined;
CBindInfoEx _bindInfoPrev;
bool _useMixerMT;
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
#endif
#ifdef USE_MIXER_MT
NCoderMixer2::CMixerMT *_mixerMT;
#endif
NCoderMixer2::CMixer *_mixer;
CMyComPtr<IUnknown> _mixerRef;
public:
CDecoder(bool useMixerMT);
HRESULT Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
UInt64 startPos,
const CFolders &folders, unsigned folderIndex,
const UInt64 *unpackSize // if (!unpackSize), then full folder is required
// if (unpackSize), then only *unpackSize bytes from folder are required
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
, ISequentialInStream **inStreamMainRes
, bool &dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST)
, bool mtMode, UInt32 numThreads, UInt64 memUsage
#endif
);
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,92 +1,92 @@
// 7zEncode.h
#ifndef __7Z_ENCODE_H
#define __7Z_ENCODE_H
#include "7zCompressionMode.h"
#include "../Common/CoderMixer2.h"
#include "7zItem.h"
namespace NArchive {
namespace N7z {
class CMtEncMultiProgress:
public ICompressProgressInfo,
public CMyUnknownImp
{
CMyComPtr<ICompressProgressInfo> _progress;
#ifndef _7ZIP_ST
NWindows::NSynchronization::CCriticalSection CriticalSection;
#endif
public:
UInt64 OutSize;
CMtEncMultiProgress(): OutSize(0) {}
void Init(ICompressProgressInfo *progress);
void AddOutSize(UInt64 addOutSize)
{
#ifndef _7ZIP_ST
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
#endif
OutSize += addOutSize;
}
MY_UNKNOWN_IMP1(ICompressProgressInfo)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
class CEncoder
{
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
#endif
#ifdef USE_MIXER_MT
NCoderMixer2::CMixerMT *_mixerMT;
#endif
NCoderMixer2::CMixer *_mixer;
CMyComPtr<IUnknown> _mixerRef;
CCompressionMethodMode _options;
NCoderMixer2::CBindInfo _bindInfo;
CRecordVector<CMethodId> _decompressionMethods;
CRecordVector<UInt32> _SrcIn_to_DestOut;
CRecordVector<UInt32> _SrcOut_to_DestIn;
// CRecordVector<UInt32> _DestIn_to_SrcOut;
CRecordVector<UInt32> _DestOut_to_SrcIn;
void InitBindConv();
void SetFolder(CFolder &folder);
HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce);
bool _constructed;
public:
CEncoder(const CCompressionMethodMode &options);
~CEncoder();
HRESULT EncoderConstr();
HRESULT Encode(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
// const UInt64 *inStreamSize,
const UInt64 *inSizeForReduce,
CFolder &folderItem,
CRecordVector<UInt64> &coderUnpackSizes,
UInt64 &unpackSize,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress);
};
}}
#endif
// 7zEncode.h
#ifndef __7Z_ENCODE_H
#define __7Z_ENCODE_H
#include "7zCompressionMode.h"
#include "../Common/CoderMixer2.h"
#include "7zItem.h"
namespace NArchive {
namespace N7z {
class CMtEncMultiProgress:
public ICompressProgressInfo,
public CMyUnknownImp
{
CMyComPtr<ICompressProgressInfo> _progress;
#ifndef _7ZIP_ST
NWindows::NSynchronization::CCriticalSection CriticalSection;
#endif
public:
UInt64 OutSize;
CMtEncMultiProgress(): OutSize(0) {}
void Init(ICompressProgressInfo *progress);
void AddOutSize(UInt64 addOutSize)
{
#ifndef _7ZIP_ST
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
#endif
OutSize += addOutSize;
}
MY_UNKNOWN_IMP1(ICompressProgressInfo)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
class CEncoder
{
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
#endif
#ifdef USE_MIXER_MT
NCoderMixer2::CMixerMT *_mixerMT;
#endif
NCoderMixer2::CMixer *_mixer;
CMyComPtr<IUnknown> _mixerRef;
CCompressionMethodMode _options;
NCoderMixer2::CBindInfo _bindInfo;
CRecordVector<CMethodId> _decompressionMethods;
CRecordVector<UInt32> _SrcIn_to_DestOut;
CRecordVector<UInt32> _SrcOut_to_DestIn;
// CRecordVector<UInt32> _DestIn_to_SrcOut;
CRecordVector<UInt32> _DestOut_to_SrcIn;
void InitBindConv();
void SetFolder(CFolder &folder);
HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce);
bool _constructed;
public:
CEncoder(const CCompressionMethodMode &options);
~CEncoder();
HRESULT EncoderConstr();
HRESULT Encode(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
// const UInt64 *inStreamSize,
const UInt64 *inSizeForReduce,
CFolder &folderItem,
CRecordVector<UInt64> &coderUnpackSizes,
UInt64 &unpackSize,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress);
};
}}
#endif

View File

@@ -1,423 +1,423 @@
// 7zExtract.cpp
#include "StdAfx.h"
#include "../../../../C/7zCrc.h"
#include "../../../Common/ComTry.h"
#include "../../Common/ProgressUtils.h"
#include "7zDecode.h"
#include "7zHandler.h"
// EXTERN_g_ExternalCodecs
namespace NArchive {
namespace N7z {
class CFolderOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
public:
bool TestMode;
bool CheckCrc;
private:
bool _fileIsOpen;
bool _calcCrc;
UInt32 _crc;
UInt64 _rem;
const UInt32 *_indexes;
unsigned _numFiles;
unsigned _fileIndex;
HRESULT OpenFile(bool isCorrupted = false);
HRESULT CloseFile_and_SetResult(Int32 res);
HRESULT CloseFile();
HRESULT ProcessEmptyFiles();
public:
MY_UNKNOWN_IMP1(ISequentialOutStream)
const CDbEx *_db;
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
bool ExtraWriteWasCut;
CFolderOutStream():
TestMode(false),
CheckCrc(true)
{}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles);
HRESULT FlushCorrupted(Int32 callbackOperationResult);
bool WasWritingFinished() const { return _numFiles == 0; }
};
HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles)
{
_fileIndex = startIndex;
_indexes = indexes;
_numFiles = numFiles;
_fileIsOpen = false;
ExtraWriteWasCut = false;
return ProcessEmptyFiles();
}
HRESULT CFolderOutStream::OpenFile(bool isCorrupted)
{
const CFileItem &fi = _db->Files[_fileIndex];
UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex);
Int32 askMode = (_fileIndex == nextFileIndex) ?
(TestMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
NExtract::NAskMode::kSkip;
if (isCorrupted
&& askMode == NExtract::NAskMode::kExtract
&& !_db->IsItemAnti(_fileIndex)
&& !fi.IsDir)
askMode = NExtract::NAskMode::kTest;
CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode));
_stream = realOutStream;
_crc = CRC_INIT_VAL;
_calcCrc = (CheckCrc && fi.CrcDefined && !fi.IsDir);
_fileIsOpen = true;
_rem = fi.Size;
if (askMode == NExtract::NAskMode::kExtract
&& !realOutStream
&& !_db->IsItemAnti(_fileIndex)
&& !fi.IsDir)
askMode = NExtract::NAskMode::kSkip;
return ExtractCallback->PrepareOperation(askMode);
}
HRESULT CFolderOutStream::CloseFile_and_SetResult(Int32 res)
{
_stream.Release();
_fileIsOpen = false;
if (!_indexes)
_numFiles--;
else if (*_indexes == _fileIndex)
{
_indexes++;
_numFiles--;
}
_fileIndex++;
return ExtractCallback->SetOperationResult(res);
}
HRESULT CFolderOutStream::CloseFile()
{
const CFileItem &fi = _db->Files[_fileIndex];
return CloseFile_and_SetResult((!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) ?
NExtract::NOperationResult::kOK :
NExtract::NOperationResult::kCRCError);
}
HRESULT CFolderOutStream::ProcessEmptyFiles()
{
while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0)
{
RINOK(OpenFile());
RINOK(CloseFile());
}
return S_OK;
}
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
while (size != 0)
{
if (_fileIsOpen)
{
UInt32 cur = (size < _rem ? size : (UInt32)_rem);
if (_calcCrc)
{
const UInt32 k_Step = (UInt32)1 << 20;
if (cur > k_Step)
cur = k_Step;
}
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, cur, &cur);
if (_calcCrc)
_crc = CrcUpdate(_crc, data, cur);
if (processedSize)
*processedSize += cur;
data = (const Byte *)data + cur;
size -= cur;
_rem -= cur;
if (_rem == 0)
{
RINOK(CloseFile());
RINOK(ProcessEmptyFiles());
}
RINOK(result);
if (cur == 0)
break;
continue;
}
RINOK(ProcessEmptyFiles());
if (_numFiles == 0)
{
// we support partial extracting
/*
if (processedSize)
*processedSize += size;
break;
*/
ExtraWriteWasCut = true;
// return S_FALSE;
return k_My_HRESULT_WritingWasCut;
}
RINOK(OpenFile());
}
return S_OK;
}
HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult)
{
while (_numFiles != 0)
{
if (_fileIsOpen)
{
RINOK(CloseFile_and_SetResult(callbackOperationResult));
}
else
{
RINOK(OpenFile(true));
}
}
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
{
COM_TRY_BEGIN
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
UInt64 importantTotalUnpacked = 0;
// numItems = (UInt32)(Int32)-1;
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _db.Files.Size();
if (numItems == 0)
return S_OK;
{
CNum prevFolder = kNumNoIndex;
UInt32 nextFile = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
UInt32 fileIndex = allFilesMode ? i : indices[i];
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
if (folderIndex == kNumNoIndex)
continue;
if (folderIndex != prevFolder || fileIndex < nextFile)
nextFile = _db.FolderStartFileIndex[folderIndex];
for (CNum index = nextFile; index <= fileIndex; index++)
importantTotalUnpacked += _db.Files[index].Size;
nextFile = fileIndex + 1;
prevFolder = folderIndex;
}
}
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CDecoder decoder(
#if !defined(USE_MIXER_MT)
false
#elif !defined(USE_MIXER_ST)
true
#elif !defined(__7Z_SET_PROPERTIES)
#ifdef _7ZIP_ST
false
#else
true
#endif
#else
_useMultiThreadMixer
#endif
);
UInt64 curPacked, curUnpacked;
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
folderOutStream->_db = &_db;
folderOutStream->ExtractCallback = extractCallback;
folderOutStream->TestMode = (testModeSpec != 0);
folderOutStream->CheckCrc = (_crcSize != 0);
for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked)
{
RINOK(lps->SetCur());
if (i >= numItems)
break;
curUnpacked = 0;
curPacked = 0;
UInt32 fileIndex = allFilesMode ? i : indices[i];
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
UInt32 numSolidFiles = 1;
if (folderIndex != kNumNoIndex)
{
curPacked = _db.GetFolderFullPackSize(folderIndex);
UInt32 nextFile = fileIndex + 1;
fileIndex = _db.FolderStartFileIndex[folderIndex];
UInt32 k;
for (k = i + 1; k < numItems; k++)
{
UInt32 fileIndex2 = allFilesMode ? k : indices[k];
if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex
|| fileIndex2 < nextFile)
break;
nextFile = fileIndex2 + 1;
}
numSolidFiles = k - i;
for (k = fileIndex; k < nextFile; k++)
curUnpacked += _db.Files[k].Size;
}
{
HRESULT result = folderOutStream->Init(fileIndex,
allFilesMode ? NULL : indices + i,
numSolidFiles);
i += numSolidFiles;
RINOK(result);
}
// to test solid block with zero unpacked size we disable that code
if (folderOutStream->WasWritingFinished())
continue;
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (extractCallback)
extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
#endif
try
{
#ifndef _NO_CRYPTO
bool isEncrypted = false;
bool passwordIsDefined = false;
UString password;
#endif
bool dataAfterEnd_Error = false;
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
_inStream,
_db.ArcInfo.DataStartPosition,
_db, folderIndex,
&curUnpacked,
outStream,
progress,
NULL // *inStreamMainRes
, dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST)
, true, _numThreads, _memUsage
#endif
);
if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error)
{
bool wasFinished = folderOutStream->WasWritingFinished();
int resOp = NExtract::NOperationResult::kDataError;
if (result != S_FALSE)
{
if (result == E_NOTIMPL)
resOp = NExtract::NOperationResult::kUnsupportedMethod;
else if (wasFinished && dataAfterEnd_Error)
resOp = NExtract::NOperationResult::kDataAfterEnd;
}
RINOK(folderOutStream->FlushCorrupted(resOp));
if (wasFinished)
{
// we don't show error, if it's after required files
if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage)
{
RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp));
}
}
continue;
}
if (result != S_OK)
return result;
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
continue;
}
catch(...)
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
// continue;
return E_FAIL;
}
}
return S_OK;
COM_TRY_END
}
}}
// 7zExtract.cpp
#include "StdAfx.h"
#include "../../../../C/7zCrc.h"
#include "../../../Common/ComTry.h"
#include "../../Common/ProgressUtils.h"
#include "7zDecode.h"
#include "7zHandler.h"
// EXTERN_g_ExternalCodecs
namespace NArchive {
namespace N7z {
class CFolderOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
public:
bool TestMode;
bool CheckCrc;
private:
bool _fileIsOpen;
bool _calcCrc;
UInt32 _crc;
UInt64 _rem;
const UInt32 *_indexes;
unsigned _numFiles;
unsigned _fileIndex;
HRESULT OpenFile(bool isCorrupted = false);
HRESULT CloseFile_and_SetResult(Int32 res);
HRESULT CloseFile();
HRESULT ProcessEmptyFiles();
public:
MY_UNKNOWN_IMP1(ISequentialOutStream)
const CDbEx *_db;
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
bool ExtraWriteWasCut;
CFolderOutStream():
TestMode(false),
CheckCrc(true)
{}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles);
HRESULT FlushCorrupted(Int32 callbackOperationResult);
bool WasWritingFinished() const { return _numFiles == 0; }
};
HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles)
{
_fileIndex = startIndex;
_indexes = indexes;
_numFiles = numFiles;
_fileIsOpen = false;
ExtraWriteWasCut = false;
return ProcessEmptyFiles();
}
HRESULT CFolderOutStream::OpenFile(bool isCorrupted)
{
const CFileItem &fi = _db->Files[_fileIndex];
UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex);
Int32 askMode = (_fileIndex == nextFileIndex) ?
(TestMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
NExtract::NAskMode::kSkip;
if (isCorrupted
&& askMode == NExtract::NAskMode::kExtract
&& !_db->IsItemAnti(_fileIndex)
&& !fi.IsDir)
askMode = NExtract::NAskMode::kTest;
CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode));
_stream = realOutStream;
_crc = CRC_INIT_VAL;
_calcCrc = (CheckCrc && fi.CrcDefined && !fi.IsDir);
_fileIsOpen = true;
_rem = fi.Size;
if (askMode == NExtract::NAskMode::kExtract
&& !realOutStream
&& !_db->IsItemAnti(_fileIndex)
&& !fi.IsDir)
askMode = NExtract::NAskMode::kSkip;
return ExtractCallback->PrepareOperation(askMode);
}
HRESULT CFolderOutStream::CloseFile_and_SetResult(Int32 res)
{
_stream.Release();
_fileIsOpen = false;
if (!_indexes)
_numFiles--;
else if (*_indexes == _fileIndex)
{
_indexes++;
_numFiles--;
}
_fileIndex++;
return ExtractCallback->SetOperationResult(res);
}
HRESULT CFolderOutStream::CloseFile()
{
const CFileItem &fi = _db->Files[_fileIndex];
return CloseFile_and_SetResult((!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) ?
NExtract::NOperationResult::kOK :
NExtract::NOperationResult::kCRCError);
}
HRESULT CFolderOutStream::ProcessEmptyFiles()
{
while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0)
{
RINOK(OpenFile());
RINOK(CloseFile());
}
return S_OK;
}
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
while (size != 0)
{
if (_fileIsOpen)
{
UInt32 cur = (size < _rem ? size : (UInt32)_rem);
if (_calcCrc)
{
const UInt32 k_Step = (UInt32)1 << 20;
if (cur > k_Step)
cur = k_Step;
}
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, cur, &cur);
if (_calcCrc)
_crc = CrcUpdate(_crc, data, cur);
if (processedSize)
*processedSize += cur;
data = (const Byte *)data + cur;
size -= cur;
_rem -= cur;
if (_rem == 0)
{
RINOK(CloseFile());
RINOK(ProcessEmptyFiles());
}
RINOK(result);
if (cur == 0)
break;
continue;
}
RINOK(ProcessEmptyFiles());
if (_numFiles == 0)
{
// we support partial extracting
/*
if (processedSize)
*processedSize += size;
break;
*/
ExtraWriteWasCut = true;
// return S_FALSE;
return k_My_HRESULT_WritingWasCut;
}
RINOK(OpenFile());
}
return S_OK;
}
HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult)
{
while (_numFiles != 0)
{
if (_fileIsOpen)
{
RINOK(CloseFile_and_SetResult(callbackOperationResult));
}
else
{
RINOK(OpenFile(true));
}
}
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
{
COM_TRY_BEGIN
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
UInt64 importantTotalUnpacked = 0;
// numItems = (UInt32)(Int32)-1;
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _db.Files.Size();
if (numItems == 0)
return S_OK;
{
CNum prevFolder = kNumNoIndex;
UInt32 nextFile = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
UInt32 fileIndex = allFilesMode ? i : indices[i];
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
if (folderIndex == kNumNoIndex)
continue;
if (folderIndex != prevFolder || fileIndex < nextFile)
nextFile = _db.FolderStartFileIndex[folderIndex];
for (CNum index = nextFile; index <= fileIndex; index++)
importantTotalUnpacked += _db.Files[index].Size;
nextFile = fileIndex + 1;
prevFolder = folderIndex;
}
}
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CDecoder decoder(
#if !defined(USE_MIXER_MT)
false
#elif !defined(USE_MIXER_ST)
true
#elif !defined(__7Z_SET_PROPERTIES)
#ifdef _7ZIP_ST
false
#else
true
#endif
#else
_useMultiThreadMixer
#endif
);
UInt64 curPacked, curUnpacked;
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
folderOutStream->_db = &_db;
folderOutStream->ExtractCallback = extractCallback;
folderOutStream->TestMode = (testModeSpec != 0);
folderOutStream->CheckCrc = (_crcSize != 0);
for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked)
{
RINOK(lps->SetCur());
if (i >= numItems)
break;
curUnpacked = 0;
curPacked = 0;
UInt32 fileIndex = allFilesMode ? i : indices[i];
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
UInt32 numSolidFiles = 1;
if (folderIndex != kNumNoIndex)
{
curPacked = _db.GetFolderFullPackSize(folderIndex);
UInt32 nextFile = fileIndex + 1;
fileIndex = _db.FolderStartFileIndex[folderIndex];
UInt32 k;
for (k = i + 1; k < numItems; k++)
{
UInt32 fileIndex2 = allFilesMode ? k : indices[k];
if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex
|| fileIndex2 < nextFile)
break;
nextFile = fileIndex2 + 1;
}
numSolidFiles = k - i;
for (k = fileIndex; k < nextFile; k++)
curUnpacked += _db.Files[k].Size;
}
{
HRESULT result = folderOutStream->Init(fileIndex,
allFilesMode ? NULL : indices + i,
numSolidFiles);
i += numSolidFiles;
RINOK(result);
}
// to test solid block with zero unpacked size we disable that code
if (folderOutStream->WasWritingFinished())
continue;
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (extractCallback)
extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
#endif
try
{
#ifndef _NO_CRYPTO
bool isEncrypted = false;
bool passwordIsDefined = false;
UString password;
#endif
bool dataAfterEnd_Error = false;
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
_inStream,
_db.ArcInfo.DataStartPosition,
_db, folderIndex,
&curUnpacked,
outStream,
progress,
NULL // *inStreamMainRes
, dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST)
, true, _numThreads, _memUsage
#endif
);
if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error)
{
bool wasFinished = folderOutStream->WasWritingFinished();
int resOp = NExtract::NOperationResult::kDataError;
if (result != S_FALSE)
{
if (result == E_NOTIMPL)
resOp = NExtract::NOperationResult::kUnsupportedMethod;
else if (wasFinished && dataAfterEnd_Error)
resOp = NExtract::NOperationResult::kDataAfterEnd;
}
RINOK(folderOutStream->FlushCorrupted(resOp));
if (wasFinished)
{
// we don't show error, if it's after required files
if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage)
{
RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp));
}
}
continue;
}
if (result != S_OK)
return result;
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
continue;
}
catch(...)
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
// continue;
return E_FAIL;
}
}
return S_OK;
COM_TRY_END
}
}}

View File

@@ -1,139 +1,139 @@
// 7zFolderInStream.cpp
#include "StdAfx.h"
#include "7zFolderInStream.h"
namespace NArchive {
namespace N7z {
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
const UInt32 *indexes, unsigned numFiles)
{
_updateCallback = updateCallback;
_indexes = indexes;
_numFiles = numFiles;
_index = 0;
Processed.ClearAndReserve(numFiles);
CRCs.ClearAndReserve(numFiles);
Sizes.ClearAndReserve(numFiles);
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
_stream.Release();
}
HRESULT CFolderInStream::OpenStream()
{
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
while (_index < _numFiles)
{
CMyComPtr<ISequentialInStream> stream;
HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream);
if (result != S_OK)
{
if (result != S_FALSE)
return result;
}
_stream = stream;
if (stream)
{
CMyComPtr<IStreamGetSize> streamGetSize;
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
if (streamGetSize)
{
if (streamGetSize->GetSize(&_size) == S_OK)
_size_Defined = true;
}
return S_OK;
}
_index++;
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
AddFileInfo(result == S_OK);
}
return S_OK;
}
void CFolderInStream::AddFileInfo(bool isProcessed)
{
Processed.Add(isProcessed);
Sizes.Add(_pos);
CRCs.Add(CRC_GET_DIGEST(_crc));
}
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
while (size != 0)
{
if (_stream)
{
UInt32 cur = size;
const UInt32 kMax = (UInt32)1 << 20;
if (cur > kMax)
cur = kMax;
RINOK(_stream->Read(data, cur, &cur));
if (cur != 0)
{
_crc = CrcUpdate(_crc, data, cur);
_pos += cur;
if (processedSize)
*processedSize = cur;
return S_OK;
}
_stream.Release();
_index++;
AddFileInfo(true);
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
if (_index >= _numFiles)
break;
RINOK(OpenStream());
}
return S_OK;
}
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
if (subStream > Sizes.Size())
return S_FALSE; // E_FAIL;
unsigned index = (unsigned)subStream;
if (index < Sizes.Size())
{
*value = Sizes[index];
return S_OK;
}
if (!_size_Defined)
{
*value = _pos;
return S_FALSE;
}
*value = (_pos > _size ? _pos : _size);
return S_OK;
}
}}
// 7zFolderInStream.cpp
#include "StdAfx.h"
#include "7zFolderInStream.h"
namespace NArchive {
namespace N7z {
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
const UInt32 *indexes, unsigned numFiles)
{
_updateCallback = updateCallback;
_indexes = indexes;
_numFiles = numFiles;
_index = 0;
Processed.ClearAndReserve(numFiles);
CRCs.ClearAndReserve(numFiles);
Sizes.ClearAndReserve(numFiles);
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
_stream.Release();
}
HRESULT CFolderInStream::OpenStream()
{
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
while (_index < _numFiles)
{
CMyComPtr<ISequentialInStream> stream;
HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream);
if (result != S_OK)
{
if (result != S_FALSE)
return result;
}
_stream = stream;
if (stream)
{
CMyComPtr<IStreamGetSize> streamGetSize;
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
if (streamGetSize)
{
if (streamGetSize->GetSize(&_size) == S_OK)
_size_Defined = true;
}
return S_OK;
}
_index++;
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
AddFileInfo(result == S_OK);
}
return S_OK;
}
void CFolderInStream::AddFileInfo(bool isProcessed)
{
Processed.Add(isProcessed);
Sizes.Add(_pos);
CRCs.Add(CRC_GET_DIGEST(_crc));
}
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
while (size != 0)
{
if (_stream)
{
UInt32 cur = size;
const UInt32 kMax = (UInt32)1 << 20;
if (cur > kMax)
cur = kMax;
RINOK(_stream->Read(data, cur, &cur));
if (cur != 0)
{
_crc = CrcUpdate(_crc, data, cur);
_pos += cur;
if (processedSize)
*processedSize = cur;
return S_OK;
}
_stream.Release();
_index++;
AddFileInfo(true);
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
if (_index >= _numFiles)
break;
RINOK(OpenStream());
}
return S_OK;
}
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
if (subStream > Sizes.Size())
return S_FALSE; // E_FAIL;
unsigned index = (unsigned)subStream;
if (index < Sizes.Size())
{
*value = Sizes[index];
return S_OK;
}
if (!_size_Defined)
{
*value = _pos;
return S_FALSE;
}
*value = (_pos > _size ? _pos : _size);
return S_OK;
}
}}

View File

@@ -1,61 +1,61 @@
// 7zFolderInStream.h
#ifndef __7Z_FOLDER_IN_STREAM_H
#define __7Z_FOLDER_IN_STREAM_H
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../ICoder.h"
#include "../IArchive.h"
namespace NArchive {
namespace N7z {
class CFolderInStream:
public ISequentialInStream,
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _stream;
UInt64 _pos;
UInt32 _crc;
bool _size_Defined;
UInt64 _size;
const UInt32 *_indexes;
unsigned _numFiles;
unsigned _index;
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
HRESULT OpenStream();
void AddFileInfo(bool isProcessed);
public:
CRecordVector<bool> Processed;
CRecordVector<UInt32> CRCs;
CRecordVector<UInt64> Sizes;
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles);
bool WasFinished() const { return _index == _numFiles; }
UInt64 GetFullSize() const
{
UInt64 size = 0;
FOR_VECTOR (i, Sizes)
size += Sizes[i];
return size;
}
};
}}
#endif
// 7zFolderInStream.h
#ifndef __7Z_FOLDER_IN_STREAM_H
#define __7Z_FOLDER_IN_STREAM_H
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../ICoder.h"
#include "../IArchive.h"
namespace NArchive {
namespace N7z {
class CFolderInStream:
public ISequentialInStream,
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _stream;
UInt64 _pos;
UInt32 _crc;
bool _size_Defined;
UInt64 _size;
const UInt32 *_indexes;
unsigned _numFiles;
unsigned _index;
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
HRESULT OpenStream();
void AddFileInfo(bool isProcessed);
public:
CRecordVector<bool> Processed;
CRecordVector<UInt32> CRCs;
CRecordVector<UInt64> Sizes;
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles);
bool WasFinished() const { return _index == _numFiles; }
UInt64 GetFullSize() const
{
UInt64 size = 0;
FOR_VECTOR (i, Sizes)
size += Sizes[i];
return size;
}
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,181 +1,181 @@
// 7z/Handler.h
#ifndef __7Z_HANDLER_H
#define __7Z_HANDLER_H
#include "../../ICoder.h"
#include "../IArchive.h"
#include "../../Common/CreateCoder.h"
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
#if !defined(_7ZIP_ST) && !defined(_SFX)
#define __7Z_SET_PROPERTIES
#endif
#else
#define __7Z_SET_PROPERTIES
#endif
#endif
// #ifdef __7Z_SET_PROPERTIES
#include "../Common/HandlerOut.h"
// #endif
#include "7zCompressionMode.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
#ifndef EXTRACT_ONLY
class COutHandler: public CMultiMethodProps
{
HRESULT SetSolidFromString(const UString &s);
HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
public:
UInt64 _numSolidFiles;
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
bool _solidExtension;
bool _useTypeSorting;
bool _compressHeaders;
bool _encryptHeadersSpecified;
bool _encryptHeaders;
// bool _useParents; 9.26
CBoolPair Write_CTime;
CBoolPair Write_ATime;
CBoolPair Write_MTime;
CBoolPair Write_Attrib;
bool _useMultiThreadMixer;
bool _removeSfxBlock;
// bool _volumeMode;
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
void InitSolid()
{
InitSolidFiles();
InitSolidSize();
_solidExtension = false;
_numSolidBytesDefined = false;
}
void InitProps7z();
void InitProps();
COutHandler() { InitProps7z(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
#endif
class CHandler:
public IInArchive,
public IArchiveGetRawProps,
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
#ifndef EXTRACT_ONLY
public IOutArchive,
#endif
PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp,
#ifndef EXTRACT_ONLY
public COutHandler
#else
public CCommonMethodProps
#endif
{
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
#ifdef __7Z_SET_PROPERTIES
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
#ifndef EXTRACT_ONLY
MY_QUERYINTERFACE_ENTRY(IOutArchive)
#endif
QUERY_ENTRY_ISetCompressCodecsInfo
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
INTERFACE_IArchiveGetRawProps(;)
#ifdef __7Z_SET_PROPERTIES
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#endif
#ifndef EXTRACT_ONLY
INTERFACE_IOutArchive(;)
#endif
DECL_ISetCompressCodecsInfo
CHandler();
private:
CMyComPtr<IInStream> _inStream;
NArchive::N7z::CDbEx _db;
#ifndef _NO_CRYPTO
bool _isEncrypted;
bool _passwordIsDefined;
UString _password;
#endif
#ifdef EXTRACT_ONLY
#ifdef __7Z_SET_PROPERTIES
bool _useMultiThreadMixer;
#endif
UInt32 _crcSize;
#else
CRecordVector<CBond2> _bonds;
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
HRESULT SetMainMethod(CCompressionMethodMode &method
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
#endif
bool IsFolderEncrypted(CNum folderIndex) const;
#ifndef _SFX
CRecordVector<UInt64> _fileInfoPopIDs;
void FillPopIDs();
void AddMethodName(AString &s, UInt64 id);
HRESULT SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const;
#endif
DECL_EXTERNAL_CODECS_VARS
};
}}
#endif
// 7z/Handler.h
#ifndef __7Z_HANDLER_H
#define __7Z_HANDLER_H
#include "../../ICoder.h"
#include "../IArchive.h"
#include "../../Common/CreateCoder.h"
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
#if !defined(_7ZIP_ST) && !defined(_SFX)
#define __7Z_SET_PROPERTIES
#endif
#else
#define __7Z_SET_PROPERTIES
#endif
#endif
// #ifdef __7Z_SET_PROPERTIES
#include "../Common/HandlerOut.h"
// #endif
#include "7zCompressionMode.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
#ifndef EXTRACT_ONLY
class COutHandler: public CMultiMethodProps
{
HRESULT SetSolidFromString(const UString &s);
HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
public:
UInt64 _numSolidFiles;
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
bool _solidExtension;
bool _useTypeSorting;
bool _compressHeaders;
bool _encryptHeadersSpecified;
bool _encryptHeaders;
// bool _useParents; 9.26
CBoolPair Write_CTime;
CBoolPair Write_ATime;
CBoolPair Write_MTime;
CBoolPair Write_Attrib;
bool _useMultiThreadMixer;
bool _removeSfxBlock;
// bool _volumeMode;
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
void InitSolid()
{
InitSolidFiles();
InitSolidSize();
_solidExtension = false;
_numSolidBytesDefined = false;
}
void InitProps7z();
void InitProps();
COutHandler() { InitProps7z(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
#endif
class CHandler:
public IInArchive,
public IArchiveGetRawProps,
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
#ifndef EXTRACT_ONLY
public IOutArchive,
#endif
PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp,
#ifndef EXTRACT_ONLY
public COutHandler
#else
public CCommonMethodProps
#endif
{
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
#ifdef __7Z_SET_PROPERTIES
MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
#ifndef EXTRACT_ONLY
MY_QUERYINTERFACE_ENTRY(IOutArchive)
#endif
QUERY_ENTRY_ISetCompressCodecsInfo
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
INTERFACE_IArchiveGetRawProps(;)
#ifdef __7Z_SET_PROPERTIES
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#endif
#ifndef EXTRACT_ONLY
INTERFACE_IOutArchive(;)
#endif
DECL_ISetCompressCodecsInfo
CHandler();
private:
CMyComPtr<IInStream> _inStream;
NArchive::N7z::CDbEx _db;
#ifndef _NO_CRYPTO
bool _isEncrypted;
bool _passwordIsDefined;
UString _password;
#endif
#ifdef EXTRACT_ONLY
#ifdef __7Z_SET_PROPERTIES
bool _useMultiThreadMixer;
#endif
UInt32 _crcSize;
#else
CRecordVector<CBond2> _bonds;
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
HRESULT SetMainMethod(CCompressionMethodMode &method
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
#endif
bool IsFolderEncrypted(CNum folderIndex) const;
#ifndef _SFX
CRecordVector<UInt64> _fileInfoPopIDs;
void FillPopIDs();
void AddMethodName(AString &s, UInt64 id);
HRESULT SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const;
#endif
DECL_EXTERNAL_CODECS_VARS
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,19 @@
// 7zHeader.cpp
#include "StdAfx.h"
#include "7zHeader.h"
namespace NArchive {
namespace N7z {
Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
#ifdef _7Z_VOL
Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
#endif
// We can change signature. So file doesn't contain correct signature.
// struct SignatureInitializer { SignatureInitializer() { kSignature[0]--; } };
// static SignatureInitializer g_SignatureInitializer;
}}
// 7zHeader.cpp
#include "StdAfx.h"
#include "7zHeader.h"
namespace NArchive {
namespace N7z {
Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
#ifdef _7Z_VOL
Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
#endif
// We can change signature. So file doesn't contain correct signature.
// struct SignatureInitializer { SignatureInitializer() { kSignature[0]--; } };
// static SignatureInitializer g_SignatureInitializer;
}}

View File

@@ -1,155 +1,155 @@
// 7z/7zHeader.h
#ifndef __7Z_HEADER_H
#define __7Z_HEADER_H
#include "../../../Common/MyTypes.h"
namespace NArchive {
namespace N7z {
const unsigned kSignatureSize = 6;
extern Byte kSignature[kSignatureSize];
// #define _7Z_VOL
// 7z-MultiVolume is not finished yet.
// It can work already, but I still do not like some
// things of that new multivolume format.
// So please keep it commented.
#ifdef _7Z_VOL
extern Byte kFinishSignature[kSignatureSize];
#endif
struct CArchiveVersion
{
Byte Major;
Byte Minor;
};
const Byte kMajorVersion = 0;
struct CStartHeader
{
UInt64 NextHeaderOffset;
UInt64 NextHeaderSize;
UInt32 NextHeaderCRC;
};
const UInt32 kStartHeaderSize = 20;
#ifdef _7Z_VOL
struct CFinishHeader: public CStartHeader
{
UInt64 ArchiveStartOffset; // data offset from end if that struct
UInt64 AdditionalStartBlockSize; // start signature & start header size
};
const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;
#endif
namespace NID
{
enum EEnum
{
kEnd,
kHeader,
kArchiveProperties,
kAdditionalStreamsInfo,
kMainStreamsInfo,
kFilesInfo,
kPackInfo,
kUnpackInfo,
kSubStreamsInfo,
kSize,
kCRC,
kFolder,
kCodersUnpackSize,
kNumUnpackStream,
kEmptyStream,
kEmptyFile,
kAnti,
kName,
kCTime,
kATime,
kMTime,
kWinAttrib,
kComment,
kEncodedHeader,
kStartPos,
kDummy
// kNtSecure,
// kParent,
// kIsAux
};
}
const UInt32 k_Copy = 0;
const UInt32 k_Delta = 3;
const UInt32 k_LZMA2 = 0x21;
const UInt32 k_SWAP2 = 0x20302;
const UInt32 k_SWAP4 = 0x20304;
const UInt32 k_LZMA = 0x30101;
const UInt32 k_PPMD = 0x30401;
const UInt32 k_Deflate = 0x40108;
const UInt32 k_BZip2 = 0x40202;
const UInt32 k_BCJ = 0x3030103;
const UInt32 k_BCJ2 = 0x303011B;
const UInt32 k_PPC = 0x3030205;
const UInt32 k_IA64 = 0x3030401;
const UInt32 k_ARM = 0x3030501;
const UInt32 k_ARMT = 0x3030701;
const UInt32 k_SPARC = 0x3030805;
const UInt32 k_LZHAM = 0x4F71001;
const UInt32 k_ZSTD = 0x4F71101;
const UInt32 k_BROTLI= 0x4F71102;
const UInt32 k_LZ4 = 0x4F71104;
const UInt32 k_LZ5 = 0x4F71105;
const UInt32 k_LIZARD= 0x4F71106;
const UInt32 k_AES = 0x6F10701;
static inline bool IsFilterMethod(UInt64 m)
{
if (m > (UInt64)0xFFFFFFFF)
return false;
switch ((UInt32)m)
{
case k_Delta:
case k_BCJ:
case k_BCJ2:
case k_PPC:
case k_IA64:
case k_ARM:
case k_ARMT:
case k_SPARC:
case k_SWAP2:
case k_SWAP4:
return true;
}
return false;
}
}}
#endif
// 7z/7zHeader.h
#ifndef __7Z_HEADER_H
#define __7Z_HEADER_H
#include "../../../Common/MyTypes.h"
namespace NArchive {
namespace N7z {
const unsigned kSignatureSize = 6;
extern Byte kSignature[kSignatureSize];
// #define _7Z_VOL
// 7z-MultiVolume is not finished yet.
// It can work already, but I still do not like some
// things of that new multivolume format.
// So please keep it commented.
#ifdef _7Z_VOL
extern Byte kFinishSignature[kSignatureSize];
#endif
struct CArchiveVersion
{
Byte Major;
Byte Minor;
};
const Byte kMajorVersion = 0;
struct CStartHeader
{
UInt64 NextHeaderOffset;
UInt64 NextHeaderSize;
UInt32 NextHeaderCRC;
};
const UInt32 kStartHeaderSize = 20;
#ifdef _7Z_VOL
struct CFinishHeader: public CStartHeader
{
UInt64 ArchiveStartOffset; // data offset from end if that struct
UInt64 AdditionalStartBlockSize; // start signature & start header size
};
const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;
#endif
namespace NID
{
enum EEnum
{
kEnd,
kHeader,
kArchiveProperties,
kAdditionalStreamsInfo,
kMainStreamsInfo,
kFilesInfo,
kPackInfo,
kUnpackInfo,
kSubStreamsInfo,
kSize,
kCRC,
kFolder,
kCodersUnpackSize,
kNumUnpackStream,
kEmptyStream,
kEmptyFile,
kAnti,
kName,
kCTime,
kATime,
kMTime,
kWinAttrib,
kComment,
kEncodedHeader,
kStartPos,
kDummy
// kNtSecure,
// kParent,
// kIsAux
};
}
const UInt32 k_Copy = 0;
const UInt32 k_Delta = 3;
const UInt32 k_LZMA2 = 0x21;
const UInt32 k_SWAP2 = 0x20302;
const UInt32 k_SWAP4 = 0x20304;
const UInt32 k_LZMA = 0x30101;
const UInt32 k_PPMD = 0x30401;
const UInt32 k_Deflate = 0x40108;
const UInt32 k_BZip2 = 0x40202;
const UInt32 k_BCJ = 0x3030103;
const UInt32 k_BCJ2 = 0x303011B;
const UInt32 k_PPC = 0x3030205;
const UInt32 k_IA64 = 0x3030401;
const UInt32 k_ARM = 0x3030501;
const UInt32 k_ARMT = 0x3030701;
const UInt32 k_SPARC = 0x3030805;
const UInt32 k_LZHAM = 0x4F71001;
const UInt32 k_ZSTD = 0x4F71101;
const UInt32 k_BROTLI= 0x4F71102;
const UInt32 k_LZ4 = 0x4F71104;
const UInt32 k_LZ5 = 0x4F71105;
const UInt32 k_LIZARD= 0x4F71106;
const UInt32 k_AES = 0x6F10701;
static inline bool IsFilterMethod(UInt64 m)
{
if (m > (UInt64)0xFFFFFFFF)
return false;
switch ((UInt32)m)
{
case k_Delta:
case k_BCJ:
case k_BCJ2:
case k_PPC:
case k_IA64:
case k_ARM:
case k_ARMT:
case k_SPARC:
case k_SWAP2:
case k_SWAP4:
return true;
}
return false;
}
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,445 +1,445 @@
// 7zIn.h
#ifndef __7Z_IN_H
#define __7Z_IN_H
#include "../../../Common/MyCom.h"
#include "../../../Windows/PropVariant.h"
#include "../../IPassword.h"
#include "../../IStream.h"
#include "../../Common/CreateCoder.h"
#include "../../Common/InBuffer.h"
#include "7zItem.h"
namespace NArchive {
namespace N7z {
/*
We don't need to init isEncrypted and passwordIsDefined
We must upgrade them only */
#ifdef _NO_CRYPTO
#define _7Z_DECODER_CRYPRO_VARS_DECL
#define _7Z_DECODER_CRYPRO_VARS
#else
#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password
#endif
struct CParsedMethods
{
Byte Lzma2Prop;
UInt32 LzmaDic;
CRecordVector<UInt64> IDs;
CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {}
};
struct CFolderEx: public CFolder
{
unsigned UnpackCoder;
};
struct CFolders
{
CNum NumPackStreams;
CNum NumFolders;
CObjArray<UInt64> PackPositions; // NumPackStreams + 1
// CUInt32DefVector PackCRCs; // we don't use PackCRCs now
CUInt32DefVector FolderCRCs; // NumFolders
CObjArray<CNum> NumUnpackStreamsVector; // NumFolders
CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1
CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1
CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders
CObjArray<size_t> FoCodersDataOffset; // NumFolders + 1
CByteBuffer CodersData;
CParsedMethods ParsedMethods;
void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const;
void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const
{
ParseFolderInfo(folderIndex, folder);
folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex];
}
unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const
{
return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]);
}
UInt64 GetFolderUnpackSize(unsigned folderIndex) const
{
return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]];
}
UInt64 GetStreamPackSize(unsigned index) const
{
return PackPositions[index + 1] - PackPositions[index];
}
CFolders(): NumPackStreams(0), NumFolders(0) {}
void Clear()
{
NumPackStreams = 0;
PackPositions.Free();
// PackCRCs.Clear();
NumFolders = 0;
FolderCRCs.Clear();
NumUnpackStreamsVector.Free();
CoderUnpackSizes.Free();
FoToCoderUnpackSizes.Free();
FoStartPackStreamIndex.Free();
FoToMainUnpackSizeIndex.Free();
FoCodersDataOffset.Free();
CodersData.Free();
}
};
struct CDatabase: public CFolders
{
CRecordVector<CFileItem> Files;
CUInt64DefVector CTime;
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
CUInt32DefVector Attrib;
CBoolVector IsAnti;
/*
CBoolVector IsAux;
CByteBuffer SecureBuf;
CRecordVector<UInt32> SecureIDs;
*/
CByteBuffer NamesBuf;
CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols
/*
void ClearSecure()
{
SecureBuf.Free();
SecureIDs.Clear();
}
*/
void Clear()
{
CFolders::Clear();
// ClearSecure();
NamesBuf.Free();
NameOffsets.Free();
Files.Clear();
CTime.Clear();
ATime.Clear();
MTime.Clear();
StartPos.Clear();
Attrib.Clear();
IsAnti.Clear();
// IsAux.Clear();
}
bool IsSolid() const
{
for (CNum i = 0; i < NumFolders; i++)
if (NumUnpackStreamsVector[i] > 1)
return true;
return false;
}
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
// bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
/*
const void* GetName(unsigned index) const
{
if (!NameOffsets || !NamesBuf)
return NULL;
return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
};
*/
void GetPath(unsigned index, UString &path) const;
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
};
struct CInArchiveInfo
{
CArchiveVersion Version;
UInt64 StartPosition;
UInt64 StartPositionAfterHeader;
UInt64 DataStartPosition;
UInt64 DataStartPosition2;
CRecordVector<UInt64> FileInfoPopIDs;
void Clear()
{
StartPosition = 0;
StartPositionAfterHeader = 0;
DataStartPosition = 0;
DataStartPosition2 = 0;
FileInfoPopIDs.Clear();
}
};
struct CDbEx: public CDatabase
{
CInArchiveInfo ArcInfo;
CObjArray<CNum> FolderStartFileIndex;
CObjArray<CNum> FileIndexToFolderIndexMap;
UInt64 HeadersSize;
UInt64 PhySize;
/*
CRecordVector<size_t> SecureOffsets;
bool IsTree;
bool ThereAreAltStreams;
*/
bool IsArc;
bool PhySizeWasConfirmed;
bool ThereIsHeaderError;
bool UnexpectedEnd;
// bool UnsupportedVersion;
bool StartHeaderWasRecovered;
bool UnsupportedFeatureWarning;
bool UnsupportedFeatureError;
/*
void ClearSecureEx()
{
ClearSecure();
SecureOffsets.Clear();
}
*/
void Clear()
{
IsArc = false;
PhySizeWasConfirmed = false;
ThereIsHeaderError = false;
UnexpectedEnd = false;
// UnsupportedVersion = false;
StartHeaderWasRecovered = false;
UnsupportedFeatureError = false;
UnsupportedFeatureWarning = false;
/*
IsTree = false;
ThereAreAltStreams = false;
*/
CDatabase::Clear();
// SecureOffsets.Clear();
ArcInfo.Clear();
FolderStartFileIndex.Free();
FileIndexToFolderIndexMap.Free();
HeadersSize = 0;
PhySize = 0;
}
bool CanUpdate() const
{
if (ThereIsHeaderError
|| UnexpectedEnd
|| StartHeaderWasRecovered
|| UnsupportedFeatureError)
return false;
return true;
}
void FillLinks();
UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const
{
return ArcInfo.DataStartPosition +
PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder];
}
UInt64 GetFolderFullPackSize(CNum folderIndex) const
{
return
PackPositions[FoStartPackStreamIndex[folderIndex + 1]] -
PackPositions[FoStartPackStreamIndex[folderIndex]];
}
UInt64 GetFolderPackStreamSize(CNum folderIndex, unsigned streamIndex) const
{
size_t i = FoStartPackStreamIndex[folderIndex] + streamIndex;
return PackPositions[i + 1] - PackPositions[i];
}
UInt64 GetFilePackSize(CNum fileIndex) const
{
CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
if (folderIndex != kNumNoIndex)
if (FolderStartFileIndex[folderIndex] == fileIndex)
return GetFolderFullPackSize(folderIndex);
return 0;
}
};
const unsigned kNumBufLevelsMax = 4;
struct CInByte2
{
const Byte *_buffer;
public:
size_t _size;
size_t _pos;
size_t GetRem() const { return _size - _pos; }
const Byte *GetPtr() const { return _buffer + _pos; }
void Init(const Byte *buffer, size_t size)
{
_buffer = buffer;
_size = size;
_pos = 0;
}
Byte ReadByte();
void ReadBytes(Byte *data, size_t size);
void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; }
void SkipData(UInt64 size);
void SkipData();
void SkipRem() { _pos = _size; }
UInt64 ReadNumber();
CNum ReadNum();
UInt32 ReadUInt32();
UInt64 ReadUInt64();
void ParseFolder(CFolder &folder);
};
class CStreamSwitch;
const UInt32 kHeaderSize = 32;
class CInArchive
{
friend class CStreamSwitch;
CMyComPtr<IInStream> _stream;
unsigned _numInByteBufs;
CInByte2 _inByteVector[kNumBufLevelsMax];
CInByte2 *_inByteBack;
bool ThereIsHeaderError;
UInt64 _arhiveBeginStreamPosition;
UInt64 _fileEndPosition;
Byte _header[kHeaderSize];
UInt64 HeadersSize;
bool _useMixerMT;
void AddByteStream(const Byte *buffer, size_t size);
void DeleteByteStream(bool needUpdatePos)
{
_numInByteBufs--;
if (_numInByteBufs > 0)
{
_inByteBack = &_inByteVector[_numInByteBufs - 1];
if (needUpdatePos)
_inByteBack->_pos += _inByteVector[_numInByteBufs]._pos;
}
}
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
Byte ReadByte() { return _inByteBack->ReadByte(); }
UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
CNum ReadNum() { return _inByteBack->ReadNum(); }
UInt64 ReadID() { return _inByteBack->ReadNumber(); }
UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }
UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
void SkipData(UInt64 size) { _inByteBack->SkipData(size); }
void SkipData() { _inByteBack->SkipData(); }
void WaitId(UInt64 id);
void Read_UInt32_Vector(CUInt32DefVector &v);
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
void ReadPackInfo(CFolders &f);
void ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector,
CFolders &folders);
void ReadSubStreamsInfo(
CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
CUInt32DefVector &digests);
void ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
CUInt32DefVector &digests);
void ReadBoolVector(unsigned numItems, CBoolVector &v);
void ReadBoolVector2(unsigned numItems, CBoolVector &v);
void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
CUInt64DefVector &v, unsigned numItems);
HRESULT ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset, UInt64 &dataOffset,
CObjectVector<CByteBuffer> &dataVector
_7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
_7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
_7Z_DECODER_CRYPRO_VARS_DECL
);
public:
CInArchive(bool useMixerMT):
_numInByteBufs(0),
_useMixerMT(useMixerMT)
{}
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
void Close();
HRESULT ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
_7Z_DECODER_CRYPRO_VARS_DECL
);
};
}}
#endif
// 7zIn.h
#ifndef __7Z_IN_H
#define __7Z_IN_H
#include "../../../Common/MyCom.h"
#include "../../../Windows/PropVariant.h"
#include "../../IPassword.h"
#include "../../IStream.h"
#include "../../Common/CreateCoder.h"
#include "../../Common/InBuffer.h"
#include "7zItem.h"
namespace NArchive {
namespace N7z {
/*
We don't need to init isEncrypted and passwordIsDefined
We must upgrade them only */
#ifdef _NO_CRYPTO
#define _7Z_DECODER_CRYPRO_VARS_DECL
#define _7Z_DECODER_CRYPRO_VARS
#else
#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password
#endif
struct CParsedMethods
{
Byte Lzma2Prop;
UInt32 LzmaDic;
CRecordVector<UInt64> IDs;
CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {}
};
struct CFolderEx: public CFolder
{
unsigned UnpackCoder;
};
struct CFolders
{
CNum NumPackStreams;
CNum NumFolders;
CObjArray<UInt64> PackPositions; // NumPackStreams + 1
// CUInt32DefVector PackCRCs; // we don't use PackCRCs now
CUInt32DefVector FolderCRCs; // NumFolders
CObjArray<CNum> NumUnpackStreamsVector; // NumFolders
CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1
CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1
CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders
CObjArray<size_t> FoCodersDataOffset; // NumFolders + 1
CByteBuffer CodersData;
CParsedMethods ParsedMethods;
void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const;
void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const
{
ParseFolderInfo(folderIndex, folder);
folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex];
}
unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const
{
return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]);
}
UInt64 GetFolderUnpackSize(unsigned folderIndex) const
{
return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]];
}
UInt64 GetStreamPackSize(unsigned index) const
{
return PackPositions[index + 1] - PackPositions[index];
}
CFolders(): NumPackStreams(0), NumFolders(0) {}
void Clear()
{
NumPackStreams = 0;
PackPositions.Free();
// PackCRCs.Clear();
NumFolders = 0;
FolderCRCs.Clear();
NumUnpackStreamsVector.Free();
CoderUnpackSizes.Free();
FoToCoderUnpackSizes.Free();
FoStartPackStreamIndex.Free();
FoToMainUnpackSizeIndex.Free();
FoCodersDataOffset.Free();
CodersData.Free();
}
};
struct CDatabase: public CFolders
{
CRecordVector<CFileItem> Files;
CUInt64DefVector CTime;
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
CUInt32DefVector Attrib;
CBoolVector IsAnti;
/*
CBoolVector IsAux;
CByteBuffer SecureBuf;
CRecordVector<UInt32> SecureIDs;
*/
CByteBuffer NamesBuf;
CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols
/*
void ClearSecure()
{
SecureBuf.Free();
SecureIDs.Clear();
}
*/
void Clear()
{
CFolders::Clear();
// ClearSecure();
NamesBuf.Free();
NameOffsets.Free();
Files.Clear();
CTime.Clear();
ATime.Clear();
MTime.Clear();
StartPos.Clear();
Attrib.Clear();
IsAnti.Clear();
// IsAux.Clear();
}
bool IsSolid() const
{
for (CNum i = 0; i < NumFolders; i++)
if (NumUnpackStreamsVector[i] > 1)
return true;
return false;
}
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
// bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
/*
const void* GetName(unsigned index) const
{
if (!NameOffsets || !NamesBuf)
return NULL;
return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
};
*/
void GetPath(unsigned index, UString &path) const;
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
};
struct CInArchiveInfo
{
CArchiveVersion Version;
UInt64 StartPosition;
UInt64 StartPositionAfterHeader;
UInt64 DataStartPosition;
UInt64 DataStartPosition2;
CRecordVector<UInt64> FileInfoPopIDs;
void Clear()
{
StartPosition = 0;
StartPositionAfterHeader = 0;
DataStartPosition = 0;
DataStartPosition2 = 0;
FileInfoPopIDs.Clear();
}
};
struct CDbEx: public CDatabase
{
CInArchiveInfo ArcInfo;
CObjArray<CNum> FolderStartFileIndex;
CObjArray<CNum> FileIndexToFolderIndexMap;
UInt64 HeadersSize;
UInt64 PhySize;
/*
CRecordVector<size_t> SecureOffsets;
bool IsTree;
bool ThereAreAltStreams;
*/
bool IsArc;
bool PhySizeWasConfirmed;
bool ThereIsHeaderError;
bool UnexpectedEnd;
// bool UnsupportedVersion;
bool StartHeaderWasRecovered;
bool UnsupportedFeatureWarning;
bool UnsupportedFeatureError;
/*
void ClearSecureEx()
{
ClearSecure();
SecureOffsets.Clear();
}
*/
void Clear()
{
IsArc = false;
PhySizeWasConfirmed = false;
ThereIsHeaderError = false;
UnexpectedEnd = false;
// UnsupportedVersion = false;
StartHeaderWasRecovered = false;
UnsupportedFeatureError = false;
UnsupportedFeatureWarning = false;
/*
IsTree = false;
ThereAreAltStreams = false;
*/
CDatabase::Clear();
// SecureOffsets.Clear();
ArcInfo.Clear();
FolderStartFileIndex.Free();
FileIndexToFolderIndexMap.Free();
HeadersSize = 0;
PhySize = 0;
}
bool CanUpdate() const
{
if (ThereIsHeaderError
|| UnexpectedEnd
|| StartHeaderWasRecovered
|| UnsupportedFeatureError)
return false;
return true;
}
void FillLinks();
UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const
{
return ArcInfo.DataStartPosition +
PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder];
}
UInt64 GetFolderFullPackSize(CNum folderIndex) const
{
return
PackPositions[FoStartPackStreamIndex[folderIndex + 1]] -
PackPositions[FoStartPackStreamIndex[folderIndex]];
}
UInt64 GetFolderPackStreamSize(CNum folderIndex, unsigned streamIndex) const
{
size_t i = FoStartPackStreamIndex[folderIndex] + streamIndex;
return PackPositions[i + 1] - PackPositions[i];
}
UInt64 GetFilePackSize(CNum fileIndex) const
{
CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
if (folderIndex != kNumNoIndex)
if (FolderStartFileIndex[folderIndex] == fileIndex)
return GetFolderFullPackSize(folderIndex);
return 0;
}
};
const unsigned kNumBufLevelsMax = 4;
struct CInByte2
{
const Byte *_buffer;
public:
size_t _size;
size_t _pos;
size_t GetRem() const { return _size - _pos; }
const Byte *GetPtr() const { return _buffer + _pos; }
void Init(const Byte *buffer, size_t size)
{
_buffer = buffer;
_size = size;
_pos = 0;
}
Byte ReadByte();
void ReadBytes(Byte *data, size_t size);
void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; }
void SkipData(UInt64 size);
void SkipData();
void SkipRem() { _pos = _size; }
UInt64 ReadNumber();
CNum ReadNum();
UInt32 ReadUInt32();
UInt64 ReadUInt64();
void ParseFolder(CFolder &folder);
};
class CStreamSwitch;
const UInt32 kHeaderSize = 32;
class CInArchive
{
friend class CStreamSwitch;
CMyComPtr<IInStream> _stream;
unsigned _numInByteBufs;
CInByte2 _inByteVector[kNumBufLevelsMax];
CInByte2 *_inByteBack;
bool ThereIsHeaderError;
UInt64 _arhiveBeginStreamPosition;
UInt64 _fileEndPosition;
Byte _header[kHeaderSize];
UInt64 HeadersSize;
bool _useMixerMT;
void AddByteStream(const Byte *buffer, size_t size);
void DeleteByteStream(bool needUpdatePos)
{
_numInByteBufs--;
if (_numInByteBufs > 0)
{
_inByteBack = &_inByteVector[_numInByteBufs - 1];
if (needUpdatePos)
_inByteBack->_pos += _inByteVector[_numInByteBufs]._pos;
}
}
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
Byte ReadByte() { return _inByteBack->ReadByte(); }
UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
CNum ReadNum() { return _inByteBack->ReadNum(); }
UInt64 ReadID() { return _inByteBack->ReadNumber(); }
UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }
UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
void SkipData(UInt64 size) { _inByteBack->SkipData(size); }
void SkipData() { _inByteBack->SkipData(); }
void WaitId(UInt64 id);
void Read_UInt32_Vector(CUInt32DefVector &v);
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
void ReadPackInfo(CFolders &f);
void ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector,
CFolders &folders);
void ReadSubStreamsInfo(
CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
CUInt32DefVector &digests);
void ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
CFolders &folders,
CRecordVector<UInt64> &unpackSizes,
CUInt32DefVector &digests);
void ReadBoolVector(unsigned numItems, CBoolVector &v);
void ReadBoolVector2(unsigned numItems, CBoolVector &v);
void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
CUInt64DefVector &v, unsigned numItems);
HRESULT ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset, UInt64 &dataOffset,
CObjectVector<CByteBuffer> &dataVector
_7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
_7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
_7Z_DECODER_CRYPRO_VARS_DECL
);
public:
CInArchive(bool useMixerMT):
_numInByteBufs(0),
_useMixerMT(useMixerMT)
{}
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
void Close();
HRESULT ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
_7Z_DECODER_CRYPRO_VARS_DECL
);
};
}}
#endif

View File

@@ -1,202 +1,202 @@
// 7zItem.h
#ifndef __7Z_ITEM_H
#define __7Z_ITEM_H
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
#include "../../Common/MethodId.h"
#include "7zHeader.h"
namespace NArchive {
namespace N7z {
typedef UInt32 CNum;
const CNum kNumMax = 0x7FFFFFFF;
const CNum kNumNoIndex = 0xFFFFFFFF;
struct CCoderInfo
{
CMethodId MethodID;
CByteBuffer Props;
UInt32 NumStreams;
bool IsSimpleCoder() const { return NumStreams == 1; }
};
struct CBond
{
UInt32 PackIndex;
UInt32 UnpackIndex;
};
struct CFolder
{
CLASS_NO_COPY(CFolder)
public:
CObjArray2<CCoderInfo> Coders;
CObjArray2<CBond> Bonds;
CObjArray2<UInt32> PackStreams;
CFolder() {}
bool IsDecodingSupported() const { return Coders.Size() <= 32; }
int Find_in_PackStreams(UInt32 packStream) const
{
FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == packStream)
return i;
return -1;
}
int FindBond_for_PackStream(UInt32 packStream) const
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].PackIndex == packStream)
return i;
return -1;
}
/*
int FindBond_for_UnpackStream(UInt32 unpackStream) const
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].UnpackIndex == unpackStream)
return i;
return -1;
}
int FindOutCoder() const
{
for (int i = (int)Coders.Size() - 1; i >= 0; i--)
if (FindBond_for_UnpackStream(i) < 0)
return i;
return -1;
}
*/
bool IsEncrypted() const
{
FOR_VECTOR(i, Coders)
if (Coders[i].MethodID == k_AES)
return true;
return false;
}
};
struct CUInt32DefVector
{
CBoolVector Defs;
CRecordVector<UInt32> Vals;
void ClearAndSetSize(unsigned newSize)
{
Defs.ClearAndSetSize(newSize);
Vals.ClearAndSetSize(newSize);
}
void Clear()
{
Defs.Clear();
Vals.Clear();
}
void ReserveDown()
{
Defs.ReserveDown();
Vals.ReserveDown();
}
bool GetItem(unsigned index, UInt32 &value) const
{
if (index < Defs.Size() && Defs[index])
{
value = Vals[index];
return true;
}
value = 0;
return false;
}
bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
void SetItem(unsigned index, bool defined, UInt32 value);
};
struct CUInt64DefVector
{
CBoolVector Defs;
CRecordVector<UInt64> Vals;
void Clear()
{
Defs.Clear();
Vals.Clear();
}
void ReserveDown()
{
Defs.ReserveDown();
Vals.ReserveDown();
}
bool GetItem(unsigned index, UInt64 &value) const
{
if (index < Defs.Size() && Defs[index])
{
value = Vals[index];
return true;
}
value = 0;
return false;
}
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
void SetItem(unsigned index, bool defined, UInt64 value);
};
struct CFileItem
{
UInt64 Size;
UInt32 Crc;
/*
int Parent;
bool IsAltStream;
*/
bool HasStream; // Test it !!! it means that there is
// stream in some folder. It can be empty stream
bool IsDir;
bool CrcDefined;
/*
void Clear()
{
HasStream = true;
IsDir = false;
CrcDefined = false;
}
CFileItem():
// Parent(-1),
// IsAltStream(false),
HasStream(true),
IsDir(false),
CrcDefined(false),
{}
*/
};
}}
#endif
// 7zItem.h
#ifndef __7Z_ITEM_H
#define __7Z_ITEM_H
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
#include "../../Common/MethodId.h"
#include "7zHeader.h"
namespace NArchive {
namespace N7z {
typedef UInt32 CNum;
const CNum kNumMax = 0x7FFFFFFF;
const CNum kNumNoIndex = 0xFFFFFFFF;
struct CCoderInfo
{
CMethodId MethodID;
CByteBuffer Props;
UInt32 NumStreams;
bool IsSimpleCoder() const { return NumStreams == 1; }
};
struct CBond
{
UInt32 PackIndex;
UInt32 UnpackIndex;
};
struct CFolder
{
CLASS_NO_COPY(CFolder)
public:
CObjArray2<CCoderInfo> Coders;
CObjArray2<CBond> Bonds;
CObjArray2<UInt32> PackStreams;
CFolder() {}
bool IsDecodingSupported() const { return Coders.Size() <= 32; }
int Find_in_PackStreams(UInt32 packStream) const
{
FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == packStream)
return i;
return -1;
}
int FindBond_for_PackStream(UInt32 packStream) const
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].PackIndex == packStream)
return i;
return -1;
}
/*
int FindBond_for_UnpackStream(UInt32 unpackStream) const
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].UnpackIndex == unpackStream)
return i;
return -1;
}
int FindOutCoder() const
{
for (int i = (int)Coders.Size() - 1; i >= 0; i--)
if (FindBond_for_UnpackStream(i) < 0)
return i;
return -1;
}
*/
bool IsEncrypted() const
{
FOR_VECTOR(i, Coders)
if (Coders[i].MethodID == k_AES)
return true;
return false;
}
};
struct CUInt32DefVector
{
CBoolVector Defs;
CRecordVector<UInt32> Vals;
void ClearAndSetSize(unsigned newSize)
{
Defs.ClearAndSetSize(newSize);
Vals.ClearAndSetSize(newSize);
}
void Clear()
{
Defs.Clear();
Vals.Clear();
}
void ReserveDown()
{
Defs.ReserveDown();
Vals.ReserveDown();
}
bool GetItem(unsigned index, UInt32 &value) const
{
if (index < Defs.Size() && Defs[index])
{
value = Vals[index];
return true;
}
value = 0;
return false;
}
bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
void SetItem(unsigned index, bool defined, UInt32 value);
};
struct CUInt64DefVector
{
CBoolVector Defs;
CRecordVector<UInt64> Vals;
void Clear()
{
Defs.Clear();
Vals.Clear();
}
void ReserveDown()
{
Defs.ReserveDown();
Vals.ReserveDown();
}
bool GetItem(unsigned index, UInt64 &value) const
{
if (index < Defs.Size() && Defs[index])
{
value = Vals[index];
return true;
}
value = 0;
return false;
}
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
void SetItem(unsigned index, bool defined, UInt64 value);
};
struct CFileItem
{
UInt64 Size;
UInt32 Crc;
/*
int Parent;
bool IsAltStream;
*/
bool HasStream; // Test it !!! it means that there is
// stream in some folder. It can be empty stream
bool IsDir;
bool CrcDefined;
/*
void Clear()
{
HasStream = true;
IsDir = false;
CrcDefined = false;
}
CFileItem():
// Parent(-1),
// IsAltStream(false),
HasStream(true),
IsDir(false),
CrcDefined(false),
{}
*/
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,335 +1,335 @@
// 7zOut.h
#ifndef __7Z_OUT_H
#define __7Z_OUT_H
#include "7zCompressionMode.h"
#include "7zEncode.h"
#include "7zHeader.h"
#include "7zItem.h"
#include "../../Common/OutBuffer.h"
#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace N7z {
class CWriteBufferLoc
{
Byte *_data;
size_t _size;
size_t _pos;
public:
CWriteBufferLoc(): _size(0), _pos(0) {}
void Init(Byte *data, size_t size)
{
_data = data;
_size = size;
_pos = 0;
}
void WriteBytes(const void *data, size_t size)
{
if (size == 0)
return;
if (size > _size - _pos)
throw 1;
memcpy(_data + _pos, data, size);
_pos += size;
}
void WriteByte(Byte b)
{
if (_size == _pos)
throw 1;
_data[_pos++] = b;
}
size_t GetPos() const { return _pos; }
};
struct CHeaderOptions
{
bool CompressMainHeader;
/*
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
*/
CHeaderOptions():
CompressMainHeader(true)
/*
, WriteCTime(false)
, WriteATime(false)
, WriteMTime(true)
*/
{}
};
struct CFileItem2
{
UInt64 CTime;
UInt64 ATime;
UInt64 MTime;
UInt64 StartPos;
UInt32 Attrib;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool StartPosDefined;
bool AttribDefined;
bool IsAnti;
// bool IsAux;
/*
void Init()
{
CTimeDefined = false;
ATimeDefined = false;
MTimeDefined = false;
StartPosDefined = false;
AttribDefined = false;
IsAnti = false;
// IsAux = false;
}
*/
};
struct COutFolders
{
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
CRecordVector<CNum> NumUnpackStreamsVector;
CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
void OutFoldersClear()
{
FolderUnpackCRCs.Clear();
NumUnpackStreamsVector.Clear();
CoderUnpackSizes.Clear();
}
void OutFoldersReserveDown()
{
FolderUnpackCRCs.ReserveDown();
NumUnpackStreamsVector.ReserveDown();
CoderUnpackSizes.ReserveDown();
}
};
struct CArchiveDatabaseOut: public COutFolders
{
CRecordVector<UInt64> PackSizes;
CUInt32DefVector PackCRCs;
CObjectVector<CFolder> Folders;
CRecordVector<CFileItem> Files;
UStringVector Names;
CUInt64DefVector CTime;
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
CUInt32DefVector Attrib;
CBoolVector IsAnti;
/*
CBoolVector IsAux;
CByteBuffer SecureBuf;
CRecordVector<UInt32> SecureSizes;
CRecordVector<UInt32> SecureIDs;
void ClearSecure()
{
SecureBuf.Free();
SecureSizes.Clear();
SecureIDs.Clear();
}
*/
void Clear()
{
OutFoldersClear();
PackSizes.Clear();
PackCRCs.Clear();
Folders.Clear();
Files.Clear();
Names.Clear();
CTime.Clear();
ATime.Clear();
MTime.Clear();
StartPos.Clear();
Attrib.Clear();
IsAnti.Clear();
/*
IsAux.Clear();
ClearSecure();
*/
}
void ReserveDown()
{
OutFoldersReserveDown();
PackSizes.ReserveDown();
PackCRCs.ReserveDown();
Folders.ReserveDown();
Files.ReserveDown();
Names.ReserveDown();
CTime.ReserveDown();
ATime.ReserveDown();
MTime.ReserveDown();
StartPos.ReserveDown();
Attrib.ReserveDown();
IsAnti.ReserveDown();
/*
IsAux.ReserveDown();
*/
}
bool IsEmpty() const
{
return (
PackSizes.IsEmpty() &&
NumUnpackStreamsVector.IsEmpty() &&
Folders.IsEmpty() &&
Files.IsEmpty());
}
bool CheckNumFiles() const
{
unsigned size = Files.Size();
return (
CTime.CheckSize(size)
&& ATime.CheckSize(size)
&& MTime.CheckSize(size)
&& StartPos.CheckSize(size)
&& Attrib.CheckSize(size)
&& (size == IsAnti.Size() || IsAnti.Size() == 0));
}
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
// bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
void SetItem_Anti(unsigned index, bool isAnti)
{
while (index >= IsAnti.Size())
IsAnti.Add(false);
IsAnti[index] = isAnti;
}
/*
void SetItem_Aux(unsigned index, bool isAux)
{
while (index >= IsAux.Size())
IsAux.Add(false);
IsAux[index] = isAux;
}
*/
void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
};
class COutArchive
{
UInt64 _prefixHeaderPos;
HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); }
UInt64 GetPos() const;
void WriteBytes(const void *data, size_t size);
void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); }
void WriteByte(Byte b);
void WriteUInt32(UInt32 value);
void WriteUInt64(UInt64 value);
void WriteNumber(UInt64 value);
void WriteID(UInt64 value) { WriteNumber(value); }
void WriteFolder(const CFolder &folder);
HRESULT WriteFileHeader(const CFileItem &itemInfo);
void WriteBoolVector(const CBoolVector &boolVector);
void WritePropBoolVector(Byte id, const CBoolVector &boolVector);
void WriteHashDigests(const CUInt32DefVector &digests);
void WritePackInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
const CUInt32DefVector &packCRCs);
void WriteUnpackInfo(
const CObjectVector<CFolder> &folders,
const COutFolders &outFolders);
void WriteSubStreamsInfo(
const CObjectVector<CFolder> &folders,
const COutFolders &outFolders,
const CRecordVector<UInt64> &unpackSizes,
const CUInt32DefVector &digests);
void SkipToAligned(unsigned pos, unsigned alignShifts);
void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts);
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
HRESULT EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data,
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders);
void WriteHeader(
const CArchiveDatabaseOut &db,
// const CHeaderOptions &headerOptions,
UInt64 &headerOffset);
bool _countMode;
bool _writeToStream;
size_t _countSize;
UInt32 _crc;
COutBuffer _outByte;
CWriteBufferLoc _outByte2;
#ifdef _7Z_VOL
bool _endMarker;
#endif
bool _useAlign;
HRESULT WriteSignature();
#ifdef _7Z_VOL
HRESULT WriteFinishSignature();
#endif
HRESULT WriteStartHeader(const CStartHeader &h);
#ifdef _7Z_VOL
HRESULT WriteFinishHeader(const CFinishHeader &h);
#endif
CMyComPtr<IOutStream> Stream;
public:
COutArchive() { _outByte.Create(1 << 16); }
CMyComPtr<ISequentialOutStream> SeqStream;
HRESULT Create(ISequentialOutStream *stream, bool endMarker);
void Close();
HRESULT SkipPrefixArchiveHeader();
HRESULT WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
const CArchiveDatabaseOut &db,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions);
#ifdef _7Z_VOL
static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
#endif
};
}}
#endif
// 7zOut.h
#ifndef __7Z_OUT_H
#define __7Z_OUT_H
#include "7zCompressionMode.h"
#include "7zEncode.h"
#include "7zHeader.h"
#include "7zItem.h"
#include "../../Common/OutBuffer.h"
#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace N7z {
class CWriteBufferLoc
{
Byte *_data;
size_t _size;
size_t _pos;
public:
CWriteBufferLoc(): _size(0), _pos(0) {}
void Init(Byte *data, size_t size)
{
_data = data;
_size = size;
_pos = 0;
}
void WriteBytes(const void *data, size_t size)
{
if (size == 0)
return;
if (size > _size - _pos)
throw 1;
memcpy(_data + _pos, data, size);
_pos += size;
}
void WriteByte(Byte b)
{
if (_size == _pos)
throw 1;
_data[_pos++] = b;
}
size_t GetPos() const { return _pos; }
};
struct CHeaderOptions
{
bool CompressMainHeader;
/*
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
*/
CHeaderOptions():
CompressMainHeader(true)
/*
, WriteCTime(false)
, WriteATime(false)
, WriteMTime(true)
*/
{}
};
struct CFileItem2
{
UInt64 CTime;
UInt64 ATime;
UInt64 MTime;
UInt64 StartPos;
UInt32 Attrib;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool StartPosDefined;
bool AttribDefined;
bool IsAnti;
// bool IsAux;
/*
void Init()
{
CTimeDefined = false;
ATimeDefined = false;
MTimeDefined = false;
StartPosDefined = false;
AttribDefined = false;
IsAnti = false;
// IsAux = false;
}
*/
};
struct COutFolders
{
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
CRecordVector<CNum> NumUnpackStreamsVector;
CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
void OutFoldersClear()
{
FolderUnpackCRCs.Clear();
NumUnpackStreamsVector.Clear();
CoderUnpackSizes.Clear();
}
void OutFoldersReserveDown()
{
FolderUnpackCRCs.ReserveDown();
NumUnpackStreamsVector.ReserveDown();
CoderUnpackSizes.ReserveDown();
}
};
struct CArchiveDatabaseOut: public COutFolders
{
CRecordVector<UInt64> PackSizes;
CUInt32DefVector PackCRCs;
CObjectVector<CFolder> Folders;
CRecordVector<CFileItem> Files;
UStringVector Names;
CUInt64DefVector CTime;
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
CUInt32DefVector Attrib;
CBoolVector IsAnti;
/*
CBoolVector IsAux;
CByteBuffer SecureBuf;
CRecordVector<UInt32> SecureSizes;
CRecordVector<UInt32> SecureIDs;
void ClearSecure()
{
SecureBuf.Free();
SecureSizes.Clear();
SecureIDs.Clear();
}
*/
void Clear()
{
OutFoldersClear();
PackSizes.Clear();
PackCRCs.Clear();
Folders.Clear();
Files.Clear();
Names.Clear();
CTime.Clear();
ATime.Clear();
MTime.Clear();
StartPos.Clear();
Attrib.Clear();
IsAnti.Clear();
/*
IsAux.Clear();
ClearSecure();
*/
}
void ReserveDown()
{
OutFoldersReserveDown();
PackSizes.ReserveDown();
PackCRCs.ReserveDown();
Folders.ReserveDown();
Files.ReserveDown();
Names.ReserveDown();
CTime.ReserveDown();
ATime.ReserveDown();
MTime.ReserveDown();
StartPos.ReserveDown();
Attrib.ReserveDown();
IsAnti.ReserveDown();
/*
IsAux.ReserveDown();
*/
}
bool IsEmpty() const
{
return (
PackSizes.IsEmpty() &&
NumUnpackStreamsVector.IsEmpty() &&
Folders.IsEmpty() &&
Files.IsEmpty());
}
bool CheckNumFiles() const
{
unsigned size = Files.Size();
return (
CTime.CheckSize(size)
&& ATime.CheckSize(size)
&& MTime.CheckSize(size)
&& StartPos.CheckSize(size)
&& Attrib.CheckSize(size)
&& (size == IsAnti.Size() || IsAnti.Size() == 0));
}
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
// bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
void SetItem_Anti(unsigned index, bool isAnti)
{
while (index >= IsAnti.Size())
IsAnti.Add(false);
IsAnti[index] = isAnti;
}
/*
void SetItem_Aux(unsigned index, bool isAux)
{
while (index >= IsAux.Size())
IsAux.Add(false);
IsAux[index] = isAux;
}
*/
void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
};
class COutArchive
{
UInt64 _prefixHeaderPos;
HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); }
UInt64 GetPos() const;
void WriteBytes(const void *data, size_t size);
void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); }
void WriteByte(Byte b);
void WriteUInt32(UInt32 value);
void WriteUInt64(UInt64 value);
void WriteNumber(UInt64 value);
void WriteID(UInt64 value) { WriteNumber(value); }
void WriteFolder(const CFolder &folder);
HRESULT WriteFileHeader(const CFileItem &itemInfo);
void WriteBoolVector(const CBoolVector &boolVector);
void WritePropBoolVector(Byte id, const CBoolVector &boolVector);
void WriteHashDigests(const CUInt32DefVector &digests);
void WritePackInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
const CUInt32DefVector &packCRCs);
void WriteUnpackInfo(
const CObjectVector<CFolder> &folders,
const COutFolders &outFolders);
void WriteSubStreamsInfo(
const CObjectVector<CFolder> &folders,
const COutFolders &outFolders,
const CRecordVector<UInt64> &unpackSizes,
const CUInt32DefVector &digests);
void SkipToAligned(unsigned pos, unsigned alignShifts);
void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts);
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
HRESULT EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data,
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders);
void WriteHeader(
const CArchiveDatabaseOut &db,
// const CHeaderOptions &headerOptions,
UInt64 &headerOffset);
bool _countMode;
bool _writeToStream;
size_t _countSize;
UInt32 _crc;
COutBuffer _outByte;
CWriteBufferLoc _outByte2;
#ifdef _7Z_VOL
bool _endMarker;
#endif
bool _useAlign;
HRESULT WriteSignature();
#ifdef _7Z_VOL
HRESULT WriteFinishSignature();
#endif
HRESULT WriteStartHeader(const CStartHeader &h);
#ifdef _7Z_VOL
HRESULT WriteFinishHeader(const CFinishHeader &h);
#endif
CMyComPtr<IOutStream> Stream;
public:
COutArchive() { _outByte.Create(1 << 16); }
CMyComPtr<ISequentialOutStream> SeqStream;
HRESULT Create(ISequentialOutStream *stream, bool endMarker);
void Close();
HRESULT SkipPrefixArchiveHeader();
HRESULT WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
const CArchiveDatabaseOut &db,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions);
#ifdef _7Z_VOL
static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
#endif
};
}}
#endif

View File

@@ -1,174 +1,174 @@
// 7zProperties.cpp
#include "StdAfx.h"
#include "7zProperties.h"
#include "7zHeader.h"
#include "7zHandler.h"
// #define _MULTI_PACK
namespace NArchive {
namespace N7z {
struct CPropMap
{
UInt32 FilePropID;
CStatProp StatProp;
};
static const CPropMap kPropMap[] =
{
{ NID::kName, { NULL, kpidPath, VT_BSTR } },
{ NID::kSize, { NULL, kpidSize, VT_UI8 } },
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
#ifdef _MULTI_PACK
{ 100, { "Pack0", kpidPackedSize0, VT_UI8 } },
{ 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
{ 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
{ 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
{ 104, { "Pack4", kpidPackedSize4, VT_UI8 } },
#endif
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
{ NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
{ NID::kStartPos, { NULL, kpidPosition, VT_UI8 } },
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } },
{ NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }
#ifndef _SFX
,
{ 97, { NULL, kpidEncrypted, VT_BOOL } },
{ 98, { NULL, kpidMethod, VT_BSTR } },
{ 99, { NULL, kpidBlock, VT_UI4 } }
#endif
};
static void CopyOneItem(CRecordVector<UInt64> &src,
CRecordVector<UInt64> &dest, UInt32 item)
{
FOR_VECTOR (i, src)
if (src[i] == item)
{
dest.Add(item);
src.Delete(i);
return;
}
}
static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
{
FOR_VECTOR (i, src)
if (src[i] == item)
{
src.Delete(i);
return;
}
}
static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
{
FOR_VECTOR (i, dest)
if (dest[i] == item)
{
dest.Delete(i);
break;
}
dest.Insert(0, item);
}
#define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id);
void CHandler::FillPopIDs()
{
_fileInfoPopIDs.Clear();
#ifdef _7Z_VOL
if (_volumes.Size() < 1)
return;
const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_db = volume.Database;
#endif
CRecordVector<UInt64> fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs;
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
/*
RemoveOneItem(fileInfoPopIDs, NID::kParent);
RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
*/
COPY_ONE_ITEM(kName);
COPY_ONE_ITEM(kAnti);
COPY_ONE_ITEM(kSize);
COPY_ONE_ITEM(kPackInfo);
COPY_ONE_ITEM(kCTime);
COPY_ONE_ITEM(kMTime);
COPY_ONE_ITEM(kATime);
COPY_ONE_ITEM(kWinAttrib);
COPY_ONE_ITEM(kCRC);
COPY_ONE_ITEM(kComment);
_fileInfoPopIDs += fileInfoPopIDs;
#ifndef _SFX
_fileInfoPopIDs.Add(97);
_fileInfoPopIDs.Add(98);
_fileInfoPopIDs.Add(99);
#endif
#ifdef _MULTI_PACK
_fileInfoPopIDs.Add(100);
_fileInfoPopIDs.Add(101);
_fileInfoPopIDs.Add(102);
_fileInfoPopIDs.Add(103);
_fileInfoPopIDs.Add(104);
#endif
#ifndef _SFX
InsertToHead(_fileInfoPopIDs, NID::kMTime);
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
InsertToHead(_fileInfoPopIDs, NID::kSize);
InsertToHead(_fileInfoPopIDs, NID::kName);
#endif
}
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
{
*numProps = _fileInfoPopIDs.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
{
if (index >= _fileInfoPopIDs.Size())
return E_INVALIDARG;
UInt64 id = _fileInfoPopIDs[index];
for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++)
{
const CPropMap &pr = kPropMap[i];
if (pr.FilePropID == id)
{
const CStatProp &st = pr.StatProp;
*propID = st.PropID;
*varType = st.vt;
/*
if (st.lpwstrName)
*name = ::SysAllocString(st.lpwstrName);
else
*/
*name = NULL;
return S_OK;
}
}
return E_INVALIDARG;
}
}}
// 7zProperties.cpp
#include "StdAfx.h"
#include "7zProperties.h"
#include "7zHeader.h"
#include "7zHandler.h"
// #define _MULTI_PACK
namespace NArchive {
namespace N7z {
struct CPropMap
{
UInt32 FilePropID;
CStatProp StatProp;
};
static const CPropMap kPropMap[] =
{
{ NID::kName, { NULL, kpidPath, VT_BSTR } },
{ NID::kSize, { NULL, kpidSize, VT_UI8 } },
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
#ifdef _MULTI_PACK
{ 100, { "Pack0", kpidPackedSize0, VT_UI8 } },
{ 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
{ 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
{ 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
{ 104, { "Pack4", kpidPackedSize4, VT_UI8 } },
#endif
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
{ NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
{ NID::kStartPos, { NULL, kpidPosition, VT_UI8 } },
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } },
{ NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }
#ifndef _SFX
,
{ 97, { NULL, kpidEncrypted, VT_BOOL } },
{ 98, { NULL, kpidMethod, VT_BSTR } },
{ 99, { NULL, kpidBlock, VT_UI4 } }
#endif
};
static void CopyOneItem(CRecordVector<UInt64> &src,
CRecordVector<UInt64> &dest, UInt32 item)
{
FOR_VECTOR (i, src)
if (src[i] == item)
{
dest.Add(item);
src.Delete(i);
return;
}
}
static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
{
FOR_VECTOR (i, src)
if (src[i] == item)
{
src.Delete(i);
return;
}
}
static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
{
FOR_VECTOR (i, dest)
if (dest[i] == item)
{
dest.Delete(i);
break;
}
dest.Insert(0, item);
}
#define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id);
void CHandler::FillPopIDs()
{
_fileInfoPopIDs.Clear();
#ifdef _7Z_VOL
if (_volumes.Size() < 1)
return;
const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_db = volume.Database;
#endif
CRecordVector<UInt64> fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs;
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
/*
RemoveOneItem(fileInfoPopIDs, NID::kParent);
RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
*/
COPY_ONE_ITEM(kName);
COPY_ONE_ITEM(kAnti);
COPY_ONE_ITEM(kSize);
COPY_ONE_ITEM(kPackInfo);
COPY_ONE_ITEM(kCTime);
COPY_ONE_ITEM(kMTime);
COPY_ONE_ITEM(kATime);
COPY_ONE_ITEM(kWinAttrib);
COPY_ONE_ITEM(kCRC);
COPY_ONE_ITEM(kComment);
_fileInfoPopIDs += fileInfoPopIDs;
#ifndef _SFX
_fileInfoPopIDs.Add(97);
_fileInfoPopIDs.Add(98);
_fileInfoPopIDs.Add(99);
#endif
#ifdef _MULTI_PACK
_fileInfoPopIDs.Add(100);
_fileInfoPopIDs.Add(101);
_fileInfoPopIDs.Add(102);
_fileInfoPopIDs.Add(103);
_fileInfoPopIDs.Add(104);
#endif
#ifndef _SFX
InsertToHead(_fileInfoPopIDs, NID::kMTime);
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
InsertToHead(_fileInfoPopIDs, NID::kSize);
InsertToHead(_fileInfoPopIDs, NID::kName);
#endif
}
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
{
*numProps = _fileInfoPopIDs.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
{
if (index >= _fileInfoPopIDs.Size())
return E_INVALIDARG;
UInt64 id = _fileInfoPopIDs[index];
for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++)
{
const CPropMap &pr = kPropMap[i];
if (pr.FilePropID == id)
{
const CStatProp &st = pr.StatProp;
*propID = st.PropID;
*varType = st.vt;
/*
if (st.lpwstrName)
*name = ::SysAllocString(st.lpwstrName);
else
*/
*name = NULL;
return S_OK;
}
}
return E_INVALIDARG;
}
}}

View File

@@ -1,22 +1,22 @@
// 7zProperties.h
#ifndef __7Z_PROPERTIES_H
#define __7Z_PROPERTIES_H
#include "../../PropID.h"
namespace NArchive {
namespace N7z {
enum
{
kpidPackedSize0 = kpidUserDefined,
kpidPackedSize1,
kpidPackedSize2,
kpidPackedSize3,
kpidPackedSize4
};
}}
#endif
// 7zProperties.h
#ifndef __7Z_PROPERTIES_H
#define __7Z_PROPERTIES_H
#include "../../PropID.h"
namespace NArchive {
namespace N7z {
enum
{
kpidPackedSize0 = kpidUserDefined,
kpidPackedSize1,
kpidPackedSize2,
kpidPackedSize3,
kpidPackedSize4
};
}}
#endif

View File

@@ -1,21 +1,21 @@
// 7zRegister.cpp
#include "StdAfx.h"
#include "../../Common/RegisterArc.h"
#include "7zHandler.h"
namespace NArchive {
namespace N7z {
static Byte k_Signature_Dec[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
REGISTER_ARC_IO_DECREMENT_SIG(
"7z", "7z", NULL, 7,
k_Signature_Dec,
0,
NArcInfoFlags::kFindSignature,
NULL);
}}
// 7zRegister.cpp
#include "StdAfx.h"
#include "../../Common/RegisterArc.h"
#include "7zHandler.h"
namespace NArchive {
namespace N7z {
static Byte k_Signature_Dec[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
REGISTER_ARC_IO_DECREMENT_SIG(
"7z", "7z", NULL, 7,
k_Signature_Dec,
0,
NArcInfoFlags::kFindSignature,
NULL);
}}

View File

@@ -1,22 +1,22 @@
// 7zSpecStream.cpp
#include "StdAfx.h"
#include "7zSpecStream.h"
STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize)
*processedSize = realProcessedSize;
return result;
}
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
if (!_getSubStreamSize)
return E_NOTIMPL;
return _getSubStreamSize->GetSubStreamSize(subStream, value);
}
// 7zSpecStream.cpp
#include "StdAfx.h"
#include "7zSpecStream.h"
STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize)
*processedSize = realProcessedSize;
return result;
}
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
if (!_getSubStreamSize)
return E_NOTIMPL;
return _getSubStreamSize->GetSubStreamSize(subStream, value);
}

View File

@@ -1,35 +1,35 @@
// 7zSpecStream.h
#ifndef __7Z_SPEC_STREAM_H
#define __7Z_SPEC_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../ICoder.h"
class CSequentialInStreamSizeCount2:
public ISequentialInStream,
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _stream;
CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
UInt64 _size;
public:
void Init(ISequentialInStream *stream)
{
_size = 0;
_getSubStreamSize.Release();
_stream = stream;
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
}
UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
};
#endif
// 7zSpecStream.h
#ifndef __7Z_SPEC_STREAM_H
#define __7Z_SPEC_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../ICoder.h"
class CSequentialInStreamSizeCount2:
public ISequentialInStream,
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _stream;
CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
UInt64 _size;
public:
void Init(ISequentialInStream *stream)
{
_size = 0;
_getSubStreamSize.Release();
_stream = stream;
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
}
UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
};
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,139 +1,139 @@
// 7zUpdate.h
#ifndef __7Z_UPDATE_H
#define __7Z_UPDATE_H
#include "../IArchive.h"
// #include "../../Common/UniqBlocks.h"
#include "7zCompressionMode.h"
#include "7zIn.h"
#include "7zOut.h"
namespace NArchive {
namespace N7z {
/*
struct CTreeFolder
{
UString Name;
int Parent;
CIntVector SubFolders;
int UpdateItemIndex;
int SortIndex;
int SortIndexEnd;
CTreeFolder(): UpdateItemIndex(-1) {}
};
*/
struct CUpdateItem
{
int IndexInArchive;
int IndexInClient;
UInt64 CTime;
UInt64 ATime;
UInt64 MTime;
UInt64 Size;
UString Name;
/*
bool IsAltStream;
int ParentFolderIndex;
int TreeFolderIndex;
*/
// that code is not used in 9.26
// int ParentSortIndex;
// int ParentSortIndexEnd;
UInt32 Attrib;
bool NewData;
bool NewProps;
bool IsAnti;
bool IsDir;
bool AttribDefined;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
// int SecureIndex; // 0 means (no_security)
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
// bool HasStream() const { return !IsDir && !IsAnti /* && Size != 0 */; } // for test purposes
CUpdateItem():
// ParentSortIndex(-1),
// IsAltStream(false),
IsAnti(false),
IsDir(false),
AttribDefined(false),
CTimeDefined(false),
ATimeDefined(false),
MTimeDefined(false)
// SecureIndex(0)
{}
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }
// unsigned GetExtensionPos() const;
// UString GetExtension() const;
};
struct CUpdateOptions
{
const CCompressionMethodMode *Method;
const CCompressionMethodMode *HeaderMethod;
bool UseFilters; // use additional filters for some files
bool MaxFilter; // use BCJ2 filter instead of BCJ
int AnalysisLevel;
CHeaderOptions HeaderOptions;
UInt64 NumSolidFiles;
UInt64 NumSolidBytes;
bool SolidExtension;
bool UseTypeSorting;
bool RemoveSfxBlock;
bool MultiThreadMixer;
CUpdateOptions():
Method(NULL),
HeaderMethod(NULL),
UseFilters(false),
MaxFilter(false),
AnalysisLevel(-1),
NumSolidFiles((UInt64)(Int64)(-1)),
NumSolidBytes((UInt64)(Int64)(-1)),
SolidExtension(false),
UseTypeSorting(true),
RemoveSfxBlock(false),
MultiThreadMixer(true)
{}
};
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
const CDbEx *db,
const CObjectVector<CUpdateItem> &updateItems,
// const CObjectVector<CTreeFolder> &treeFolders, // treeFolders[0] is root
// const CUniqBlocks &secureBlocks,
COutArchive &archive,
CArchiveDatabaseOut &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options
#ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getDecoderPassword
#endif
);
}}
#endif
// 7zUpdate.h
#ifndef __7Z_UPDATE_H
#define __7Z_UPDATE_H
#include "../IArchive.h"
// #include "../../Common/UniqBlocks.h"
#include "7zCompressionMode.h"
#include "7zIn.h"
#include "7zOut.h"
namespace NArchive {
namespace N7z {
/*
struct CTreeFolder
{
UString Name;
int Parent;
CIntVector SubFolders;
int UpdateItemIndex;
int SortIndex;
int SortIndexEnd;
CTreeFolder(): UpdateItemIndex(-1) {}
};
*/
struct CUpdateItem
{
int IndexInArchive;
int IndexInClient;
UInt64 CTime;
UInt64 ATime;
UInt64 MTime;
UInt64 Size;
UString Name;
/*
bool IsAltStream;
int ParentFolderIndex;
int TreeFolderIndex;
*/
// that code is not used in 9.26
// int ParentSortIndex;
// int ParentSortIndexEnd;
UInt32 Attrib;
bool NewData;
bool NewProps;
bool IsAnti;
bool IsDir;
bool AttribDefined;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
// int SecureIndex; // 0 means (no_security)
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
// bool HasStream() const { return !IsDir && !IsAnti /* && Size != 0 */; } // for test purposes
CUpdateItem():
// ParentSortIndex(-1),
// IsAltStream(false),
IsAnti(false),
IsDir(false),
AttribDefined(false),
CTimeDefined(false),
ATimeDefined(false),
MTimeDefined(false)
// SecureIndex(0)
{}
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }
// unsigned GetExtensionPos() const;
// UString GetExtension() const;
};
struct CUpdateOptions
{
const CCompressionMethodMode *Method;
const CCompressionMethodMode *HeaderMethod;
bool UseFilters; // use additional filters for some files
bool MaxFilter; // use BCJ2 filter instead of BCJ
int AnalysisLevel;
CHeaderOptions HeaderOptions;
UInt64 NumSolidFiles;
UInt64 NumSolidBytes;
bool SolidExtension;
bool UseTypeSorting;
bool RemoveSfxBlock;
bool MultiThreadMixer;
CUpdateOptions():
Method(NULL),
HeaderMethod(NULL),
UseFilters(false),
MaxFilter(false),
AnalysisLevel(-1),
NumSolidFiles((UInt64)(Int64)(-1)),
NumSolidBytes((UInt64)(Int64)(-1)),
SolidExtension(false),
UseTypeSorting(true),
RemoveSfxBlock(false),
MultiThreadMixer(true)
{}
};
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
const CDbEx *db,
const CObjectVector<CUpdateItem> &updateItems,
// const CObjectVector<CTreeFolder> &treeFolders, // treeFolders[0] is root
// const CUniqBlocks &secureBlocks,
COutArchive &archive,
CArchiveDatabaseOut &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options
#ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getDecoderPassword
#endif
);
}}
#endif

View File

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

View File

@@ -1,8 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

@@ -1,81 +1,81 @@
PROG = 7z.dll
DEF_FILE = ../Archive.def
CFLAGS = $(CFLAGS) \
-DEXTERNAL_CODECS \
AR_OBJS = \
$O\ArchiveExports.obj \
$O\DllExports.obj \
7Z_OBJS = \
$O\7zCompressionMode.obj \
$O\7zDecode.obj \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
$O\7zOut.obj \
$O\7zProperties.obj \
$O\7zSpecStream.obj \
$O\7zUpdate.obj \
$O\7zRegister.obj \
COMMON_OBJS = \
$O\CRC.obj \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\MyVector.obj \
$O\Wildcard.obj \
WIN_OBJS = \
$O\DLL.obj \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
$O\FileName.obj \
$O\PropVariant.obj \
$O\Synchronization.obj \
$O\System.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
$O\InOutTempBuffer.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
$O\LockedStream.obj \
$O\MethodId.obj \
$O\MethodProps.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
$O\PropId.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
$O\VirtThread.obj \
COMPRESS_OBJS = \
$O\CopyCoder.obj \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
$O\HandlerOut.obj \
$O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \
$O\MultiStream.obj \
$O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \
C_OBJS = \
$O\Alloc.obj \
$O\CpuArch.obj \
$O\Threads.obj \
!include "../../Crc.mak"
!include "../../7zip.mak"
PROG = 7z.dll
DEF_FILE = ../Archive.def
CFLAGS = $(CFLAGS) \
-DEXTERNAL_CODECS \
AR_OBJS = \
$O\ArchiveExports.obj \
$O\DllExports.obj \
7Z_OBJS = \
$O\7zCompressionMode.obj \
$O\7zDecode.obj \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
$O\7zOut.obj \
$O\7zProperties.obj \
$O\7zSpecStream.obj \
$O\7zUpdate.obj \
$O\7zRegister.obj \
COMMON_OBJS = \
$O\CRC.obj \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\MyVector.obj \
$O\Wildcard.obj \
WIN_OBJS = \
$O\DLL.obj \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
$O\FileName.obj \
$O\PropVariant.obj \
$O\Synchronization.obj \
$O\System.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
$O\InOutTempBuffer.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
$O\LockedStream.obj \
$O\MethodId.obj \
$O\MethodProps.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
$O\PropId.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
$O\VirtThread.obj \
COMPRESS_OBJS = \
$O\CopyCoder.obj \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
$O\HandlerOut.obj \
$O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \
$O\MultiStream.obj \
$O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \
C_OBJS = \
$O\Alloc.obj \
$O\CpuArch.obj \
$O\Threads.obj \
!include "../../Crc.mak"
!include "../../7zip.mak"

View File

@@ -1,11 +1,11 @@
#include "../../MyVersionInfo.rc"
MY_VERSION_INFO_DLL("7z Plugin", "7z")
0 ICON "../Icons/7z.ico"
STRINGTABLE
BEGIN
100 "7z:0"
END
#include "../../MyVersionInfo.rc"
MY_VERSION_INFO_DLL("7z Plugin", "7z")
0 ICON "../Icons/7z.ico"
STRINGTABLE
BEGIN
100 "7z:0"
END

View File

@@ -1,315 +1,315 @@
// ApmHandler.cpp
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/Defs.h"
#include "../../Windows/PropVariant.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "HandlerCont.h"
#define Get16(p) GetBe16(p)
#define Get32(p) GetBe32(p)
using namespace NWindows;
namespace NArchive {
namespace NApm {
static const Byte kSig0 = 'E';
static const Byte kSig1 = 'R';
struct CItem
{
UInt32 StartBlock;
UInt32 NumBlocks;
char Name[32];
char Type[32];
/*
UInt32 DataStartBlock;
UInt32 NumDataBlocks;
UInt32 Status;
UInt32 BootStartBlock;
UInt32 BootSize;
UInt32 BootAddr;
UInt32 BootEntry;
UInt32 BootChecksum;
char Processor[16];
*/
bool Parse(const Byte *p, UInt32 &numBlocksInMap)
{
numBlocksInMap = Get32(p + 4);
StartBlock = Get32(p + 8);
NumBlocks = Get32(p + 0xC);
memcpy(Name, p + 0x10, 32);
memcpy(Type, p + 0x30, 32);
if (p[0] != 0x50 || p[1] != 0x4D || p[2] != 0 || p[3] != 0)
return false;
/*
DataStartBlock = Get32(p + 0x50);
NumDataBlocks = Get32(p + 0x54);
Status = Get32(p + 0x58);
BootStartBlock = Get32(p + 0x5C);
BootSize = Get32(p + 0x60);
BootAddr = Get32(p + 0x64);
if (Get32(p + 0x68) != 0)
return false;
BootEntry = Get32(p + 0x6C);
if (Get32(p + 0x70) != 0)
return false;
BootChecksum = Get32(p + 0x74);
memcpy(Processor, p + 0x78, 16);
*/
return true;
}
};
class CHandler: public CHandlerCont
{
CRecordVector<CItem> _items;
unsigned _blockSizeLog;
UInt32 _numBlocks;
UInt64 _phySize;
bool _isArc;
HRESULT ReadTables(IInStream *stream);
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CItem &item = _items[index];
pos = BlocksToBytes(item.StartBlock);
size = BlocksToBytes(item.NumBlocks);
return NExtract::NOperationResult::kOK;
}
public:
INTERFACE_IInArchive_Cont(;)
};
static const UInt32 kSectorSize = 512;
API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size)
{
if (size < kSectorSize)
return k_IsArc_Res_NEED_MORE;
if (p[0] != kSig0 || p[1] != kSig1)
return k_IsArc_Res_NO;
unsigned i;
for (i = 8; i < 16; i++)
if (p[i] != 0)
return k_IsArc_Res_NO;
UInt32 blockSize = Get16(p + 2);
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
if (i >= 12)
return k_IsArc_Res_NO;
return k_IsArc_Res_YES;
}
}
HRESULT CHandler::ReadTables(IInStream *stream)
{
Byte buf[kSectorSize];
{
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
if (buf[0] != kSig0 || buf[1] != kSig1)
return S_FALSE;
UInt32 blockSize = Get16(buf + 2);
unsigned i;
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
if (i >= 12)
return S_FALSE;
_blockSizeLog = i;
_numBlocks = Get32(buf + 4);
for (i = 8; i < 16; i++)
if (buf[i] != 0)
return S_FALSE;
}
unsigned numSkips = (unsigned)1 << (_blockSizeLog - 9);
for (unsigned j = 1; j < numSkips; j++)
{
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
}
UInt32 numBlocksInMap = 0;
for (unsigned i = 0;;)
{
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
CItem item;
UInt32 numBlocksInMap2 = 0;
if (!item.Parse(buf, numBlocksInMap2))
return S_FALSE;
if (i == 0)
{
numBlocksInMap = numBlocksInMap2;
if (numBlocksInMap > (1 << 8))
return S_FALSE;
}
else if (numBlocksInMap2 != numBlocksInMap)
return S_FALSE;
UInt32 finish = item.StartBlock + item.NumBlocks;
if (finish < item.StartBlock)
return S_FALSE;
_numBlocks = MyMax(_numBlocks, finish);
_items.Add(item);
for (unsigned j = 1; j < numSkips; j++)
{
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
}
if (++i == numBlocksInMap)
break;
}
_phySize = BlocksToBytes(_numBlocks);
_isArc = true;
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)
{
COM_TRY_BEGIN
Close();
RINOK(ReadTables(stream));
_stream = stream;
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_isArc = false;
_phySize = 0;
_items.Clear();
_stream.Release();
return S_OK;
}
static const Byte kProps[] =
{
kpidPath,
kpidSize,
kpidOffset
};
static const Byte kArcProps[] =
{
kpidClusterSize
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
static AString GetString(const char *s)
{
AString res;
for (unsigned i = 0; i < 32 && s[i] != 0; i++)
res += s[i];
return res;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
switch (propID)
{
case kpidMainSubfile:
{
int mainIndex = -1;
FOR_VECTOR (i, _items)
{
AString s (GetString(_items[i].Type));
if (s != "Apple_Free" &&
s != "Apple_partition_map")
{
if (mainIndex >= 0)
{
mainIndex = -1;
break;
}
mainIndex = i;
}
}
if (mainIndex >= 0)
prop = (UInt32)mainIndex;
break;
}
case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break;
case kpidPhySize: prop = _phySize; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
prop = v;
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
const CItem &item = _items[index];
switch (propID)
{
case kpidPath:
{
AString s (GetString(item.Name));
if (s.IsEmpty())
s.Add_UInt32(index);
AString type (GetString(item.Type));
if (type == "Apple_HFS")
type = "hfs";
if (!type.IsEmpty())
{
s += '.';
s += type;
}
prop = s;
break;
}
case kpidSize:
case kpidPackSize:
prop = BlocksToBytes(item.NumBlocks);
break;
case kpidOffset: prop = BlocksToBytes(item.StartBlock); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
static const Byte k_Signature[] = { kSig0, kSig1 };
REGISTER_ARC_I(
"APM", "apm", 0, 0xD4,
k_Signature,
0,
0,
IsArc_Apm)
}}
// ApmHandler.cpp
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/Defs.h"
#include "../../Windows/PropVariant.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "HandlerCont.h"
#define Get16(p) GetBe16(p)
#define Get32(p) GetBe32(p)
using namespace NWindows;
namespace NArchive {
namespace NApm {
static const Byte kSig0 = 'E';
static const Byte kSig1 = 'R';
struct CItem
{
UInt32 StartBlock;
UInt32 NumBlocks;
char Name[32];
char Type[32];
/*
UInt32 DataStartBlock;
UInt32 NumDataBlocks;
UInt32 Status;
UInt32 BootStartBlock;
UInt32 BootSize;
UInt32 BootAddr;
UInt32 BootEntry;
UInt32 BootChecksum;
char Processor[16];
*/
bool Parse(const Byte *p, UInt32 &numBlocksInMap)
{
numBlocksInMap = Get32(p + 4);
StartBlock = Get32(p + 8);
NumBlocks = Get32(p + 0xC);
memcpy(Name, p + 0x10, 32);
memcpy(Type, p + 0x30, 32);
if (p[0] != 0x50 || p[1] != 0x4D || p[2] != 0 || p[3] != 0)
return false;
/*
DataStartBlock = Get32(p + 0x50);
NumDataBlocks = Get32(p + 0x54);
Status = Get32(p + 0x58);
BootStartBlock = Get32(p + 0x5C);
BootSize = Get32(p + 0x60);
BootAddr = Get32(p + 0x64);
if (Get32(p + 0x68) != 0)
return false;
BootEntry = Get32(p + 0x6C);
if (Get32(p + 0x70) != 0)
return false;
BootChecksum = Get32(p + 0x74);
memcpy(Processor, p + 0x78, 16);
*/
return true;
}
};
class CHandler: public CHandlerCont
{
CRecordVector<CItem> _items;
unsigned _blockSizeLog;
UInt32 _numBlocks;
UInt64 _phySize;
bool _isArc;
HRESULT ReadTables(IInStream *stream);
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CItem &item = _items[index];
pos = BlocksToBytes(item.StartBlock);
size = BlocksToBytes(item.NumBlocks);
return NExtract::NOperationResult::kOK;
}
public:
INTERFACE_IInArchive_Cont(;)
};
static const UInt32 kSectorSize = 512;
API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size)
{
if (size < kSectorSize)
return k_IsArc_Res_NEED_MORE;
if (p[0] != kSig0 || p[1] != kSig1)
return k_IsArc_Res_NO;
unsigned i;
for (i = 8; i < 16; i++)
if (p[i] != 0)
return k_IsArc_Res_NO;
UInt32 blockSize = Get16(p + 2);
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
if (i >= 12)
return k_IsArc_Res_NO;
return k_IsArc_Res_YES;
}
}
HRESULT CHandler::ReadTables(IInStream *stream)
{
Byte buf[kSectorSize];
{
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
if (buf[0] != kSig0 || buf[1] != kSig1)
return S_FALSE;
UInt32 blockSize = Get16(buf + 2);
unsigned i;
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
if (i >= 12)
return S_FALSE;
_blockSizeLog = i;
_numBlocks = Get32(buf + 4);
for (i = 8; i < 16; i++)
if (buf[i] != 0)
return S_FALSE;
}
unsigned numSkips = (unsigned)1 << (_blockSizeLog - 9);
for (unsigned j = 1; j < numSkips; j++)
{
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
}
UInt32 numBlocksInMap = 0;
for (unsigned i = 0;;)
{
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
CItem item;
UInt32 numBlocksInMap2 = 0;
if (!item.Parse(buf, numBlocksInMap2))
return S_FALSE;
if (i == 0)
{
numBlocksInMap = numBlocksInMap2;
if (numBlocksInMap > (1 << 8))
return S_FALSE;
}
else if (numBlocksInMap2 != numBlocksInMap)
return S_FALSE;
UInt32 finish = item.StartBlock + item.NumBlocks;
if (finish < item.StartBlock)
return S_FALSE;
_numBlocks = MyMax(_numBlocks, finish);
_items.Add(item);
for (unsigned j = 1; j < numSkips; j++)
{
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
}
if (++i == numBlocksInMap)
break;
}
_phySize = BlocksToBytes(_numBlocks);
_isArc = true;
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)
{
COM_TRY_BEGIN
Close();
RINOK(ReadTables(stream));
_stream = stream;
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_isArc = false;
_phySize = 0;
_items.Clear();
_stream.Release();
return S_OK;
}
static const Byte kProps[] =
{
kpidPath,
kpidSize,
kpidOffset
};
static const Byte kArcProps[] =
{
kpidClusterSize
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
static AString GetString(const char *s)
{
AString res;
for (unsigned i = 0; i < 32 && s[i] != 0; i++)
res += s[i];
return res;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
switch (propID)
{
case kpidMainSubfile:
{
int mainIndex = -1;
FOR_VECTOR (i, _items)
{
AString s (GetString(_items[i].Type));
if (s != "Apple_Free" &&
s != "Apple_partition_map")
{
if (mainIndex >= 0)
{
mainIndex = -1;
break;
}
mainIndex = i;
}
}
if (mainIndex >= 0)
prop = (UInt32)mainIndex;
break;
}
case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break;
case kpidPhySize: prop = _phySize; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
prop = v;
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
const CItem &item = _items[index];
switch (propID)
{
case kpidPath:
{
AString s (GetString(item.Name));
if (s.IsEmpty())
s.Add_UInt32(index);
AString type (GetString(item.Type));
if (type == "Apple_HFS")
type = "hfs";
if (!type.IsEmpty())
{
s += '.';
s += type;
}
prop = s;
break;
}
case kpidSize:
case kpidPackSize:
prop = BlocksToBytes(item.NumBlocks);
break;
case kpidOffset: prop = BlocksToBytes(item.StartBlock); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
static const Byte k_Signature[] = { kSig0, kSig1 };
REGISTER_ARC_I(
"APM", "apm", 0, 0xD4,
k_Signature,
0,
0,
IsArc_Apm)
}}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
GetIsArc PRIVATE
SetCodecs PRIVATE
SetLargePageMode PRIVATE
SetCaseSensitive PRIVATE
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
GetIsArc PRIVATE
SetCodecs PRIVATE
SetLargePageMode PRIVATE
SetCaseSensitive PRIVATE

View File

@@ -1,19 +1,19 @@
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
GetIsArc PRIVATE
GetNumberOfMethods PRIVATE
GetMethodProperty PRIVATE
CreateDecoder PRIVATE
CreateEncoder PRIVATE
GetHashers PRIVATE
SetCodecs PRIVATE
SetLargePageMode PRIVATE
SetCaseSensitive PRIVATE
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
GetIsArc PRIVATE
GetNumberOfMethods PRIVATE
GetMethodProperty PRIVATE
CreateDecoder PRIVATE
CreateEncoder PRIVATE
GetHashers PRIVATE
SetCodecs PRIVATE
SetLargePageMode PRIVATE
SetCaseSensitive PRIVATE

View File

@@ -1,151 +1,151 @@
// ArchiveExports.cpp
#include "StdAfx.h"
#include "../../../C/7zVersion.h"
#include "../../Common/ComTry.h"
#include "../../Windows/PropVariant.h"
#include "../Common/RegisterArc.h"
static const unsigned kNumArcsMax = 64;
static unsigned g_NumArcs = 0;
static unsigned g_DefaultArcIndex = 0;
static const CArcInfo *g_Arcs[kNumArcsMax];
void RegisterArc(const CArcInfo *arcInfo) throw()
{
if (g_NumArcs < kNumArcsMax)
{
const char *p = arcInfo->Name;
if (p[0] == '7' && p[1] == 'z' && p[2] == 0)
g_DefaultArcIndex = g_NumArcs;
g_Arcs[g_NumArcs++] = arcInfo;
}
}
DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value)
{
if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
value->vt = VT_BSTR;
return S_OK;
}
static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
{
return SetPropStrFromBin((const char *)&guid, sizeof(guid), value);
}
int FindFormatCalssId(const GUID *clsid)
{
GUID cls = *clsid;
CLS_ARC_ID_ITEM(cls) = 0;
if (cls != CLSID_CArchiveHandler)
return -1;
Byte id = CLS_ARC_ID_ITEM(*clsid);
for (unsigned i = 0; i < g_NumArcs; i++)
if (g_Arcs[i]->Id == id)
return (int)i;
return -1;
}
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
{
COM_TRY_BEGIN
{
int needIn = (*iid == IID_IInArchive);
int needOut = (*iid == IID_IOutArchive);
if (!needIn && !needOut)
return E_NOINTERFACE;
int formatIndex = FindFormatCalssId(clsid);
if (formatIndex < 0)
return CLASS_E_CLASSNOTAVAILABLE;
const CArcInfo &arc = *g_Arcs[formatIndex];
if (needIn)
{
*outObject = arc.CreateInArchive();
((IInArchive *)*outObject)->AddRef();
}
else
{
if (!arc.CreateOutArchive)
return CLASS_E_CLASSNOTAVAILABLE;
*outObject = arc.CreateOutArchive();
((IOutArchive *)*outObject)->AddRef();
}
}
COM_TRY_END
return S_OK;
}
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::PropVariant_Clear(value);
if (formatIndex >= g_NumArcs)
return E_INVALIDARG;
const CArcInfo &arc = *g_Arcs[formatIndex];
NWindows::NCOM::CPropVariant prop;
switch (propID)
{
case NArchive::NHandlerPropID::kName: prop = arc.Name; break;
case NArchive::NHandlerPropID::kClassID:
{
GUID clsId = CLSID_CArchiveHandler;
CLS_ARC_ID_ITEM(clsId) = arc.Id;
return SetPropGUID(clsId, value);
}
case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break;
case NArchive::NHandlerPropID::kAddExtension: if (arc.AddExt) prop = arc.AddExt; break;
case NArchive::NHandlerPropID::kUpdate: prop = (bool)(arc.CreateOutArchive != NULL); break;
case NArchive::NHandlerPropID::kKeepName: prop = ((arc.Flags & NArcInfoFlags::kKeepName) != 0); break;
case NArchive::NHandlerPropID::kAltStreams: prop = ((arc.Flags & NArcInfoFlags::kAltStreams) != 0); break;
case NArchive::NHandlerPropID::kNtSecure: prop = ((arc.Flags & NArcInfoFlags::kNtSecure) != 0); break;
case NArchive::NHandlerPropID::kFlags: prop = (UInt32)arc.Flags; break;
case NArchive::NHandlerPropID::kSignatureOffset: prop = (UInt32)arc.SignatureOffset; break;
// case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break;
case NArchive::NHandlerPropID::kSignature:
if (arc.SignatureSize != 0 && !arc.IsMultiSignature())
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
break;
case NArchive::NHandlerPropID::kMultiSignature:
if (arc.SignatureSize != 0 && arc.IsMultiSignature())
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
{
return GetHandlerProperty2(g_DefaultArcIndex, propID, value);
}
STDAPI GetNumberOfFormats(UINT32 *numFormats)
{
*numFormats = g_NumArcs;
return S_OK;
}
STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc)
{
*isArc = NULL;
if (formatIndex >= g_NumArcs)
return E_INVALIDARG;
*isArc = g_Arcs[formatIndex]->IsArc;
return S_OK;
}
// ArchiveExports.cpp
#include "StdAfx.h"
#include "../../../C/7zVersion.h"
#include "../../Common/ComTry.h"
#include "../../Windows/PropVariant.h"
#include "../Common/RegisterArc.h"
static const unsigned kNumArcsMax = 64;
static unsigned g_NumArcs = 0;
static unsigned g_DefaultArcIndex = 0;
static const CArcInfo *g_Arcs[kNumArcsMax];
void RegisterArc(const CArcInfo *arcInfo) throw()
{
if (g_NumArcs < kNumArcsMax)
{
const char *p = arcInfo->Name;
if (p[0] == '7' && p[1] == 'z' && p[2] == 0)
g_DefaultArcIndex = g_NumArcs;
g_Arcs[g_NumArcs++] = arcInfo;
}
}
DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value)
{
if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
value->vt = VT_BSTR;
return S_OK;
}
static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
{
return SetPropStrFromBin((const char *)&guid, sizeof(guid), value);
}
int FindFormatCalssId(const GUID *clsid)
{
GUID cls = *clsid;
CLS_ARC_ID_ITEM(cls) = 0;
if (cls != CLSID_CArchiveHandler)
return -1;
Byte id = CLS_ARC_ID_ITEM(*clsid);
for (unsigned i = 0; i < g_NumArcs; i++)
if (g_Arcs[i]->Id == id)
return (int)i;
return -1;
}
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
{
COM_TRY_BEGIN
{
int needIn = (*iid == IID_IInArchive);
int needOut = (*iid == IID_IOutArchive);
if (!needIn && !needOut)
return E_NOINTERFACE;
int formatIndex = FindFormatCalssId(clsid);
if (formatIndex < 0)
return CLASS_E_CLASSNOTAVAILABLE;
const CArcInfo &arc = *g_Arcs[formatIndex];
if (needIn)
{
*outObject = arc.CreateInArchive();
((IInArchive *)*outObject)->AddRef();
}
else
{
if (!arc.CreateOutArchive)
return CLASS_E_CLASSNOTAVAILABLE;
*outObject = arc.CreateOutArchive();
((IOutArchive *)*outObject)->AddRef();
}
}
COM_TRY_END
return S_OK;
}
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::PropVariant_Clear(value);
if (formatIndex >= g_NumArcs)
return E_INVALIDARG;
const CArcInfo &arc = *g_Arcs[formatIndex];
NWindows::NCOM::CPropVariant prop;
switch (propID)
{
case NArchive::NHandlerPropID::kName: prop = arc.Name; break;
case NArchive::NHandlerPropID::kClassID:
{
GUID clsId = CLSID_CArchiveHandler;
CLS_ARC_ID_ITEM(clsId) = arc.Id;
return SetPropGUID(clsId, value);
}
case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break;
case NArchive::NHandlerPropID::kAddExtension: if (arc.AddExt) prop = arc.AddExt; break;
case NArchive::NHandlerPropID::kUpdate: prop = (bool)(arc.CreateOutArchive != NULL); break;
case NArchive::NHandlerPropID::kKeepName: prop = ((arc.Flags & NArcInfoFlags::kKeepName) != 0); break;
case NArchive::NHandlerPropID::kAltStreams: prop = ((arc.Flags & NArcInfoFlags::kAltStreams) != 0); break;
case NArchive::NHandlerPropID::kNtSecure: prop = ((arc.Flags & NArcInfoFlags::kNtSecure) != 0); break;
case NArchive::NHandlerPropID::kFlags: prop = (UInt32)arc.Flags; break;
case NArchive::NHandlerPropID::kSignatureOffset: prop = (UInt32)arc.SignatureOffset; break;
// case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break;
case NArchive::NHandlerPropID::kSignature:
if (arc.SignatureSize != 0 && !arc.IsMultiSignature())
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
break;
case NArchive::NHandlerPropID::kMultiSignature:
if (arc.SignatureSize != 0 && arc.IsMultiSignature())
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
{
return GetHandlerProperty2(g_DefaultArcIndex, propID, value);
}
STDAPI GetNumberOfFormats(UINT32 *numFormats)
{
*numFormats = g_NumArcs;
return S_OK;
}
STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc)
{
*isArc = NULL;
if (formatIndex >= g_NumArcs)
return E_INVALIDARG;
*isArc = g_Arcs[formatIndex]->IsArc;
return S_OK;
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,416 +1,416 @@
// Bz2Handler.cpp
#include "StdAfx.h"
#include "../../Common/ComTry.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "../Compress/BZip2Decoder.h"
#include "../Compress/BZip2Encoder.h"
#include "../Compress/CopyCoder.h"
#include "Common/DummyOutStream.h"
#include "Common/HandlerOut.h"
using namespace NWindows;
namespace NArchive {
namespace NBz2 {
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
public IOutArchive,
public ISetProperties,
public CMyUnknownImp
{
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
bool _isArc;
bool _needSeekToStart;
bool _dataAfterEnd;
bool _needMoreInput;
bool _packSize_Defined;
bool _unpackSize_Defined;
bool _numStreams_Defined;
bool _numBlocks_Defined;
UInt64 _packSize;
UInt64 _unpackSize;
UInt64 _numStreams;
UInt64 _numBlocks;
CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(
IInArchive,
IArchiveOpenSeq,
IOutArchive,
ISetProperties)
INTERFACE_IInArchive(;)
INTERFACE_IOutArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
CHandler() { }
};
static const Byte kProps[] =
{
kpidSize,
kpidPackSize
};
static const Byte kArcProps[] =
{
kpidNumStreams,
kpidNumBlocks
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break;
case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break;
case kpidNumBlocks: if (_numBlocks_Defined) prop = _numBlocks; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
prop = v;
}
}
prop.Detach(value);
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = 1;
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break;
}
prop.Detach(value);
return S_OK;
}
static const unsigned kSignatureCheckSize = 10;
API_FUNC_static_IsArc IsArc_BZip2(const Byte *p, size_t size)
{
if (size < kSignatureCheckSize)
return k_IsArc_Res_NEED_MORE;
if (p[0] != 'B' || p[1] != 'Z' || p[2] != 'h' || p[3] < '1' || p[3] > '9')
return k_IsArc_Res_NO;
p += 4;
if (NCompress::NBZip2::IsBlockSig(p))
return k_IsArc_Res_YES;
if (NCompress::NBZip2::IsEndSig(p))
return k_IsArc_Res_YES;
return k_IsArc_Res_NO;
}
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)
{
COM_TRY_BEGIN
Close();
{
Byte buf[kSignatureCheckSize];
RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize));
if (IsArc_BZip2(buf, kSignatureCheckSize) == k_IsArc_Res_NO)
return S_FALSE;
_isArc = true;
_stream = stream;
_seqStream = stream;
_needSeekToStart = true;
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
_isArc = true;
_seqStream = stream;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
_isArc = false;
_needSeekToStart = false;
_dataAfterEnd = false;
_needMoreInput = false;
_packSize_Defined = false;
_unpackSize_Defined = false;
_numStreams_Defined = false;
_numBlocks_Defined = false;
_packSize = 0;
_seqStream.Release();
_stream.Release();
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
if (_packSize_Defined)
extractCallback->SetTotal(_packSize);
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
if (!testMode && !realOutStream)
return S_OK;
extractCallback->PrepareOperation(askMode);
if (_needSeekToStart)
{
if (!_stream)
return E_FAIL;
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
else
_needSeekToStart = true;
// try {
NCompress::NBZip2::CDecoder *decoderSpec = new NCompress::NBZip2::CDecoder;
CMyComPtr<ICompressCoder> decoder = decoderSpec;
#ifndef _7ZIP_ST
RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads));
#endif
CDummyOutStream *outStreamSpec = new CDummyOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, true);
decoderSpec->FinishMode = true;
decoderSpec->Base.DecodeAllStreams = true;
_dataAfterEnd = false;
_needMoreInput = false;
lps->InSize = 0;
lps->OutSize = 0;
HRESULT result = decoderSpec->Code(_seqStream, outStream, NULL, NULL, progress);
if (result != S_FALSE && result != S_OK)
return result;
if (decoderSpec->Base.NumStreams == 0)
{
_isArc = false;
result = S_FALSE;
}
else
{
const UInt64 inProcessedSize = decoderSpec->GetInputProcessedSize();
UInt64 packSize = inProcessedSize;
if (decoderSpec->Base.NeedMoreInput)
_needMoreInput = true;
if (!decoderSpec->Base.IsBz)
{
packSize = decoderSpec->Base.FinishedPackSize;
if (packSize != inProcessedSize)
_dataAfterEnd = true;
}
_packSize = packSize;
_unpackSize = decoderSpec->GetOutProcessedSize();
_numStreams = decoderSpec->Base.NumStreams;
_numBlocks = decoderSpec->GetNumBlocks();
_packSize_Defined = true;
_unpackSize_Defined = true;
_numStreams_Defined = true;
_numBlocks_Defined = true;
}
outStream.Release();
Int32 opRes;
if (!_isArc)
opRes = NExtract::NOperationResult::kIsNotArc;
else if (_needMoreInput)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
else if (decoderSpec->GetCrcError())
opRes = NExtract::NOperationResult::kCRCError;
else if (_dataAfterEnd)
opRes = NExtract::NOperationResult::kDataAfterEnd;
else if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else if (decoderSpec->Base.MinorError)
opRes = NExtract::NOperationResult::kDataError;
else if (result == S_OK)
opRes = NExtract::NOperationResult::kOK;
else
return result;
return extractCallback->SetOperationResult(opRes);
// } catch(...) { return E_FAIL; }
COM_TRY_END
}
static HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
const CProps &props,
IArchiveUpdateCallback *updateCallback)
{
RINOK(updateCallback->SetTotal(unpackSize));
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(0, &fileInStream));
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(updateCallback, true);
NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder;
CMyComPtr<ICompressCoder> encoder = encoderSpec;
RINOK(props.SetCoderProps(encoderSpec, NULL));
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
*type = NFileTimeType::kUnix;
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
if (numItems != 1)
return E_INVALIDARG;
Int32 newData, newProps;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
if (IntToBool(newProps))
{
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
if (prop.vt != VT_EMPTY)
if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)
return E_INVALIDARG;
}
}
if (IntToBool(newData))
{
UInt64 size;
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
CMethodProps props2 = _props;
#ifndef _7ZIP_ST
props2.AddProp_NumThreads(_props._numThreads);
#endif
return UpdateArchive(size, outStream, props2, updateCallback);
}
if (indexInArchive != 0)
return E_INVALIDARG;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
if (opCallback)
{
RINOK(opCallback->ReportOperation(
NEventIndexType::kInArcIndex, 0,
NUpdateNotifyOp::kReplicate))
}
if (_stream)
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
return NCompress::CopyStream(_stream, outStream, progress);
COM_TRY_END
}
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
return _props.SetProperties(names, values, numProps);
}
static const Byte k_Signature[] = { 'B', 'Z', 'h' };
REGISTER_ARC_IO(
"bzip2", "bz2 bzip2 tbz2 tbz", "* * .tar .tar", 2,
k_Signature,
0,
NArcInfoFlags::kKeepName,
IsArc_BZip2)
}}
// Bz2Handler.cpp
#include "StdAfx.h"
#include "../../Common/ComTry.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "../Compress/BZip2Decoder.h"
#include "../Compress/BZip2Encoder.h"
#include "../Compress/CopyCoder.h"
#include "Common/DummyOutStream.h"
#include "Common/HandlerOut.h"
using namespace NWindows;
namespace NArchive {
namespace NBz2 {
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
public IOutArchive,
public ISetProperties,
public CMyUnknownImp
{
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
bool _isArc;
bool _needSeekToStart;
bool _dataAfterEnd;
bool _needMoreInput;
bool _packSize_Defined;
bool _unpackSize_Defined;
bool _numStreams_Defined;
bool _numBlocks_Defined;
UInt64 _packSize;
UInt64 _unpackSize;
UInt64 _numStreams;
UInt64 _numBlocks;
CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(
IInArchive,
IArchiveOpenSeq,
IOutArchive,
ISetProperties)
INTERFACE_IInArchive(;)
INTERFACE_IOutArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
CHandler() { }
};
static const Byte kProps[] =
{
kpidSize,
kpidPackSize
};
static const Byte kArcProps[] =
{
kpidNumStreams,
kpidNumBlocks
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break;
case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break;
case kpidNumBlocks: if (_numBlocks_Defined) prop = _numBlocks; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
prop = v;
}
}
prop.Detach(value);
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = 1;
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break;
}
prop.Detach(value);
return S_OK;
}
static const unsigned kSignatureCheckSize = 10;
API_FUNC_static_IsArc IsArc_BZip2(const Byte *p, size_t size)
{
if (size < kSignatureCheckSize)
return k_IsArc_Res_NEED_MORE;
if (p[0] != 'B' || p[1] != 'Z' || p[2] != 'h' || p[3] < '1' || p[3] > '9')
return k_IsArc_Res_NO;
p += 4;
if (NCompress::NBZip2::IsBlockSig(p))
return k_IsArc_Res_YES;
if (NCompress::NBZip2::IsEndSig(p))
return k_IsArc_Res_YES;
return k_IsArc_Res_NO;
}
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)
{
COM_TRY_BEGIN
Close();
{
Byte buf[kSignatureCheckSize];
RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize));
if (IsArc_BZip2(buf, kSignatureCheckSize) == k_IsArc_Res_NO)
return S_FALSE;
_isArc = true;
_stream = stream;
_seqStream = stream;
_needSeekToStart = true;
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
_isArc = true;
_seqStream = stream;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
_isArc = false;
_needSeekToStart = false;
_dataAfterEnd = false;
_needMoreInput = false;
_packSize_Defined = false;
_unpackSize_Defined = false;
_numStreams_Defined = false;
_numBlocks_Defined = false;
_packSize = 0;
_seqStream.Release();
_stream.Release();
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
if (_packSize_Defined)
extractCallback->SetTotal(_packSize);
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
if (!testMode && !realOutStream)
return S_OK;
extractCallback->PrepareOperation(askMode);
if (_needSeekToStart)
{
if (!_stream)
return E_FAIL;
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
else
_needSeekToStart = true;
// try {
NCompress::NBZip2::CDecoder *decoderSpec = new NCompress::NBZip2::CDecoder;
CMyComPtr<ICompressCoder> decoder = decoderSpec;
#ifndef _7ZIP_ST
RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads));
#endif
CDummyOutStream *outStreamSpec = new CDummyOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, true);
decoderSpec->FinishMode = true;
decoderSpec->Base.DecodeAllStreams = true;
_dataAfterEnd = false;
_needMoreInput = false;
lps->InSize = 0;
lps->OutSize = 0;
HRESULT result = decoderSpec->Code(_seqStream, outStream, NULL, NULL, progress);
if (result != S_FALSE && result != S_OK)
return result;
if (decoderSpec->Base.NumStreams == 0)
{
_isArc = false;
result = S_FALSE;
}
else
{
const UInt64 inProcessedSize = decoderSpec->GetInputProcessedSize();
UInt64 packSize = inProcessedSize;
if (decoderSpec->Base.NeedMoreInput)
_needMoreInput = true;
if (!decoderSpec->Base.IsBz)
{
packSize = decoderSpec->Base.FinishedPackSize;
if (packSize != inProcessedSize)
_dataAfterEnd = true;
}
_packSize = packSize;
_unpackSize = decoderSpec->GetOutProcessedSize();
_numStreams = decoderSpec->Base.NumStreams;
_numBlocks = decoderSpec->GetNumBlocks();
_packSize_Defined = true;
_unpackSize_Defined = true;
_numStreams_Defined = true;
_numBlocks_Defined = true;
}
outStream.Release();
Int32 opRes;
if (!_isArc)
opRes = NExtract::NOperationResult::kIsNotArc;
else if (_needMoreInput)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
else if (decoderSpec->GetCrcError())
opRes = NExtract::NOperationResult::kCRCError;
else if (_dataAfterEnd)
opRes = NExtract::NOperationResult::kDataAfterEnd;
else if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else if (decoderSpec->Base.MinorError)
opRes = NExtract::NOperationResult::kDataError;
else if (result == S_OK)
opRes = NExtract::NOperationResult::kOK;
else
return result;
return extractCallback->SetOperationResult(opRes);
// } catch(...) { return E_FAIL; }
COM_TRY_END
}
static HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
const CProps &props,
IArchiveUpdateCallback *updateCallback)
{
RINOK(updateCallback->SetTotal(unpackSize));
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(0, &fileInStream));
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(updateCallback, true);
NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder;
CMyComPtr<ICompressCoder> encoder = encoderSpec;
RINOK(props.SetCoderProps(encoderSpec, NULL));
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
*type = NFileTimeType::kUnix;
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
if (numItems != 1)
return E_INVALIDARG;
Int32 newData, newProps;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
if (IntToBool(newProps))
{
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
if (prop.vt != VT_EMPTY)
if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)
return E_INVALIDARG;
}
}
if (IntToBool(newData))
{
UInt64 size;
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
CMethodProps props2 = _props;
#ifndef _7ZIP_ST
props2.AddProp_NumThreads(_props._numThreads);
#endif
return UpdateArchive(size, outStream, props2, updateCallback);
}
if (indexInArchive != 0)
return E_INVALIDARG;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
if (opCallback)
{
RINOK(opCallback->ReportOperation(
NEventIndexType::kInArcIndex, 0,
NUpdateNotifyOp::kReplicate))
}
if (_stream)
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
return NCompress::CopyStream(_stream, outStream, progress);
COM_TRY_END
}
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
return _props.SetProperties(names, values, numProps);
}
static const Byte k_Signature[] = { 'B', 'Z', 'h' };
REGISTER_ARC_IO(
"bzip2", "bz2 bzip2 tbz2 tbz", "* * .tar .tar", 2,
k_Signature,
0,
NArcInfoFlags::kKeepName,
IsArc_BZip2)
}}

View File

@@ -1,100 +1,100 @@
// CabBlockInStream.cpp
#include "StdAfx.h"
#include "../../../../C/Alloc.h"
#include "../../../../C/CpuArch.h"
#include "../../Common/StreamUtils.h"
#include "CabBlockInStream.h"
namespace NArchive {
namespace NCab {
static const UInt32 kBlockSize = (1 << 16);
bool CCabBlockInStream::Create()
{
if (!_buf)
_buf = (Byte *)::MyAlloc(kBlockSize);
return _buf != 0;
}
CCabBlockInStream::~CCabBlockInStream()
{
::MyFree(_buf);
}
static UInt32 CheckSum(const Byte *p, UInt32 size)
{
UInt32 sum = 0;
for (; size >= 8; size -= 8)
{
sum ^= GetUi32(p) ^ GetUi32(p + 4);
p += 8;
}
if (size >= 4)
{
sum ^= GetUi32(p);
p += 4;
}
size &= 3;
if (size > 2) sum ^= (UInt32)(*p++) << 16;
if (size > 1) sum ^= (UInt32)(*p++) << 8;
if (size > 0) sum ^= (UInt32)(*p++);
return sum;
}
HRESULT CCabBlockInStream::PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize)
{
const UInt32 kHeaderSize = 8;
const UInt32 kReservedMax = 256;
Byte header[kHeaderSize + kReservedMax];
RINOK(ReadStream_FALSE(stream, header, kHeaderSize + ReservedSize))
packSize = GetUi16(header + 4);
unpackSize = GetUi16(header + 6);
if (packSize > kBlockSize - _size)
return S_FALSE;
RINOK(ReadStream_FALSE(stream, _buf + _size, packSize));
if (MsZip)
{
if (_size == 0)
{
if (packSize < 2 || _buf[0] != 0x43 || _buf[1] != 0x4B)
return S_FALSE;
_pos = 2;
}
if (_size + packSize > ((UInt32)1 << 15) + 12) /* v9.31 fix. MSZIP specification */
return S_FALSE;
}
if (GetUi32(header) != 0) // checkSum
if (CheckSum(header, kHeaderSize + ReservedSize) != CheckSum(_buf + _size, packSize))
return S_FALSE;
_size += packSize;
return S_OK;
}
STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (size != 0)
{
UInt32 rem = _size - _pos;
if (size > rem)
size = rem;
memcpy(data, _buf + _pos, size);
_pos += size;
}
if (processedSize)
*processedSize = size;
return S_OK;
}
}}
// CabBlockInStream.cpp
#include "StdAfx.h"
#include "../../../../C/Alloc.h"
#include "../../../../C/CpuArch.h"
#include "../../Common/StreamUtils.h"
#include "CabBlockInStream.h"
namespace NArchive {
namespace NCab {
static const UInt32 kBlockSize = (1 << 16);
bool CCabBlockInStream::Create()
{
if (!_buf)
_buf = (Byte *)::MyAlloc(kBlockSize);
return _buf != 0;
}
CCabBlockInStream::~CCabBlockInStream()
{
::MyFree(_buf);
}
static UInt32 CheckSum(const Byte *p, UInt32 size)
{
UInt32 sum = 0;
for (; size >= 8; size -= 8)
{
sum ^= GetUi32(p) ^ GetUi32(p + 4);
p += 8;
}
if (size >= 4)
{
sum ^= GetUi32(p);
p += 4;
}
size &= 3;
if (size > 2) sum ^= (UInt32)(*p++) << 16;
if (size > 1) sum ^= (UInt32)(*p++) << 8;
if (size > 0) sum ^= (UInt32)(*p++);
return sum;
}
HRESULT CCabBlockInStream::PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize)
{
const UInt32 kHeaderSize = 8;
const UInt32 kReservedMax = 256;
Byte header[kHeaderSize + kReservedMax];
RINOK(ReadStream_FALSE(stream, header, kHeaderSize + ReservedSize))
packSize = GetUi16(header + 4);
unpackSize = GetUi16(header + 6);
if (packSize > kBlockSize - _size)
return S_FALSE;
RINOK(ReadStream_FALSE(stream, _buf + _size, packSize));
if (MsZip)
{
if (_size == 0)
{
if (packSize < 2 || _buf[0] != 0x43 || _buf[1] != 0x4B)
return S_FALSE;
_pos = 2;
}
if (_size + packSize > ((UInt32)1 << 15) + 12) /* v9.31 fix. MSZIP specification */
return S_FALSE;
}
if (GetUi32(header) != 0) // checkSum
if (CheckSum(header, kHeaderSize + ReservedSize) != CheckSum(_buf + _size, packSize))
return S_FALSE;
_size += packSize;
return S_OK;
}
STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (size != 0)
{
UInt32 rem = _size - _pos;
if (size > rem)
size = rem;
memcpy(data, _buf + _pos, size);
_pos += size;
}
if (processedSize)
*processedSize = size;
return S_OK;
}
}}

View File

@@ -1,43 +1,43 @@
// CabBlockInStream.h
#ifndef __CAB_BLOCK_IN_STREAM_H
#define __CAB_BLOCK_IN_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
namespace NArchive {
namespace NCab {
class CCabBlockInStream:
public ISequentialInStream,
public CMyUnknownImp
{
Byte *_buf;
UInt32 _size;
UInt32 _pos;
public:
UInt32 ReservedSize; // < 256
bool MsZip;
MY_UNKNOWN_IMP
CCabBlockInStream(): _buf(0), ReservedSize(0), MsZip(false) {}
~CCabBlockInStream();
bool Create();
void InitForNewBlock() { _size = 0; _pos = 0; }
HRESULT PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize);
UInt32 GetPackSizeAvail() const { return _size - _pos; }
const Byte *GetData() const { return _buf + _pos; }
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
}}
#endif
// CabBlockInStream.h
#ifndef __CAB_BLOCK_IN_STREAM_H
#define __CAB_BLOCK_IN_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
namespace NArchive {
namespace NCab {
class CCabBlockInStream:
public ISequentialInStream,
public CMyUnknownImp
{
Byte *_buf;
UInt32 _size;
UInt32 _pos;
public:
UInt32 ReservedSize; // < 256
bool MsZip;
MY_UNKNOWN_IMP
CCabBlockInStream(): _buf(0), ReservedSize(0), MsZip(false) {}
~CCabBlockInStream();
bool Create();
void InitForNewBlock() { _size = 0; _pos = 0; }
HRESULT PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize);
UInt32 GetPackSizeAvail() const { return _size - _pos; }
const Byte *GetData() const { return _buf + _pos; }
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,37 @@
// CabHandler.h
#ifndef __CAB_HANDLER_H
#define __CAB_HANDLER_H
#include "../../../Common/MyCom.h"
#include "../IArchive.h"
#include "CabIn.h"
namespace NArchive {
namespace NCab {
class CHandler:
public IInArchive,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(IInArchive)
INTERFACE_IInArchive(;)
private:
CMvDatabaseEx m_Database;
UString _errorMessage;
bool _isArc;
bool _errorInHeaders;
bool _unexpectedEnd;
// int _mainVolIndex;
UInt32 _phySize;
UInt64 _offset;
};
}}
#endif
// CabHandler.h
#ifndef __CAB_HANDLER_H
#define __CAB_HANDLER_H
#include "../../../Common/MyCom.h"
#include "../IArchive.h"
#include "CabIn.h"
namespace NArchive {
namespace NCab {
class CHandler:
public IInArchive,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(IInArchive)
INTERFACE_IInArchive(;)
private:
CMvDatabaseEx m_Database;
UString _errorMessage;
bool _isArc;
bool _errorInHeaders;
bool _unexpectedEnd;
// int _mainVolIndex;
UInt32 _phySize;
UInt64 _offset;
};
}}
#endif

View File

@@ -1,15 +1,15 @@
// CabHeader.cpp
#include "StdAfx.h"
#include "CabHeader.h"
namespace NArchive {
namespace NCab {
namespace NHeader {
const Byte kMarker[kMarkerSize] = {'M', 'S', 'C', 'F', 0, 0, 0, 0 };
// struct CSignatureInitializer { CSignatureInitializer() { kMarker[0]--; } } g_SignatureInitializer;
}}}
// CabHeader.cpp
#include "StdAfx.h"
#include "CabHeader.h"
namespace NArchive {
namespace NCab {
namespace NHeader {
const Byte kMarker[kMarkerSize] = {'M', 'S', 'C', 'F', 0, 0, 0, 0 };
// struct CSignatureInitializer { CSignatureInitializer() { kMarker[0]--; } } g_SignatureInitializer;
}}}

View File

@@ -1,41 +1,41 @@
// Archive/CabHeader.h
#ifndef __ARCHIVE_CAB_HEADER_H
#define __ARCHIVE_CAB_HEADER_H
#include "../../../Common/MyTypes.h"
namespace NArchive {
namespace NCab {
namespace NHeader {
const unsigned kMarkerSize = 8;
extern const Byte kMarker[kMarkerSize];
namespace NArcFlags
{
const unsigned kPrevCabinet = 1;
const unsigned kNextCabinet = 2;
const unsigned kReservePresent = 4;
}
namespace NMethod
{
const Byte kNone = 0;
const Byte kMSZip = 1;
const Byte kQuantum = 2;
const Byte kLZX = 3;
}
const unsigned kFileNameIsUtf8_Mask = 0x80;
namespace NFolderIndex
{
const unsigned kContinuedFromPrev = 0xFFFD;
const unsigned kContinuedToNext = 0xFFFE;
const unsigned kContinuedPrevAndNext = 0xFFFF;
}
}}}
#endif
// Archive/CabHeader.h
#ifndef __ARCHIVE_CAB_HEADER_H
#define __ARCHIVE_CAB_HEADER_H
#include "../../../Common/MyTypes.h"
namespace NArchive {
namespace NCab {
namespace NHeader {
const unsigned kMarkerSize = 8;
extern const Byte kMarker[kMarkerSize];
namespace NArcFlags
{
const unsigned kPrevCabinet = 1;
const unsigned kNextCabinet = 2;
const unsigned kReservePresent = 4;
}
namespace NMethod
{
const Byte kNone = 0;
const Byte kMSZip = 1;
const Byte kQuantum = 2;
const Byte kLZX = 3;
}
const unsigned kFileNameIsUtf8_Mask = 0x80;
namespace NFolderIndex
{
const unsigned kContinuedFromPrev = 0xFFFD;
const unsigned kContinuedToNext = 0xFFFE;
const unsigned kContinuedPrevAndNext = 0xFFFF;
}
}}}
#endif

View File

@@ -1,491 +1,491 @@
// Archive/CabIn.cpp
#include "StdAfx.h"
// #include <stdio.h>
#include "../../../../C/CpuArch.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/StreamUtils.h"
#include "CabIn.h"
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
namespace NArchive {
namespace NCab {
struct CUnexpectedEndException {};
void CInArchive::Skip(unsigned size)
{
if (_inBuffer.Skip(size) != size)
throw CUnexpectedEndException();
}
void CInArchive::Read(Byte *data, unsigned size)
{
if (_inBuffer.ReadBytes(data, size) != size)
throw CUnexpectedEndException();
}
void CInArchive::ReadName(AString &s)
{
for (size_t i = 0; i < ((size_t)1 << 13); i++)
{
Byte b;
if (!_inBuffer.ReadByte(b))
throw CUnexpectedEndException();
if (b == 0)
{
s.SetFrom((const char *)(const Byte *)_tempBuf, (unsigned)i);
return;
}
if (_tempBuf.Size() == i)
_tempBuf.ChangeSize_KeepData(i * 2, i);
_tempBuf[i] = b;
}
for (;;)
{
Byte b;
if (!_inBuffer.ReadByte(b))
throw CUnexpectedEndException();
if (b == 0)
break;
}
ErrorInNames = true;
s = "[ERROR-LONG-PATH]";
}
void CInArchive::ReadOtherArc(COtherArc &oa)
{
ReadName(oa.FileName);
ReadName(oa.DiskName);
}
struct CSignatureFinder
{
Byte *Buf;
UInt32 Pos;
UInt32 End;
const Byte *Signature;
UInt32 SignatureSize;
UInt32 _HeaderSize;
UInt32 _AlignSize;
UInt32 _BufUseCapacity;
ISequentialInStream *Stream;
UInt64 Processed; // Global offset of start of Buf
const UInt64 *SearchLimit;
UInt32 GetTotalCapacity(UInt32 basicSize, UInt32 headerSize)
{
_HeaderSize = headerSize;
for (_AlignSize = (1 << 5); _AlignSize < _HeaderSize; _AlignSize <<= 1);
_BufUseCapacity = basicSize + _AlignSize;
return _BufUseCapacity + 16;
}
/*
returns:
S_OK - signature found (at Pos)
S_FALSE - signature not found
*/
HRESULT Find();
};
HRESULT CSignatureFinder::Find()
{
for (;;)
{
Buf[End] = Signature[0]; // it's for fast search;
while (End - Pos >= _HeaderSize)
{
const Byte *p = Buf + Pos;
Byte b = Signature[0];
for (;;)
{
if (*p == b) break; p++;
if (*p == b) break; p++;
}
Pos = (UInt32)(p - Buf);
if (End - Pos < _HeaderSize)
{
Pos = End - _HeaderSize + 1;
break;
}
UInt32 i;
for (i = 1; i < SignatureSize && p[i] == Signature[i]; i++);
if (i == SignatureSize)
return S_OK;
Pos++;
}
if (Pos >= _AlignSize)
{
UInt32 num = (Pos & ~(_AlignSize - 1));
Processed += num;
Pos -= num;
End -= num;
memmove(Buf, Buf + num, End);
}
UInt32 rem = _BufUseCapacity - End;
if (SearchLimit)
{
if (Processed + Pos > *SearchLimit)
return S_FALSE;
UInt64 rem2 = *SearchLimit - (Processed + End) + _HeaderSize;
if (rem > rem2)
rem = (UInt32)rem2;
}
UInt32 processedSize;
if (Processed == 0 && rem == _BufUseCapacity - _HeaderSize)
rem -= _AlignSize; // to make reads more aligned.
RINOK(Stream->Read(Buf + End, rem, &processedSize));
if (processedSize == 0)
return S_FALSE;
End += processedSize;
}
}
bool CInArcInfo::Parse(const Byte *p)
{
if (Get32(p + 0x0C) != 0 ||
Get32(p + 0x14) != 0)
return false;
Size = Get32(p + 8);
if (Size < 36)
return false;
Flags = Get16(p + 0x1E);
if (Flags > 7)
return false;
FileHeadersOffset = Get32(p + 0x10);
if (FileHeadersOffset != 0 && FileHeadersOffset > Size)
return false;
VersionMinor = p[0x18];
VersionMajor = p[0x19];
NumFolders = Get16(p + 0x1A);
NumFiles = Get16(p + 0x1C);
return true;
}
HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
IsArc = false;
ErrorInNames = false;
UnexpectedEnd = false;
HeaderError = false;
db.Clear();
RINOK(db.Stream->Seek(0, STREAM_SEEK_CUR, &db.StartPosition));
// UInt64 temp = db.StartPosition;
CByteBuffer buffer;
CInArcInfo &ai = db.ArcInfo;
UInt64 startInBuf = 0;
CLimitedSequentialInStream *limitedStreamSpec = NULL;
CMyComPtr<ISequentialInStream> limitedStream;
// for (int iii = 0; iii < 10000; iii++)
{
// db.StartPosition = temp; RINOK(db.Stream->Seek(db.StartPosition, STREAM_SEEK_SET, NULL));
const UInt32 kMainHeaderSize = 32;
Byte header[kMainHeaderSize];
const UInt32 kBufSize = 1 << 15;
RINOK(ReadStream_FALSE(db.Stream, header, kMainHeaderSize));
if (memcmp(header, NHeader::kMarker, NHeader::kMarkerSize) == 0 && ai.Parse(header))
{
limitedStreamSpec = new CLimitedSequentialInStream;
limitedStream = limitedStreamSpec;
limitedStreamSpec->SetStream(db.Stream);
limitedStreamSpec->Init(ai.Size - NHeader::kMarkerSize);
buffer.Alloc(kBufSize);
memcpy(buffer, header, kMainHeaderSize);
UInt32 numProcessedBytes;
RINOK(limitedStream->Read(buffer + kMainHeaderSize, kBufSize - kMainHeaderSize, &numProcessedBytes));
_inBuffer.SetBuf(buffer, (UInt32)kBufSize, kMainHeaderSize + numProcessedBytes, kMainHeaderSize);
}
else
{
if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0)
return S_FALSE;
CSignatureFinder finder;
finder.Stream = db.Stream;
finder.Signature = NHeader::kMarker;
finder.SignatureSize = NHeader::kMarkerSize;
finder.SearchLimit = searchHeaderSizeLimit;
buffer.Alloc(finder.GetTotalCapacity(kBufSize, kMainHeaderSize));
finder.Buf = buffer;
memcpy(buffer, header, kMainHeaderSize);
finder.Processed = db.StartPosition;
finder.End = kMainHeaderSize;
finder.Pos = 1;
for (;;)
{
RINOK(finder.Find());
if (ai.Parse(finder.Buf + finder.Pos))
{
db.StartPosition = finder.Processed + finder.Pos;
limitedStreamSpec = new CLimitedSequentialInStream;
limitedStreamSpec->SetStream(db.Stream);
limitedStream = limitedStreamSpec;
UInt32 remInFinder = finder.End - finder.Pos;
if (ai.Size <= remInFinder)
{
limitedStreamSpec->Init(0);
finder.End = finder.Pos + ai.Size;
}
else
limitedStreamSpec->Init(ai.Size - remInFinder);
startInBuf = finder.Pos;
_inBuffer.SetBuf(buffer, (UInt32)kBufSize, finder.End, finder.Pos + kMainHeaderSize);
break;
}
finder.Pos++;
}
}
}
IsArc = true;
_inBuffer.SetStream(limitedStream);
if (_tempBuf.Size() == 0)
_tempBuf.Alloc(1 << 12);
Byte p[16];
unsigned nextSize = 4 + (ai.ReserveBlockPresent() ? 4 : 0);
Read(p, nextSize);
ai.SetID = Get16(p);
ai.CabinetNumber = Get16(p + 2);
if (ai.ReserveBlockPresent())
{
ai.PerCabinet_AreaSize = Get16(p + 4);
ai.PerFolder_AreaSize = p[6];
ai.PerDataBlock_AreaSize = p[7];
Skip(ai.PerCabinet_AreaSize);
}
if (ai.IsTherePrev()) ReadOtherArc(ai.PrevArc);
if (ai.IsThereNext()) ReadOtherArc(ai.NextArc);
UInt32 i;
db.Folders.ClearAndReserve(ai.NumFolders);
for (i = 0; i < ai.NumFolders; i++)
{
Read(p, 8);
CFolder folder;
folder.DataStart = Get32(p);
folder.NumDataBlocks = Get16(p + 4);
folder.MethodMajor = p[6];
folder.MethodMinor = p[7];
Skip(ai.PerFolder_AreaSize);
db.Folders.AddInReserved(folder);
}
// for (int iii = 0; iii < 10000; iii++) {
if (_inBuffer.GetProcessedSize() - startInBuf != ai.FileHeadersOffset)
{
// printf("\n!!! Seek Error !!!!\n");
// fflush(stdout);
RINOK(db.Stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));
limitedStreamSpec->Init(ai.Size - ai.FileHeadersOffset);
_inBuffer.Init();
}
db.Items.ClearAndReserve(ai.NumFiles);
for (i = 0; i < ai.NumFiles; i++)
{
Read(p, 16);
CItem &item = db.Items.AddNewInReserved();
item.Size = Get32(p);
item.Offset = Get32(p + 4);
item.FolderIndex = Get16(p + 8);
UInt16 pureDate = Get16(p + 10);
UInt16 pureTime = Get16(p + 12);
item.Time = (((UInt32)pureDate << 16)) | pureTime;
item.Attributes = Get16(p + 14);
ReadName(item.Name);
if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size())
{
HeaderError = true;
return S_FALSE;
}
}
// }
return S_OK;
}
HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
try
{
return Open2(db, searchHeaderSizeLimit);
}
catch(const CInBufferException &e) { return e.ErrorCode; }
catch(CUnexpectedEndException &) { UnexpectedEnd = true; return S_FALSE; }
}
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
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.IsDir();
bool isDir2 = item2.IsDir();
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));
RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex));
return MyCompare(p1->ItemIndex, p2->ItemIndex);
}
bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned 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];;
return GetFolderIndex(p1) == GetFolderIndex(p2)
&& item1.Offset == item2.Offset
&& item1.Size == item2.Size
&& item1.Name == item2.Name;
}
void CMvDatabaseEx::FillSortAndShrink()
{
Items.Clear();
StartFolderOfVol.Clear();
FolderStartFileIndex.Clear();
int offset = 0;
FOR_VECTOR (v, Volumes)
{
const CDatabaseEx &db = Volumes[v];
int curOffset = offset;
if (db.IsTherePrevFolder())
curOffset--;
StartFolderOfVol.Add(curOffset);
offset += db.GetNumberOfNewFolders();
CMvItem mvItem;
mvItem.VolumeIndex = v;
FOR_VECTOR (i, db.Items)
{
mvItem.ItemIndex = i;
Items.Add(mvItem);
}
}
if (Items.Size() > 1)
{
Items.Sort(CompareMvItems, (void *)this);
unsigned j = 1;
unsigned i = 1;
for (; i < Items.Size(); i++)
if (!AreItemsEqual(i, i - 1))
Items[j++] = Items[i];
Items.DeleteFrom(j);
}
FOR_VECTOR (i, Items)
{
int folderIndex = GetFolderIndex(&Items[i]);
while (folderIndex >= (int)FolderStartFileIndex.Size())
FolderStartFileIndex.Add(i);
}
}
bool CMvDatabaseEx::Check()
{
for (unsigned 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.MethodMajor != f1.MethodMajor ||
f0.MethodMinor != f1.MethodMinor)
return false;
}
}
UInt32 beginPos = 0;
UInt64 endPos = 0;
int prevFolder = -2;
FOR_VECTOR (i, Items)
{
const CMvItem &mvItem = Items[i];
int fIndex = GetFolderIndex(&mvItem);
if (fIndex >= (int)FolderStartFileIndex.Size())
return false;
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDir())
continue;
int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder)
prevFolder = folderIndex;
else if (item.Offset < endPos &&
(item.Offset != beginPos || item.GetEndOffset() != endPos))
return false;
beginPos = item.Offset;
endPos = item.GetEndOffset();
}
return true;
}
}}
// Archive/CabIn.cpp
#include "StdAfx.h"
// #include <stdio.h>
#include "../../../../C/CpuArch.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/StreamUtils.h"
#include "CabIn.h"
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
namespace NArchive {
namespace NCab {
struct CUnexpectedEndException {};
void CInArchive::Skip(unsigned size)
{
if (_inBuffer.Skip(size) != size)
throw CUnexpectedEndException();
}
void CInArchive::Read(Byte *data, unsigned size)
{
if (_inBuffer.ReadBytes(data, size) != size)
throw CUnexpectedEndException();
}
void CInArchive::ReadName(AString &s)
{
for (size_t i = 0; i < ((size_t)1 << 13); i++)
{
Byte b;
if (!_inBuffer.ReadByte(b))
throw CUnexpectedEndException();
if (b == 0)
{
s.SetFrom((const char *)(const Byte *)_tempBuf, (unsigned)i);
return;
}
if (_tempBuf.Size() == i)
_tempBuf.ChangeSize_KeepData(i * 2, i);
_tempBuf[i] = b;
}
for (;;)
{
Byte b;
if (!_inBuffer.ReadByte(b))
throw CUnexpectedEndException();
if (b == 0)
break;
}
ErrorInNames = true;
s = "[ERROR-LONG-PATH]";
}
void CInArchive::ReadOtherArc(COtherArc &oa)
{
ReadName(oa.FileName);
ReadName(oa.DiskName);
}
struct CSignatureFinder
{
Byte *Buf;
UInt32 Pos;
UInt32 End;
const Byte *Signature;
UInt32 SignatureSize;
UInt32 _HeaderSize;
UInt32 _AlignSize;
UInt32 _BufUseCapacity;
ISequentialInStream *Stream;
UInt64 Processed; // Global offset of start of Buf
const UInt64 *SearchLimit;
UInt32 GetTotalCapacity(UInt32 basicSize, UInt32 headerSize)
{
_HeaderSize = headerSize;
for (_AlignSize = (1 << 5); _AlignSize < _HeaderSize; _AlignSize <<= 1);
_BufUseCapacity = basicSize + _AlignSize;
return _BufUseCapacity + 16;
}
/*
returns:
S_OK - signature found (at Pos)
S_FALSE - signature not found
*/
HRESULT Find();
};
HRESULT CSignatureFinder::Find()
{
for (;;)
{
Buf[End] = Signature[0]; // it's for fast search;
while (End - Pos >= _HeaderSize)
{
const Byte *p = Buf + Pos;
Byte b = Signature[0];
for (;;)
{
if (*p == b) break; p++;
if (*p == b) break; p++;
}
Pos = (UInt32)(p - Buf);
if (End - Pos < _HeaderSize)
{
Pos = End - _HeaderSize + 1;
break;
}
UInt32 i;
for (i = 1; i < SignatureSize && p[i] == Signature[i]; i++);
if (i == SignatureSize)
return S_OK;
Pos++;
}
if (Pos >= _AlignSize)
{
UInt32 num = (Pos & ~(_AlignSize - 1));
Processed += num;
Pos -= num;
End -= num;
memmove(Buf, Buf + num, End);
}
UInt32 rem = _BufUseCapacity - End;
if (SearchLimit)
{
if (Processed + Pos > *SearchLimit)
return S_FALSE;
UInt64 rem2 = *SearchLimit - (Processed + End) + _HeaderSize;
if (rem > rem2)
rem = (UInt32)rem2;
}
UInt32 processedSize;
if (Processed == 0 && rem == _BufUseCapacity - _HeaderSize)
rem -= _AlignSize; // to make reads more aligned.
RINOK(Stream->Read(Buf + End, rem, &processedSize));
if (processedSize == 0)
return S_FALSE;
End += processedSize;
}
}
bool CInArcInfo::Parse(const Byte *p)
{
if (Get32(p + 0x0C) != 0 ||
Get32(p + 0x14) != 0)
return false;
Size = Get32(p + 8);
if (Size < 36)
return false;
Flags = Get16(p + 0x1E);
if (Flags > 7)
return false;
FileHeadersOffset = Get32(p + 0x10);
if (FileHeadersOffset != 0 && FileHeadersOffset > Size)
return false;
VersionMinor = p[0x18];
VersionMajor = p[0x19];
NumFolders = Get16(p + 0x1A);
NumFiles = Get16(p + 0x1C);
return true;
}
HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
IsArc = false;
ErrorInNames = false;
UnexpectedEnd = false;
HeaderError = false;
db.Clear();
RINOK(db.Stream->Seek(0, STREAM_SEEK_CUR, &db.StartPosition));
// UInt64 temp = db.StartPosition;
CByteBuffer buffer;
CInArcInfo &ai = db.ArcInfo;
UInt64 startInBuf = 0;
CLimitedSequentialInStream *limitedStreamSpec = NULL;
CMyComPtr<ISequentialInStream> limitedStream;
// for (int iii = 0; iii < 10000; iii++)
{
// db.StartPosition = temp; RINOK(db.Stream->Seek(db.StartPosition, STREAM_SEEK_SET, NULL));
const UInt32 kMainHeaderSize = 32;
Byte header[kMainHeaderSize];
const UInt32 kBufSize = 1 << 15;
RINOK(ReadStream_FALSE(db.Stream, header, kMainHeaderSize));
if (memcmp(header, NHeader::kMarker, NHeader::kMarkerSize) == 0 && ai.Parse(header))
{
limitedStreamSpec = new CLimitedSequentialInStream;
limitedStream = limitedStreamSpec;
limitedStreamSpec->SetStream(db.Stream);
limitedStreamSpec->Init(ai.Size - NHeader::kMarkerSize);
buffer.Alloc(kBufSize);
memcpy(buffer, header, kMainHeaderSize);
UInt32 numProcessedBytes;
RINOK(limitedStream->Read(buffer + kMainHeaderSize, kBufSize - kMainHeaderSize, &numProcessedBytes));
_inBuffer.SetBuf(buffer, (UInt32)kBufSize, kMainHeaderSize + numProcessedBytes, kMainHeaderSize);
}
else
{
if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0)
return S_FALSE;
CSignatureFinder finder;
finder.Stream = db.Stream;
finder.Signature = NHeader::kMarker;
finder.SignatureSize = NHeader::kMarkerSize;
finder.SearchLimit = searchHeaderSizeLimit;
buffer.Alloc(finder.GetTotalCapacity(kBufSize, kMainHeaderSize));
finder.Buf = buffer;
memcpy(buffer, header, kMainHeaderSize);
finder.Processed = db.StartPosition;
finder.End = kMainHeaderSize;
finder.Pos = 1;
for (;;)
{
RINOK(finder.Find());
if (ai.Parse(finder.Buf + finder.Pos))
{
db.StartPosition = finder.Processed + finder.Pos;
limitedStreamSpec = new CLimitedSequentialInStream;
limitedStreamSpec->SetStream(db.Stream);
limitedStream = limitedStreamSpec;
UInt32 remInFinder = finder.End - finder.Pos;
if (ai.Size <= remInFinder)
{
limitedStreamSpec->Init(0);
finder.End = finder.Pos + ai.Size;
}
else
limitedStreamSpec->Init(ai.Size - remInFinder);
startInBuf = finder.Pos;
_inBuffer.SetBuf(buffer, (UInt32)kBufSize, finder.End, finder.Pos + kMainHeaderSize);
break;
}
finder.Pos++;
}
}
}
IsArc = true;
_inBuffer.SetStream(limitedStream);
if (_tempBuf.Size() == 0)
_tempBuf.Alloc(1 << 12);
Byte p[16];
unsigned nextSize = 4 + (ai.ReserveBlockPresent() ? 4 : 0);
Read(p, nextSize);
ai.SetID = Get16(p);
ai.CabinetNumber = Get16(p + 2);
if (ai.ReserveBlockPresent())
{
ai.PerCabinet_AreaSize = Get16(p + 4);
ai.PerFolder_AreaSize = p[6];
ai.PerDataBlock_AreaSize = p[7];
Skip(ai.PerCabinet_AreaSize);
}
if (ai.IsTherePrev()) ReadOtherArc(ai.PrevArc);
if (ai.IsThereNext()) ReadOtherArc(ai.NextArc);
UInt32 i;
db.Folders.ClearAndReserve(ai.NumFolders);
for (i = 0; i < ai.NumFolders; i++)
{
Read(p, 8);
CFolder folder;
folder.DataStart = Get32(p);
folder.NumDataBlocks = Get16(p + 4);
folder.MethodMajor = p[6];
folder.MethodMinor = p[7];
Skip(ai.PerFolder_AreaSize);
db.Folders.AddInReserved(folder);
}
// for (int iii = 0; iii < 10000; iii++) {
if (_inBuffer.GetProcessedSize() - startInBuf != ai.FileHeadersOffset)
{
// printf("\n!!! Seek Error !!!!\n");
// fflush(stdout);
RINOK(db.Stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));
limitedStreamSpec->Init(ai.Size - ai.FileHeadersOffset);
_inBuffer.Init();
}
db.Items.ClearAndReserve(ai.NumFiles);
for (i = 0; i < ai.NumFiles; i++)
{
Read(p, 16);
CItem &item = db.Items.AddNewInReserved();
item.Size = Get32(p);
item.Offset = Get32(p + 4);
item.FolderIndex = Get16(p + 8);
UInt16 pureDate = Get16(p + 10);
UInt16 pureTime = Get16(p + 12);
item.Time = (((UInt32)pureDate << 16)) | pureTime;
item.Attributes = Get16(p + 14);
ReadName(item.Name);
if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size())
{
HeaderError = true;
return S_FALSE;
}
}
// }
return S_OK;
}
HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
try
{
return Open2(db, searchHeaderSizeLimit);
}
catch(const CInBufferException &e) { return e.ErrorCode; }
catch(CUnexpectedEndException &) { UnexpectedEnd = true; return S_FALSE; }
}
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
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.IsDir();
bool isDir2 = item2.IsDir();
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));
RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex));
return MyCompare(p1->ItemIndex, p2->ItemIndex);
}
bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned 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];;
return GetFolderIndex(p1) == GetFolderIndex(p2)
&& item1.Offset == item2.Offset
&& item1.Size == item2.Size
&& item1.Name == item2.Name;
}
void CMvDatabaseEx::FillSortAndShrink()
{
Items.Clear();
StartFolderOfVol.Clear();
FolderStartFileIndex.Clear();
int offset = 0;
FOR_VECTOR (v, Volumes)
{
const CDatabaseEx &db = Volumes[v];
int curOffset = offset;
if (db.IsTherePrevFolder())
curOffset--;
StartFolderOfVol.Add(curOffset);
offset += db.GetNumberOfNewFolders();
CMvItem mvItem;
mvItem.VolumeIndex = v;
FOR_VECTOR (i, db.Items)
{
mvItem.ItemIndex = i;
Items.Add(mvItem);
}
}
if (Items.Size() > 1)
{
Items.Sort(CompareMvItems, (void *)this);
unsigned j = 1;
unsigned i = 1;
for (; i < Items.Size(); i++)
if (!AreItemsEqual(i, i - 1))
Items[j++] = Items[i];
Items.DeleteFrom(j);
}
FOR_VECTOR (i, Items)
{
int folderIndex = GetFolderIndex(&Items[i]);
while (folderIndex >= (int)FolderStartFileIndex.Size())
FolderStartFileIndex.Add(i);
}
}
bool CMvDatabaseEx::Check()
{
for (unsigned 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.MethodMajor != f1.MethodMajor ||
f0.MethodMinor != f1.MethodMinor)
return false;
}
}
UInt32 beginPos = 0;
UInt64 endPos = 0;
int prevFolder = -2;
FOR_VECTOR (i, Items)
{
const CMvItem &mvItem = Items[i];
int fIndex = GetFolderIndex(&mvItem);
if (fIndex >= (int)FolderStartFileIndex.Size())
return false;
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDir())
continue;
int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder)
prevFolder = folderIndex;
else if (item.Offset < endPos &&
(item.Offset != beginPos || item.GetEndOffset() != endPos))
return false;
beginPos = item.Offset;
endPos = item.GetEndOffset();
}
return true;
}
}}

View File

@@ -1,176 +1,176 @@
// Archive/CabIn.h
#ifndef __ARCHIVE_CAB_IN_H
#define __ARCHIVE_CAB_IN_H
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyCom.h"
#include "../../Common/InBuffer.h"
#include "CabItem.h"
namespace NArchive {
namespace NCab {
struct COtherArc
{
AString FileName;
AString DiskName;
void Clear()
{
FileName.Empty();
DiskName.Empty();
}
};
struct CArchInfo
{
Byte VersionMinor; // cabinet file format version, minor
Byte VersionMajor; // cabinet file format version, major
UInt32 NumFolders; // number of CFFOLDER entries in this cabinet
UInt32 NumFiles; // number of CFFILE entries in this cabinet
UInt32 Flags; // cabinet file option indicators
UInt32 SetID; // must be the same for all cabinets in a set
UInt32 CabinetNumber; // number of this cabinet file in a set
UInt16 PerCabinet_AreaSize; // (optional) size of per-cabinet reserved area
Byte PerFolder_AreaSize; // (optional) size of per-folder reserved area
Byte PerDataBlock_AreaSize; // (optional) size of per-datablock reserved area
COtherArc PrevArc; // prev link can skip some volumes !!!
COtherArc NextArc;
bool ReserveBlockPresent() const { return (Flags & NHeader::NArcFlags::kReservePresent) != 0; }
bool IsTherePrev() const { return (Flags & NHeader::NArcFlags::kPrevCabinet) != 0; }
bool IsThereNext() const { return (Flags & NHeader::NArcFlags::kNextCabinet) != 0; }
Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlock_AreaSize : 0); }
CArchInfo()
{
PerCabinet_AreaSize = 0;
PerFolder_AreaSize = 0;
PerDataBlock_AreaSize = 0;
}
void Clear()
{
PerCabinet_AreaSize = 0;
PerFolder_AreaSize = 0;
PerDataBlock_AreaSize = 0;
PrevArc.Clear();
NextArc.Clear();
}
};
struct CInArcInfo: public CArchInfo
{
UInt32 Size; // size of this cabinet file in bytes
UInt32 FileHeadersOffset; // offset of the first CFFILE entry
bool Parse(const Byte *p);
};
struct CDatabase
{
CRecordVector<CFolder> Folders;
CObjectVector<CItem> Items;
UInt64 StartPosition;
CInArcInfo ArcInfo;
void Clear()
{
ArcInfo.Clear();
Folders.Clear();
Items.Clear();
}
bool IsTherePrevFolder() const
{
FOR_VECTOR (i, Items)
if (Items[i].ContinuedFromPrev())
return true;
return false;
}
int GetNumberOfNewFolders() const
{
int res = Folders.Size();
if (IsTherePrevFolder())
res--;
return res;
}
};
struct CDatabaseEx: public CDatabase
{
CMyComPtr<IInStream> Stream;
};
struct CMvItem
{
unsigned VolumeIndex;
unsigned ItemIndex;
};
class CMvDatabaseEx
{
bool AreItemsEqual(unsigned i1, unsigned i2);
public:
CObjectVector<CDatabaseEx> Volumes;
CRecordVector<CMvItem> Items;
CRecordVector<int> StartFolderOfVol; // can be negative
CRecordVector<unsigned> FolderStartFileIndex;
int GetFolderIndex(const CMvItem *mvi) const
{
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
return StartFolderOfVol[mvi->VolumeIndex] +
db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
}
void Clear()
{
Volumes.Clear();
Items.Clear();
StartFolderOfVol.Clear();
FolderStartFileIndex.Clear();
}
void FillSortAndShrink();
bool Check();
};
class CInArchive
{
CInBufferBase _inBuffer;
CByteBuffer _tempBuf;
void Skip(unsigned size);
void Read(Byte *data, unsigned size);
void ReadName(AString &s);
void ReadOtherArc(COtherArc &oa);
HRESULT Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
public:
bool IsArc;
bool ErrorInNames;
bool UnexpectedEnd;
bool HeaderError;
HRESULT Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
};
}}
#endif
// Archive/CabIn.h
#ifndef __ARCHIVE_CAB_IN_H
#define __ARCHIVE_CAB_IN_H
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyCom.h"
#include "../../Common/InBuffer.h"
#include "CabItem.h"
namespace NArchive {
namespace NCab {
struct COtherArc
{
AString FileName;
AString DiskName;
void Clear()
{
FileName.Empty();
DiskName.Empty();
}
};
struct CArchInfo
{
Byte VersionMinor; // cabinet file format version, minor
Byte VersionMajor; // cabinet file format version, major
UInt32 NumFolders; // number of CFFOLDER entries in this cabinet
UInt32 NumFiles; // number of CFFILE entries in this cabinet
UInt32 Flags; // cabinet file option indicators
UInt32 SetID; // must be the same for all cabinets in a set
UInt32 CabinetNumber; // number of this cabinet file in a set
UInt16 PerCabinet_AreaSize; // (optional) size of per-cabinet reserved area
Byte PerFolder_AreaSize; // (optional) size of per-folder reserved area
Byte PerDataBlock_AreaSize; // (optional) size of per-datablock reserved area
COtherArc PrevArc; // prev link can skip some volumes !!!
COtherArc NextArc;
bool ReserveBlockPresent() const { return (Flags & NHeader::NArcFlags::kReservePresent) != 0; }
bool IsTherePrev() const { return (Flags & NHeader::NArcFlags::kPrevCabinet) != 0; }
bool IsThereNext() const { return (Flags & NHeader::NArcFlags::kNextCabinet) != 0; }
Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlock_AreaSize : 0); }
CArchInfo()
{
PerCabinet_AreaSize = 0;
PerFolder_AreaSize = 0;
PerDataBlock_AreaSize = 0;
}
void Clear()
{
PerCabinet_AreaSize = 0;
PerFolder_AreaSize = 0;
PerDataBlock_AreaSize = 0;
PrevArc.Clear();
NextArc.Clear();
}
};
struct CInArcInfo: public CArchInfo
{
UInt32 Size; // size of this cabinet file in bytes
UInt32 FileHeadersOffset; // offset of the first CFFILE entry
bool Parse(const Byte *p);
};
struct CDatabase
{
CRecordVector<CFolder> Folders;
CObjectVector<CItem> Items;
UInt64 StartPosition;
CInArcInfo ArcInfo;
void Clear()
{
ArcInfo.Clear();
Folders.Clear();
Items.Clear();
}
bool IsTherePrevFolder() const
{
FOR_VECTOR (i, Items)
if (Items[i].ContinuedFromPrev())
return true;
return false;
}
int GetNumberOfNewFolders() const
{
int res = Folders.Size();
if (IsTherePrevFolder())
res--;
return res;
}
};
struct CDatabaseEx: public CDatabase
{
CMyComPtr<IInStream> Stream;
};
struct CMvItem
{
unsigned VolumeIndex;
unsigned ItemIndex;
};
class CMvDatabaseEx
{
bool AreItemsEqual(unsigned i1, unsigned i2);
public:
CObjectVector<CDatabaseEx> Volumes;
CRecordVector<CMvItem> Items;
CRecordVector<int> StartFolderOfVol; // can be negative
CRecordVector<unsigned> FolderStartFileIndex;
int GetFolderIndex(const CMvItem *mvi) const
{
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
return StartFolderOfVol[mvi->VolumeIndex] +
db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
}
void Clear()
{
Volumes.Clear();
Items.Clear();
StartFolderOfVol.Clear();
FolderStartFileIndex.Clear();
}
void FillSortAndShrink();
bool Check();
};
class CInArchive
{
CInBufferBase _inBuffer;
CByteBuffer _tempBuf;
void Skip(unsigned size);
void Read(Byte *data, unsigned size);
void ReadName(AString &s);
void ReadOtherArc(COtherArc &oa);
HRESULT Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
public:
bool IsArc;
bool ErrorInNames;
bool UnexpectedEnd;
bool HeaderError;
HRESULT Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit);
};
}}
#endif

View File

@@ -1,66 +1,66 @@
// Archive/CabItem.h
#ifndef __ARCHIVE_CAB_ITEM_H
#define __ARCHIVE_CAB_ITEM_H
#include "../../../Common/MyString.h"
#include "CabHeader.h"
namespace NArchive {
namespace NCab {
const unsigned kNumMethodsMax = 16;
struct CFolder
{
UInt32 DataStart; // offset of the first CFDATA block in this folder
UInt16 NumDataBlocks; // number of CFDATA blocks in this folder
Byte MethodMajor;
Byte MethodMinor;
Byte GetMethod() const { return (Byte)(MethodMajor & 0xF); }
};
struct CItem
{
AString Name;
UInt32 Offset;
UInt32 Size;
UInt32 Time;
UInt32 FolderIndex;
UInt16 Flags;
UInt16 Attributes;
UInt64 GetEndOffset() const { return (UInt64)Offset + Size; }
UInt32 GetWinAttrib() const { return (UInt32)Attributes & ~(UInt32)NHeader::kFileNameIsUtf8_Mask; }
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUtf8_Mask) != 0; }
bool IsDir() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
bool ContinuedFromPrev() const
{
return
FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev ||
FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext;
}
bool ContinuedToNext() const
{
return
FolderIndex == NHeader::NFolderIndex::kContinuedToNext ||
FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext;
}
int GetFolderIndex(unsigned numFolders) const
{
if (ContinuedFromPrev())
return 0;
if (ContinuedToNext())
return numFolders - 1;
return FolderIndex;
}
};
}}
#endif
// Archive/CabItem.h
#ifndef __ARCHIVE_CAB_ITEM_H
#define __ARCHIVE_CAB_ITEM_H
#include "../../../Common/MyString.h"
#include "CabHeader.h"
namespace NArchive {
namespace NCab {
const unsigned kNumMethodsMax = 16;
struct CFolder
{
UInt32 DataStart; // offset of the first CFDATA block in this folder
UInt16 NumDataBlocks; // number of CFDATA blocks in this folder
Byte MethodMajor;
Byte MethodMinor;
Byte GetMethod() const { return (Byte)(MethodMajor & 0xF); }
};
struct CItem
{
AString Name;
UInt32 Offset;
UInt32 Size;
UInt32 Time;
UInt32 FolderIndex;
UInt16 Flags;
UInt16 Attributes;
UInt64 GetEndOffset() const { return (UInt64)Offset + Size; }
UInt32 GetWinAttrib() const { return (UInt32)Attributes & ~(UInt32)NHeader::kFileNameIsUtf8_Mask; }
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUtf8_Mask) != 0; }
bool IsDir() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
bool ContinuedFromPrev() const
{
return
FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev ||
FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext;
}
bool ContinuedToNext() const
{
return
FolderIndex == NHeader::NFolderIndex::kContinuedToNext ||
FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext;
}
int GetFolderIndex(unsigned numFolders) const
{
if (ContinuedFromPrev())
return 0;
if (ContinuedToNext())
return numFolders - 1;
return FolderIndex;
}
};
}}
#endif

View File

@@ -1,19 +1,19 @@
// CabRegister.cpp
#include "StdAfx.h"
#include "../../Common/RegisterArc.h"
#include "CabHandler.h"
namespace NArchive {
namespace NCab {
REGISTER_ARC_I(
"Cab", "cab", 0, 8,
NHeader::kMarker,
0,
NArcInfoFlags::kFindSignature,
NULL)
}}
// CabRegister.cpp
#include "StdAfx.h"
#include "../../Common/RegisterArc.h"
#include "CabHandler.h"
namespace NArchive {
namespace NCab {
REGISTER_ARC_I(
"Cab", "cab", 0, 8,
NHeader::kMarker,
0,
NArcInfoFlags::kFindSignature,
NULL)
}}

View File

@@ -1,8 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,35 +1,35 @@
// ChmHandler.h
#ifndef __ARCHIVE_CHM_HANDLER_H
#define __ARCHIVE_CHM_HANDLER_H
#include "../../../Common/MyCom.h"
#include "../IArchive.h"
#include "ChmIn.h"
namespace NArchive {
namespace NChm {
class CHandler:
public IInArchive,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(IInArchive)
INTERFACE_IInArchive(;)
bool _help2;
CHandler(bool help2): _help2(help2) {}
private:
CFilesDatabase m_Database;
CMyComPtr<IInStream> m_Stream;
UInt32 m_ErrorFlags;
};
}}
#endif
// ChmHandler.h
#ifndef __ARCHIVE_CHM_HANDLER_H
#define __ARCHIVE_CHM_HANDLER_H
#include "../../../Common/MyCom.h"
#include "../IArchive.h"
#include "ChmIn.h"
namespace NArchive {
namespace NChm {
class CHandler:
public IInArchive,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(IInArchive)
INTERFACE_IInArchive(;)
bool _help2;
CHandler(bool help2): _help2(help2) {}
private:
CFilesDatabase m_Database;
CMyComPtr<IInStream> m_Stream;
UInt32 m_ErrorFlags;
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,270 +1,270 @@
// Archive/ChmIn.h
#ifndef __ARCHIVE_CHM_IN_H
#define __ARCHIVE_CHM_IN_H
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
#include "../../IStream.h"
#include "../../Common/InBuffer.h"
namespace NArchive {
namespace NChm {
struct CItem
{
UInt64 Section;
UInt64 Offset;
UInt64 Size;
AString Name;
bool IsFormatRelatedItem() const
{
if (Name.Len() < 2)
return false;
return Name[0] == ':' && Name[1] == ':';
}
bool IsUserItem() const
{
if (Name.Len() < 2)
return false;
return Name[0] == '/';
}
bool IsDir() const
{
if (Name.IsEmpty())
return false;
return (Name.Back() == '/');
}
};
struct CDatabase
{
UInt64 StartPosition;
UInt64 ContentOffset;
CObjectVector<CItem> Items;
AString NewFormatString;
bool Help2Format;
bool NewFormat;
UInt64 PhySize;
void UpdatePhySize(UInt64 v) { if (PhySize < v) PhySize = v; }
int FindItem(const AString &name) const
{
FOR_VECTOR (i, Items)
if (Items[i].Name == name)
return i;
return -1;
}
void Clear()
{
NewFormat = false;
NewFormatString.Empty();
Help2Format = false;
Items.Clear();
StartPosition = 0;
PhySize = 0;
}
};
const UInt32 kBlockSize = 1 << 15;
struct CResetTable
{
UInt64 UncompressedSize;
UInt64 CompressedSize;
// unsigned BlockSizeBits;
CRecordVector<UInt64> ResetOffsets;
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
{
if (blockIndex >= ResetOffsets.Size())
return false;
UInt64 startPos = ResetOffsets[(unsigned)blockIndex];
if (blockIndex + numBlocks >= ResetOffsets.Size())
size = CompressedSize - startPos;
else
size = ResetOffsets[(unsigned)(blockIndex + numBlocks)] - startPos;
return true;
}
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
{
return GetCompressedSizeOfBlocks(blockIndex, 1, size);
}
UInt64 GetNumBlocks(UInt64 size) const
{
return (size + kBlockSize - 1) / kBlockSize;
}
};
struct CLzxInfo
{
UInt32 Version;
unsigned ResetIntervalBits;
unsigned WindowSizeBits;
UInt32 CacheSize;
CResetTable ResetTable;
unsigned GetNumDictBits() const
{
if (Version == 2 || Version == 3)
return 15 + WindowSizeBits;
return 0;
}
UInt64 GetFolderSize() const { return kBlockSize << ResetIntervalBits; }
UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); }
UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); }
UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex << ResetIntervalBits; }
bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
{
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
if (blockIndex >= ResetTable.ResetOffsets.Size())
return false;
offset = ResetTable.ResetOffsets[(unsigned)blockIndex];
return true;
}
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
{
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
return ResetTable.GetCompressedSizeOfBlocks(blockIndex, (UInt32)1 << ResetIntervalBits, size);
}
};
struct CMethodInfo
{
Byte Guid[16];
CByteBuffer ControlData;
CLzxInfo LzxInfo;
bool IsLzx() const;
bool IsDes() const;
AString GetGuidString() const;
AString GetName() const;
};
struct CSectionInfo
{
UInt64 Offset;
UInt64 CompressedSize;
UInt64 UncompressedSize;
AString Name;
CObjectVector<CMethodInfo> Methods;
bool IsLzx() const;
UString GetMethodName() const;
};
class CFilesDatabase: public CDatabase
{
public:
bool LowLevel;
CUIntVector Indices;
CObjectVector<CSectionInfo> Sections;
UInt64 GetFileSize(unsigned fileIndex) const { return Items[Indices[fileIndex]].Size; }
UInt64 GetFileOffset(unsigned fileIndex) const { return Items[Indices[fileIndex]].Offset; }
UInt64 GetFolder(unsigned fileIndex) const
{
const CItem &item = Items[Indices[fileIndex]];
if (item.Section < Sections.Size())
{
const CSectionInfo &section = Sections[(unsigned)item.Section];
if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset);
}
return 0;
}
UInt64 GetLastFolder(unsigned fileIndex) const
{
const CItem &item = Items[Indices[fileIndex]];
if (item.Section < Sections.Size())
{
const CSectionInfo &section = Sections[(unsigned)item.Section];
if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);
}
return 0;
}
void HighLevelClear()
{
LowLevel = true;
Indices.Clear();
Sections.Clear();
}
void Clear()
{
CDatabase::Clear();
HighLevelClear();
}
void SetIndices();
void Sort();
bool Check();
bool CheckSectionRefs();
};
class CInArchive
{
CMyComPtr<ISequentialInStream> m_InStreamRef;
::CInBuffer _inBuffer;
UInt64 _chunkSize;
bool _help2;
Byte ReadByte();
void ReadBytes(Byte *data, UInt32 size);
void Skip(size_t size);
UInt16 ReadUInt16();
UInt32 ReadUInt32();
UInt64 ReadUInt64();
UInt64 ReadEncInt();
void ReadString(unsigned size, AString &s);
void ReadUString(unsigned size, UString &s);
void ReadGUID(Byte *g);
HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size);
HRESULT ReadDirEntry(CDatabase &database);
HRESULT DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name);
public:
bool IsArc;
bool HeadersError;
bool UnexpectedEnd;
bool UnsupportedFeature;
CInArchive(bool help2) { _help2 = help2; }
HRESULT OpenChm(IInStream *inStream, CDatabase &database);
HRESULT OpenHelp2(IInStream *inStream, CDatabase &database);
HRESULT OpenHighLevel(IInStream *inStream, CFilesDatabase &database);
HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database);
HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database);
};
}}
#endif
// Archive/ChmIn.h
#ifndef __ARCHIVE_CHM_IN_H
#define __ARCHIVE_CHM_IN_H
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
#include "../../IStream.h"
#include "../../Common/InBuffer.h"
namespace NArchive {
namespace NChm {
struct CItem
{
UInt64 Section;
UInt64 Offset;
UInt64 Size;
AString Name;
bool IsFormatRelatedItem() const
{
if (Name.Len() < 2)
return false;
return Name[0] == ':' && Name[1] == ':';
}
bool IsUserItem() const
{
if (Name.Len() < 2)
return false;
return Name[0] == '/';
}
bool IsDir() const
{
if (Name.IsEmpty())
return false;
return (Name.Back() == '/');
}
};
struct CDatabase
{
UInt64 StartPosition;
UInt64 ContentOffset;
CObjectVector<CItem> Items;
AString NewFormatString;
bool Help2Format;
bool NewFormat;
UInt64 PhySize;
void UpdatePhySize(UInt64 v) { if (PhySize < v) PhySize = v; }
int FindItem(const AString &name) const
{
FOR_VECTOR (i, Items)
if (Items[i].Name == name)
return i;
return -1;
}
void Clear()
{
NewFormat = false;
NewFormatString.Empty();
Help2Format = false;
Items.Clear();
StartPosition = 0;
PhySize = 0;
}
};
const UInt32 kBlockSize = 1 << 15;
struct CResetTable
{
UInt64 UncompressedSize;
UInt64 CompressedSize;
// unsigned BlockSizeBits;
CRecordVector<UInt64> ResetOffsets;
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
{
if (blockIndex >= ResetOffsets.Size())
return false;
UInt64 startPos = ResetOffsets[(unsigned)blockIndex];
if (blockIndex + numBlocks >= ResetOffsets.Size())
size = CompressedSize - startPos;
else
size = ResetOffsets[(unsigned)(blockIndex + numBlocks)] - startPos;
return true;
}
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
{
return GetCompressedSizeOfBlocks(blockIndex, 1, size);
}
UInt64 GetNumBlocks(UInt64 size) const
{
return (size + kBlockSize - 1) / kBlockSize;
}
};
struct CLzxInfo
{
UInt32 Version;
unsigned ResetIntervalBits;
unsigned WindowSizeBits;
UInt32 CacheSize;
CResetTable ResetTable;
unsigned GetNumDictBits() const
{
if (Version == 2 || Version == 3)
return 15 + WindowSizeBits;
return 0;
}
UInt64 GetFolderSize() const { return kBlockSize << ResetIntervalBits; }
UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); }
UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); }
UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex << ResetIntervalBits; }
bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
{
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
if (blockIndex >= ResetTable.ResetOffsets.Size())
return false;
offset = ResetTable.ResetOffsets[(unsigned)blockIndex];
return true;
}
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
{
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
return ResetTable.GetCompressedSizeOfBlocks(blockIndex, (UInt32)1 << ResetIntervalBits, size);
}
};
struct CMethodInfo
{
Byte Guid[16];
CByteBuffer ControlData;
CLzxInfo LzxInfo;
bool IsLzx() const;
bool IsDes() const;
AString GetGuidString() const;
AString GetName() const;
};
struct CSectionInfo
{
UInt64 Offset;
UInt64 CompressedSize;
UInt64 UncompressedSize;
AString Name;
CObjectVector<CMethodInfo> Methods;
bool IsLzx() const;
UString GetMethodName() const;
};
class CFilesDatabase: public CDatabase
{
public:
bool LowLevel;
CUIntVector Indices;
CObjectVector<CSectionInfo> Sections;
UInt64 GetFileSize(unsigned fileIndex) const { return Items[Indices[fileIndex]].Size; }
UInt64 GetFileOffset(unsigned fileIndex) const { return Items[Indices[fileIndex]].Offset; }
UInt64 GetFolder(unsigned fileIndex) const
{
const CItem &item = Items[Indices[fileIndex]];
if (item.Section < Sections.Size())
{
const CSectionInfo &section = Sections[(unsigned)item.Section];
if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset);
}
return 0;
}
UInt64 GetLastFolder(unsigned fileIndex) const
{
const CItem &item = Items[Indices[fileIndex]];
if (item.Section < Sections.Size())
{
const CSectionInfo &section = Sections[(unsigned)item.Section];
if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);
}
return 0;
}
void HighLevelClear()
{
LowLevel = true;
Indices.Clear();
Sections.Clear();
}
void Clear()
{
CDatabase::Clear();
HighLevelClear();
}
void SetIndices();
void Sort();
bool Check();
bool CheckSectionRefs();
};
class CInArchive
{
CMyComPtr<ISequentialInStream> m_InStreamRef;
::CInBuffer _inBuffer;
UInt64 _chunkSize;
bool _help2;
Byte ReadByte();
void ReadBytes(Byte *data, UInt32 size);
void Skip(size_t size);
UInt16 ReadUInt16();
UInt32 ReadUInt32();
UInt64 ReadUInt64();
UInt64 ReadEncInt();
void ReadString(unsigned size, AString &s);
void ReadUString(unsigned size, UString &s);
void ReadGUID(Byte *g);
HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size);
HRESULT ReadDirEntry(CDatabase &database);
HRESULT DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name);
public:
bool IsArc;
bool HeadersError;
bool UnexpectedEnd;
bool UnsupportedFeature;
CInArchive(bool help2) { _help2 = help2; }
HRESULT OpenChm(IInStream *inStream, CDatabase &database);
HRESULT OpenHelp2(IInStream *inStream, CDatabase &database);
HRESULT OpenHighLevel(IInStream *inStream, CFilesDatabase &database);
HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database);
HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database);
};
}}
#endif

View File

@@ -1,8 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,447 +1,447 @@
// CoderMixer2.h
#ifndef __CODER_MIXER2_H
#define __CODER_MIXER2_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../ICoder.h"
#include "../../Common/CreateCoder.h"
#ifdef _7ZIP_ST
#define USE_MIXER_ST
#else
#define USE_MIXER_MT
#ifndef _SFX
#define USE_MIXER_ST
#endif
#endif
#ifdef USE_MIXER_MT
#include "../../Common/StreamBinder.h"
#include "../../Common/VirtThread.h"
#endif
#ifdef USE_MIXER_ST
class CSequentialInStreamCalcSize:
public ISequentialInStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
private:
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
bool _wasFinished;
public:
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
_wasFinished = false;
}
void ReleaseStream() { _stream.Release(); }
UInt64 GetSize() const { return _size; }
bool WasFinished() const { return _wasFinished; }
};
class COutStreamCalcSize:
public ISequentialOutStream,
public IOutStreamFinish,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public:
MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(OutStreamFinish)();
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init() { _size = 0; }
UInt64 GetSize() const { return _size; }
};
#endif
namespace NCoderMixer2 {
struct CBond
{
UInt32 PackIndex;
UInt32 UnpackIndex;
UInt32 Get_InIndex(bool encodeMode) const { return encodeMode ? UnpackIndex : PackIndex; }
UInt32 Get_OutIndex(bool encodeMode) const { return encodeMode ? PackIndex : UnpackIndex; }
};
struct CCoderStreamsInfo
{
UInt32 NumStreams;
};
struct CBindInfo
{
CRecordVector<CCoderStreamsInfo> Coders;
CRecordVector<CBond> Bonds;
CRecordVector<UInt32> PackStreams;
unsigned UnpackCoder;
unsigned GetNum_Bonds_and_PackStreams() const { return Bonds.Size() + PackStreams.Size(); }
int FindBond_for_PackStream(UInt32 packStream) const
{
FOR_VECTOR (i, Bonds)
if (Bonds[i].PackIndex == packStream)
return i;
return -1;
}
int FindBond_for_UnpackStream(UInt32 unpackStream) const
{
FOR_VECTOR (i, Bonds)
if (Bonds[i].UnpackIndex == unpackStream)
return i;
return -1;
}
bool SetUnpackCoder()
{
bool isOk = false;
FOR_VECTOR(i, Coders)
{
if (FindBond_for_UnpackStream(i) < 0)
{
if (isOk)
return false;
UnpackCoder = i;
isOk = true;
}
}
return isOk;
}
bool IsStream_in_PackStreams(UInt32 streamIndex) const
{
return FindStream_in_PackStreams(streamIndex) >= 0;
}
int FindStream_in_PackStreams(UInt32 streamIndex) const
{
FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == streamIndex)
return i;
return -1;
}
// that function is used before Maps is calculated
UInt32 GetStream_for_Coder(UInt32 coderIndex) const
{
UInt32 streamIndex = 0;
for (UInt32 i = 0; i < coderIndex; i++)
streamIndex += Coders[i].NumStreams;
return streamIndex;
}
// ---------- Maps Section ----------
CRecordVector<UInt32> Coder_to_Stream;
CRecordVector<UInt32> Stream_to_Coder;
void ClearMaps();
bool CalcMapsAndCheck();
// ---------- End of Maps Section ----------
void Clear()
{
Coders.Clear();
Bonds.Clear();
PackStreams.Clear();
ClearMaps();
}
void GetCoder_for_Stream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const
{
coderIndex = Stream_to_Coder[streamIndex];
coderStreamIndex = streamIndex - Coder_to_Stream[coderIndex];
}
};
class CCoder
{
CLASS_NO_COPY(CCoder);
public:
CMyComPtr<ICompressCoder> Coder;
CMyComPtr<ICompressCoder2> Coder2;
UInt32 NumStreams;
UInt64 UnpackSize;
const UInt64 *UnpackSizePointer;
CRecordVector<UInt64> PackSizes;
CRecordVector<const UInt64 *> PackSizePointers;
bool Finish;
CCoder(): Finish(false) {}
void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish);
HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const;
IUnknown *GetUnknown() const
{
return Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
}
HRESULT QueryInterface(REFGUID iid, void** pp) const
{
return GetUnknown()->QueryInterface(iid, pp);
}
};
class CMixer
{
bool Is_PackSize_Correct_for_Stream(UInt32 streamIndex);
protected:
CBindInfo _bi;
int FindBond_for_Stream(bool forInputStream, UInt32 streamIndex) const
{
if (EncodeMode == forInputStream)
return _bi.FindBond_for_UnpackStream(streamIndex);
else
return _bi.FindBond_for_PackStream(streamIndex);
}
CBoolVector IsFilter_Vector;
CBoolVector IsExternal_Vector;
bool EncodeMode;
public:
unsigned MainCoderIndex;
// bool InternalPackSizeError;
CMixer(bool encodeMode):
EncodeMode(encodeMode),
MainCoderIndex(0)
// , InternalPackSizeError(false)
{}
/*
Sequence of calling:
SetBindInfo();
for each coder
AddCoder();
SelectMainCoder();
for each file
{
ReInit()
for each coder
SetCoderInfo();
Code();
}
*/
virtual HRESULT SetBindInfo(const CBindInfo &bindInfo)
{
_bi = bindInfo;
IsFilter_Vector.Clear();
MainCoderIndex = 0;
return S_OK;
}
virtual void AddCoder(const CCreatedCoder &cod) = 0;
virtual CCoder &GetCoder(unsigned index) = 0;
virtual void SelectMainCoder(bool useFirst) = 0;
virtual void ReInit() = 0;
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) = 0;
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
ICompressProgressInfo *progress,
bool &dataAfterEnd_Error) = 0;
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0;
bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex);
bool Is_PackSize_Correct_for_Coder(UInt32 coderIndex);
bool IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex);
};
#ifdef USE_MIXER_ST
struct CCoderST: public CCoder
{
bool CanRead;
bool CanWrite;
CCoderST(): CanRead(false), CanWrite(false) {}
};
struct CStBinderStream
{
CSequentialInStreamCalcSize *InStreamSpec;
COutStreamCalcSize *OutStreamSpec;
CMyComPtr<IUnknown> StreamRef;
CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {}
};
class CMixerST:
public IUnknown,
public CMixer,
public CMyUnknownImp
{
HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
UInt32 outStreamIndex, ISequentialInStream **inStreamRes);
HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
UInt32 inStreamIndex, ISequentialInStream **inStreamRes);
HRESULT GetOutStream(ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */
UInt32 outStreamIndex, ISequentialOutStream **outStreamRes);
HRESULT FinishStream(UInt32 streamIndex);
HRESULT FinishCoder(UInt32 coderIndex);
public:
CObjectVector<CCoderST> _coders;
CObjectVector<CStBinderStream> _binderStreams;
MY_UNKNOWN_IMP
CMixerST(bool encodeMode);
~CMixerST();
virtual void AddCoder(const CCreatedCoder &cod);
virtual CCoder &GetCoder(unsigned index);
virtual void SelectMainCoder(bool useFirst);
virtual void ReInit();
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
ICompressProgressInfo *progress,
bool &dataAfterEnd_Error);
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
HRESULT GetMainUnpackStream(
ISequentialInStream * const *inStreams,
ISequentialInStream **inStreamRes);
};
#endif
#ifdef USE_MIXER_MT
class CCoderMT: public CCoder, public CVirtThread
{
CLASS_NO_COPY(CCoderMT)
CRecordVector<ISequentialInStream*> InStreamPointers;
CRecordVector<ISequentialOutStream*> OutStreamPointers;
private:
void Execute();
public:
bool EncodeMode;
HRESULT Result;
CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
void Release()
{
InStreamPointers.Clear();
OutStreamPointers.Clear();
unsigned i;
for (i = 0; i < InStreams.Size(); i++)
InStreams[i].Release();
for (i = 0; i < OutStreams.Size(); i++)
OutStreams[i].Release();
}
class CReleaser
{
CLASS_NO_COPY(CReleaser)
CCoderMT &_c;
public:
CReleaser(CCoderMT &c): _c(c) {}
~CReleaser() { _c.Release(); }
};
CCoderMT(): EncodeMode(false) {}
~CCoderMT() { CVirtThread::WaitThreadFinish(); }
void Code(ICompressProgressInfo *progress);
};
class CMixerMT:
public IUnknown,
public CMixer,
public CMyUnknownImp
{
CObjectVector<CStreamBinder> _streamBinders;
HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);
HRESULT ReturnIfError(HRESULT code);
public:
CObjectVector<CCoderMT> _coders;
MY_UNKNOWN_IMP
virtual HRESULT SetBindInfo(const CBindInfo &bindInfo);
virtual void AddCoder(const CCreatedCoder &cod);
virtual CCoder &GetCoder(unsigned index);
virtual void SelectMainCoder(bool useFirst);
virtual void ReInit();
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
ICompressProgressInfo *progress,
bool &dataAfterEnd_Error);
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
CMixerMT(bool encodeMode): CMixer(encodeMode) {}
};
#endif
}
#endif
// CoderMixer2.h
#ifndef __CODER_MIXER2_H
#define __CODER_MIXER2_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../ICoder.h"
#include "../../Common/CreateCoder.h"
#ifdef _7ZIP_ST
#define USE_MIXER_ST
#else
#define USE_MIXER_MT
#ifndef _SFX
#define USE_MIXER_ST
#endif
#endif
#ifdef USE_MIXER_MT
#include "../../Common/StreamBinder.h"
#include "../../Common/VirtThread.h"
#endif
#ifdef USE_MIXER_ST
class CSequentialInStreamCalcSize:
public ISequentialInStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
private:
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
bool _wasFinished;
public:
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
_wasFinished = false;
}
void ReleaseStream() { _stream.Release(); }
UInt64 GetSize() const { return _size; }
bool WasFinished() const { return _wasFinished; }
};
class COutStreamCalcSize:
public ISequentialOutStream,
public IOutStreamFinish,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public:
MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(OutStreamFinish)();
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init() { _size = 0; }
UInt64 GetSize() const { return _size; }
};
#endif
namespace NCoderMixer2 {
struct CBond
{
UInt32 PackIndex;
UInt32 UnpackIndex;
UInt32 Get_InIndex(bool encodeMode) const { return encodeMode ? UnpackIndex : PackIndex; }
UInt32 Get_OutIndex(bool encodeMode) const { return encodeMode ? PackIndex : UnpackIndex; }
};
struct CCoderStreamsInfo
{
UInt32 NumStreams;
};
struct CBindInfo
{
CRecordVector<CCoderStreamsInfo> Coders;
CRecordVector<CBond> Bonds;
CRecordVector<UInt32> PackStreams;
unsigned UnpackCoder;
unsigned GetNum_Bonds_and_PackStreams() const { return Bonds.Size() + PackStreams.Size(); }
int FindBond_for_PackStream(UInt32 packStream) const
{
FOR_VECTOR (i, Bonds)
if (Bonds[i].PackIndex == packStream)
return i;
return -1;
}
int FindBond_for_UnpackStream(UInt32 unpackStream) const
{
FOR_VECTOR (i, Bonds)
if (Bonds[i].UnpackIndex == unpackStream)
return i;
return -1;
}
bool SetUnpackCoder()
{
bool isOk = false;
FOR_VECTOR(i, Coders)
{
if (FindBond_for_UnpackStream(i) < 0)
{
if (isOk)
return false;
UnpackCoder = i;
isOk = true;
}
}
return isOk;
}
bool IsStream_in_PackStreams(UInt32 streamIndex) const
{
return FindStream_in_PackStreams(streamIndex) >= 0;
}
int FindStream_in_PackStreams(UInt32 streamIndex) const
{
FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == streamIndex)
return i;
return -1;
}
// that function is used before Maps is calculated
UInt32 GetStream_for_Coder(UInt32 coderIndex) const
{
UInt32 streamIndex = 0;
for (UInt32 i = 0; i < coderIndex; i++)
streamIndex += Coders[i].NumStreams;
return streamIndex;
}
// ---------- Maps Section ----------
CRecordVector<UInt32> Coder_to_Stream;
CRecordVector<UInt32> Stream_to_Coder;
void ClearMaps();
bool CalcMapsAndCheck();
// ---------- End of Maps Section ----------
void Clear()
{
Coders.Clear();
Bonds.Clear();
PackStreams.Clear();
ClearMaps();
}
void GetCoder_for_Stream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const
{
coderIndex = Stream_to_Coder[streamIndex];
coderStreamIndex = streamIndex - Coder_to_Stream[coderIndex];
}
};
class CCoder
{
CLASS_NO_COPY(CCoder);
public:
CMyComPtr<ICompressCoder> Coder;
CMyComPtr<ICompressCoder2> Coder2;
UInt32 NumStreams;
UInt64 UnpackSize;
const UInt64 *UnpackSizePointer;
CRecordVector<UInt64> PackSizes;
CRecordVector<const UInt64 *> PackSizePointers;
bool Finish;
CCoder(): Finish(false) {}
void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish);
HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const;
IUnknown *GetUnknown() const
{
return Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
}
HRESULT QueryInterface(REFGUID iid, void** pp) const
{
return GetUnknown()->QueryInterface(iid, pp);
}
};
class CMixer
{
bool Is_PackSize_Correct_for_Stream(UInt32 streamIndex);
protected:
CBindInfo _bi;
int FindBond_for_Stream(bool forInputStream, UInt32 streamIndex) const
{
if (EncodeMode == forInputStream)
return _bi.FindBond_for_UnpackStream(streamIndex);
else
return _bi.FindBond_for_PackStream(streamIndex);
}
CBoolVector IsFilter_Vector;
CBoolVector IsExternal_Vector;
bool EncodeMode;
public:
unsigned MainCoderIndex;
// bool InternalPackSizeError;
CMixer(bool encodeMode):
EncodeMode(encodeMode),
MainCoderIndex(0)
// , InternalPackSizeError(false)
{}
/*
Sequence of calling:
SetBindInfo();
for each coder
AddCoder();
SelectMainCoder();
for each file
{
ReInit()
for each coder
SetCoderInfo();
Code();
}
*/
virtual HRESULT SetBindInfo(const CBindInfo &bindInfo)
{
_bi = bindInfo;
IsFilter_Vector.Clear();
MainCoderIndex = 0;
return S_OK;
}
virtual void AddCoder(const CCreatedCoder &cod) = 0;
virtual CCoder &GetCoder(unsigned index) = 0;
virtual void SelectMainCoder(bool useFirst) = 0;
virtual void ReInit() = 0;
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) = 0;
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
ICompressProgressInfo *progress,
bool &dataAfterEnd_Error) = 0;
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0;
bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex);
bool Is_PackSize_Correct_for_Coder(UInt32 coderIndex);
bool IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex);
};
#ifdef USE_MIXER_ST
struct CCoderST: public CCoder
{
bool CanRead;
bool CanWrite;
CCoderST(): CanRead(false), CanWrite(false) {}
};
struct CStBinderStream
{
CSequentialInStreamCalcSize *InStreamSpec;
COutStreamCalcSize *OutStreamSpec;
CMyComPtr<IUnknown> StreamRef;
CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {}
};
class CMixerST:
public IUnknown,
public CMixer,
public CMyUnknownImp
{
HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
UInt32 outStreamIndex, ISequentialInStream **inStreamRes);
HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
UInt32 inStreamIndex, ISequentialInStream **inStreamRes);
HRESULT GetOutStream(ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */
UInt32 outStreamIndex, ISequentialOutStream **outStreamRes);
HRESULT FinishStream(UInt32 streamIndex);
HRESULT FinishCoder(UInt32 coderIndex);
public:
CObjectVector<CCoderST> _coders;
CObjectVector<CStBinderStream> _binderStreams;
MY_UNKNOWN_IMP
CMixerST(bool encodeMode);
~CMixerST();
virtual void AddCoder(const CCreatedCoder &cod);
virtual CCoder &GetCoder(unsigned index);
virtual void SelectMainCoder(bool useFirst);
virtual void ReInit();
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
ICompressProgressInfo *progress,
bool &dataAfterEnd_Error);
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
HRESULT GetMainUnpackStream(
ISequentialInStream * const *inStreams,
ISequentialInStream **inStreamRes);
};
#endif
#ifdef USE_MIXER_MT
class CCoderMT: public CCoder, public CVirtThread
{
CLASS_NO_COPY(CCoderMT)
CRecordVector<ISequentialInStream*> InStreamPointers;
CRecordVector<ISequentialOutStream*> OutStreamPointers;
private:
void Execute();
public:
bool EncodeMode;
HRESULT Result;
CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
void Release()
{
InStreamPointers.Clear();
OutStreamPointers.Clear();
unsigned i;
for (i = 0; i < InStreams.Size(); i++)
InStreams[i].Release();
for (i = 0; i < OutStreams.Size(); i++)
OutStreams[i].Release();
}
class CReleaser
{
CLASS_NO_COPY(CReleaser)
CCoderMT &_c;
public:
CReleaser(CCoderMT &c): _c(c) {}
~CReleaser() { _c.Release(); }
};
CCoderMT(): EncodeMode(false) {}
~CCoderMT() { CVirtThread::WaitThreadFinish(); }
void Code(ICompressProgressInfo *progress);
};
class CMixerMT:
public IUnknown,
public CMixer,
public CMyUnknownImp
{
CObjectVector<CStreamBinder> _streamBinders;
HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);
HRESULT ReturnIfError(HRESULT code);
public:
CObjectVector<CCoderMT> _coders;
MY_UNKNOWN_IMP
virtual HRESULT SetBindInfo(const CBindInfo &bindInfo);
virtual void AddCoder(const CCreatedCoder &cod);
virtual CCoder &GetCoder(unsigned index);
virtual void SelectMainCoder(bool useFirst);
virtual void ReInit();
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
ICompressProgressInfo *progress,
bool &dataAfterEnd_Error);
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
CMixerMT(bool encodeMode): CMixer(encodeMode) {}
};
#endif
}
#endif

View File

@@ -1,17 +1,17 @@
// DummyOutStream.cpp
#include "StdAfx.h"
#include "DummyOutStream.h"
STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize = size;
HRESULT res = S_OK;
if (_stream)
res = _stream->Write(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize)
*processedSize = realProcessedSize;
return res;
}
// DummyOutStream.cpp
#include "StdAfx.h"
#include "DummyOutStream.h"
STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize = size;
HRESULT res = S_OK;
if (_stream)
res = _stream->Write(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize)
*processedSize = realProcessedSize;
return res;
}

View File

@@ -1,25 +1,25 @@
// DummyOutStream.h
#ifndef __DUMMY_OUT_STREAM_H
#define __DUMMY_OUT_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
class CDummyOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public:
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
void ReleaseStream() { _stream.Release(); }
void Init() { _size = 0; }
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _size; }
};
#endif
// DummyOutStream.h
#ifndef __DUMMY_OUT_STREAM_H
#define __DUMMY_OUT_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
class CDummyOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public:
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
void ReleaseStream() { _stream.Release(); }
void Init() { _size = 0; }
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _size; }
};
#endif

View File

@@ -1,62 +1,62 @@
// FindSignature.cpp
#include "StdAfx.h"
#include <string.h>
#include "../../../Common/MyBuffer.h"
#include "../../Common/StreamUtils.h"
#include "FindSignature.h"
HRESULT FindSignatureInStream(ISequentialInStream *stream,
const Byte *signature, unsigned signatureSize,
const UInt64 *limit, UInt64 &resPos)
{
resPos = 0;
CByteBuffer byteBuffer2(signatureSize);
RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize));
if (memcmp(byteBuffer2, signature, signatureSize) == 0)
return S_OK;
const UInt32 kBufferSize = (1 << 16);
CByteBuffer byteBuffer(kBufferSize);
Byte *buffer = byteBuffer;
UInt32 numPrevBytes = signatureSize - 1;
memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes);
resPos = 1;
for (;;)
{
if (limit != NULL)
if (resPos > *limit)
return S_FALSE;
do
{
UInt32 numReadBytes = kBufferSize - numPrevBytes;
UInt32 processedSize;
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
numPrevBytes += processedSize;
if (processedSize == 0)
return S_FALSE;
}
while (numPrevBytes < signatureSize);
UInt32 numTests = numPrevBytes - signatureSize + 1;
for (UInt32 pos = 0; pos < numTests; pos++)
{
Byte b = signature[0];
for (; buffer[pos] != b && pos < numTests; pos++);
if (pos == numTests)
break;
if (memcmp(buffer + pos, signature, signatureSize) == 0)
{
resPos += pos;
return S_OK;
}
}
resPos += numTests;
numPrevBytes -= numTests;
memmove(buffer, buffer + numTests, numPrevBytes);
}
}
// FindSignature.cpp
#include "StdAfx.h"
#include <string.h>
#include "../../../Common/MyBuffer.h"
#include "../../Common/StreamUtils.h"
#include "FindSignature.h"
HRESULT FindSignatureInStream(ISequentialInStream *stream,
const Byte *signature, unsigned signatureSize,
const UInt64 *limit, UInt64 &resPos)
{
resPos = 0;
CByteBuffer byteBuffer2(signatureSize);
RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize));
if (memcmp(byteBuffer2, signature, signatureSize) == 0)
return S_OK;
const UInt32 kBufferSize = (1 << 16);
CByteBuffer byteBuffer(kBufferSize);
Byte *buffer = byteBuffer;
UInt32 numPrevBytes = signatureSize - 1;
memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes);
resPos = 1;
for (;;)
{
if (limit != NULL)
if (resPos > *limit)
return S_FALSE;
do
{
UInt32 numReadBytes = kBufferSize - numPrevBytes;
UInt32 processedSize;
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
numPrevBytes += processedSize;
if (processedSize == 0)
return S_FALSE;
}
while (numPrevBytes < signatureSize);
UInt32 numTests = numPrevBytes - signatureSize + 1;
for (UInt32 pos = 0; pos < numTests; pos++)
{
Byte b = signature[0];
for (; buffer[pos] != b && pos < numTests; pos++);
if (pos == numTests)
break;
if (memcmp(buffer + pos, signature, signatureSize) == 0)
{
resPos += pos;
return S_OK;
}
}
resPos += numTests;
numPrevBytes -= numTests;
memmove(buffer, buffer + numTests, numPrevBytes);
}
}

View File

@@ -1,12 +1,12 @@
// FindSignature.h
#ifndef __FIND_SIGNATURE_H
#define __FIND_SIGNATURE_H
#include "../../IStream.h"
HRESULT FindSignatureInStream(ISequentialInStream *stream,
const Byte *signature, unsigned signatureSize,
const UInt64 *limit, UInt64 &resPos);
#endif
// FindSignature.h
#ifndef __FIND_SIGNATURE_H
#define __FIND_SIGNATURE_H
#include "../../IStream.h"
HRESULT FindSignatureInStream(ISequentialInStream *stream,
const Byte *signature, unsigned signatureSize,
const UInt64 *limit, UInt64 &resPos);
#endif

View File

@@ -1,232 +1,232 @@
// HandlerOut.cpp
#include "StdAfx.h"
#include "../../../Common/StringToInt.h"
#include "../Common/ParseProperties.h"
#include "HandlerOut.h"
namespace NArchive {
bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res)
{
if (*s == 0)
{
switch (prop.vt)
{
case VT_UI4: res = prop.ulVal; return true;
case VT_UI8: res = prop.uhVal.QuadPart; return true;
case VT_BSTR:
s = prop.bstrVal;
break;
default: return false;
}
}
else if (prop.vt != VT_EMPTY)
return false;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(s, &end);
if (s == end)
return false;
wchar_t c = *end;
if (c == 0)
{
res = v;
return true;
}
if (end[1] != 0)
return false;
if (c == '%')
{
res = percentsBase / 100 * v;
return true;
}
unsigned numBits;
switch (MyCharLower_Ascii(c))
{
case 'b': numBits = 0; break;
case 'k': numBits = 10; break;
case 'm': numBits = 20; break;
case 'g': numBits = 30; break;
case 't': numBits = 40; break;
default: return false;
}
UInt64 val2 = v << numBits;
if ((val2 >> numBits) != v)
return false;
res = val2;
return true;
}
bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres)
{
hres = S_OK;
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
#ifndef _7ZIP_ST
hres = ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads);
#endif
return true;
}
if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
{
if (!ParseSizeString(name.Ptr(6), value, _memAvail, _memUsage))
hres = E_INVALIDARG;
return true;
}
return false;
}
#ifndef EXTRACT_ONLY
static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
{
if (m.FindProp(propID) < 0)
m.AddProp32(propID, value);
}
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
{
UInt32 level = _level;
if (level != (UInt32)(Int32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
}
#ifndef _7ZIP_ST
void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads)
{
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
}
#endif
void CMultiMethodProps::InitMulti()
{
_level = (UInt32)(Int32)-1;
_analysisLevel = -1;
_crcSize = 4;
_autoFilter = true;
}
void CMultiMethodProps::Init()
{
InitCommon();
InitMulti();
_methods.Clear();
_filterMethod.Clear();
}
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
if (name[0] == 'x')
{
name.Delete(0);
_level = 9;
return ParsePropToUInt32(name, value, _level);
}
if (name.IsPrefixedBy_Ascii_NoCase("yx"))
{
name.Delete(0, 2);
UInt32 v = 9;
RINOK(ParsePropToUInt32(name, value, v));
_analysisLevel = (int)v;
return S_OK;
}
if (name.IsPrefixedBy_Ascii_NoCase("crc"))
{
name.Delete(0, 3);
_crcSize = 4;
return ParsePropToUInt32(name, value, _crcSize);
}
{
HRESULT hres;
if (SetCommonProperty(name, value, hres))
return hres;
}
UInt32 number;
unsigned index = ParseStringToUInt32(name, number);
UString realName = name.Ptr(index);
if (index == 0)
{
if (name.IsEqualTo("f"))
{
HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
if (res == S_OK)
return res;
if (value.vt != VT_BSTR)
return E_INVALIDARG;
return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value);
}
number = 0;
}
if (number > 64)
return E_FAIL;
for (int j = _methods.Size(); j <= (int)number; j++)
_methods.Add(COneMethodInfo());
return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
}
void CSingleMethodProps::Init()
{
InitCommon();
InitSingle();
Clear();
}
HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
Init();
for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
if (name[0] == L'x')
{
UInt32 a = 9;
RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
_level = a;
AddProp_Level(a);
continue;
}
{
HRESULT hres;
if (SetCommonProperty(name, value, hres))
{
RINOK(hres)
continue;
}
}
RINOK(ParseMethodFromPROPVARIANT(names[i], value));
}
return S_OK;
}
#endif
}
// HandlerOut.cpp
#include "StdAfx.h"
#include "../../../Common/StringToInt.h"
#include "../Common/ParseProperties.h"
#include "HandlerOut.h"
namespace NArchive {
bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res)
{
if (*s == 0)
{
switch (prop.vt)
{
case VT_UI4: res = prop.ulVal; return true;
case VT_UI8: res = prop.uhVal.QuadPart; return true;
case VT_BSTR:
s = prop.bstrVal;
break;
default: return false;
}
}
else if (prop.vt != VT_EMPTY)
return false;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(s, &end);
if (s == end)
return false;
wchar_t c = *end;
if (c == 0)
{
res = v;
return true;
}
if (end[1] != 0)
return false;
if (c == '%')
{
res = percentsBase / 100 * v;
return true;
}
unsigned numBits;
switch (MyCharLower_Ascii(c))
{
case 'b': numBits = 0; break;
case 'k': numBits = 10; break;
case 'm': numBits = 20; break;
case 'g': numBits = 30; break;
case 't': numBits = 40; break;
default: return false;
}
UInt64 val2 = v << numBits;
if ((val2 >> numBits) != v)
return false;
res = val2;
return true;
}
bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres)
{
hres = S_OK;
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
#ifndef _7ZIP_ST
hres = ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads);
#endif
return true;
}
if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
{
if (!ParseSizeString(name.Ptr(6), value, _memAvail, _memUsage))
hres = E_INVALIDARG;
return true;
}
return false;
}
#ifndef EXTRACT_ONLY
static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
{
if (m.FindProp(propID) < 0)
m.AddProp32(propID, value);
}
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
{
UInt32 level = _level;
if (level != (UInt32)(Int32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
}
#ifndef _7ZIP_ST
void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads)
{
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
}
#endif
void CMultiMethodProps::InitMulti()
{
_level = (UInt32)(Int32)-1;
_analysisLevel = -1;
_crcSize = 4;
_autoFilter = true;
}
void CMultiMethodProps::Init()
{
InitCommon();
InitMulti();
_methods.Clear();
_filterMethod.Clear();
}
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
if (name[0] == 'x')
{
name.Delete(0);
_level = 9;
return ParsePropToUInt32(name, value, _level);
}
if (name.IsPrefixedBy_Ascii_NoCase("yx"))
{
name.Delete(0, 2);
UInt32 v = 9;
RINOK(ParsePropToUInt32(name, value, v));
_analysisLevel = (int)v;
return S_OK;
}
if (name.IsPrefixedBy_Ascii_NoCase("crc"))
{
name.Delete(0, 3);
_crcSize = 4;
return ParsePropToUInt32(name, value, _crcSize);
}
{
HRESULT hres;
if (SetCommonProperty(name, value, hres))
return hres;
}
UInt32 number;
unsigned index = ParseStringToUInt32(name, number);
UString realName = name.Ptr(index);
if (index == 0)
{
if (name.IsEqualTo("f"))
{
HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
if (res == S_OK)
return res;
if (value.vt != VT_BSTR)
return E_INVALIDARG;
return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value);
}
number = 0;
}
if (number > 64)
return E_FAIL;
for (int j = _methods.Size(); j <= (int)number; j++)
_methods.Add(COneMethodInfo());
return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
}
void CSingleMethodProps::Init()
{
InitCommon();
InitSingle();
Clear();
}
HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
Init();
for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
name.MakeLower_Ascii();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
if (name[0] == L'x')
{
UInt32 a = 9;
RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
_level = a;
AddProp_Level(a);
continue;
}
{
HRESULT hres;
if (SetCommonProperty(name, value, hres))
{
RINOK(hres)
continue;
}
}
RINOK(ParseMethodFromPROPVARIANT(names[i], value));
}
return S_OK;
}
#endif
}

View File

@@ -1,110 +1,110 @@
// HandlerOut.h
#ifndef __HANDLER_OUT_H
#define __HANDLER_OUT_H
#include "../../../Windows/System.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
bool ParseSizeString(const wchar_t *name, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res);
class CCommonMethodProps
{
protected:
void InitCommon()
{
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
#endif
UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28;
_memAvail = memAvail;
_memUsage = memAvail;
if (NWindows::NSystem::GetRamSize(memAvail))
{
_memAvail = memAvail;
_memUsage = memAvail / 32 * 17;
}
}
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
UInt64 _memUsage;
UInt64 _memAvail;
bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
CCommonMethodProps() { InitCommon(); }
};
#ifndef EXTRACT_ONLY
class CMultiMethodProps: public CCommonMethodProps
{
UInt32 _level;
int _analysisLevel;
void InitMulti();
public:
UInt32 _crcSize;
CObjectVector<COneMethodInfo> _methods;
COneMethodInfo _filterMethod;
bool _autoFilter;
void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const;
#ifndef _7ZIP_ST
static void SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads);
#endif
unsigned GetNumEmptyMethods() const
{
unsigned i;
for (i = 0; i < _methods.Size(); i++)
if (!_methods[i].IsEmpty())
break;
return i;
}
int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
int GetAnalysisLevel() const { return _analysisLevel; }
void Init();
CMultiMethodProps() { InitMulti(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
class CSingleMethodProps: public COneMethodInfo, public CCommonMethodProps
{
UInt32 _level;
void InitSingle()
{
_level = (UInt32)(Int32)-1;
}
public:
void Init();
CSingleMethodProps() { InitSingle(); }
int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
};
#endif
}
#endif
// HandlerOut.h
#ifndef __HANDLER_OUT_H
#define __HANDLER_OUT_H
#include "../../../Windows/System.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
bool ParseSizeString(const wchar_t *name, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res);
class CCommonMethodProps
{
protected:
void InitCommon()
{
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
#endif
UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28;
_memAvail = memAvail;
_memUsage = memAvail;
if (NWindows::NSystem::GetRamSize(memAvail))
{
_memAvail = memAvail;
_memUsage = memAvail / 32 * 17;
}
}
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
UInt64 _memUsage;
UInt64 _memAvail;
bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
CCommonMethodProps() { InitCommon(); }
};
#ifndef EXTRACT_ONLY
class CMultiMethodProps: public CCommonMethodProps
{
UInt32 _level;
int _analysisLevel;
void InitMulti();
public:
UInt32 _crcSize;
CObjectVector<COneMethodInfo> _methods;
COneMethodInfo _filterMethod;
bool _autoFilter;
void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const;
#ifndef _7ZIP_ST
static void SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads);
#endif
unsigned GetNumEmptyMethods() const
{
unsigned i;
for (i = 0; i < _methods.Size(); i++)
if (!_methods[i].IsEmpty())
break;
return i;
}
int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
int GetAnalysisLevel() const { return _analysisLevel; }
void Init();
CMultiMethodProps() { InitMulti(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
class CSingleMethodProps: public COneMethodInfo, public CCommonMethodProps
{
UInt32 _level;
void InitSingle()
{
_level = (UInt32)(Int32)-1;
}
public:
void Init();
CSingleMethodProps() { InitSingle(); }
int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
};
#endif
}
#endif

View File

@@ -1,46 +1,46 @@
// InStreamWithCRC.cpp
#include "StdAfx.h"
#include "InStreamWithCRC.h"
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessed = 0;
HRESULT result = S_OK;
if (_stream)
result = _stream->Read(data, size, &realProcessed);
_size += realProcessed;
if (size != 0 && realProcessed == 0)
_wasFinished = true;
_crc = CrcUpdate(_crc, data, realProcessed);
if (processedSize)
*processedSize = realProcessed;
return result;
}
STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessed = 0;
HRESULT result = S_OK;
if (_stream)
result = _stream->Read(data, size, &realProcessed);
_size += realProcessed;
/*
if (size != 0 && realProcessed == 0)
_wasFinished = true;
*/
_crc = CrcUpdate(_crc, data, realProcessed);
if (processedSize)
*processedSize = realProcessed;
return result;
}
STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
if (seekOrigin != STREAM_SEEK_SET || offset != 0)
return E_FAIL;
_size = 0;
_crc = CRC_INIT_VAL;
return _stream->Seek(offset, seekOrigin, newPosition);
}
// InStreamWithCRC.cpp
#include "StdAfx.h"
#include "InStreamWithCRC.h"
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessed = 0;
HRESULT result = S_OK;
if (_stream)
result = _stream->Read(data, size, &realProcessed);
_size += realProcessed;
if (size != 0 && realProcessed == 0)
_wasFinished = true;
_crc = CrcUpdate(_crc, data, realProcessed);
if (processedSize)
*processedSize = realProcessed;
return result;
}
STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessed = 0;
HRESULT result = S_OK;
if (_stream)
result = _stream->Read(data, size, &realProcessed);
_size += realProcessed;
/*
if (size != 0 && realProcessed == 0)
_wasFinished = true;
*/
_crc = CrcUpdate(_crc, data, realProcessed);
if (processedSize)
*processedSize = realProcessed;
return result;
}
STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
if (seekOrigin != STREAM_SEEK_SET || offset != 0)
return E_FAIL;
_size = 0;
_crc = CRC_INIT_VAL;
return _stream->Seek(offset, seekOrigin, newPosition);
}

View File

@@ -1,67 +1,67 @@
// InStreamWithCRC.h
#ifndef __IN_STREAM_WITH_CRC_H
#define __IN_STREAM_WITH_CRC_H
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
class CSequentialInStreamWithCRC:
public ISequentialInStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
private:
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
UInt32 _crc;
bool _wasFinished;
public:
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
_wasFinished = false;
_crc = CRC_INIT_VAL;
}
void ReleaseStream() { _stream.Release(); }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
UInt64 GetSize() const { return _size; }
bool WasFinished() const { return _wasFinished; }
};
class CInStreamWithCRC:
public IInStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
private:
CMyComPtr<IInStream> _stream;
UInt64 _size;
UInt32 _crc;
// bool _wasFinished;
public:
void SetStream(IInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
// _wasFinished = false;
_crc = CRC_INIT_VAL;
}
void ReleaseStream() { _stream.Release(); }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
UInt64 GetSize() const { return _size; }
// bool WasFinished() const { return _wasFinished; }
};
#endif
// InStreamWithCRC.h
#ifndef __IN_STREAM_WITH_CRC_H
#define __IN_STREAM_WITH_CRC_H
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
class CSequentialInStreamWithCRC:
public ISequentialInStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
private:
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
UInt32 _crc;
bool _wasFinished;
public:
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
_wasFinished = false;
_crc = CRC_INIT_VAL;
}
void ReleaseStream() { _stream.Release(); }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
UInt64 GetSize() const { return _size; }
bool WasFinished() const { return _wasFinished; }
};
class CInStreamWithCRC:
public IInStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
private:
CMyComPtr<IInStream> _stream;
UInt64 _size;
UInt32 _crc;
// bool _wasFinished;
public:
void SetStream(IInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
// _wasFinished = false;
_crc = CRC_INIT_VAL;
}
void ReleaseStream() { _stream.Release(); }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
UInt64 GetSize() const { return _size; }
// bool WasFinished() const { return _wasFinished; }
};
#endif

View File

@@ -1,88 +1,88 @@
// Archive/Common/ItemNameUtils.cpp
#include "StdAfx.h"
#include "ItemNameUtils.h"
namespace NArchive {
namespace NItemName {
static const wchar_t kOsPathSepar = WCHAR_PATH_SEPARATOR;
static const wchar_t kUnixPathSepar = L'/';
void ReplaceSlashes_OsToUnix
#if WCHAR_PATH_SEPARATOR != L'/'
(UString &name)
{
name.Replace(kOsPathSepar, kUnixPathSepar);
}
#else
(UString &) {}
#endif
UString GetOsPath(const UString &name)
{
#if WCHAR_PATH_SEPARATOR != L'/'
UString newName = name;
newName.Replace(kUnixPathSepar, kOsPathSepar);
return newName;
#else
return name;
#endif
}
UString GetOsPath_Remove_TailSlash(const UString &name)
{
if (name.IsEmpty())
return UString();
UString newName = GetOsPath(name);
if (newName.Back() == kOsPathSepar)
newName.DeleteBack();
return newName;
}
void ReplaceToOsSlashes_Remove_TailSlash(UString &name)
{
if (!name.IsEmpty())
{
#if WCHAR_PATH_SEPARATOR != L'/'
name.Replace(kUnixPathSepar, kOsPathSepar);
#endif
if (name.Back() == kOsPathSepar)
name.DeleteBack();
}
}
bool HasTailSlash(const AString &name, UINT
#if defined(_WIN32) && !defined(UNDER_CE)
codePage
#endif
)
{
if (name.IsEmpty())
return false;
char c =
#if defined(_WIN32) && !defined(UNDER_CE)
*CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0);
#else
name.Back();
#endif
return (c == '/');
}
#ifndef _WIN32
UString WinPathToOsPath(const UString &name)
{
UString newName = name;
newName.Replace(L'\\', WCHAR_PATH_SEPARATOR);
return newName;
}
#endif
}}
// Archive/Common/ItemNameUtils.cpp
#include "StdAfx.h"
#include "ItemNameUtils.h"
namespace NArchive {
namespace NItemName {
static const wchar_t kOsPathSepar = WCHAR_PATH_SEPARATOR;
static const wchar_t kUnixPathSepar = L'/';
void ReplaceSlashes_OsToUnix
#if WCHAR_PATH_SEPARATOR != L'/'
(UString &name)
{
name.Replace(kOsPathSepar, kUnixPathSepar);
}
#else
(UString &) {}
#endif
UString GetOsPath(const UString &name)
{
#if WCHAR_PATH_SEPARATOR != L'/'
UString newName = name;
newName.Replace(kUnixPathSepar, kOsPathSepar);
return newName;
#else
return name;
#endif
}
UString GetOsPath_Remove_TailSlash(const UString &name)
{
if (name.IsEmpty())
return UString();
UString newName = GetOsPath(name);
if (newName.Back() == kOsPathSepar)
newName.DeleteBack();
return newName;
}
void ReplaceToOsSlashes_Remove_TailSlash(UString &name)
{
if (!name.IsEmpty())
{
#if WCHAR_PATH_SEPARATOR != L'/'
name.Replace(kUnixPathSepar, kOsPathSepar);
#endif
if (name.Back() == kOsPathSepar)
name.DeleteBack();
}
}
bool HasTailSlash(const AString &name, UINT
#if defined(_WIN32) && !defined(UNDER_CE)
codePage
#endif
)
{
if (name.IsEmpty())
return false;
char c =
#if defined(_WIN32) && !defined(UNDER_CE)
*CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0);
#else
name.Back();
#endif
return (c == '/');
}
#ifndef _WIN32
UString WinPathToOsPath(const UString &name)
{
UString newName = name;
newName.Replace(L'\\', WCHAR_PATH_SEPARATOR);
return newName;
}
#endif
}}

View File

@@ -1,28 +1,28 @@
// Archive/Common/ItemNameUtils.h
#ifndef __ARCHIVE_ITEM_NAME_UTILS_H
#define __ARCHIVE_ITEM_NAME_UTILS_H
#include "../../../Common/MyString.h"
namespace NArchive {
namespace NItemName {
void ReplaceSlashes_OsToUnix(UString &name);
UString GetOsPath(const UString &name);
UString GetOsPath_Remove_TailSlash(const UString &name);
void ReplaceToOsSlashes_Remove_TailSlash(UString &name);
bool HasTailSlash(const AString &name, UINT codePage);
#ifdef _WIN32
inline UString WinPathToOsPath(const UString &name) { return name; }
#else
UString WinPathToOsPath(const UString &name);
#endif
}}
#endif
// Archive/Common/ItemNameUtils.h
#ifndef __ARCHIVE_ITEM_NAME_UTILS_H
#define __ARCHIVE_ITEM_NAME_UTILS_H
#include "../../../Common/MyString.h"
namespace NArchive {
namespace NItemName {
void ReplaceSlashes_OsToUnix(UString &name);
UString GetOsPath(const UString &name);
UString GetOsPath_Remove_TailSlash(const UString &name);
void ReplaceToOsSlashes_Remove_TailSlash(UString &name);
bool HasTailSlash(const AString &name, UINT codePage);
#ifdef _WIN32
inline UString WinPathToOsPath(const UString &name) { return name; }
#else
UString WinPathToOsPath(const UString &name);
#endif
}}
#endif

View File

@@ -1,191 +1,191 @@
// MultiStream.cpp
#include "StdAfx.h"
#include "MultiStream.h"
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
if (size == 0)
return S_OK;
if (_pos >= _totalLength)
return S_OK;
{
unsigned left = 0, mid = _streamIndex, right = Streams.Size();
for (;;)
{
CSubStreamInfo &m = Streams[mid];
if (_pos < m.GlobalOffset)
right = mid;
else if (_pos >= m.GlobalOffset + m.Size)
left = mid + 1;
else
{
_streamIndex = mid;
break;
}
mid = (left + right) / 2;
}
_streamIndex = mid;
}
CSubStreamInfo &s = Streams[_streamIndex];
UInt64 localPos = _pos - s.GlobalOffset;
if (localPos != s.LocalPos)
{
RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos));
}
UInt64 rem = s.Size - localPos;
if (size > rem)
size = (UInt32)rem;
HRESULT result = s.Stream->Read(data, size, &size);
_pos += size;
s.LocalPos += size;
if (processedSize)
*processedSize = size;
return result;
}
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
case STREAM_SEEK_CUR: offset += _pos; break;
case STREAM_SEEK_END: offset += _totalLength; break;
default: return STG_E_INVALIDFUNCTION;
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
_pos = offset;
if (newPosition)
*newPosition = offset;
return S_OK;
}
/*
class COutVolumeStream:
public ISequentialOutStream,
public CMyUnknownImp
{
unsigned _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 COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
while (size > 0)
{
if (_streamIndex >= Streams.Size())
{
CSubStreamInfo subStream;
RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
subStream.Pos = 0;
Streams.Add(subStream);
continue;
}
CSubStreamInfo &subStream = Streams[_streamIndex];
if (_offsetPos >= subStream.Size)
{
_offsetPos -= subStream.Size;
_streamIndex++;
continue;
}
if (_offsetPos != subStream.Pos)
{
CMyComPtr<IOutStream> outStream;
RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
subStream.Pos = _offsetPos;
}
UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
UInt32 realProcessed;
RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
data = (void *)((Byte *)data + realProcessed);
size -= realProcessed;
subStream.Pos += realProcessed;
_offsetPos += realProcessed;
_absPos += realProcessed;
if (_absPos > _length)
_length = _absPos;
if (processedSize)
*processedSize += realProcessed;
if (subStream.Pos == subStream.Size)
{
_streamIndex++;
_offsetPos = 0;
}
if (realProcessed != curSize && realProcessed == 0)
return E_FAIL;
}
return S_OK;
}
STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
case STREAM_SEEK_CUR: offset += _absPos; break;
case STREAM_SEEK_END: offset += _length; break;
default: return STG_E_INVALIDFUNCTION;
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
_absPos = offset;
_offsetPos = _absPos;
_streamIndex = 0;
if (newPosition)
*newPosition = offset;
return S_OK;
}
*/
// MultiStream.cpp
#include "StdAfx.h"
#include "MultiStream.h"
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
if (size == 0)
return S_OK;
if (_pos >= _totalLength)
return S_OK;
{
unsigned left = 0, mid = _streamIndex, right = Streams.Size();
for (;;)
{
CSubStreamInfo &m = Streams[mid];
if (_pos < m.GlobalOffset)
right = mid;
else if (_pos >= m.GlobalOffset + m.Size)
left = mid + 1;
else
{
_streamIndex = mid;
break;
}
mid = (left + right) / 2;
}
_streamIndex = mid;
}
CSubStreamInfo &s = Streams[_streamIndex];
UInt64 localPos = _pos - s.GlobalOffset;
if (localPos != s.LocalPos)
{
RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos));
}
UInt64 rem = s.Size - localPos;
if (size > rem)
size = (UInt32)rem;
HRESULT result = s.Stream->Read(data, size, &size);
_pos += size;
s.LocalPos += size;
if (processedSize)
*processedSize = size;
return result;
}
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
case STREAM_SEEK_CUR: offset += _pos; break;
case STREAM_SEEK_END: offset += _totalLength; break;
default: return STG_E_INVALIDFUNCTION;
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
_pos = offset;
if (newPosition)
*newPosition = offset;
return S_OK;
}
/*
class COutVolumeStream:
public ISequentialOutStream,
public CMyUnknownImp
{
unsigned _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 COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
while (size > 0)
{
if (_streamIndex >= Streams.Size())
{
CSubStreamInfo subStream;
RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
subStream.Pos = 0;
Streams.Add(subStream);
continue;
}
CSubStreamInfo &subStream = Streams[_streamIndex];
if (_offsetPos >= subStream.Size)
{
_offsetPos -= subStream.Size;
_streamIndex++;
continue;
}
if (_offsetPos != subStream.Pos)
{
CMyComPtr<IOutStream> outStream;
RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
subStream.Pos = _offsetPos;
}
UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
UInt32 realProcessed;
RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
data = (void *)((Byte *)data + realProcessed);
size -= realProcessed;
subStream.Pos += realProcessed;
_offsetPos += realProcessed;
_absPos += realProcessed;
if (_absPos > _length)
_length = _absPos;
if (processedSize)
*processedSize += realProcessed;
if (subStream.Pos == subStream.Size)
{
_streamIndex++;
_offsetPos = 0;
}
if (realProcessed != curSize && realProcessed == 0)
return E_FAIL;
}
return S_OK;
}
STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
case STREAM_SEEK_CUR: offset += _absPos; break;
case STREAM_SEEK_END: offset += _length; break;
default: return STG_E_INVALIDFUNCTION;
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
_absPos = offset;
_offsetPos = _absPos;
_streamIndex = 0;
if (newPosition)
*newPosition = offset;
return S_OK;
}
*/

View File

@@ -1,89 +1,89 @@
// MultiStream.h
#ifndef __MULTI_STREAM_H
#define __MULTI_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../IStream.h"
class CMultiStream:
public IInStream,
public CMyUnknownImp
{
UInt64 _pos;
UInt64 _totalLength;
unsigned _streamIndex;
public:
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
UInt64 Size;
UInt64 GlobalOffset;
UInt64 LocalPos;
CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {}
};
CObjectVector<CSubStreamInfo> Streams;
HRESULT Init()
{
UInt64 total = 0;
FOR_VECTOR (i, Streams)
{
CSubStreamInfo &s = Streams[i];
s.GlobalOffset = total;
total += Streams[i].Size;
RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos));
}
_totalLength = total;
_pos = 0;
_streamIndex = 0;
return S_OK;
}
MY_UNKNOWN_IMP1(IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
/*
class COutMultiStream:
public IOutStream,
public CMyUnknownImp
{
unsigned _streamIndex; // required stream
UInt64 _offsetPos; // offset from start of _streamIndex index
UInt64 _absPos;
UInt64 _length;
struct CSubStreamInfo
{
CMyComPtr<ISequentialOutStream> Stream;
UInt64 Size;
UInt64 Pos;
};
CObjectVector<CSubStreamInfo> Streams;
public:
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
void Init()
{
_streamIndex = 0;
_offsetPos = 0;
_absPos = 0;
_length = 0;
}
MY_UNKNOWN_IMP1(IOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
*/
#endif
// MultiStream.h
#ifndef __MULTI_STREAM_H
#define __MULTI_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../IStream.h"
class CMultiStream:
public IInStream,
public CMyUnknownImp
{
UInt64 _pos;
UInt64 _totalLength;
unsigned _streamIndex;
public:
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
UInt64 Size;
UInt64 GlobalOffset;
UInt64 LocalPos;
CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {}
};
CObjectVector<CSubStreamInfo> Streams;
HRESULT Init()
{
UInt64 total = 0;
FOR_VECTOR (i, Streams)
{
CSubStreamInfo &s = Streams[i];
s.GlobalOffset = total;
total += Streams[i].Size;
RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos));
}
_totalLength = total;
_pos = 0;
_streamIndex = 0;
return S_OK;
}
MY_UNKNOWN_IMP1(IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
/*
class COutMultiStream:
public IOutStream,
public CMyUnknownImp
{
unsigned _streamIndex; // required stream
UInt64 _offsetPos; // offset from start of _streamIndex index
UInt64 _absPos;
UInt64 _length;
struct CSubStreamInfo
{
CMyComPtr<ISequentialOutStream> Stream;
UInt64 Size;
UInt64 Pos;
};
CObjectVector<CSubStreamInfo> Streams;
public:
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
void Init()
{
_streamIndex = 0;
_offsetPos = 0;
_absPos = 0;
_length = 0;
}
MY_UNKNOWN_IMP1(IOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
*/
#endif

View File

@@ -1,18 +1,18 @@
// OutStreamWithCRC.cpp
#include "StdAfx.h"
#include "OutStreamWithCRC.h"
STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, size, &size);
if (_calculate)
_crc = CrcUpdate(_crc, data, size);
_size += size;
if (processedSize != NULL)
*processedSize = size;
return result;
}
// OutStreamWithCRC.cpp
#include "StdAfx.h"
#include "OutStreamWithCRC.h"
STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, size, &size);
if (_calculate)
_crc = CrcUpdate(_crc, data, size);
_size += size;
if (processedSize != NULL)
*processedSize = size;
return result;
}

View File

@@ -1,37 +1,37 @@
// OutStreamWithCRC.h
#ifndef __OUT_STREAM_WITH_CRC_H
#define __OUT_STREAM_WITH_CRC_H
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
class COutStreamWithCRC:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
UInt32 _crc;
bool _calculate;
public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init(bool calculate = true)
{
_size = 0;
_calculate = calculate;
_crc = CRC_INIT_VAL;
}
void EnableCalc(bool calculate) { _calculate = calculate; }
void InitCRC() { _crc = CRC_INIT_VAL; }
UInt64 GetSize() const { return _size; }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
};
#endif
// OutStreamWithCRC.h
#ifndef __OUT_STREAM_WITH_CRC_H
#define __OUT_STREAM_WITH_CRC_H
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
class COutStreamWithCRC:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
UInt32 _crc;
bool _calculate;
public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init(bool calculate = true)
{
_size = 0;
_calculate = calculate;
_crc = CRC_INIT_VAL;
}
void EnableCalc(bool calculate) { _calculate = calculate; }
void InitCRC() { _crc = CRC_INIT_VAL; }
UInt64 GetSize() const { return _size; }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
};
#endif

View File

@@ -1,18 +1,18 @@
// OutStreamWithSha1.cpp
#include "StdAfx.h"
#include "OutStreamWithSha1.h"
STDMETHODIMP COutStreamWithSha1::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, size, &size);
if (_calculate)
Sha1_Update(&_sha, (const Byte *)data, size);
_size += size;
if (processedSize)
*processedSize = size;
return result;
}
// OutStreamWithSha1.cpp
#include "StdAfx.h"
#include "OutStreamWithSha1.h"
STDMETHODIMP COutStreamWithSha1::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, size, &size);
if (_calculate)
Sha1_Update(&_sha, (const Byte *)data, size);
_size += size;
if (processedSize)
*processedSize = size;
return result;
}

View File

@@ -1,36 +1,36 @@
// OutStreamWithSha1.h
#ifndef __OUT_STREAM_WITH_SHA1_H
#define __OUT_STREAM_WITH_SHA1_H
#include "../../../../C/Sha1.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
class COutStreamWithSha1:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
CSha1 _sha;
bool _calculate;
public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init(bool calculate = true)
{
_size = 0;
_calculate = calculate;
Sha1_Init(&_sha);
}
void InitSha1() { Sha1_Init(&_sha); }
UInt64 GetSize() const { return _size; }
void Final(Byte *digest) { Sha1_Final(&_sha, digest); }
};
#endif
// OutStreamWithSha1.h
#ifndef __OUT_STREAM_WITH_SHA1_H
#define __OUT_STREAM_WITH_SHA1_H
#include "../../../../C/Sha1.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
class COutStreamWithSha1:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
CSha1 _sha;
bool _calculate;
public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init(bool calculate = true)
{
_size = 0;
_calculate = calculate;
Sha1_Init(&_sha);
}
void InitSha1() { Sha1_Init(&_sha); }
UInt64 GetSize() const { return _size; }
void Final(Byte *digest) { Sha1_Final(&_sha, digest); }
};
#endif

View File

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

View File

@@ -1,6 +1,6 @@
// ParseProperties.h
#ifndef __PARSE_PROPERTIES_H
#define __PARSE_PROPERTIES_H
#endif
// ParseProperties.h
#ifndef __PARSE_PROPERTIES_H
#define __PARSE_PROPERTIES_H
#endif

View File

@@ -1,8 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,6 +1,6 @@
// DeflateProps.h
#ifndef __DEFLATE_PROPS_H
#define __DEFLATE_PROPS_H
#endif
// DeflateProps.h
#ifndef __DEFLATE_PROPS_H
#define __DEFLATE_PROPS_H
#endif

View File

@@ -1,94 +1,94 @@
// DLLExports.cpp
#include "StdAfx.h"
#if defined(_7ZIP_LARGE_PAGES)
#include "../../../C/Alloc.h"
#endif
#include "../../Common/MyInitGuid.h"
#include "../../Common/ComTry.h"
#include "../../Windows/NtCheck.h"
#include "../../Windows/PropVariant.h"
#include "../ICoder.h"
#include "../IPassword.h"
#include "../Common/CreateCoder.h"
#include "IArchive.h"
HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE;
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
g_hInstance = hInstance;
NT_CHECK;
}
return TRUE;
}
DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
return CreateArchiver(clsid, iid, outObject);
}
STDAPI SetLargePageMode()
{
#if defined(_7ZIP_LARGE_PAGES)
SetLargePageSize();
#endif
return S_OK;
}
extern bool g_CaseSensitive;
STDAPI SetCaseSensitive(Int32 caseSensitive)
{
g_CaseSensitive = (caseSensitive != 0);
return S_OK;
}
#ifdef EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
{
COM_TRY_BEGIN
// OutputDebugStringA(compressCodecsInfo ? "SetCodecs" : "SetCodecs NULL");
if (compressCodecsInfo)
{
g_ExternalCodecs.GetCodecs = compressCodecsInfo;
return g_ExternalCodecs.Load();
}
g_ExternalCodecs.ClearAndRelease();
return S_OK;
COM_TRY_END
}
#else
STDAPI SetCodecs(ICompressCodecsInfo *)
{
return S_OK;
}
#endif
// DLLExports.cpp
#include "StdAfx.h"
#if defined(_7ZIP_LARGE_PAGES)
#include "../../../C/Alloc.h"
#endif
#include "../../Common/MyInitGuid.h"
#include "../../Common/ComTry.h"
#include "../../Windows/NtCheck.h"
#include "../../Windows/PropVariant.h"
#include "../ICoder.h"
#include "../IPassword.h"
#include "../Common/CreateCoder.h"
#include "IArchive.h"
HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE;
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
g_hInstance = hInstance;
NT_CHECK;
}
return TRUE;
}
DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
return CreateArchiver(clsid, iid, outObject);
}
STDAPI SetLargePageMode()
{
#if defined(_7ZIP_LARGE_PAGES)
SetLargePageSize();
#endif
return S_OK;
}
extern bool g_CaseSensitive;
STDAPI SetCaseSensitive(Int32 caseSensitive)
{
g_CaseSensitive = (caseSensitive != 0);
return S_OK;
}
#ifdef EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
{
COM_TRY_BEGIN
// OutputDebugStringA(compressCodecsInfo ? "SetCodecs" : "SetCodecs NULL");
if (compressCodecsInfo)
{
g_ExternalCodecs.GetCodecs = compressCodecsInfo;
return g_ExternalCodecs.Load();
}
g_ExternalCodecs.ClearAndRelease();
return S_OK;
COM_TRY_END
}
#else
STDAPI SetCodecs(ICompressCodecsInfo *)
{
return S_OK;
}
#endif

View File

@@ -1,122 +1,122 @@
// DLLExports2.cpp
#include "StdAfx.h"
#include "../../Common/MyWindows.h"
#include "../../Common/MyInitGuid.h"
#if defined(_7ZIP_LARGE_PAGES)
#include "../../../C/Alloc.h"
#endif
#include "../../Common/ComTry.h"
#include "../../Windows/NtCheck.h"
#include "../../Windows/PropVariant.h"
#include "../ICoder.h"
#include "../IPassword.h"
#include "../Common/CreateCoder.h"
#include "IArchive.h"
HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE;
#ifdef _WIN32
extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
HANDLE
#else
HINSTANCE
#endif
hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// OutputDebugStringA("7z.dll DLL_PROCESS_ATTACH");
g_hInstance = (HINSTANCE)hInstance;
NT_CHECK;
}
/*
if (dwReason == DLL_PROCESS_DETACH)
{
OutputDebugStringA("7z.dll DLL_PROCESS_DETACH");
}
*/
return TRUE;
}
#endif
DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateHasher(const GUID *clsid, IHasher **hasher);
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
// COM_TRY_BEGIN
*outObject = 0;
if (*iid == IID_ICompressCoder ||
*iid == IID_ICompressCoder2 ||
*iid == IID_ICompressFilter)
return CreateCoder(clsid, iid, outObject);
if (*iid == IID_IHasher)
return CreateHasher(clsid, (IHasher **)outObject);
return CreateArchiver(clsid, iid, outObject);
// COM_TRY_END
}
STDAPI SetLargePageMode()
{
#if defined(_7ZIP_LARGE_PAGES)
SetLargePageSize();
#endif
return S_OK;
}
extern bool g_CaseSensitive;
STDAPI SetCaseSensitive(Int32 caseSensitive)
{
g_CaseSensitive = (caseSensitive != 0);
return S_OK;
}
#ifdef EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
{
COM_TRY_BEGIN
// OutputDebugStringA(compressCodecsInfo ? "SetCodecs" : "SetCodecs NULL");
if (compressCodecsInfo)
{
g_ExternalCodecs.GetCodecs = compressCodecsInfo;
return g_ExternalCodecs.Load();
}
g_ExternalCodecs.ClearAndRelease();
return S_OK;
COM_TRY_END
}
#else
STDAPI SetCodecs(ICompressCodecsInfo *)
{
return S_OK;
}
#endif
// DLLExports2.cpp
#include "StdAfx.h"
#include "../../Common/MyWindows.h"
#include "../../Common/MyInitGuid.h"
#if defined(_7ZIP_LARGE_PAGES)
#include "../../../C/Alloc.h"
#endif
#include "../../Common/ComTry.h"
#include "../../Windows/NtCheck.h"
#include "../../Windows/PropVariant.h"
#include "../ICoder.h"
#include "../IPassword.h"
#include "../Common/CreateCoder.h"
#include "IArchive.h"
HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE;
#ifdef _WIN32
extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
HANDLE
#else
HINSTANCE
#endif
hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// OutputDebugStringA("7z.dll DLL_PROCESS_ATTACH");
g_hInstance = (HINSTANCE)hInstance;
NT_CHECK;
}
/*
if (dwReason == DLL_PROCESS_DETACH)
{
OutputDebugStringA("7z.dll DLL_PROCESS_DETACH");
}
*/
return TRUE;
}
#endif
DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateHasher(const GUID *clsid, IHasher **hasher);
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
// COM_TRY_BEGIN
*outObject = 0;
if (*iid == IID_ICompressCoder ||
*iid == IID_ICompressCoder2 ||
*iid == IID_ICompressFilter)
return CreateCoder(clsid, iid, outObject);
if (*iid == IID_IHasher)
return CreateHasher(clsid, (IHasher **)outObject);
return CreateArchiver(clsid, iid, outObject);
// COM_TRY_END
}
STDAPI SetLargePageMode()
{
#if defined(_7ZIP_LARGE_PAGES)
SetLargePageSize();
#endif
return S_OK;
}
extern bool g_CaseSensitive;
STDAPI SetCaseSensitive(Int32 caseSensitive)
{
g_CaseSensitive = (caseSensitive != 0);
return S_OK;
}
#ifdef EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
{
COM_TRY_BEGIN
// OutputDebugStringA(compressCodecsInfo ? "SetCodecs" : "SetCodecs NULL");
if (compressCodecsInfo)
{
g_ExternalCodecs.GetCodecs = compressCodecsInfo;
return g_ExternalCodecs.Load();
}
g_ExternalCodecs.ClearAndRelease();
return S_OK;
COM_TRY_END
}
#else
STDAPI SetCodecs(ICompressCodecsInfo *)
{
return S_OK;
}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,403 +1,403 @@
// GptHandler.cpp
#include "StdAfx.h"
#include "../../../C/7zCrc.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/IntToString.h"
#include "../../Common/MyBuffer.h"
#include "../../Windows/PropVariantUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "HandlerCont.h"
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
#define Get64(p) GetUi64(p)
using namespace NWindows;
namespace NArchive {
namespace NGpt {
#define SIGNATURE { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 }
static const unsigned k_SignatureSize = 12;
static const Byte k_Signature[k_SignatureSize] = SIGNATURE;
static const UInt32 kSectorSize = 512;
static const CUInt32PCharPair g_PartitionFlags[] =
{
{ 0, "Sys" },
{ 1, "Ignore" },
{ 2, "Legacy" },
{ 60, "Win-Read-only" },
{ 62, "Win-Hidden" },
{ 63, "Win-Not-Automount" }
};
static const unsigned kNameLen = 36;
struct CPartition
{
Byte Type[16];
Byte Id[16];
UInt64 FirstLba;
UInt64 LastLba;
UInt64 Flags;
Byte Name[kNameLen * 2];
bool IsUnused() const
{
for (unsigned i = 0; i < 16; i++)
if (Type[i] != 0)
return false;
return true;
}
UInt64 GetSize() const { return (LastLba - FirstLba + 1) * kSectorSize; }
UInt64 GetPos() const { return FirstLba * kSectorSize; }
UInt64 GetEnd() const { return (LastLba + 1) * kSectorSize; }
void Parse(const Byte *p)
{
memcpy(Type, p, 16);
memcpy(Id, p + 16, 16);
FirstLba = Get64(p + 32);
LastLba = Get64(p + 40);
Flags = Get64(p + 48);
memcpy(Name, p + 56, kNameLen * 2);
}
};
struct CPartType
{
UInt32 Id;
const char *Ext;
const char *Type;
};
static const CPartType kPartTypes[] =
{
// { 0x0, 0, "Unused" },
{ 0x21686148, 0, "BIOS Boot" },
{ 0xC12A7328, 0, "EFI System" },
{ 0x024DEE41, 0, "MBR" },
{ 0xE3C9E316, 0, "Windows MSR" },
{ 0xEBD0A0A2, 0, "Windows BDP" },
{ 0x5808C8AA, 0, "Windows LDM Metadata" },
{ 0xAF9B60A0, 0, "Windows LDM Data" },
{ 0xDE94BBA4, 0, "Windows Recovery" },
// { 0x37AFFC90, 0, "IBM GPFS" },
// { 0xE75CAF8F, 0, "Windows Storage Spaces" },
{ 0x0FC63DAF, 0, "Linux Data" },
{ 0x0657FD6D, 0, "Linux Swap" },
{ 0x83BD6B9D, 0, "FreeBSD Boot" },
{ 0x516E7CB4, 0, "FreeBSD Data" },
{ 0x516E7CB5, 0, "FreeBSD Swap" },
{ 0x516E7CB6, "ufs", "FreeBSD UFS" },
{ 0x516E7CB8, 0, "FreeBSD Vinum" },
{ 0x516E7CB8, "zfs", "FreeBSD ZFS" },
{ 0x48465300, "hfsx", "HFS+" },
};
static int FindPartType(const Byte *guid)
{
UInt32 val = Get32(guid);
for (unsigned i = 0; i < ARRAY_SIZE(kPartTypes); i++)
if (kPartTypes[i].Id == val)
return i;
return -1;
}
static void RawLeGuidToString_Upper(const Byte *g, char *s)
{
RawLeGuidToString(g, s);
// MyStringUpper_Ascii(s);
}
class CHandler: public CHandlerCont
{
CRecordVector<CPartition> _items;
UInt64 _totalSize;
Byte Guid[16];
CByteBuffer _buffer;
HRESULT Open2(IInStream *stream);
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CPartition &item = _items[index];
pos = item.GetPos();
size = item.GetSize();
return NExtract::NOperationResult::kOK;
}
public:
INTERFACE_IInArchive_Cont(;)
};
HRESULT CHandler::Open2(IInStream *stream)
{
_buffer.Alloc(kSectorSize * 2);
RINOK(ReadStream_FALSE(stream, _buffer, kSectorSize * 2));
const Byte *buf = _buffer;
if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA)
return S_FALSE;
buf += kSectorSize;
if (memcmp(buf, k_Signature, k_SignatureSize) != 0)
return S_FALSE;
{
// if (Get32(buf + 8) != 0x10000) return S_FALSE; // revision
UInt32 headerSize = Get32(buf + 12); // = 0x5C usually
if (headerSize > kSectorSize)
return S_FALSE;
UInt32 crc = Get32(buf + 0x10);
SetUi32(_buffer + kSectorSize + 0x10, 0);
if (CrcCalc(_buffer + kSectorSize, headerSize) != crc)
return S_FALSE;
}
// UInt32 reserved = Get32(buf + 0x14);
UInt64 curLba = Get64(buf + 0x18);
if (curLba != 1)
return S_FALSE;
UInt64 backupLba = Get64(buf + 0x20);
// UInt64 firstUsableLba = Get64(buf + 0x28);
// UInt64 lastUsableLba = Get64(buf + 0x30);
memcpy(Guid, buf + 0x38, 16);
UInt64 tableLba = Get64(buf + 0x48);
if (tableLba < 2)
return S_FALSE;
UInt32 numEntries = Get32(buf + 0x50);
UInt32 entrySize = Get32(buf + 0x54); // = 128 usually
UInt32 entriesCrc = Get32(buf + 0x58);
if (entrySize < 128
|| entrySize > (1 << 12)
|| numEntries > (1 << 16)
|| tableLba < 2
|| tableLba >= ((UInt64)1 << (64 - 10)))
return S_FALSE;
UInt32 tableSize = entrySize * numEntries;
UInt32 tableSizeAligned = (tableSize + kSectorSize - 1) & ~(kSectorSize - 1);
_buffer.Alloc(tableSizeAligned);
UInt64 tableOffset = tableLba * kSectorSize;
RINOK(stream->Seek(tableOffset, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(stream, _buffer, tableSizeAligned));
if (CrcCalc(_buffer, tableSize) != entriesCrc)
return S_FALSE;
_totalSize = tableOffset + tableSizeAligned;
for (UInt32 i = 0; i < numEntries; i++)
{
CPartition item;
item.Parse(_buffer + i * entrySize);
if (item.IsUnused())
continue;
UInt64 endPos = item.GetEnd();
if (_totalSize < endPos)
_totalSize = endPos;
_items.Add(item);
}
{
const UInt64 end = (backupLba + 1) * kSectorSize;
if (_totalSize < end)
_totalSize = end;
}
{
UInt64 fileEnd;
RINOK(stream->Seek(0, STREAM_SEEK_END, &fileEnd));
if (_totalSize < fileEnd)
{
const UInt64 rem = fileEnd - _totalSize;
const UInt64 kRemMax = 1 << 22;
if (rem <= kRemMax)
{
RINOK(stream->Seek(_totalSize, STREAM_SEEK_SET, NULL));
bool areThereNonZeros = false;
UInt64 numZeros = 0;
if (ReadZeroTail(stream, areThereNonZeros, numZeros, kRemMax) == S_OK)
if (!areThereNonZeros)
_totalSize += numZeros;
}
}
}
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
Close();
RINOK(Open2(stream));
_stream = stream;
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_totalSize = 0;
memset(Guid, 0, sizeof(Guid));
_items.Clear();
_stream.Release();
return S_OK;
}
static const Byte kProps[] =
{
kpidPath,
kpidSize,
kpidFileSystem,
kpidCharacts,
kpidOffset,
kpidId
};
static const Byte kArcProps[] =
{
kpidId
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
switch (propID)
{
case kpidMainSubfile:
{
if (_items.Size() == 1)
prop = (UInt32)0;
break;
}
case kpidPhySize: prop = _totalSize; break;
case kpidId:
{
char s[48];
RawLeGuidToString_Upper(Guid, s);
prop = s;
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
const CPartition &item = _items[index];
switch (propID)
{
case kpidPath:
{
UString s;
for (unsigned i = 0; i < kNameLen; i++)
{
wchar_t c = (wchar_t)Get16(item.Name + i * 2);
if (c == 0)
break;
s += c;
}
if (s.IsEmpty())
s.Add_UInt32(index);
{
s += '.';
const char *ext = NULL;
int typeIndex = FindPartType(item.Type);
if (typeIndex >= 0)
ext = kPartTypes[(unsigned)typeIndex].Ext;
if (!ext)
ext = "img";
s += ext;
}
prop = s;
break;
}
case kpidSize:
case kpidPackSize: prop = item.GetSize(); break;
case kpidOffset: prop = item.GetPos(); break;
case kpidFileSystem:
{
char s[48];
const char *res;
int typeIndex = FindPartType(item.Type);
if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Type)
res = kPartTypes[(unsigned)typeIndex].Type;
else
{
RawLeGuidToString_Upper(item.Type, s);
res = s;
}
prop = res;
break;
}
case kpidId:
{
char s[48];
RawLeGuidToString_Upper(item.Id, s);
prop = s;
break;
}
case kpidCharacts: FLAGS64_TO_PROP(g_PartitionFlags, item.Flags, prop); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
REGISTER_ARC_I(
"GPT", "gpt mbr", NULL, 0xCB,
k_Signature,
kSectorSize,
0,
NULL)
}}
// GptHandler.cpp
#include "StdAfx.h"
#include "../../../C/7zCrc.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/IntToString.h"
#include "../../Common/MyBuffer.h"
#include "../../Windows/PropVariantUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "HandlerCont.h"
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
#define Get64(p) GetUi64(p)
using namespace NWindows;
namespace NArchive {
namespace NGpt {
#define SIGNATURE { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 }
static const unsigned k_SignatureSize = 12;
static const Byte k_Signature[k_SignatureSize] = SIGNATURE;
static const UInt32 kSectorSize = 512;
static const CUInt32PCharPair g_PartitionFlags[] =
{
{ 0, "Sys" },
{ 1, "Ignore" },
{ 2, "Legacy" },
{ 60, "Win-Read-only" },
{ 62, "Win-Hidden" },
{ 63, "Win-Not-Automount" }
};
static const unsigned kNameLen = 36;
struct CPartition
{
Byte Type[16];
Byte Id[16];
UInt64 FirstLba;
UInt64 LastLba;
UInt64 Flags;
Byte Name[kNameLen * 2];
bool IsUnused() const
{
for (unsigned i = 0; i < 16; i++)
if (Type[i] != 0)
return false;
return true;
}
UInt64 GetSize() const { return (LastLba - FirstLba + 1) * kSectorSize; }
UInt64 GetPos() const { return FirstLba * kSectorSize; }
UInt64 GetEnd() const { return (LastLba + 1) * kSectorSize; }
void Parse(const Byte *p)
{
memcpy(Type, p, 16);
memcpy(Id, p + 16, 16);
FirstLba = Get64(p + 32);
LastLba = Get64(p + 40);
Flags = Get64(p + 48);
memcpy(Name, p + 56, kNameLen * 2);
}
};
struct CPartType
{
UInt32 Id;
const char *Ext;
const char *Type;
};
static const CPartType kPartTypes[] =
{
// { 0x0, 0, "Unused" },
{ 0x21686148, 0, "BIOS Boot" },
{ 0xC12A7328, 0, "EFI System" },
{ 0x024DEE41, 0, "MBR" },
{ 0xE3C9E316, 0, "Windows MSR" },
{ 0xEBD0A0A2, 0, "Windows BDP" },
{ 0x5808C8AA, 0, "Windows LDM Metadata" },
{ 0xAF9B60A0, 0, "Windows LDM Data" },
{ 0xDE94BBA4, 0, "Windows Recovery" },
// { 0x37AFFC90, 0, "IBM GPFS" },
// { 0xE75CAF8F, 0, "Windows Storage Spaces" },
{ 0x0FC63DAF, 0, "Linux Data" },
{ 0x0657FD6D, 0, "Linux Swap" },
{ 0x83BD6B9D, 0, "FreeBSD Boot" },
{ 0x516E7CB4, 0, "FreeBSD Data" },
{ 0x516E7CB5, 0, "FreeBSD Swap" },
{ 0x516E7CB6, "ufs", "FreeBSD UFS" },
{ 0x516E7CB8, 0, "FreeBSD Vinum" },
{ 0x516E7CB8, "zfs", "FreeBSD ZFS" },
{ 0x48465300, "hfsx", "HFS+" },
};
static int FindPartType(const Byte *guid)
{
UInt32 val = Get32(guid);
for (unsigned i = 0; i < ARRAY_SIZE(kPartTypes); i++)
if (kPartTypes[i].Id == val)
return i;
return -1;
}
static void RawLeGuidToString_Upper(const Byte *g, char *s)
{
RawLeGuidToString(g, s);
// MyStringUpper_Ascii(s);
}
class CHandler: public CHandlerCont
{
CRecordVector<CPartition> _items;
UInt64 _totalSize;
Byte Guid[16];
CByteBuffer _buffer;
HRESULT Open2(IInStream *stream);
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CPartition &item = _items[index];
pos = item.GetPos();
size = item.GetSize();
return NExtract::NOperationResult::kOK;
}
public:
INTERFACE_IInArchive_Cont(;)
};
HRESULT CHandler::Open2(IInStream *stream)
{
_buffer.Alloc(kSectorSize * 2);
RINOK(ReadStream_FALSE(stream, _buffer, kSectorSize * 2));
const Byte *buf = _buffer;
if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA)
return S_FALSE;
buf += kSectorSize;
if (memcmp(buf, k_Signature, k_SignatureSize) != 0)
return S_FALSE;
{
// if (Get32(buf + 8) != 0x10000) return S_FALSE; // revision
UInt32 headerSize = Get32(buf + 12); // = 0x5C usually
if (headerSize > kSectorSize)
return S_FALSE;
UInt32 crc = Get32(buf + 0x10);
SetUi32(_buffer + kSectorSize + 0x10, 0);
if (CrcCalc(_buffer + kSectorSize, headerSize) != crc)
return S_FALSE;
}
// UInt32 reserved = Get32(buf + 0x14);
UInt64 curLba = Get64(buf + 0x18);
if (curLba != 1)
return S_FALSE;
UInt64 backupLba = Get64(buf + 0x20);
// UInt64 firstUsableLba = Get64(buf + 0x28);
// UInt64 lastUsableLba = Get64(buf + 0x30);
memcpy(Guid, buf + 0x38, 16);
UInt64 tableLba = Get64(buf + 0x48);
if (tableLba < 2)
return S_FALSE;
UInt32 numEntries = Get32(buf + 0x50);
UInt32 entrySize = Get32(buf + 0x54); // = 128 usually
UInt32 entriesCrc = Get32(buf + 0x58);
if (entrySize < 128
|| entrySize > (1 << 12)
|| numEntries > (1 << 16)
|| tableLba < 2
|| tableLba >= ((UInt64)1 << (64 - 10)))
return S_FALSE;
UInt32 tableSize = entrySize * numEntries;
UInt32 tableSizeAligned = (tableSize + kSectorSize - 1) & ~(kSectorSize - 1);
_buffer.Alloc(tableSizeAligned);
UInt64 tableOffset = tableLba * kSectorSize;
RINOK(stream->Seek(tableOffset, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(stream, _buffer, tableSizeAligned));
if (CrcCalc(_buffer, tableSize) != entriesCrc)
return S_FALSE;
_totalSize = tableOffset + tableSizeAligned;
for (UInt32 i = 0; i < numEntries; i++)
{
CPartition item;
item.Parse(_buffer + i * entrySize);
if (item.IsUnused())
continue;
UInt64 endPos = item.GetEnd();
if (_totalSize < endPos)
_totalSize = endPos;
_items.Add(item);
}
{
const UInt64 end = (backupLba + 1) * kSectorSize;
if (_totalSize < end)
_totalSize = end;
}
{
UInt64 fileEnd;
RINOK(stream->Seek(0, STREAM_SEEK_END, &fileEnd));
if (_totalSize < fileEnd)
{
const UInt64 rem = fileEnd - _totalSize;
const UInt64 kRemMax = 1 << 22;
if (rem <= kRemMax)
{
RINOK(stream->Seek(_totalSize, STREAM_SEEK_SET, NULL));
bool areThereNonZeros = false;
UInt64 numZeros = 0;
if (ReadZeroTail(stream, areThereNonZeros, numZeros, kRemMax) == S_OK)
if (!areThereNonZeros)
_totalSize += numZeros;
}
}
}
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
Close();
RINOK(Open2(stream));
_stream = stream;
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_totalSize = 0;
memset(Guid, 0, sizeof(Guid));
_items.Clear();
_stream.Release();
return S_OK;
}
static const Byte kProps[] =
{
kpidPath,
kpidSize,
kpidFileSystem,
kpidCharacts,
kpidOffset,
kpidId
};
static const Byte kArcProps[] =
{
kpidId
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
switch (propID)
{
case kpidMainSubfile:
{
if (_items.Size() == 1)
prop = (UInt32)0;
break;
}
case kpidPhySize: prop = _totalSize; break;
case kpidId:
{
char s[48];
RawLeGuidToString_Upper(Guid, s);
prop = s;
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
const CPartition &item = _items[index];
switch (propID)
{
case kpidPath:
{
UString s;
for (unsigned i = 0; i < kNameLen; i++)
{
wchar_t c = (wchar_t)Get16(item.Name + i * 2);
if (c == 0)
break;
s += c;
}
if (s.IsEmpty())
s.Add_UInt32(index);
{
s += '.';
const char *ext = NULL;
int typeIndex = FindPartType(item.Type);
if (typeIndex >= 0)
ext = kPartTypes[(unsigned)typeIndex].Ext;
if (!ext)
ext = "img";
s += ext;
}
prop = s;
break;
}
case kpidSize:
case kpidPackSize: prop = item.GetSize(); break;
case kpidOffset: prop = item.GetPos(); break;
case kpidFileSystem:
{
char s[48];
const char *res;
int typeIndex = FindPartType(item.Type);
if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Type)
res = kPartTypes[(unsigned)typeIndex].Type;
else
{
RawLeGuidToString_Upper(item.Type, s);
res = s;
}
prop = res;
break;
}
case kpidId:
{
char s[48];
RawLeGuidToString_Upper(item.Id, s);
prop = s;
break;
}
case kpidCharacts: FLAGS64_TO_PROP(g_PartitionFlags, item.Flags, prop); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
REGISTER_ARC_I(
"GPT", "gpt mbr", NULL, 0xCB,
k_Signature,
kSectorSize,
0,
NULL)
}}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,288 +1,288 @@
// HandlerCont.cpp
#include "StdAfx.h"
#include "../../Common/ComTry.h"
#include "../Common/LimitedStreams.h"
#include "../Common/ProgressUtils.h"
#include "../Common/StreamUtils.h"
#include "../Compress/CopyCoder.h"
#include "HandlerCont.h"
namespace NArchive {
STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
{
RINOK(GetNumberOfItems(&numItems));
}
if (numItems == 0)
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
UInt64 pos, size;
GetItem_ExtractInfo(allFilesMode ? i : indices[i], pos, size);
totalSize += size;
}
extractCallback->SetTotal(totalSize);
totalSize = 0;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_stream);
for (i = 0; i < numItems; i++)
{
lps->InSize = totalSize;
lps->OutSize = totalSize;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> outStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i];
RINOK(extractCallback->GetStream(index, &outStream, askMode));
UInt64 pos, size;
int opRes = GetItem_ExtractInfo(index, pos, size);
totalSize += size;
if (!testMode && !outStream)
continue;
RINOK(extractCallback->PrepareOperation(askMode));
if (opRes == NExtract::NOperationResult::kOK)
{
RINOK(_stream->Seek(pos, STREAM_SEEK_SET, NULL));
streamSpec->Init(size);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
opRes = NExtract::NOperationResult::kDataError;
if (copyCoderSpec->TotalSize == size)
opRes = NExtract::NOperationResult::kOK;
else if (copyCoderSpec->TotalSize < size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
}
outStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream)
{
COM_TRY_BEGIN
*stream = NULL;
UInt64 pos, size;
if (GetItem_ExtractInfo(index, pos, size) != NExtract::NOperationResult::kOK)
return S_FALSE;
return CreateLimitedInStream(_stream, pos, size, stream);
COM_TRY_END
}
CHandlerImg::CHandlerImg():
_imgExt(NULL)
{
ClearStreamVars();
}
STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
case STREAM_SEEK_CUR: offset += _virtPos; break;
case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
_virtPos = offset;
if (newPosition)
*newPosition = offset;
return S_OK;
}
static const Byte k_GDP_Signature[] = { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' };
static const char *GetImgExt(ISequentialInStream *stream)
{
const size_t kHeaderSize = 1 << 10;
Byte buf[kHeaderSize];
if (ReadStream_FAIL(stream, buf, kHeaderSize) == S_OK)
{
if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA)
{
if (memcmp(buf + 512, k_GDP_Signature, sizeof(k_GDP_Signature)) == 0)
return "gpt";
return "mbr";
}
}
return NULL;
}
void CHandlerImg::CloseAtError()
{
Stream.Release();
}
STDMETHODIMP CHandlerImg::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * openCallback)
{
COM_TRY_BEGIN
{
Close();
HRESULT res;
try
{
res = Open2(stream, openCallback);
if (res == S_OK)
{
CMyComPtr<ISequentialInStream> inStream;
HRESULT res2 = GetStream(0, &inStream);
if (res2 == S_OK && inStream)
_imgExt = GetImgExt(inStream);
return S_OK;
}
}
catch(...)
{
CloseAtError();
throw;
}
CloseAtError();
return res;
}
COM_TRY_END
}
STDMETHODIMP CHandlerImg::GetNumberOfItems(UInt32 *numItems)
{
*numItems = 1;
return S_OK;
}
STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
RINOK(extractCallback->SetTotal(_size));
CMyComPtr<ISequentialOutStream> outStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &outStream, askMode));
if (!testMode && !outStream)
return S_OK;
RINOK(extractCallback->PrepareOperation(askMode));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
int opRes = NExtract::NOperationResult::kDataError;
ClearStreamVars();
CMyComPtr<ISequentialInStream> inStream;
HRESULT hres = GetStream(0, &inStream);
if (hres == S_FALSE)
hres = E_NOTIMPL;
if (hres == S_OK && inStream)
{
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
hres = copyCoder->Code(inStream, outStream, NULL, &_size, progress);
if (hres == S_OK)
{
if (copyCoderSpec->TotalSize == _size)
opRes = NExtract::NOperationResult::kOK;
if (_stream_unavailData)
opRes = NExtract::NOperationResult::kUnavailable;
else if (_stream_unsupportedMethod)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
else if (_stream_dataError)
opRes = NExtract::NOperationResult::kDataError;
else if (copyCoderSpec->TotalSize < _size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
}
}
inStream.Release();
outStream.Release();
if (hres != S_OK)
{
if (hres == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else if (hres == E_NOTIMPL)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
else
return hres;
}
return extractCallback->SetOperationResult(opRes);
COM_TRY_END
}
HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize)
{
areThereNonZeros = false;
numZeros = 0;
const size_t kBufSize = 1 << 11;
Byte buf[kBufSize];
for (;;)
{
UInt32 size = 0;
HRESULT(stream->Read(buf, kBufSize, &size));
if (size == 0)
return S_OK;
for (UInt32 i = 0; i < size; i++)
if (buf[i] != 0)
{
areThereNonZeros = true;
numZeros += i;
return S_OK;
}
numZeros += size;
if (numZeros > maxSize)
return S_OK;
}
}
}
// HandlerCont.cpp
#include "StdAfx.h"
#include "../../Common/ComTry.h"
#include "../Common/LimitedStreams.h"
#include "../Common/ProgressUtils.h"
#include "../Common/StreamUtils.h"
#include "../Compress/CopyCoder.h"
#include "HandlerCont.h"
namespace NArchive {
STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
{
RINOK(GetNumberOfItems(&numItems));
}
if (numItems == 0)
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
UInt64 pos, size;
GetItem_ExtractInfo(allFilesMode ? i : indices[i], pos, size);
totalSize += size;
}
extractCallback->SetTotal(totalSize);
totalSize = 0;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_stream);
for (i = 0; i < numItems; i++)
{
lps->InSize = totalSize;
lps->OutSize = totalSize;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> outStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i];
RINOK(extractCallback->GetStream(index, &outStream, askMode));
UInt64 pos, size;
int opRes = GetItem_ExtractInfo(index, pos, size);
totalSize += size;
if (!testMode && !outStream)
continue;
RINOK(extractCallback->PrepareOperation(askMode));
if (opRes == NExtract::NOperationResult::kOK)
{
RINOK(_stream->Seek(pos, STREAM_SEEK_SET, NULL));
streamSpec->Init(size);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
opRes = NExtract::NOperationResult::kDataError;
if (copyCoderSpec->TotalSize == size)
opRes = NExtract::NOperationResult::kOK;
else if (copyCoderSpec->TotalSize < size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
}
outStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream)
{
COM_TRY_BEGIN
*stream = NULL;
UInt64 pos, size;
if (GetItem_ExtractInfo(index, pos, size) != NExtract::NOperationResult::kOK)
return S_FALSE;
return CreateLimitedInStream(_stream, pos, size, stream);
COM_TRY_END
}
CHandlerImg::CHandlerImg():
_imgExt(NULL)
{
ClearStreamVars();
}
STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
switch (seekOrigin)
{
case STREAM_SEEK_SET: break;
case STREAM_SEEK_CUR: offset += _virtPos; break;
case STREAM_SEEK_END: offset += _size; break;
default: return STG_E_INVALIDFUNCTION;
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
_virtPos = offset;
if (newPosition)
*newPosition = offset;
return S_OK;
}
static const Byte k_GDP_Signature[] = { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' };
static const char *GetImgExt(ISequentialInStream *stream)
{
const size_t kHeaderSize = 1 << 10;
Byte buf[kHeaderSize];
if (ReadStream_FAIL(stream, buf, kHeaderSize) == S_OK)
{
if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA)
{
if (memcmp(buf + 512, k_GDP_Signature, sizeof(k_GDP_Signature)) == 0)
return "gpt";
return "mbr";
}
}
return NULL;
}
void CHandlerImg::CloseAtError()
{
Stream.Release();
}
STDMETHODIMP CHandlerImg::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * openCallback)
{
COM_TRY_BEGIN
{
Close();
HRESULT res;
try
{
res = Open2(stream, openCallback);
if (res == S_OK)
{
CMyComPtr<ISequentialInStream> inStream;
HRESULT res2 = GetStream(0, &inStream);
if (res2 == S_OK && inStream)
_imgExt = GetImgExt(inStream);
return S_OK;
}
}
catch(...)
{
CloseAtError();
throw;
}
CloseAtError();
return res;
}
COM_TRY_END
}
STDMETHODIMP CHandlerImg::GetNumberOfItems(UInt32 *numItems)
{
*numItems = 1;
return S_OK;
}
STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
RINOK(extractCallback->SetTotal(_size));
CMyComPtr<ISequentialOutStream> outStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &outStream, askMode));
if (!testMode && !outStream)
return S_OK;
RINOK(extractCallback->PrepareOperation(askMode));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
int opRes = NExtract::NOperationResult::kDataError;
ClearStreamVars();
CMyComPtr<ISequentialInStream> inStream;
HRESULT hres = GetStream(0, &inStream);
if (hres == S_FALSE)
hres = E_NOTIMPL;
if (hres == S_OK && inStream)
{
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
hres = copyCoder->Code(inStream, outStream, NULL, &_size, progress);
if (hres == S_OK)
{
if (copyCoderSpec->TotalSize == _size)
opRes = NExtract::NOperationResult::kOK;
if (_stream_unavailData)
opRes = NExtract::NOperationResult::kUnavailable;
else if (_stream_unsupportedMethod)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
else if (_stream_dataError)
opRes = NExtract::NOperationResult::kDataError;
else if (copyCoderSpec->TotalSize < _size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
}
}
inStream.Release();
outStream.Release();
if (hres != S_OK)
{
if (hres == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else if (hres == E_NOTIMPL)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
else
return hres;
}
return extractCallback->SetOperationResult(opRes);
COM_TRY_END
}
HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize)
{
areThereNonZeros = false;
numZeros = 0;
const size_t kBufSize = 1 << 11;
Byte buf[kBufSize];
for (;;)
{
UInt32 size = 0;
HRESULT(stream->Read(buf, kBufSize, &size));
if (size == 0)
return S_OK;
for (UInt32 i = 0; i < size; i++)
if (buf[i] != 0)
{
areThereNonZeros = true;
numZeros += i;
return S_OK;
}
numZeros += size;
if (numZeros > maxSize)
return S_OK;
}
}
}

View File

@@ -1,116 +1,116 @@
// HandlerCont.h
#ifndef __HANDLER_CONT_H
#define __HANDLER_CONT_H
#include "../../Common/MyCom.h"
#include "IArchive.h"
namespace NArchive {
#define INTERFACE_IInArchive_Cont(x) \
STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
/* STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; */ \
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
class CHandlerCont:
public IInArchive,
public IInArchiveGetStream,
public CMyUnknownImp
{
protected:
CMyComPtr<IInStream> _stream;
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const = 0;
public:
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive_Cont(PURE)
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY;
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
// destructor must be virtual for this class
virtual ~CHandlerCont() {}
};
#define INTERFACE_IInArchive_Img(x) \
/* STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; */ \
STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \
/* STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; */ \
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
/* STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; */ \
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
class CHandlerImg:
public IInStream,
public IInArchive,
public IInArchiveGetStream,
public CMyUnknownImp
{
protected:
UInt64 _virtPos;
UInt64 _posInArc;
UInt64 _size;
CMyComPtr<IInStream> Stream;
const char *_imgExt;
bool _stream_unavailData;
bool _stream_unsupportedMethod;
bool _stream_dataError;
// bool _stream_UsePackSize;
// UInt64 _stream_PackSize;
void ClearStreamVars()
{
_stream_unavailData = false;
_stream_unsupportedMethod = false;
_stream_dataError = false;
// _stream_UsePackSize = false;
// _stream_PackSize = 0;
}
virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0;
virtual void CloseAtError();
public:
MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IInStream)
INTERFACE_IInArchive_Img(PURE)
STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback);
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback);
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) = 0;
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0;
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
CHandlerImg();
// destructor must be virtual for this class
virtual ~CHandlerImg() {}
};
HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize);
}
#endif
// HandlerCont.h
#ifndef __HANDLER_CONT_H
#define __HANDLER_CONT_H
#include "../../Common/MyCom.h"
#include "IArchive.h"
namespace NArchive {
#define INTERFACE_IInArchive_Cont(x) \
STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
/* STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; */ \
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
class CHandlerCont:
public IInArchive,
public IInArchiveGetStream,
public CMyUnknownImp
{
protected:
CMyComPtr<IInStream> _stream;
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const = 0;
public:
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive_Cont(PURE)
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY;
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
// destructor must be virtual for this class
virtual ~CHandlerCont() {}
};
#define INTERFACE_IInArchive_Img(x) \
/* STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; */ \
STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \
/* STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; */ \
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
/* STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; */ \
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
class CHandlerImg:
public IInStream,
public IInArchive,
public IInArchiveGetStream,
public CMyUnknownImp
{
protected:
UInt64 _virtPos;
UInt64 _posInArc;
UInt64 _size;
CMyComPtr<IInStream> Stream;
const char *_imgExt;
bool _stream_unavailData;
bool _stream_unsupportedMethod;
bool _stream_dataError;
// bool _stream_UsePackSize;
// UInt64 _stream_PackSize;
void ClearStreamVars()
{
_stream_unavailData = false;
_stream_unsupportedMethod = false;
_stream_dataError = false;
// _stream_UsePackSize = false;
// _stream_PackSize = 0;
}
virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0;
virtual void CloseAtError();
public:
MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IInStream)
INTERFACE_IInArchive_Img(PURE)
STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback);
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback);
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) = 0;
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0;
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
CHandlerImg();
// destructor must be virtual for this class
virtual ~CHandlerImg() {}
};
HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize);
}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,497 +1,497 @@
// IhexHandler.cpp
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/DynamicBuffer.h"
#include "../../Common/IntToString.h"
#include "../../Common/MyVector.h"
#include "../../Windows/PropVariant.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "../Common/InBuffer.h"
namespace NArchive {
namespace NIhex {
/* We still don't support files with custom record types: 20, 22: used by Samsung */
struct CBlock
{
CByteDynamicBuffer Data;
UInt32 Offset;
};
class CHandler:
public IInArchive,
public CMyUnknownImp
{
bool _isArc;
bool _needMoreInput;
bool _dataError;
UInt64 _phySize;
CObjectVector<CBlock> _blocks;
public:
MY_UNKNOWN_IMP1(IInArchive)
INTERFACE_IInArchive(;)
};
static const Byte kProps[] =
{
kpidPath,
kpidSize,
kpidVa
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO_Table
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _blocks.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NWindows::NCOM::CPropVariant prop;
switch (propID)
{
case kpidPhySize: if (_phySize != 0) prop = _phySize; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_dataError) v |= kpv_ErrorFlags_DataError;
prop = v;
}
}
prop.Detach(value);
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
const CBlock &block = _blocks[index];
switch (propID)
{
case kpidSize: prop = (UInt64)block.Data.GetPos(); break;
case kpidVa: prop = block.Offset; break;
case kpidPath:
{
if (_blocks.Size() != 1)
{
char s[16];
ConvertUInt32ToString(index, s);
prop = s;
}
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
static inline int HexToByte(unsigned c)
{
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
return -1;
}
static int Parse(const Byte *p)
{
int c1 = HexToByte(p[0]); if (c1 < 0) return -1;
int c2 = HexToByte(p[1]); if (c2 < 0) return -1;
return (c1 << 4) | c2;
}
#define kType_Data 0
#define kType_Eof 1
#define kType_Seg 2
#define kType_CsIp 3
#define kType_High 4
#define kType_Ip32 5
#define kType_MAX 5
#define IS_LINE_DELIMITER(c) ((c) == 0 || (c) == 10 || (c) == 13)
API_FUNC_static_IsArc IsArc_Ihex(const Byte *p, size_t size)
{
if (size < 1)
return k_IsArc_Res_NEED_MORE;
if (p[0] != ':')
return k_IsArc_Res_NO;
p++;
size--;
const unsigned kNumLinesToCheck = 3; // 1 line is OK also, but we don't want false detection
for (unsigned j = 0; j < kNumLinesToCheck; j++)
{
if (size < 4 * 2)
return k_IsArc_Res_NEED_MORE;
int num = Parse(p);
if (num < 0)
return k_IsArc_Res_NO;
int type = Parse(p + 6);
if (type < 0 || type > kType_MAX)
return k_IsArc_Res_NO;
unsigned numChars = ((unsigned)num + 5) * 2;
unsigned sum = 0;
for (unsigned i = 0; i < numChars; i += 2)
{
if (i + 2 > size)
return k_IsArc_Res_NEED_MORE;
int v = Parse(p + i);
if (v < 0)
return k_IsArc_Res_NO;
sum += (unsigned)v;
}
if ((sum & 0xFF) != 0)
return k_IsArc_Res_NO;
if (type == kType_Data)
{
// we don't want to open :0000000000 files
if (num == 0)
return k_IsArc_Res_NO;
}
else
{
if (type == kType_Eof)
{
if (num != 0)
return k_IsArc_Res_NO;
return k_IsArc_Res_YES;
}
if (p[2] != 0 ||
p[3] != 0 ||
p[4] != 0 ||
p[5] != 0)
return k_IsArc_Res_NO;
if (type == kType_Seg || type == kType_High)
{
if (num != 2)
return k_IsArc_Res_NO;
}
else
{
if (num != 4)
return k_IsArc_Res_NO;
}
}
p += numChars;
size -= numChars;
for (;;)
{
if (size == 0)
return k_IsArc_Res_NEED_MORE;
char b = *p++;
size--;
if (IS_LINE_DELIMITER(b))
continue;
if (b == ':')
break;
return k_IsArc_Res_NO;
}
}
return k_IsArc_Res_YES;
}
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)
{
COM_TRY_BEGIN
{
Close();
try
{
const unsigned kStartSize = (2 + (256 + 5) + 2) * 2;
Byte temp[kStartSize];
{
size_t size = kStartSize;
RINOK(ReadStream(stream, temp, &size));
UInt32 isArcRes = IsArc_Ihex(temp, size);
if (isArcRes == k_IsArc_Res_NO)
return S_FALSE;
if (isArcRes == k_IsArc_Res_NEED_MORE && size != kStartSize)
return S_FALSE;
}
_isArc = true;
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
CInBuffer s;
if (!s.Create(1 << 15))
return E_OUTOFMEMORY;
s.SetStream(stream);
s.Init();
{
Byte b;
if (!s.ReadByte(b))
{
_needMoreInput = true;
return S_FALSE;
}
if (b != ':')
{
_dataError = true;
return S_FALSE;
}
}
UInt32 globalOffset = 0;
for (;;)
{
if (s.ReadBytes(temp, 2) != 2)
{
_needMoreInput = true;
return S_FALSE;
}
int num = Parse(temp);
if (num < 0)
{
_dataError = true;
return S_FALSE;
}
{
size_t numPairs = ((unsigned)num + 4);
size_t numBytes = numPairs * 2;
if (s.ReadBytes(temp, numBytes) != numBytes)
{
_needMoreInput = true;
return S_FALSE;
}
unsigned sum = num;
for (size_t i = 0; i < numPairs; i++)
{
int a = Parse(temp + i * 2);
if (a < 0)
{
_dataError = true;
return S_FALSE;
}
temp[i] = (Byte)a;
sum += a;
}
if ((sum & 0xFF) != 0)
{
_dataError = true;
return S_FALSE;
}
}
unsigned type = temp[2];
if (type > kType_MAX)
{
_dataError = true;
return S_FALSE;
}
UInt32 a = GetBe16(temp);
if (type == kType_Data)
{
if (num == 0)
{
// we don't want to open :0000000000 files
// maybe it can mean EOF in old-style files?
_dataError = true;
return S_FALSE;
}
// if (num != 0)
{
UInt32 offs = globalOffset + a;
CBlock *block = NULL;
if (!_blocks.IsEmpty())
{
block = &_blocks.Back();
if (block->Offset + block->Data.GetPos() != offs)
block = NULL;
}
if (!block)
{
block = &_blocks.AddNew();
block->Offset = offs;
}
block->Data.AddData(temp + 3, (unsigned)num);
}
}
else if (type == kType_Eof)
{
_phySize = s.GetProcessedSize();
{
Byte b;
if (s.ReadByte(b))
{
if (b == 10)
_phySize++;
else if (b == 13)
{
_phySize++;
if (s.ReadByte(b))
{
if (b == 10)
_phySize++;
}
}
}
}
return S_OK;
}
else
{
if (a != 0)
{
_dataError = true;
return S_FALSE;
}
if (type == kType_Seg || type == kType_High)
{
if (num != 2)
{
_dataError = true;
return S_FALSE;
}
UInt32 d = GetBe16(temp + 3);
globalOffset = d << (type == kType_Seg ? 4 : 16);
}
else
{
if (num != 4)
{
_dataError = true;
return S_FALSE;
}
}
}
for (;;)
{
Byte b;
if (!s.ReadByte(b))
{
_needMoreInput = true;
return S_FALSE;
}
if (IS_LINE_DELIMITER(b))
continue;
if (b == ':')
break;
_dataError = true;
return S_FALSE;
}
}
}
catch(const CInBufferException &e) { return e.ErrorCode; }
}
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_phySize = 0;
_isArc = false;
_needMoreInput = false;
_dataError = false;
_blocks.Clear();
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _blocks.Size();
if (numItems == 0)
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
totalSize += _blocks[allFilesMode ? i : indices[i]].Data.GetPos();
extractCallback->SetTotal(totalSize);
UInt64 currentTotalSize = 0;
UInt64 currentItemSize;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{
currentItemSize = 0;
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
UInt32 index = allFilesMode ? i : indices[i];
const CByteDynamicBuffer &data = _blocks[index].Data;
currentItemSize = data.GetPos();
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if (!testMode && !realOutStream)
continue;
extractCallback->PrepareOperation(askMode);
if (realOutStream)
{
RINOK(WriteStream(realOutStream, (const Byte *)data, data.GetPos()));
}
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
}
lps->InSize = lps->OutSize = currentTotalSize;
return lps->SetCur();
COM_TRY_END
}
// k_Signature: { ':', '1' }
REGISTER_ARC_I_NO_SIG(
"IHex", "ihex", 0, 0xCD,
0,
NArcInfoFlags::kStartOpen,
IsArc_Ihex)
}}
// IhexHandler.cpp
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/DynamicBuffer.h"
#include "../../Common/IntToString.h"
#include "../../Common/MyVector.h"
#include "../../Windows/PropVariant.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "../Common/InBuffer.h"
namespace NArchive {
namespace NIhex {
/* We still don't support files with custom record types: 20, 22: used by Samsung */
struct CBlock
{
CByteDynamicBuffer Data;
UInt32 Offset;
};
class CHandler:
public IInArchive,
public CMyUnknownImp
{
bool _isArc;
bool _needMoreInput;
bool _dataError;
UInt64 _phySize;
CObjectVector<CBlock> _blocks;
public:
MY_UNKNOWN_IMP1(IInArchive)
INTERFACE_IInArchive(;)
};
static const Byte kProps[] =
{
kpidPath,
kpidSize,
kpidVa
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO_Table
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _blocks.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NWindows::NCOM::CPropVariant prop;
switch (propID)
{
case kpidPhySize: if (_phySize != 0) prop = _phySize; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_dataError) v |= kpv_ErrorFlags_DataError;
prop = v;
}
}
prop.Detach(value);
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
const CBlock &block = _blocks[index];
switch (propID)
{
case kpidSize: prop = (UInt64)block.Data.GetPos(); break;
case kpidVa: prop = block.Offset; break;
case kpidPath:
{
if (_blocks.Size() != 1)
{
char s[16];
ConvertUInt32ToString(index, s);
prop = s;
}
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
static inline int HexToByte(unsigned c)
{
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
return -1;
}
static int Parse(const Byte *p)
{
int c1 = HexToByte(p[0]); if (c1 < 0) return -1;
int c2 = HexToByte(p[1]); if (c2 < 0) return -1;
return (c1 << 4) | c2;
}
#define kType_Data 0
#define kType_Eof 1
#define kType_Seg 2
#define kType_CsIp 3
#define kType_High 4
#define kType_Ip32 5
#define kType_MAX 5
#define IS_LINE_DELIMITER(c) ((c) == 0 || (c) == 10 || (c) == 13)
API_FUNC_static_IsArc IsArc_Ihex(const Byte *p, size_t size)
{
if (size < 1)
return k_IsArc_Res_NEED_MORE;
if (p[0] != ':')
return k_IsArc_Res_NO;
p++;
size--;
const unsigned kNumLinesToCheck = 3; // 1 line is OK also, but we don't want false detection
for (unsigned j = 0; j < kNumLinesToCheck; j++)
{
if (size < 4 * 2)
return k_IsArc_Res_NEED_MORE;
int num = Parse(p);
if (num < 0)
return k_IsArc_Res_NO;
int type = Parse(p + 6);
if (type < 0 || type > kType_MAX)
return k_IsArc_Res_NO;
unsigned numChars = ((unsigned)num + 5) * 2;
unsigned sum = 0;
for (unsigned i = 0; i < numChars; i += 2)
{
if (i + 2 > size)
return k_IsArc_Res_NEED_MORE;
int v = Parse(p + i);
if (v < 0)
return k_IsArc_Res_NO;
sum += (unsigned)v;
}
if ((sum & 0xFF) != 0)
return k_IsArc_Res_NO;
if (type == kType_Data)
{
// we don't want to open :0000000000 files
if (num == 0)
return k_IsArc_Res_NO;
}
else
{
if (type == kType_Eof)
{
if (num != 0)
return k_IsArc_Res_NO;
return k_IsArc_Res_YES;
}
if (p[2] != 0 ||
p[3] != 0 ||
p[4] != 0 ||
p[5] != 0)
return k_IsArc_Res_NO;
if (type == kType_Seg || type == kType_High)
{
if (num != 2)
return k_IsArc_Res_NO;
}
else
{
if (num != 4)
return k_IsArc_Res_NO;
}
}
p += numChars;
size -= numChars;
for (;;)
{
if (size == 0)
return k_IsArc_Res_NEED_MORE;
char b = *p++;
size--;
if (IS_LINE_DELIMITER(b))
continue;
if (b == ':')
break;
return k_IsArc_Res_NO;
}
}
return k_IsArc_Res_YES;
}
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)
{
COM_TRY_BEGIN
{
Close();
try
{
const unsigned kStartSize = (2 + (256 + 5) + 2) * 2;
Byte temp[kStartSize];
{
size_t size = kStartSize;
RINOK(ReadStream(stream, temp, &size));
UInt32 isArcRes = IsArc_Ihex(temp, size);
if (isArcRes == k_IsArc_Res_NO)
return S_FALSE;
if (isArcRes == k_IsArc_Res_NEED_MORE && size != kStartSize)
return S_FALSE;
}
_isArc = true;
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
CInBuffer s;
if (!s.Create(1 << 15))
return E_OUTOFMEMORY;
s.SetStream(stream);
s.Init();
{
Byte b;
if (!s.ReadByte(b))
{
_needMoreInput = true;
return S_FALSE;
}
if (b != ':')
{
_dataError = true;
return S_FALSE;
}
}
UInt32 globalOffset = 0;
for (;;)
{
if (s.ReadBytes(temp, 2) != 2)
{
_needMoreInput = true;
return S_FALSE;
}
int num = Parse(temp);
if (num < 0)
{
_dataError = true;
return S_FALSE;
}
{
size_t numPairs = ((unsigned)num + 4);
size_t numBytes = numPairs * 2;
if (s.ReadBytes(temp, numBytes) != numBytes)
{
_needMoreInput = true;
return S_FALSE;
}
unsigned sum = num;
for (size_t i = 0; i < numPairs; i++)
{
int a = Parse(temp + i * 2);
if (a < 0)
{
_dataError = true;
return S_FALSE;
}
temp[i] = (Byte)a;
sum += a;
}
if ((sum & 0xFF) != 0)
{
_dataError = true;
return S_FALSE;
}
}
unsigned type = temp[2];
if (type > kType_MAX)
{
_dataError = true;
return S_FALSE;
}
UInt32 a = GetBe16(temp);
if (type == kType_Data)
{
if (num == 0)
{
// we don't want to open :0000000000 files
// maybe it can mean EOF in old-style files?
_dataError = true;
return S_FALSE;
}
// if (num != 0)
{
UInt32 offs = globalOffset + a;
CBlock *block = NULL;
if (!_blocks.IsEmpty())
{
block = &_blocks.Back();
if (block->Offset + block->Data.GetPos() != offs)
block = NULL;
}
if (!block)
{
block = &_blocks.AddNew();
block->Offset = offs;
}
block->Data.AddData(temp + 3, (unsigned)num);
}
}
else if (type == kType_Eof)
{
_phySize = s.GetProcessedSize();
{
Byte b;
if (s.ReadByte(b))
{
if (b == 10)
_phySize++;
else if (b == 13)
{
_phySize++;
if (s.ReadByte(b))
{
if (b == 10)
_phySize++;
}
}
}
}
return S_OK;
}
else
{
if (a != 0)
{
_dataError = true;
return S_FALSE;
}
if (type == kType_Seg || type == kType_High)
{
if (num != 2)
{
_dataError = true;
return S_FALSE;
}
UInt32 d = GetBe16(temp + 3);
globalOffset = d << (type == kType_Seg ? 4 : 16);
}
else
{
if (num != 4)
{
_dataError = true;
return S_FALSE;
}
}
}
for (;;)
{
Byte b;
if (!s.ReadByte(b))
{
_needMoreInput = true;
return S_FALSE;
}
if (IS_LINE_DELIMITER(b))
continue;
if (b == ':')
break;
_dataError = true;
return S_FALSE;
}
}
}
catch(const CInBufferException &e) { return e.ErrorCode; }
}
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_phySize = 0;
_isArc = false;
_needMoreInput = false;
_dataError = false;
_blocks.Clear();
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _blocks.Size();
if (numItems == 0)
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
totalSize += _blocks[allFilesMode ? i : indices[i]].Data.GetPos();
extractCallback->SetTotal(totalSize);
UInt64 currentTotalSize = 0;
UInt64 currentItemSize;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{
currentItemSize = 0;
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
UInt32 index = allFilesMode ? i : indices[i];
const CByteDynamicBuffer &data = _blocks[index].Data;
currentItemSize = data.GetPos();
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if (!testMode && !realOutStream)
continue;
extractCallback->PrepareOperation(askMode);
if (realOutStream)
{
RINOK(WriteStream(realOutStream, (const Byte *)data, data.GetPos()));
}
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
}
lps->InSize = lps->OutSize = currentTotalSize;
return lps->SetCur();
COM_TRY_END
}
// k_Signature: { ':', '1' }
REGISTER_ARC_I_NO_SIG(
"IHex", "ihex", 0, 0xCD,
0,
NArcInfoFlags::kStartOpen,
IsArc_Ihex)
}}

View File

@@ -1,489 +1,489 @@
// IsoHandler.cpp
#include "StdAfx.h"
#include "../../../Common/ComTry.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/TimeUtils.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h"
#include "../../Compress/CopyCoder.h"
#include "../Common/ItemNameUtils.h"
#include "IsoHandler.h"
using namespace NWindows;
using namespace NTime;
namespace NArchive {
namespace NIso {
static const Byte kProps[] =
{
kpidPath,
kpidIsDir,
kpidSize,
kpidPackSize,
kpidMTime,
// kpidCTime,
// kpidATime,
kpidPosixAttrib,
// kpidUser,
// kpidGroup,
// kpidLinks,
kpidSymLink
};
static const Byte kArcProps[] =
{
kpidComment,
kpidCTime,
kpidMTime,
// kpidHeadersSize
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
Close();
{
RINOK(_archive.Open(stream));
_stream = stream;
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_archive.Clear();
_stream.Release();
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _archive.Refs.Size() + _archive.BootEntries.Size();
return S_OK;
}
static void AddString(AString &s, const char *name, const Byte *p, unsigned size)
{
unsigned i;
for (i = 0; i < size && p[i]; i++);
for (; i > 0 && p[i - 1] == ' '; i--);
if (i != 0)
{
AString d;
d.SetFrom((const char *)p, i);
s += '\n';
s += name;
s += ": ";
s += d;
}
}
#define ADD_STRING(n, v) AddString(s, n, vol. v, sizeof(vol. v))
static void AddErrorMessage(AString &s, const char *message)
{
if (!s.IsEmpty())
s += ". ";
s += message;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
if (_stream)
{
const CVolumeDescriptor &vol = _archive.VolDescs[_archive.MainVolDescIndex];
switch (propID)
{
case kpidComment:
{
AString s;
ADD_STRING("System", SystemId);
ADD_STRING("Volume", VolumeId);
ADD_STRING("VolumeSet", VolumeSetId);
ADD_STRING("Publisher", PublisherId);
ADD_STRING("Preparer", DataPreparerId);
ADD_STRING("Application", ApplicationId);
ADD_STRING("Copyright", CopyrightFileId);
ADD_STRING("Abstract", AbstractFileId);
ADD_STRING("Bib", BibFileId);
prop = s;
break;
}
case kpidCTime: { FILETIME utc; if (vol.CTime.GetFileTime(utc)) prop = utc; break; }
case kpidMTime: { FILETIME utc; if (vol.MTime.GetFileTime(utc)) prop = utc; break; }
}
}
switch (propID)
{
case kpidPhySize: prop = _archive.PhySize; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc;
if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_archive.HeadersError) v |= kpv_ErrorFlags_HeadersError;
prop = v;
break;
}
case kpidError:
{
AString s;
if (_archive.IncorrectBigEndian)
AddErrorMessage(s, "Incorrect big-endian headers");
if (_archive.SelfLinkedDirs)
AddErrorMessage(s, "Self-linked directory");
if (_archive.TooDeepDirs)
AddErrorMessage(s, "Too deep directory levels");
if (!s.IsEmpty())
prop = s;
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
if (index >= (UInt32)_archive.Refs.Size())
{
index -= _archive.Refs.Size();
const CBootInitialEntry &be = _archive.BootEntries[index];
switch (propID)
{
case kpidPath:
{
AString s ("[BOOT]" STRING_PATH_SEPARATOR);
if (_archive.BootEntries.Size() != 1)
{
s.Add_UInt32(index + 1);
s += '-';
}
s += be.GetName();
prop = s;
break;
}
case kpidIsDir: prop = false; break;
case kpidSize:
case kpidPackSize:
prop = (UInt64)_archive.GetBootItemSize(index);
break;
}
}
else
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
switch (propID)
{
case kpidPath:
// if (item.FileId.GetCapacity() >= 0)
{
UString s;
if (_archive.IsJoliet())
item.GetPathU(s);
else
s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP);
if (s.Len() >= 2 && s[s.Len() - 2] == ';' && s.Back() == '1')
s.DeleteFrom(s.Len() - 2);
if (!s.IsEmpty() && s.Back() == L'.')
s.DeleteBack();
NItemName::ReplaceToOsSlashes_Remove_TailSlash(s);
prop = s;
}
break;
case kpidSymLink:
if (_archive.IsSusp)
{
UString s;
UInt32 mode;
if (item.GetPx(_archive.SuspSkipSize, k_Px_Mode, mode))
{
if (((mode >> 12) & 0xF) == 10)
{
AString s8;
if (item.GetSymLink(_archive.SuspSkipSize, s8))
{
s = MultiByteToUnicodeString(s8, CP_OEMCP);
prop = s;
}
}
}
}
break;
case kpidPosixAttrib:
/*
case kpidLinks:
case kpidUser:
case kpidGroup:
*/
{
if (_archive.IsSusp)
{
UInt32 t = 0;
switch (propID)
{
case kpidPosixAttrib: t = k_Px_Mode; break;
/*
case kpidLinks: t = k_Px_Links; break;
case kpidUser: t = k_Px_User; break;
case kpidGroup: t = k_Px_Group; break;
*/
}
UInt32 v;
if (item.GetPx(_archive.SuspSkipSize, t, v))
prop = v;
}
break;
}
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize:
case kpidPackSize:
if (!item.IsDir())
prop = (UInt64)ref.TotalSize;
break;
case kpidMTime:
// case kpidCTime:
// case kpidATime:
{
FILETIME utc;
if (/* propID == kpidMTime && */ item.DateTime.GetFileTime(utc))
prop = utc;
/*
else
{
UInt32 t = 0;
switch (propID)
{
case kpidMTime: t = k_Tf_MTime; break;
case kpidCTime: t = k_Tf_CTime; break;
case kpidATime: t = k_Tf_ATime; break;
}
CRecordingDateTime dt;
if (item.GetTf(_archive.SuspSkipSize, t, dt))
{
FILETIME utc;
if (dt.GetFileTime(utc))
prop = utc;
}
}
*/
break;
}
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _archive.Refs.Size();
if (numItems == 0)
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
UInt32 index = (allFilesMode ? i : indices[i]);
if (index < (UInt32)_archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
if (!item.IsDir())
totalSize += ref.TotalSize;
}
else
totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
}
extractCallback->SetTotal(totalSize);
UInt64 currentTotalSize = 0;
UInt64 currentItemSize;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_stream);
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
currentItemSize = 0;
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
UInt32 index = allFilesMode ? i : indices[i];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
UInt64 blockIndex;
if (index < (UInt32)_archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
if (item.IsDir())
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
continue;
}
currentItemSize = ref.TotalSize;
blockIndex = item.ExtentLocation;
}
else
{
unsigned bootIndex = index - _archive.Refs.Size();
const CBootInitialEntry &be = _archive.BootEntries[bootIndex];
currentItemSize = _archive.GetBootItemSize(bootIndex);
blockIndex = be.LoadRBA;
}
if (!testMode && !realOutStream)
continue;
RINOK(extractCallback->PrepareOperation(askMode));
bool isOK = true;
if (index < (UInt32)_archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
UInt64 offset = 0;
for (UInt32 e = 0; e < ref.NumExtents; e++)
{
const CDir &item2 = ref.Dir->_subItems[ref.Index + e];
if (item2.Size == 0)
continue;
lps->InSize = lps->OutSize = currentTotalSize + offset;
RINOK(_stream->Seek((UInt64)item2.ExtentLocation * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(item2.Size);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != item2.Size)
{
isOK = false;
break;
}
offset += item2.Size;
}
}
else
{
RINOK(_stream->Seek((UInt64)blockIndex * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(currentItemSize);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != currentItemSize)
isOK = false;
}
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(isOK ?
NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kDataError));
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
COM_TRY_BEGIN
*stream = 0;
UInt64 blockIndex;
UInt64 currentItemSize;
if (index < _archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
if (item.IsDir())
return S_FALSE;
if (ref.NumExtents > 1)
{
CExtentsStream *extentStreamSpec = new CExtentsStream();
CMyComPtr<ISequentialInStream> extentStream = extentStreamSpec;
extentStreamSpec->Stream = _stream;
UInt64 virtOffset = 0;
for (UInt32 i = 0; i < ref.NumExtents; i++)
{
const CDir &item2 = ref.Dir->_subItems[ref.Index + i];
if (item2.Size == 0)
continue;
CSeekExtent se;
se.Phy = (UInt64)item2.ExtentLocation * kBlockSize;
se.Virt = virtOffset;
extentStreamSpec->Extents.Add(se);
virtOffset += item2.Size;
}
if (virtOffset != ref.TotalSize)
return S_FALSE;
CSeekExtent se;
se.Phy = 0;
se.Virt = virtOffset;
extentStreamSpec->Extents.Add(se);
extentStreamSpec->Init();
*stream = extentStream.Detach();
return S_OK;
}
currentItemSize = item.Size;
blockIndex = item.ExtentLocation;
}
else
{
unsigned bootIndex = index - _archive.Refs.Size();
const CBootInitialEntry &be = _archive.BootEntries[bootIndex];
currentItemSize = _archive.GetBootItemSize(bootIndex);
blockIndex = be.LoadRBA;
}
return CreateLimitedInStream(_stream, (UInt64)blockIndex * kBlockSize, currentItemSize, stream);
COM_TRY_END
}
}}
// IsoHandler.cpp
#include "StdAfx.h"
#include "../../../Common/ComTry.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/TimeUtils.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h"
#include "../../Compress/CopyCoder.h"
#include "../Common/ItemNameUtils.h"
#include "IsoHandler.h"
using namespace NWindows;
using namespace NTime;
namespace NArchive {
namespace NIso {
static const Byte kProps[] =
{
kpidPath,
kpidIsDir,
kpidSize,
kpidPackSize,
kpidMTime,
// kpidCTime,
// kpidATime,
kpidPosixAttrib,
// kpidUser,
// kpidGroup,
// kpidLinks,
kpidSymLink
};
static const Byte kArcProps[] =
{
kpidComment,
kpidCTime,
kpidMTime,
// kpidHeadersSize
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
{
COM_TRY_BEGIN
Close();
{
RINOK(_archive.Open(stream));
_stream = stream;
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
_archive.Clear();
_stream.Release();
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _archive.Refs.Size() + _archive.BootEntries.Size();
return S_OK;
}
static void AddString(AString &s, const char *name, const Byte *p, unsigned size)
{
unsigned i;
for (i = 0; i < size && p[i]; i++);
for (; i > 0 && p[i - 1] == ' '; i--);
if (i != 0)
{
AString d;
d.SetFrom((const char *)p, i);
s += '\n';
s += name;
s += ": ";
s += d;
}
}
#define ADD_STRING(n, v) AddString(s, n, vol. v, sizeof(vol. v))
static void AddErrorMessage(AString &s, const char *message)
{
if (!s.IsEmpty())
s += ". ";
s += message;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
if (_stream)
{
const CVolumeDescriptor &vol = _archive.VolDescs[_archive.MainVolDescIndex];
switch (propID)
{
case kpidComment:
{
AString s;
ADD_STRING("System", SystemId);
ADD_STRING("Volume", VolumeId);
ADD_STRING("VolumeSet", VolumeSetId);
ADD_STRING("Publisher", PublisherId);
ADD_STRING("Preparer", DataPreparerId);
ADD_STRING("Application", ApplicationId);
ADD_STRING("Copyright", CopyrightFileId);
ADD_STRING("Abstract", AbstractFileId);
ADD_STRING("Bib", BibFileId);
prop = s;
break;
}
case kpidCTime: { FILETIME utc; if (vol.CTime.GetFileTime(utc)) prop = utc; break; }
case kpidMTime: { FILETIME utc; if (vol.MTime.GetFileTime(utc)) prop = utc; break; }
}
}
switch (propID)
{
case kpidPhySize: prop = _archive.PhySize; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc;
if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_archive.HeadersError) v |= kpv_ErrorFlags_HeadersError;
prop = v;
break;
}
case kpidError:
{
AString s;
if (_archive.IncorrectBigEndian)
AddErrorMessage(s, "Incorrect big-endian headers");
if (_archive.SelfLinkedDirs)
AddErrorMessage(s, "Self-linked directory");
if (_archive.TooDeepDirs)
AddErrorMessage(s, "Too deep directory levels");
if (!s.IsEmpty())
prop = s;
break;
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
if (index >= (UInt32)_archive.Refs.Size())
{
index -= _archive.Refs.Size();
const CBootInitialEntry &be = _archive.BootEntries[index];
switch (propID)
{
case kpidPath:
{
AString s ("[BOOT]" STRING_PATH_SEPARATOR);
if (_archive.BootEntries.Size() != 1)
{
s.Add_UInt32(index + 1);
s += '-';
}
s += be.GetName();
prop = s;
break;
}
case kpidIsDir: prop = false; break;
case kpidSize:
case kpidPackSize:
prop = (UInt64)_archive.GetBootItemSize(index);
break;
}
}
else
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
switch (propID)
{
case kpidPath:
// if (item.FileId.GetCapacity() >= 0)
{
UString s;
if (_archive.IsJoliet())
item.GetPathU(s);
else
s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP);
if (s.Len() >= 2 && s[s.Len() - 2] == ';' && s.Back() == '1')
s.DeleteFrom(s.Len() - 2);
if (!s.IsEmpty() && s.Back() == L'.')
s.DeleteBack();
NItemName::ReplaceToOsSlashes_Remove_TailSlash(s);
prop = s;
}
break;
case kpidSymLink:
if (_archive.IsSusp)
{
UString s;
UInt32 mode;
if (item.GetPx(_archive.SuspSkipSize, k_Px_Mode, mode))
{
if (((mode >> 12) & 0xF) == 10)
{
AString s8;
if (item.GetSymLink(_archive.SuspSkipSize, s8))
{
s = MultiByteToUnicodeString(s8, CP_OEMCP);
prop = s;
}
}
}
}
break;
case kpidPosixAttrib:
/*
case kpidLinks:
case kpidUser:
case kpidGroup:
*/
{
if (_archive.IsSusp)
{
UInt32 t = 0;
switch (propID)
{
case kpidPosixAttrib: t = k_Px_Mode; break;
/*
case kpidLinks: t = k_Px_Links; break;
case kpidUser: t = k_Px_User; break;
case kpidGroup: t = k_Px_Group; break;
*/
}
UInt32 v;
if (item.GetPx(_archive.SuspSkipSize, t, v))
prop = v;
}
break;
}
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize:
case kpidPackSize:
if (!item.IsDir())
prop = (UInt64)ref.TotalSize;
break;
case kpidMTime:
// case kpidCTime:
// case kpidATime:
{
FILETIME utc;
if (/* propID == kpidMTime && */ item.DateTime.GetFileTime(utc))
prop = utc;
/*
else
{
UInt32 t = 0;
switch (propID)
{
case kpidMTime: t = k_Tf_MTime; break;
case kpidCTime: t = k_Tf_CTime; break;
case kpidATime: t = k_Tf_ATime; break;
}
CRecordingDateTime dt;
if (item.GetTf(_archive.SuspSkipSize, t, dt))
{
FILETIME utc;
if (dt.GetFileTime(utc))
prop = utc;
}
}
*/
break;
}
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _archive.Refs.Size();
if (numItems == 0)
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
UInt32 index = (allFilesMode ? i : indices[i]);
if (index < (UInt32)_archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
if (!item.IsDir())
totalSize += ref.TotalSize;
}
else
totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
}
extractCallback->SetTotal(totalSize);
UInt64 currentTotalSize = 0;
UInt64 currentItemSize;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_stream);
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
currentItemSize = 0;
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
UInt32 index = allFilesMode ? i : indices[i];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
UInt64 blockIndex;
if (index < (UInt32)_archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
if (item.IsDir())
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
continue;
}
currentItemSize = ref.TotalSize;
blockIndex = item.ExtentLocation;
}
else
{
unsigned bootIndex = index - _archive.Refs.Size();
const CBootInitialEntry &be = _archive.BootEntries[bootIndex];
currentItemSize = _archive.GetBootItemSize(bootIndex);
blockIndex = be.LoadRBA;
}
if (!testMode && !realOutStream)
continue;
RINOK(extractCallback->PrepareOperation(askMode));
bool isOK = true;
if (index < (UInt32)_archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
UInt64 offset = 0;
for (UInt32 e = 0; e < ref.NumExtents; e++)
{
const CDir &item2 = ref.Dir->_subItems[ref.Index + e];
if (item2.Size == 0)
continue;
lps->InSize = lps->OutSize = currentTotalSize + offset;
RINOK(_stream->Seek((UInt64)item2.ExtentLocation * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(item2.Size);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != item2.Size)
{
isOK = false;
break;
}
offset += item2.Size;
}
}
else
{
RINOK(_stream->Seek((UInt64)blockIndex * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(currentItemSize);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != currentItemSize)
isOK = false;
}
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(isOK ?
NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kDataError));
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
COM_TRY_BEGIN
*stream = 0;
UInt64 blockIndex;
UInt64 currentItemSize;
if (index < _archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
if (item.IsDir())
return S_FALSE;
if (ref.NumExtents > 1)
{
CExtentsStream *extentStreamSpec = new CExtentsStream();
CMyComPtr<ISequentialInStream> extentStream = extentStreamSpec;
extentStreamSpec->Stream = _stream;
UInt64 virtOffset = 0;
for (UInt32 i = 0; i < ref.NumExtents; i++)
{
const CDir &item2 = ref.Dir->_subItems[ref.Index + i];
if (item2.Size == 0)
continue;
CSeekExtent se;
se.Phy = (UInt64)item2.ExtentLocation * kBlockSize;
se.Virt = virtOffset;
extentStreamSpec->Extents.Add(se);
virtOffset += item2.Size;
}
if (virtOffset != ref.TotalSize)
return S_FALSE;
CSeekExtent se;
se.Phy = 0;
se.Virt = virtOffset;
extentStreamSpec->Extents.Add(se);
extentStreamSpec->Init();
*stream = extentStream.Detach();
return S_OK;
}
currentItemSize = item.Size;
blockIndex = item.ExtentLocation;
}
else
{
unsigned bootIndex = index - _archive.Refs.Size();
const CBootInitialEntry &be = _archive.BootEntries[bootIndex];
currentItemSize = _archive.GetBootItemSize(bootIndex);
blockIndex = be.LoadRBA;
}
return CreateLimitedInStream(_stream, (UInt64)blockIndex * kBlockSize, currentItemSize, stream);
COM_TRY_END
}
}}

View File

@@ -1,31 +1,31 @@
// IsoHandler.h
#ifndef __ISO_HANDLER_H
#define __ISO_HANDLER_H
#include "../../../Common/MyCom.h"
#include "../IArchive.h"
#include "IsoIn.h"
#include "IsoItem.h"
namespace NArchive {
namespace NIso {
class CHandler:
public IInArchive,
public IInArchiveGetStream,
public CMyUnknownImp
{
CMyComPtr<IInStream> _stream;
CInArchive _archive;
public:
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive(;)
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
};
}}
#endif
// IsoHandler.h
#ifndef __ISO_HANDLER_H
#define __ISO_HANDLER_H
#include "../../../Common/MyCom.h"
#include "../IArchive.h"
#include "IsoIn.h"
#include "IsoItem.h"
namespace NArchive {
namespace NIso {
class CHandler:
public IInArchive,
public IInArchiveGetStream,
public CMyUnknownImp
{
CMyComPtr<IInStream> _stream;
CInArchive _archive;
public:
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive(;)
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
};
}}
#endif

View File

@@ -1,12 +1,12 @@
// Archive/Iso/Header.h
#include "StdAfx.h"
#include "IsoHeader.h"
namespace NArchive {
namespace NIso {
const char * const kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0";
}}
// Archive/Iso/Header.h
#include "StdAfx.h"
#include "IsoHeader.h"
namespace NArchive {
namespace NIso {
const char * const kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0";
}}

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