Compare commits

..

10 Commits
9.11 ... 9.21

Author SHA1 Message Date
Igor Pavlov
35596517f2 9.21 2016-05-28 00:16:05 +01:00
Igor Pavlov
de4f8c22fe 9.20 2016-05-28 00:16:05 +01:00
Igor Pavlov
b75af1bba6 9.19 2016-05-28 00:16:04 +01:00
Igor Pavlov
c65230d858 9.18 2016-05-28 00:16:04 +01:00
Igor Pavlov
2eb60a0598 9.17 2016-05-28 00:16:04 +01:00
Igor Pavlov
044e4bb741 9.16 2016-05-28 00:16:03 +01:00
Igor Pavlov
e279500d76 9.15 2016-05-28 00:16:03 +01:00
Igor Pavlov
708873490e 9.14 2016-05-28 00:16:03 +01:00
Igor Pavlov
3dacb5eb8a 9.13 2016-05-28 00:16:03 +01:00
Igor Pavlov
76b173af78 9.12 2016-05-28 00:16:02 +01:00
476 changed files with 18531 additions and 10286 deletions

View File

@@ -1,7 +1,6 @@
/* 7zAlloc.c -- Allocation functions
2008-10-04 : Igor Pavlov : Public domain */
2010-10-29 : Igor Pavlov : Public domain */
#include <stdlib.h>
#include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */

View File

@@ -1,14 +1,10 @@
/* 7zAlloc.h -- Allocation functions
2009-02-07 : Igor Pavlov : Public domain */
2010-10-29 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address);
@@ -16,8 +12,4 @@ void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,15 +1,24 @@
/* 7zCrc.c -- CRC32 calculation
2009-11-23 : Igor Pavlov : Public domain */
/* 7zCrc.c -- CRC32 init
2010-12-01 : Igor Pavlov : Public domain */
#include "7zCrc.h"
#include "CpuArch.h"
#define kCrcPoly 0xEDB88320
#ifdef MY_CPU_LE
#define CRC_NUM_TABLES 8
#ifdef MY_CPU_X86_OR_AMD64
#define CRC_NUM_TABLES 8
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#elif defined(MY_CPU_LE)
#define CRC_NUM_TABLES 4
#else
#define CRC_NUM_TABLES 1
#define CRC_NUM_TABLES 5
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
#ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
@@ -17,25 +26,6 @@ typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size,
static CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
#if CRC_NUM_TABLES == 1
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
#else
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{
return g_CrcUpdate(v, data, size, g_CrcTable);
@@ -57,18 +47,37 @@ void MY_FAST_CALL CrcGenerateTable()
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
g_CrcTable[i] = r;
}
#if CRC_NUM_TABLES == 1
g_CrcUpdate = CrcUpdateT1;
#else
for (; i < 256 * CRC_NUM_TABLES; i++)
{
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
#ifdef MY_CPU_LE
g_CrcUpdate = CrcUpdateT4;
#ifdef MY_CPU_X86_OR_AMD64
#if CRC_NUM_TABLES == 8
if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#endif
#else
{
#ifndef MY_CPU_BE
UInt32 k = 1;
if (*(const Byte *)&k == 1)
g_CrcUpdate = CrcUpdateT4;
else
#endif
{
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{
UInt32 x = g_CrcTable[i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x);
}
g_CrcUpdate = CrcUpdateT1_BeT4;
}
}
#endif
}

View File

@@ -1,12 +1,12 @@
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
2009-11-23 : Igor Pavlov : Public domain */
/* 7zCrcOpt.c -- CRC32 calculation
2010-12-01 : Igor Pavlov : Public domain */
#include "CpuArch.h"
#ifdef MY_CPU_LE
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
#ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
@@ -32,3 +32,33 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
}
#endif
#ifndef MY_CPU_LE
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
v = CRC_UINT32_SWAP(v);
table += 0x100;
for (; size >= 4; size -= 4, p += 4)
{
v ^= *(const UInt32 *)p;
v =
table[0x000 + (v & 0xFF)] ^
table[0x100 + ((v >> 8) & 0xFF)] ^
table[0x200 + ((v >> 16) & 0xFF)] ^
table[0x300 + ((v >> 24))];
}
table -= 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
#endif

View File

@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder
2010-03-15 : Igor Pavlov : Public domain */
2010-11-02 : Igor Pavlov : Public domain */
#include <string.h>
@@ -20,6 +20,10 @@
#define k_LZMA2 0x21
#define k_LZMA 0x30101
#define k_BCJ 0x03030103
#define k_PPC 0x03030205
#define k_ARM 0x03030501
#define k_ARMT 0x03030701
#define k_SPARC 0x03030805
#define k_BCJ2 0x0303011B
#ifdef _7ZIP_PPMD_SUPPPORT
@@ -260,7 +264,6 @@ static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
IS_MAIN_METHOD((UInt32)c->MethodID);
}
#define IS_BCJ(c) ((c)->MethodID == k_BCJ && (c)->NumInStreams == 1 && (c)->NumOutStreams == 1)
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
static SRes CheckSupportedFolder(const CSzFolder *f)
@@ -277,11 +280,24 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
}
if (f->NumCoders == 2)
{
if (!IS_BCJ(&f->Coders[1]) ||
f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
CSzCoderInfo *c = &f->Coders[1];
if (c->MethodID > (UInt32)0xFFFFFFFF ||
c->NumInStreams != 1 ||
c->NumOutStreams != 1 ||
f->NumPackStreams != 1 ||
f->PackStreams[0] != 0 ||
f->NumBindPairs != 1 ||
f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
f->BindPairs[0].InIndex != 1 ||
f->BindPairs[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID)
{
case k_BCJ:
case k_ARM:
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
if (f->NumCoders == 4)
@@ -314,6 +330,8 @@ static UInt64 GetSum(const UInt64 *values, UInt32 index)
return sum;
}
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
@@ -391,14 +409,6 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
#endif
}
}
else if (coder->MethodID == k_BCJ)
{
UInt32 state;
if (ci != 1)
return SZ_ERROR_UNSUPPORTED;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
}
else if (coder->MethodID == k_BCJ2)
{
UInt64 offset = GetSum(packSizes, 1);
@@ -425,7 +435,23 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
RINOK(res)
}
else
{
if (ci != 1)
return SZ_ERROR_UNSUPPORTED;
switch(coder->MethodID)
{
case k_BCJ:
{
UInt32 state;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
break;
}
CASE_BRA_CONV(ARM)
default:
return SZ_ERROR_UNSUPPORTED;
}
}
}
return SZ_OK;
}

View File

@@ -1,5 +1,5 @@
/* 7zIn.c -- 7z Input functions
2010-03-11 : Igor Pavlov : Public domain */
2010-10-29 : Igor Pavlov : Public domain */
#include <string.h>
@@ -1218,12 +1218,16 @@ static SRes SzArEx_Open2(
ISzAlloc *allocTemp)
{
Byte header[k7zStartHeaderSize];
Int64 startArcPos;
UInt64 nextHeaderOffset, nextHeaderSize;
size_t nextHeaderSizeT;
UInt32 nextHeaderCRC;
CBuf buffer;
SRes res;
startArcPos = 0;
RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
if (!TestSignatureCandidate(header))
@@ -1235,7 +1239,7 @@ static SRes SzArEx_Open2(
nextHeaderSize = GetUi64(header + 20);
nextHeaderCRC = GetUi32(header + 28);
p->startPosAfterHeader = k7zStartHeaderSize;
p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
return SZ_ERROR_CRC;
@@ -1252,13 +1256,13 @@ static SRes SzArEx_Open2(
{
Int64 pos = 0;
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
if ((UInt64)pos < nextHeaderOffset ||
(UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
(UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
if ((UInt64)pos < startArcPos + nextHeaderOffset ||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
return SZ_ERROR_INPUT_EOF;
}
RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
return SZ_ERROR_MEM;

View File

@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 9
#define MY_VER_MINOR 11
#define MY_VER_BUILD 0
#define MY_VERSION "9.11 beta"
#define MY_DATE "2010-03-15"
#define MY_VER_MINOR 21
#define MY_VER_BUILD 00
#define MY_VERSION "9.21 beta"
#define MY_DATE "2011-04-11"
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE

View File

@@ -1,5 +1,5 @@
/* Bra.c -- Converters for RISC code
2008-10-04 : Igor Pavlov : Public domain */
2010-04-16 : Igor Pavlov : Public domain */
#include "Bra.h"
@@ -104,8 +104,8 @@ SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
size -= 4;
for (i = 0; i <= size; i += 4)
{
if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
{
UInt32 src =
((UInt32)data[i + 0] << 24) |

View File

@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code
2009-12-12: Igor Pavlov : Public domain */
2010-10-26: Igor Pavlov : Public domain */
#include "CpuArch.h"

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
2010-03-11: Igor Pavlov : Public domain */
2010-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -40,14 +40,26 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_ARM_LE
#endif
#if defined(_WIN32) && defined(_M_IA64)
#define MY_CPU_IA64_LE
#endif
#if defined(MY_CPU_X86_OR_AMD64)
#define MY_CPU_LE_UNALIGN
#endif
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE)
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
#define MY_CPU_LE
#endif
#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
#define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian
#endif
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(p))
@@ -55,6 +67,7 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define GetUi64(p) (*(const UInt64 *)(p))
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
#else
@@ -78,6 +91,10 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
SetUi32(p, (UInt32)_x64_); \
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
#endif
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */
2010-12-15 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
@@ -330,27 +330,21 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
{
CLzma2Dec decoder;
CLzma2Dec p;
SRes res;
SizeT outSize = *destLen, inSize = *srcLen;
Byte props[LZMA_PROPS_SIZE];
Lzma2Dec_Construct(&decoder);
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
decoder.decoder.dic = dest;
decoder.decoder.dicBufSize = outSize;
RINOK(Lzma2Dec_GetOldProps(prop, props));
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
Lzma2Dec_Construct(&p);
RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
p.decoder.dic = dest;
p.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&p);
*srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
*destLen = decoder.decoder.dicPos;
res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
LzmaDec_FreeProbs(&decoder.decoder, alloc);
Lzma2Dec_FreeProbs(&p, alloc);
return res;
}

View File

@@ -1,5 +1,5 @@
/* Lzma2Enc.c -- LZMA2 Encoder
2009-11-24 : Igor Pavlov : Public domain */
2010-09-24 : Igor Pavlov : Public domain */
/* #include <stdio.h> */
#include <string.h>
@@ -141,7 +141,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
PRF(printf(" "));
outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | (u >> 16) & 0x1F);
outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F));
outBuf[destPos++] = (Byte)(u >> 8);
outBuf[destPos++] = (Byte)u;
outBuf[destPos++] = (Byte)(pm >> 8);
@@ -173,6 +173,65 @@ void Lzma2EncProps_Init(CLzma2EncProps *p)
p->blockSize = 0;
}
void Lzma2EncProps_Normalize(CLzma2EncProps *p)
{
int t1, t1n, t2, t3;
{
CLzmaEncProps lzmaProps = p->lzmaProps;
LzmaEncProps_Normalize(&lzmaProps);
t1n = lzmaProps.numThreads;
}
t1 = p->lzmaProps.numThreads;
t2 = p->numBlockThreads;
t3 = p->numTotalThreads;
if (t2 > NUM_MT_CODER_THREADS_MAX)
t2 = NUM_MT_CODER_THREADS_MAX;
if (t3 <= 0)
{
if (t2 <= 0)
t2 = 1;
t3 = t1n * t2;
}
else if (t2 <= 0)
{
t2 = t3 / t1n;
if (t2 == 0)
{
t1 = 1;
t2 = t3;
}
if (t2 > NUM_MT_CODER_THREADS_MAX)
t2 = NUM_MT_CODER_THREADS_MAX;
}
else if (t1 <= 0)
{
t1 = t3 / t2;
if (t1 == 0)
t1 = 1;
}
else
t3 = t1n * t2;
p->lzmaProps.numThreads = t1;
p->numBlockThreads = t2;
p->numTotalThreads = t3;
LzmaEncProps_Normalize(&p->lzmaProps);
if (p->blockSize == 0)
{
UInt32 dictSize = p->lzmaProps.dictSize;
UInt64 blockSize = (UInt64)dictSize << 2;
const UInt32 kMinSize = (UInt32)1 << 20;
const UInt32 kMaxSize = (UInt32)1 << 28;
if (blockSize < kMinSize) blockSize = kMinSize;
if (blockSize > kMaxSize) blockSize = kMaxSize;
if (blockSize < dictSize) blockSize = dictSize;
p->blockSize = (size_t)blockSize;
}
}
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
{
@@ -181,9 +240,7 @@ static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
/* ---------- Lzma2 ---------- */
extern struct _CLzma2Enc;
typedef struct _CLzma2Enc
typedef struct
{
Byte propEncoded;
CLzma2EncProps props;
@@ -212,7 +269,7 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
if (mainEncoder->outBuf == 0)
{
mainEncoder->outBuf = IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
if (mainEncoder->outBuf == 0)
return SZ_ERROR_MEM;
}
@@ -351,70 +408,6 @@ void Lzma2Enc_Destroy(CLzma2EncHandle pp)
IAlloc_Free(p->alloc, pp);
}
void Lzma2EncProps_Normalize(CLzma2EncProps *p)
{
int t1, t1n, t2, t3;
CLzmaEncProps lzmaProps = p->lzmaProps;
LzmaEncProps_Normalize(&lzmaProps);
t1 = p->lzmaProps.numThreads;
t1n = lzmaProps.numThreads;
t2 = p->numBlockThreads;
t3 = p->numTotalThreads;
#ifndef _7ZIP_ST
if (t2 > NUM_MT_CODER_THREADS_MAX)
t2 = NUM_MT_CODER_THREADS_MAX;
#else
t2 = 1;
#endif
if (t3 <= 0)
{
if (t2 <= 0)
t2 = 1;
t3 = t1n * t2;
}
else
{
if (t2 <= 0)
{
t2 = t3 / t1n;
if (t2 == 0)
{
t1 = 1;
t2 = t3;
}
}
else if (t1 <= 0)
{
t1 = t3 / t2;
if (t1 == 0)
t1 = 1;
}
else
t3 = t1n * t2;
}
p->lzmaProps.numThreads = t1;
p->numBlockThreads = t2;
p->numTotalThreads = t3;
LzmaEncProps_Normalize(&p->lzmaProps);
if (p->blockSize == 0)
{
UInt64 blockSize = (UInt64)lzmaProps.dictSize << 2;
const UInt32 kMinSize = (UInt32)1 << 20;
const UInt32 kMaxSize = (UInt32)1 << 28;
if (blockSize < kMinSize) blockSize = kMinSize;
if (blockSize > kMaxSize) blockSize = kMaxSize;
if (blockSize < lzmaProps.dictSize)
blockSize = lzmaProps.dictSize;
p->blockSize = (size_t)blockSize;
}
}
SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
{
CLzma2Enc *p = (CLzma2Enc *)pp;

View File

@@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder
2009-09-20 : Igor Pavlov : Public domain */
2010-12-15 : Igor Pavlov : Public domain */
#include "LzmaDec.h"
@@ -442,8 +442,9 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
p->processedPos += len;
p->remainLen -= len;
while (len-- != 0)
while (len != 0)
{
len--;
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dicPos++;
}
@@ -972,28 +973,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
{
CLzmaDec p;
SRes res;
SizeT inSize = *srcLen;
SizeT outSize = *destLen;
*srcLen = *destLen = 0;
SizeT outSize = *destLen, inSize = *srcLen;
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
if (inSize < RC_INIT_SIZE)
return SZ_ERROR_INPUT_EOF;
LzmaDec_Construct(&p);
res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
if (res != 0)
return res;
RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));
p.dic = dest;
p.dicBufSize = outSize;
LzmaDec_Init(&p);
*srcLen = inSize;
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = p.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
(*destLen) = p.dicPos;
LzmaDec_FreeProbs(&p, alloc);
return res;
}

View File

@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder
2009-11-24 : Igor Pavlov : Public domain */
2011-01-27 : Igor Pavlov : Public domain */
#include <string.h>
@@ -46,6 +46,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
{
p->level = 5;
p->dictSize = p->mc = 0;
p->reduceSize = (UInt32)(Int32)-1;
p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
p->writeEndMark = 0;
}
@@ -56,6 +57,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if (level < 0) level = 5;
p->level = level;
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
if (p->dictSize > p->reduceSize)
{
unsigned i;
for (i = 15; i <= 30; i++)
{
if (p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
if (p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
}
}
if (p->lc < 0) p->lc = 3;
if (p->lp < 0) p->lp = 0;
if (p->pb < 0) p->pb = 2;
@@ -329,7 +339,6 @@ typedef struct
SRes result;
UInt32 dictSize;
UInt32 matchFinderCycles;
int needInit;
@@ -395,10 +404,9 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
LzmaEncProps_Normalize(&props);
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
return SZ_ERROR_PARAM;
p->dictSize = props.dictSize;
p->matchFinderCycles = props.mc;
{
unsigned fb = props.fb;
if (fb < 5)

View File

@@ -1,14 +1,12 @@
/* LzmaEnc.h -- LZMA Encoder
2009-02-07 : Igor Pavlov : Public domain */
2011-01-27 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H
#define __LZMA_ENC_H
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
#define LZMA_PROPS_SIZE 5
@@ -18,6 +16,8 @@ typedef struct _CLzmaEncProps
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
default = (1 << 24) */
UInt32 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
Encoder uses this value to reduce dictionary size */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */
@@ -73,8 +73,6 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif

View File

@@ -1,5 +1,5 @@
/* MtCoder.c -- Multi-thread Coder
2009-03-26 : Igor Pavlov : Public domain */
2010-09-24 : Igor Pavlov : Public domain */
#include <stdio.h>
@@ -148,7 +148,7 @@ static void CMtThread_Destruct(CMtThread *p)
#define MY_BUF_ALLOC(buf, size, newSize) \
if (buf == 0 || size != newSize) \
{ IAlloc_Free(p->mtCoder->alloc, buf); \
size = newSize; buf = IAlloc_Alloc(p->mtCoder->alloc, size); \
size = newSize; buf = (Byte *)IAlloc_Alloc(p->mtCoder->alloc, size); \
if (buf == 0) return SZ_ERROR_MEM; }
static SRes CMtThread_Prepare(CMtThread *p)
@@ -306,7 +306,7 @@ SRes MtCoder_Code(CMtCoder *p)
for (i = 0; i < numThreads; i++)
{
CMtThread *t = &p->threads[i];
if (LoopThread_StartSubThread(&t->thread) != SZ_OK || i == 10)
if (LoopThread_StartSubThread(&t->thread) != SZ_OK)
{
res = SZ_ERROR_THREAD;
p->threads[0].stopReading = True;

View File

@@ -1,5 +1,5 @@
/* Ppmd.h -- PPMD codec common code
2010-03-12 : Igor Pavlov : Public domain
2011-01-27 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H
@@ -29,6 +29,9 @@ EXTERN_C_BEGIN
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
#pragma pack(push, 1)
/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
/* SEE-contexts for PPM-contexts with masked symbols */
typedef struct
{
@@ -48,6 +51,8 @@ typedef struct
UInt16 SuccessorHigh;
} CPpmd_State;
#pragma pack(pop)
typedef
#ifdef PPMD_32BIT
CPpmd_State *

View File

@@ -1,5 +1,5 @@
/* Ppmd8.c -- PPMdI codec
2010-03-15 : Igor Pavlov : Public domain
2010-03-24 : Igor Pavlov : Public domain
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
#include <memory.h>
@@ -410,6 +410,10 @@ static void Refresh(CPpmd8 *p, CTX_PTR ctx, unsigned oldNU, unsigned scale)
unsigned i = ctx->NumStats, escFreq, sumFreq, flags;
CPpmd_State *s = (CPpmd_State *)ShrinkUnits(p, STATS(ctx), oldNU, (i + 2) >> 1);
ctx->Stats = REF(s);
#ifdef PPMD8_FREEZE_SUPPORT
/* fixed over Shkarin's code. Fixed code is not compatible with original code for some files in FREEZE mode. */
scale |= (ctx->SummFreq >= ((UInt32)1 << 15));
#endif
flags = (ctx->Flags & (0x10 + 0x04 * scale)) + 0x08 * (s->Symbol >= 0x40);
escFreq = ctx->SummFreq - s->Freq;
sumFreq = (s->Freq = (Byte)((s->Freq + scale) >> scale));

View File

@@ -1,5 +1,5 @@
/* Ppmd8.h -- PPMdI codec
2010-03-12 : Igor Pavlov : Public domain
2011-01-27 : Igor Pavlov : Public domain
This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -24,6 +24,8 @@ typedef
#endif
CPpmd8_Context_Ref;
#pragma pack(push, 1)
typedef struct CPpmd8_Context_
{
Byte NumStats;
@@ -33,10 +35,13 @@ typedef struct CPpmd8_Context_
CPpmd8_Context_Ref Suffix;
} CPpmd8_Context;
#pragma pack(pop)
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
/* There is some bug in FREEZE mode (including original code,
so we disable FREEZE mode support */
/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
code is not compatible with original code for some files compressed
in FREEZE mode. So we disable FREEZE mode support. */
enum
{

View File

@@ -1,5 +1,5 @@
/* Ppmd8Dec.c -- PPMdI Decoder
2010-03-12 : Igor Pavlov : Public domain
2010-04-16 : Igor Pavlov : Public domain
This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -33,7 +33,7 @@ static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
p->Range *= size;
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
{
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
p->Range <<= 8;

View File

@@ -1,5 +1,5 @@
/* Ppmd8Enc.c -- PPMdI Encoder
2010-03-12 : Igor Pavlov : Public domain
2010-04-16 : Igor Pavlov : Public domain
This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -19,7 +19,7 @@ void Ppmd8_RangeEnc_FlushData(CPpmd8 *p)
static void RangeEnc_Normalize(CPpmd8 *p)
{
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
{
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
p->Range <<= 8;

View File

@@ -1,9 +1,9 @@
/* Crypto/Sha256.c -- SHA-256 Hash function
2008-11-06 : Igor Pavlov : Public domain
/* Crypto/Sha256.c -- SHA-256 Hash
2010-06-11 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Sha256.h"
#include "RotateDefs.h"
#include "Sha256.h"
/* define it for speed optimization */
/* #define _SHA256_UNROLL */
@@ -71,7 +71,7 @@ void Sha256_Init(CSha256 *p)
#endif
const UInt32 K[64] = {
static const UInt32 K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,

View File

@@ -1,14 +1,12 @@
/* Sha256.h -- SHA-256 Hash
2009-02-07 : Igor Pavlov : Public domain */
2010-06-11 : Igor Pavlov : Public domain */
#ifndef __CRYPTO_SHA256_H
#define __CRYPTO_SHA256_H
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
#define SHA256_DIGEST_SIZE 32
@@ -23,8 +21,6 @@ void Sha256_Init(CSha256 *p);
void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
void Sha256_Final(CSha256 *p, Byte *digest);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif

View File

@@ -1,7 +1,5 @@
/* Sort.c -- Sort functions
2008-08-17
Igor Pavlov
Public domain */
2010-09-17 : Igor Pavlov : Public domain */
#include "Sort.h"

View File

@@ -1,5 +1,5 @@
/* Types.h -- Basic types
2010-03-11 : Igor Pavlov : Public domain */
2010-10-09 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
@@ -77,9 +77,11 @@ typedef unsigned long UInt64;
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
@@ -231,6 +233,22 @@ typedef struct
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/"
#endif
EXTERN_C_END
#endif

View File

@@ -92,6 +92,14 @@ SOURCE=..\..\7z.h
# End Source File
# Begin Source File
SOURCE=..\..\7zAlloc.c
# End Source File
# Begin Source File
SOURCE=..\..\7zAlloc.h
# End Source File
# Begin Source File
SOURCE=..\..\7zBuf.c
# End Source File
# Begin Source File
@@ -141,6 +149,10 @@ SOURCE=..\..\Bcj2.h
# End Source File
# Begin Source File
SOURCE=..\..\Bra.c
# End Source File
# Begin Source File
SOURCE=..\..\Bra.h
# End Source File
# Begin Source File
@@ -196,14 +208,6 @@ SOURCE=..\..\Types.h
# End Group
# Begin Source File
SOURCE=.\7zAlloc.c
# End Source File
# Begin Source File
SOURCE=.\7zAlloc.h
# End Source File
# Begin Source File
SOURCE=.\7zMain.c
# End Source File
# End Target

View File

@@ -1,16 +1,15 @@
/* 7zMain.c - Test application for 7z Decoder
2010-03-12 : Igor Pavlov : Public domain */
2010-10-28 : Igor Pavlov : Public domain */
#include <stdio.h>
#include <string.h>
#include "../../7z.h"
#include "../../7zAlloc.h"
#include "../../7zCrc.h"
#include "../../7zFile.h"
#include "../../7zVersion.h"
#include "7zAlloc.h"
#ifndef USE_WINDOWS_FILE
/* for mkdir */
#ifdef _WIN32
@@ -21,12 +20,6 @@
#endif
#endif
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#else
#define CHAR_PATH_SEPARATOR '/'
#endif
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
static int Buf_EnsureSize(CBuf *dest, size_t size)
@@ -104,7 +97,7 @@ static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
}
#endif
static WRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
{
int len = 0;
for (len = 0; s[len] != '\0'; len++);
@@ -117,7 +110,14 @@ static WRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
{
char defaultChar = '_';
BOOL defUsed;
int numChars = WideCharToMultiByte(fileMode ? (AreFileApisANSI() ? CP_ACP : CP_OEMCP) : CP_OEMCP,
int numChars = WideCharToMultiByte(fileMode ?
(
#ifdef UNDER_CE
CP_ACP
#else
AreFileApisANSI() ? CP_ACP : CP_OEMCP
#endif
) : CP_OEMCP,
0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
if (numChars == 0 || numChars >= size)
return SZ_ERROR_FAIL;
@@ -172,15 +172,16 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
#endif
}
static void PrintString(const UInt16 *s)
static SRes PrintString(const UInt16 *s)
{
CBuf buf;
SRes res;
Buf_Init(&buf);
if (Utf16_To_Char(&buf, s, 0) == 0)
{
printf("%s", buf.data);
res = Utf16_To_Char(&buf, s, 0);
if (res == SZ_OK)
fputs((const char *)buf.data, stdout);
Buf_Free(&buf, &g_Alloc);
}
return res;
}
static void UInt64ToStr(UInt64 value, char *s)
@@ -398,16 +399,21 @@ int MY_CDECL main(int numargs, char *args[])
}
printf("%s %s %10s ", t, attr, s);
PrintString(temp);
res = PrintString(temp);
if (res != SZ_OK)
break;
if (f->IsDir)
printf("/");
printf("\n");
continue;
}
printf(testCommand ?
fputs(testCommand ?
"Testing ":
"Extracting ");
PrintString(temp);
"Extracting ",
stdout);
res = PrintString(temp);
if (res != SZ_OK)
break;
if (f->IsDir)
printf("/");
else

View File

@@ -4,6 +4,7 @@ CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
PROG = 7zDec.exe
C_OBJS = \
$O\7zAlloc.obj \
$O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \
@@ -13,6 +14,7 @@ C_OBJS = \
$O\7zIn.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\CpuArch.obj \
$O\Lzma2Dec.obj \
@@ -21,7 +23,6 @@ C_OBJS = \
$O\Ppmd7Dec.obj \
7Z_OBJS = \
$O\7zAlloc.obj \
$O\7zMain.obj \
OBJS = \

View File

@@ -4,7 +4,7 @@ LIB =
RM = rm -f
CFLAGS = -c -O2 -Wall
OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
all: $(PROG)
@@ -15,7 +15,7 @@ $(PROG): $(OBJS)
$(CXX) $(CFLAGS) 7zMain.c
7zAlloc.o: 7zAlloc.c
$(CXX) $(CFLAGS) 7zAlloc.c
$(CXX) $(CFLAGS) ../../7zAlloc.c
7zBuf.o: ../../7zBuf.c
$(CXX) $(CFLAGS) ../../7zBuf.c
@@ -44,6 +44,9 @@ LzmaDec.o: ../../LzmaDec.c
Lzma2Dec.o: ../../Lzma2Dec.c
$(CXX) $(CFLAGS) ../../Lzma2Dec.c
Bra.o: ../../Bra.c
$(CXX) $(CFLAGS) ../../Bra.c
Bra86.o: ../../Bra86.c
$(CXX) $(CFLAGS) ../../Bra86.c

View File

@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression
2009-08-14 : Igor Pavlov : Public domain */
2010-09-20 : Igor Pavlov : Public domain */
#define _CRT_SECURE_NO_WARNINGS
@@ -249,6 +249,6 @@ int MY_CDECL main(int numArgs, const char *args[])
{
char rs[800] = { 0 };
int res = main2(numArgs, args, rs);
printf(rs);
fputs(rs, stdout);
return res;
}

587
C/Util/SfxSetup/SfxSetup.c Executable file
View File

@@ -0,0 +1,587 @@
/* SfxSetup.c - 7z SFX Setup
2010-12-13 : Igor Pavlov : Public domain */
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#ifdef _CONSOLE
#include <stdio.h>
#endif
#include "../../7z.h"
#include "../../7zAlloc.h"
#include "../../7zCrc.h"
#include "../../7zFile.h"
#include "../../CpuArch.h"
#define k_EXE_ExtIndex 1
static const char *kExts[] =
{
"bat",
"exe",
"inf",
"msi",
#ifdef UNDER_CE
"cab",
#endif
"html",
"htm"
};
static const char *kNames[] =
{
"setup",
"install",
"run",
"start"
};
static unsigned FindExt(const wchar_t *s, unsigned *extLen)
{
unsigned len = (unsigned)wcslen(s);
unsigned i;
for (i = len; i > 0; i--)
{
if (s[i - 1] == '.')
{
*extLen = len - i;
return i - 1;
}
}
*extLen = 0;
return len;
}
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, unsigned len)
{
unsigned i;
for (i = 0; i < num; i++)
{
const char *item = items[i];
unsigned itemLen = (unsigned)strlen(item);
unsigned j;
if (len != itemLen)
continue;
for (j = 0; j < len; j++)
{
unsigned c = item[j];
if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])
break;
}
if (j == len)
return i;
}
return i;
}
#ifdef _CONSOLE
static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
{
ctrlType = ctrlType;
return TRUE;
}
#endif
static void PrintErrorMessage(const char *message)
{
#ifdef _CONSOLE
printf("\n7-Zip Error: %s\n", message);
#else
#ifdef UNDER_CE
WCHAR messageW[256 + 4];
unsigned i;
for (i = 0; i < 256 && message[i] != 0; i++)
messageW[i] = message[i];
messageW[i] = 0;
MessageBoxW(0, messageW, L"7-Zip Error", MB_ICONERROR);
#else
MessageBoxA(0, message, "7-Zip Error", MB_ICONERROR);
#endif
#endif
}
static WRes MyCreateDir(const WCHAR *name)
{
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
}
#ifdef UNDER_CE
#define kBufferSize (1 << 13)
#else
#define kBufferSize (1 << 15)
#endif
#define kSignatureSearchLimit (1 << 22)
static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
{
Byte buf[kBufferSize];
size_t numPrevBytes = 0;
*resPos = 0;
for (;;)
{
size_t processed, pos;
if (*resPos > kSignatureSearchLimit)
return False;
processed = kBufferSize - numPrevBytes;
if (File_Read(stream, buf + numPrevBytes, &processed) != 0)
return False;
processed += numPrevBytes;
if (processed < k7zStartHeaderSize ||
(processed == k7zStartHeaderSize && numPrevBytes != 0))
return False;
processed -= k7zStartHeaderSize;
for (pos = 0; pos <= processed; pos++)
{
for (; buf[pos] != '7' && pos <= processed; pos++);
if (pos > processed)
break;
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8))
{
*resPos += pos;
return True;
}
}
*resPos += processed;
numPrevBytes = k7zStartHeaderSize;
memmove(buf, buf + processed, k7zStartHeaderSize);
}
}
static Bool DoesFileOrDirExist(const WCHAR *path)
{
WIN32_FIND_DATAW fd;
HANDLE handle;
handle = FindFirstFileW(path, &fd);
if (handle == INVALID_HANDLE_VALUE)
return False;
FindClose(handle);
return True;
}
static WRes RemoveDirWithSubItems(WCHAR *path)
{
WIN32_FIND_DATAW fd;
HANDLE handle;
WRes res = 0;
size_t len = wcslen(path);
wcscpy(path + len, L"*");
handle = FindFirstFileW(path, &fd);
path[len] = L'\0';
if (handle == INVALID_HANDLE_VALUE)
return GetLastError();
for (;;)
{
if (wcscmp(fd.cFileName, L".") != 0 &&
wcscmp(fd.cFileName, L"..") != 0)
{
wcscpy(path + len, fd.cFileName);
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
wcscat(path, L"\\");
res = RemoveDirWithSubItems(path);
}
else
{
SetFileAttributesW(path, 0);
if (DeleteFileW(path) == 0)
res = GetLastError();
}
if (res != 0)
break;
}
if (!FindNextFileW(handle, &fd))
{
res = GetLastError();
if (res == ERROR_NO_MORE_FILES)
res = 0;
break;
}
}
path[len] = L'\0';
FindClose(handle);
if (res == 0)
{
if (!RemoveDirectoryW(path))
res = GetLastError();
}
return res;
}
#ifdef _CONSOLE
int MY_CDECL main()
#else
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
#ifdef UNDER_CE
LPWSTR
#else
LPSTR
#endif
lpCmdLine, int nCmdShow)
#endif
{
CFileInStream archiveStream;
CLookToRead lookStream;
CSzArEx db;
SRes res = SZ_OK;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
WCHAR sfxPath[MAX_PATH + 2];
WCHAR path[MAX_PATH * 3 + 2];
size_t pathLen;
DWORD winRes;
const wchar_t *cmdLineParams;
const char *errorMessage = NULL;
Bool useShellExecute = True;
#ifdef _CONSOLE
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#else
hInstance = hInstance;
hPrevInstance = hPrevInstance;
lpCmdLine = lpCmdLine;
nCmdShow = nCmdShow;
#endif
CrcGenerateTable();
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp;
FileInStream_CreateVTable(&archiveStream);
LookToRead_CreateVTable(&lookStream, False);
winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
if (winRes == 0 || winRes > MAX_PATH)
return 1;
{
cmdLineParams = GetCommandLineW();
#ifndef UNDER_CE
{
Bool quoteMode = False;
for (;; cmdLineParams++)
{
wchar_t c = *cmdLineParams;
if (c == L'\"')
quoteMode = !quoteMode;
else if (c == 0 || (c == L' ' && !quoteMode))
break;
}
}
#endif
}
{
unsigned i;
DWORD d;
winRes = GetTempPathW(MAX_PATH, path);
if (winRes == 0 || winRes > MAX_PATH)
return 1;
pathLen = wcslen(path);
d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
for (i = 0;; i++, d += GetTickCount())
{
if (i >= 100)
{
res = SZ_ERROR_FAIL;
break;
}
wcscpy(path + pathLen, L"7z");
{
wchar_t *s = path + wcslen(path);
UInt32 value = d;
unsigned k;
for (k = 0; k < 8; k++)
{
unsigned t = value & 0xF;
value >>= 4;
s[7 - k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[k] = '\0';
}
if (DoesFileOrDirExist(path))
continue;
if (CreateDirectoryW(path, NULL))
{
wcscat(path, L"\\");
pathLen = wcslen(path);
break;
}
if (GetLastError() != ERROR_ALREADY_EXISTS)
{
res = SZ_ERROR_FAIL;
break;
}
}
if (res != SZ_OK)
errorMessage = "Can't create temp folder";
}
if (res != SZ_OK)
{
if (!errorMessage)
errorMessage = "Error";
PrintErrorMessage(errorMessage);
return 1;
}
if (InFile_OpenW(&archiveStream.file, sfxPath) != 0)
{
errorMessage = "can not open input file";
res = SZ_ERROR_FAIL;
}
else
{
UInt64 pos = 0;
if (!FindSignature(&archiveStream.file, &pos))
res = SZ_ERROR_FAIL;
else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0)
res = SZ_ERROR_FAIL;
if (res != 0)
errorMessage = "Can't find 7z archive";
}
if (res == SZ_OK)
{
lookStream.realStream = &archiveStream.s;
LookToRead_Init(&lookStream);
}
SzArEx_Init(&db);
if (res == SZ_OK)
{
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
}
if (res == SZ_OK)
{
UInt32 executeFileIndex = (UInt32)(Int32)-1;
UInt32 minPrice = 1 << 30;
UInt32 i;
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
for (i = 0; i < db.db.NumFiles; i++)
{
size_t offset = 0;
size_t outSizeProcessed = 0;
const CSzFileItem *f = db.db.Files + i;
size_t len;
WCHAR *temp;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
if (len >= MAX_PATH)
{
res = SZ_ERROR_FAIL;
break;
}
temp = path + pathLen;
SzArEx_GetFileNameUtf16(&db, i, temp);
{
res = SzArEx_Extract(&db, &lookStream.s, i,
&blockIndex, &outBuffer, &outBufferSize,
&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
if (res != SZ_OK)
break;
}
{
CSzFile outFile;
size_t processedSize;
size_t j;
size_t nameStartPos = 0;
for (j = 0; temp[j] != 0; j++)
{
if (temp[j] == '/')
{
temp[j] = 0;
MyCreateDir(path);
temp[j] = CHAR_PATH_SEPARATOR;
nameStartPos = j + 1;
}
}
if (f->IsDir)
{
MyCreateDir(path);
continue;
}
else
{
unsigned extLen;
const WCHAR *name = temp + nameStartPos;
unsigned len = (unsigned)wcslen(name);
unsigned nameLen = FindExt(temp + nameStartPos, &extLen);
unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen);
unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen);
unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12));
if (minPrice > price)
{
minPrice = price;
executeFileIndex = i;
useShellExecute = (extPrice != k_EXE_ExtIndex);
}
if (DoesFileOrDirExist(path))
{
errorMessage = "Duplicate file";
res = SZ_ERROR_FAIL;
break;
}
if (OutFile_OpenW(&outFile, path))
{
errorMessage = "Can't open output file";
res = SZ_ERROR_FAIL;
break;
}
}
processedSize = outSizeProcessed;
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
{
errorMessage = "Can't write output file";
res = SZ_ERROR_FAIL;
}
#ifdef USE_WINDOWS_FILE
if (f->MTimeDefined)
{
FILETIME mTime;
mTime.dwLowDateTime = f->MTime.Low;
mTime.dwHighDateTime = f->MTime.High;
SetFileTime(outFile.handle, NULL, NULL, &mTime);
}
#endif
{
SRes res2 = File_Close(&outFile);
if (res != SZ_OK)
break;
if (res2 != SZ_OK)
{
res = res2;
break;
}
}
#ifdef USE_WINDOWS_FILE
if (f->AttribDefined)
SetFileAttributesW(path, f->Attrib);
#endif
}
}
if (res == SZ_OK)
{
if (executeFileIndex == (UInt32)(Int32)-1)
{
errorMessage = "There is no file to execute";
res = SZ_ERROR_FAIL;
}
else
{
WCHAR *temp = path + pathLen;
UInt32 j;
SzArEx_GetFileNameUtf16(&db, executeFileIndex, temp);
for (j = 0; temp[j] != 0; j++)
if (temp[j] == '/')
temp[j] = CHAR_PATH_SEPARATOR;
}
}
IAlloc_Free(&allocImp, outBuffer);
}
SzArEx_Free(&db, &allocImp);
File_Close(&archiveStream.file);
if (res == SZ_OK)
{
HANDLE hProcess = 0;
if (useShellExecute)
{
SHELLEXECUTEINFO ei;
UINT32 executeRes;
BOOL success;
memset(&ei, 0, sizeof(ei));
ei.cbSize = sizeof(ei);
ei.lpFile = path;
ei.fMask = SEE_MASK_NOCLOSEPROCESS
#ifndef UNDER_CE
| SEE_MASK_FLAG_DDEWAIT
#endif
/* | SEE_MASK_NO_CONSOLE */
;
if (wcslen(cmdLineParams) != 0)
ei.lpParameters = cmdLineParams;
ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */
success = ShellExecuteEx(&ei);
executeRes = (UINT32)(UINT_PTR)ei.hInstApp;
if (!success || (executeRes <= 32 && executeRes != 0)) /* executeRes = 0 in Windows CE */
res = SZ_ERROR_FAIL;
else
hProcess = ei.hProcess;
}
else
{
STARTUPINFOW si;
PROCESS_INFORMATION pi;
WCHAR cmdLine[MAX_PATH * 3];
wcscpy(cmdLine, path);
wcscat(cmdLine, cmdLineParams);
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0)
res = SZ_ERROR_FAIL;
else
{
CloseHandle(pi.hThread);
hProcess = pi.hProcess;
}
}
if (hProcess != 0)
{
WaitForSingleObject(hProcess, INFINITE);
CloseHandle(hProcess);
}
}
path[pathLen] = L'\0';
RemoveDirWithSubItems(path);
if (res == SZ_OK)
return 0;
{
if (res == SZ_ERROR_UNSUPPORTED)
errorMessage = "Decoder doesn't support this archive";
else if (res == SZ_ERROR_MEM)
errorMessage = "Can't allocate required memory";
else if (res == SZ_ERROR_CRC)
errorMessage = "CRC error";
else
{
if (!errorMessage)
errorMessage = "ERROR";
}
if (errorMessage)
PrintErrorMessage(errorMessage);
}
return 1;
}

198
C/Util/SfxSetup/SfxSetup.dsp Executable file
View File

@@ -0,0 +1,198 @@
# Microsoft Developer Studio Project File - Name="SfxSetup" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=SfxSetup - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "SfxSetup.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "SfxSetup.mak" CFG="SfxSetup - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "SfxSetup - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "SfxSetup - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "SfxSetup - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "SfxSetup - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "SfxSetup - Win32 Release"
# Name "SfxSetup - Win32 Debug"
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\7z.h
# End Source File
# Begin Source File
SOURCE=..\..\7zAlloc.c
# End Source File
# Begin Source File
SOURCE=..\..\7zAlloc.h
# End Source File
# Begin Source File
SOURCE=..\..\7zBuf.c
# End Source File
# Begin Source File
SOURCE=..\..\7zBuf.h
# End Source File
# Begin Source File
SOURCE=..\..\7zCrc.c
# End Source File
# Begin Source File
SOURCE=..\..\7zCrc.h
# End Source File
# Begin Source File
SOURCE=..\..\7zCrcOpt.c
# End Source File
# Begin Source File
SOURCE=..\..\7zDec.c
# End Source File
# Begin Source File
SOURCE=..\..\7zFile.c
# End Source File
# Begin Source File
SOURCE=..\..\7zFile.h
# End Source File
# Begin Source File
SOURCE=..\..\7zIn.c
# End Source File
# Begin Source File
SOURCE=..\..\7zStream.c
# End Source File
# Begin Source File
SOURCE=..\..\Bcj2.c
# End Source File
# Begin Source File
SOURCE=..\..\Bcj2.h
# End Source File
# Begin Source File
SOURCE=..\..\Bra.c
# End Source File
# Begin Source File
SOURCE=..\..\Bra.h
# End Source File
# Begin Source File
SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.c
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.h
# End Source File
# Begin Source File
SOURCE=..\..\Types.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\SfxSetup.c
# End Source File
# End Target
# End Project

29
C/Util/SfxSetup/SfxSetup.dsw Executable file
View File

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

35
C/Util/SfxSetup/makefile Executable file
View File

@@ -0,0 +1,35 @@
PROG = 7zS2.sfx
LIBS = $(LIBS)
CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS
C_OBJS = \
$O\7zAlloc.obj \
$O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \
$O\7zCrcOpt.obj \
$O\7zFile.obj \
$O\7zDec.obj \
$O\7zIn.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\CpuArch.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
7Z_OBJS = \
$O\SfxSetup.obj \
OBJS = \
$(7Z_OBJS) \
$(C_OBJS) \
$O\resource.res
!include "../../../CPP/Build.mak"
$(7Z_OBJS): $(*B).c
$(COMPL_O1)
$(C_OBJS): ../../$(*B).c
$(COMPL_O1)

35
C/Util/SfxSetup/makefile_con Executable file
View File

@@ -0,0 +1,35 @@
PROG = 7zS2con.sfx
LIBS = $(LIBS)
CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CONSOLE
C_OBJS = \
$O\7zAlloc.obj \
$O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \
$O\7zCrcOpt.obj \
$O\7zFile.obj \
$O\7zDec.obj \
$O\7zIn.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\CpuArch.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
7Z_OBJS = \
$O\SfxSetup.obj \
OBJS = \
$(7Z_OBJS) \
$(C_OBJS) \
$O\resource.res
!include "../../../CPP/Build.mak"
$(7Z_OBJS): $(*B).c
$(COMPL_O1)
$(C_OBJS): ../../$(*B).c
$(COMPL_O1)

6
C/Util/SfxSetup/resource.rc Executable file
View File

@@ -0,0 +1,6 @@
#include "../../../CPP/7zip/MyVersionInfo.rc"
MY_VERSION_INFO_APP("7z Setup SFX small", "7zS2.sfx")
1 ICON "setup.ico"

BIN
C/Util/SfxSetup/setup.ico Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

20
C/Xz.h
View File

@@ -1,14 +1,12 @@
/* Xz.h - Xz interface
2009-04-15 : Igor Pavlov : Public domain */
2011-01-09 : Igor Pavlov : Public domain */
#ifndef __XZ_H
#define __XZ_H
#include "Sha256.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
#define XZ_ID_Subblock 1
#define XZ_ID_Delta 3
@@ -140,7 +138,7 @@ typedef enum
CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */
CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
CODER_STATUS_NOT_FINISHED, /* stream was not finished */
CODER_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */
} ECoderStatus;
typedef enum
@@ -222,7 +220,8 @@ typedef struct
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
} CXzUnpacker;
SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc);
void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc);
void XzUnpacker_Init(CXzUnpacker *p);
void XzUnpacker_Free(CXzUnpacker *p);
/*
@@ -234,8 +233,9 @@ finishMode:
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
CODER_STATUS_NOT_FINISHED,
CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams,
call XzUnpacker_IsStreamWasFinished to check that current stream was finished
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
@@ -249,8 +249,6 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif

View File

@@ -1,9 +1,9 @@
/* XzCrc64.c -- CRC64 calculation
2009-04-15 : Igor Pavlov : Public domain */
2010-04-16 : Igor Pavlov : Public domain */
#include "XzCrc64.h"
#define kCrc64Poly 0xC96C5795D7870F42
#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
UInt64 g_Crc64Table[256];
void MY_FAST_CALL Crc64GenerateTable(void)

View File

@@ -1,5 +1,5 @@
/* XzCrc64.c -- CRC64 calculation
2009-04-15 : Igor Pavlov : Public domain */
/* XzCrc64.h -- CRC64 calculation
2010-04-16 : Igor Pavlov : Public domain */
#ifndef __XZ_CRC64_H
#define __XZ_CRC64_H
@@ -8,23 +8,19 @@
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
extern UInt64 g_Crc64Table[];
void MY_FAST_CALL Crc64GenerateTable(void);
#define CRC64_INIT_VAL 0xFFFFFFFFFFFFFFFF
#define CRC64_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFFFFFFFFFF)
#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF)
#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL)
#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size);
UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif

View File

@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode
2009-06-08 : Igor Pavlov : Public domain */
2011-02-07 : Igor Pavlov : Public domain */
/* #define XZ_DUMP */
@@ -18,7 +18,8 @@
#include "Lzma2Dec.h"
#ifdef USE_SUBBLOCK
#include "SbDec.h"
#include "Bcj3Dec.c"
#include "SbDec.c"
#endif
#include "Xz.h"
@@ -72,7 +73,6 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
{
CBraState *p = ((CBraState *)pp);
alloc = alloc;
p->encodeMode = 0;
p->ip = 0;
if (p->methodId == XZ_ID_Delta)
{
@@ -195,7 +195,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
return SZ_OK;
}
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc)
{
CBraState *decoder;
if (id != XZ_ID_Delta &&
@@ -211,6 +211,7 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
if (decoder == 0)
return SZ_ERROR_MEM;
decoder->methodId = (UInt32)id;
decoder->encodeMode = encodeMode;
p->p = decoder;
p->Free = BraState_Free;
p->SetProps = BraState_SetProps;
@@ -225,8 +226,8 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
static void SbState_Free(void *pp, ISzAlloc *alloc)
{
CSubblockDec *p = (CSubblockDec *)pp;
SubblockDec_Free(p, alloc);
CSbDec *p = (CSbDec *)pp;
SbDec_Free(p);
alloc->Free(alloc, pp);
}
@@ -240,24 +241,32 @@ static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAl
static void SbState_Init(void *pp)
{
SubblockDec_Init((CSubblockDec *)pp);
SbDec_Init((CSbDec *)pp);
}
static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
{
ECoderStatus status;
SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status);
CSbDec *p = (CSbDec *)pp;
SRes res;
srcWasFinished = srcWasFinished;
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
p->dest = dest;
p->destLen = *destLen;
p->src = src;
p->srcLen = *srcLen;
p->finish = finishMode; /* change it */
res = SbDec_Decode((CSbDec *)pp);
*destLen -= p->destLen;
*srcLen -= p->srcLen;
*wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */
return res;
}
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
{
CSubblockDec *decoder;
CSbDec *decoder;
p->p = 0;
decoder = alloc->Alloc(alloc, sizeof(CSubblockDec));
decoder = alloc->Alloc(alloc, sizeof(CSbDec));
if (decoder == 0)
return SZ_ERROR_MEM;
p->p = decoder;
@@ -265,7 +274,8 @@ SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
p->SetProps = SbState_SetProps;
p->Init = SbState_Init;
p->Code = SbState_Code;
SubblockDec_Construct(decoder);
SbDec_Construct(decoder);
SbDec_SetAlloc(decoder, alloc);
return SZ_OK;
}
#endif
@@ -369,7 +379,7 @@ SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
}
if (coderIndex == 0)
return SZ_ERROR_UNSUPPORTED;
return BraState_SetFromMethod(sc, methodId, p->alloc);
return BraState_SetFromMethod(sc, methodId, 0, p->alloc);
}
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
@@ -587,13 +597,17 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
return SZ_OK;
}
SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc)
void XzUnpacker_Init(CXzUnpacker *p)
{
MixCoder_Construct(&p->decoder, alloc);
p->state = XZ_STATE_STREAM_HEADER;
p->pos = 0;
p->numStreams = 0;
return SZ_OK;
}
void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc)
{
MixCoder_Construct(&p->decoder, alloc);
XzUnpacker_Init(p);
}
void XzUnpacker_Free(CXzUnpacker *p)
@@ -858,6 +872,8 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
}
break;
}
case XZ_STATE_BLOCK: break; /* to disable GCC warning */
}
}
/*

311
C/XzEnc.c
View File

@@ -1,5 +1,5 @@
/* XzEnc.c -- Xz Encode
2009-06-04 : Igor Pavlov : Public domain */
2011-02-07 : Igor Pavlov : Public domain */
#include <stdlib.h>
#include <string.h>
@@ -9,7 +9,9 @@
#include "Bra.h"
#include "CpuArch.h"
#ifdef USE_SUBBLOCK
#include "SbEnc.h"
#include "Bcj3Enc.c"
#include "SbFind.c"
#include "SbEnc.c"
#endif
#include "XzEnc.h"
@@ -198,158 +200,147 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
/* ---------- CSeqInFilter ---------- */
/*
typedef struct _IFilter
{
void *p;
void (*Free)(void *p, ISzAlloc *alloc);
SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);
void (*Init)(void *p);
size_t (*Filter)(void *p, Byte *data, SizeT destLen);
} IFilter;
#define FILT_BUF_SIZE (1 << 19)
#define FILTER_BUF_SIZE (1 << 20)
typedef struct
{
ISeqInStream p;
ISeqInStream *realStream;
UInt32 x86State;
UInt32 ip;
UInt64 processed;
CXzCheck check;
Byte buf[FILT_BUF_SIZE];
UInt32 bufferPos;
UInt32 convertedPosBegin;
UInt32 convertedPosEnd;
IFilter *filter;
IStateCoder StateCoder;
Byte *buf;
size_t curPos;
size_t endPos;
int srcWasFinished;
} CSeqInFilter;
static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
{
CSeqInFilter *p = (CSeqInFilter *)pp;
size_t remSize = *size;
size_t sizeOriginal = *size;
if (sizeOriginal == 0)
return S_OK;
*size = 0;
while (remSize > 0)
for (;;)
{
int i;
if (p->convertedPosBegin != p->convertedPosEnd)
if (!p->srcWasFinished && p->curPos == p->endPos)
{
UInt32 sizeTemp = p->convertedPosEnd - p->convertedPosBegin;
if (remSize < sizeTemp)
sizeTemp = (UInt32)remSize;
memmove(data, p->buf + p->convertedPosBegin, sizeTemp);
p->convertedPosBegin += sizeTemp;
data = (void *)((Byte *)data + sizeTemp);
remSize -= sizeTemp;
*size += sizeTemp;
break;
}
for (i = 0; p->convertedPosEnd + i < p->bufferPos; i++)
p->buf[i] = p->buf[i + p->convertedPosEnd];
p->bufferPos = i;
p->convertedPosBegin = p->convertedPosEnd = 0;
{
size_t processedSizeTemp = FILT_BUF_SIZE - p->bufferPos;
RINOK(p->realStream->Read(p->realStream, p->buf + p->bufferPos, &processedSizeTemp));
p->bufferPos = p->bufferPos + (UInt32)processedSizeTemp;
}
p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
if (p->convertedPosEnd == 0)
{
if (p->bufferPos == 0)
break;
else
{
p->convertedPosEnd = p->bufferPos;
continue;
}
}
if (p->convertedPosEnd > p->bufferPos)
{
for (; p->bufferPos < p->convertedPosEnd; p->bufferPos++)
p->buf[p->bufferPos] = 0;
p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
}
}
return SZ_OK;
}
*/
/*
typedef struct
{
ISeqInStream p;
ISeqInStream *realStream;
CMixCoder mixCoder;
Byte buf[FILT_BUF_SIZE];
UInt32 bufPos;
UInt32 bufSize;
} CMixCoderSeqInStream;
static SRes CMixCoderSeqInStream_Read(void *pp, void *data, size_t *size)
{
CMixCoderSeqInStream *p = (CMixCoderSeqInStream *)pp;
SRes res = SZ_OK;
size_t remSize = *size;
*size = 0;
while (remSize > 0)
{
if (p->bufPos == p->bufSize)
{
size_t curSize;
p->bufPos = p->bufSize = 0;
if (*size != 0)
break;
curSize = FILT_BUF_SIZE;
RINOK(p->realStream->Read(p->realStream, p->buf, &curSize));
p->bufSize = (UInt32)curSize;
p->curPos = 0;
p->endPos = FILTER_BUF_SIZE;
RINOK(p->realStream->Read(p->realStream, p->buf, &p->endPos));
if (p->endPos == 0)
p->srcWasFinished = 1;
}
{
SizeT destLen = remSize;
SizeT srcLen = p->bufSize - p->bufPos;
res = MixCoder_Code(&p->mixCoder, data, &destLen, p->buf + p->bufPos, &srcLen, 0);
data = (void *)((Byte *)data + destLen);
remSize -= destLen;
*size += destLen;
p->bufPos += srcLen;
}
}
SizeT srcLen = p->endPos - p->curPos;
int wasFinished;
SRes res;
*size = sizeOriginal;
res = p->StateCoder.Code(p->StateCoder.p, data, size, p->buf + p->curPos, &srcLen,
p->srcWasFinished, CODER_FINISH_ANY, &wasFinished);
p->curPos += srcLen;
if (*size != 0 || srcLen == 0 || res != 0)
return res;
}
}
}
*/
static void SeqInFilter_Construct(CSeqInFilter *p)
{
p->buf = NULL;
p->p.Read = SeqInFilter_Read;
}
static void SeqInFilter_Free(CSeqInFilter *p)
{
if (p->buf)
{
g_Alloc.Free(&g_Alloc, p->buf);
p->buf = NULL;
}
}
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc);
static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
{
if (!p->buf)
{
p->buf = g_Alloc.Alloc(&g_Alloc, FILTER_BUF_SIZE);
if (!p->buf)
return SZ_ERROR_MEM;
}
p->curPos = p->endPos = 0;
p->srcWasFinished = 0;
RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, &g_Alloc));
RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, &g_Alloc));
p->StateCoder.Init(p->StateCoder.p);
return S_OK;
}
/* ---------- CSbEncInStream ---------- */
#ifdef USE_SUBBLOCK
typedef struct
{
ISeqInStream p;
CSubblockEnc sb;
UInt64 processed;
ISeqInStream *inStream;
CSbEnc enc;
} CSbEncInStream;
void SbEncInStream_Init(CSbEncInStream *p)
{
p->processed = 0;
SubblockEnc_Init(&p->sb);
}
static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
{
CSbEncInStream *p = (CSbEncInStream *)pp;
SRes res = SubblockEnc_Read(&p->sb, data, size);
p->processed += *size;
return res;
size_t sizeOriginal = *size;
if (sizeOriginal == 0)
return S_OK;
for (;;)
{
if (p->enc.needRead && !p->enc.readWasFinished)
{
size_t processed = p->enc.needReadSizeMax;
RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed));
p->enc.readPos += processed;
if (processed == 0)
{
p->enc.readWasFinished = True;
p->enc.isFinalFinished = True;
}
p->enc.needRead = False;
}
*size = sizeOriginal;
RINOK(SbEnc_Read(&p->enc, data, size));
if (*size != 0 || !p->enc.needRead)
return S_OK;
}
}
void SbEncInStream_Construct(CSbEncInStream *p, ISzAlloc *alloc)
{
SbEnc_Construct(&p->enc, alloc);
p->p.Read = SbEncInStream_Read;
}
SRes SbEncInStream_Init(CSbEncInStream *p)
{
return SbEnc_Init(&p->enc);
}
void SbEncInStream_Free(CSbEncInStream *p)
{
SbEnc_Free(&p->enc);
}
#endif
typedef struct
{
/* CMixCoderSeqInStream inStream; */
CLzma2EncHandle lzma2;
#ifdef USE_SUBBLOCK
CSbEncInStream sb;
#endif
CSeqInFilter filter;
ISzAlloc *alloc;
ISzAlloc *bigAlloc;
} CLzma2WithFilters;
@@ -361,9 +352,9 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS
p->bigAlloc = bigAlloc;
p->lzma2 = NULL;
#ifdef USE_SUBBLOCK
p->sb.p.Read = SbEncInStream_Read;
SubblockEnc_Construct(&p->sb.sb, p->alloc);
SbEncInStream_Construct(&p->sb, alloc);
#endif
SeqInFilter_Construct(&p->filter);
}
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
@@ -376,8 +367,9 @@ static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
{
SeqInFilter_Free(&p->filter);
#ifdef USE_SUBBLOCK
SubblockEnc_Free(&p->sb.sb);
SbEncInStream_Free(&p->sb);
#endif
if (p->lzma2)
{
@@ -386,17 +378,28 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
}
}
static SRes Xz_Compress(CXzStream *xz,
CLzma2WithFilters *lzmaf,
ISeqOutStream *outStream,
ISeqInStream *inStream,
const CLzma2EncProps *lzma2Props,
Bool useSubblock,
ICompressProgress *progress)
void XzProps_Init(CXzProps *p)
{
xz->flags = XZ_CHECK_CRC32;
p->lzma2Props = 0;
p->filterProps = 0;
p->checkId = XZ_CHECK_CRC32;
}
RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props));
void XzFilterProps_Init(CXzFilterProps *p)
{
p->id = 0;
p->delta = 0;
p->ip= 0;
p->ipDefined = False;
}
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
ISeqOutStream *outStream, ISeqInStream *inStream,
const CXzProps *props, ICompressProgress *progress)
{
xz->flags = (Byte)props->checkId;
RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props));
RINOK(Xz_WriteHeader(xz->flags, outStream));
{
@@ -404,15 +407,27 @@ static SRes Xz_Compress(CXzStream *xz,
CSeqSizeOutStream seqSizeOutStream;
CXzBlock block;
int filterIndex = 0;
CXzFilter *filter = NULL;
const CXzFilterProps *fp = props->filterProps;
XzBlock_ClearFlags(&block);
XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0));
XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0));
if (useSubblock)
if (fp)
{
CXzFilter *f = &block.filters[filterIndex++];
f->id = XZ_ID_Subblock;
f->propsSize = 0;
filter = &block.filters[filterIndex++];
filter->id = fp->id;
filter->propsSize = 0;
if (fp->id == XZ_ID_Delta)
{
filter->props[0] = (Byte)(fp->delta - 1);
filter->propsSize = 1;
}
else if (fp->ipDefined)
{
SetUi32(filter->props, fp->ip);
filter->propsSize = 4;
}
}
{
@@ -432,20 +447,30 @@ static SRes Xz_Compress(CXzStream *xz,
checkInStream.realStream = inStream;
SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));
#ifdef USE_SUBBLOCK
if (useSubblock)
if (fp)
{
lzmaf->sb.sb.inStream = &checkInStream.p;
SubblockEnc_Init(&lzmaf->sb.sb);
#ifdef USE_SUBBLOCK
if (fp->id == XZ_ID_Subblock)
{
lzmaf->sb.inStream = &checkInStream.p;
RINOK(SbEncInStream_Init(&lzmaf->sb));
}
else
#endif
{
lzmaf->filter.realStream = &checkInStream.p;
RINOK(SeqInFilter_Init(&lzmaf->filter, filter));
}
}
{
UInt64 packPos = seqSizeOutStream.processed;
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
fp ?
#ifdef USE_SUBBLOCK
useSubblock ? &lzmaf->sb.p:
(fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
#endif
&lzmaf->filter.p:
&checkInStream.p,
progress);
RINOK(res);
@@ -467,8 +492,7 @@ static SRes Xz_Compress(CXzStream *xz,
}
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
const CLzma2EncProps *lzma2Props, Bool useSubblock,
ICompressProgress *progress)
const CXzProps *props, ICompressProgress *progress)
{
SRes res;
CXzStream xz;
@@ -477,8 +501,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc);
res = Lzma2WithFilters_Create(&lzmaf);
if (res == SZ_OK)
res = Xz_Compress(&xz, &lzmaf, outStream, inStream,
lzma2Props, useSubblock, progress);
res = Xz_Compress(&xz, &lzmaf, outStream, inStream, props, progress);
Lzma2WithFilters_Free(&lzmaf);
Xz_Free(&xz, &g_Alloc);
return res;

View File

@@ -1,5 +1,5 @@
/* XzEnc.h -- Xz Encode
2009-04-15 : Igor Pavlov : Public domain */
2011-02-07 : Igor Pavlov : Public domain */
#ifndef __XZ_ENC_H
#define __XZ_ENC_H
@@ -8,18 +8,32 @@
#include "Xz.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
typedef struct
{
UInt32 id;
UInt32 delta;
UInt32 ip;
int ipDefined;
} CXzFilterProps;
void XzFilterProps_Init(CXzFilterProps *p);
typedef struct
{
const CLzma2EncProps *lzma2Props;
const CXzFilterProps *filterProps;
unsigned checkId;
} CXzProps;
void XzProps_Init(CXzProps *p);
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
const CLzma2EncProps *lzma2Props, Bool useSubblock,
ICompressProgress *progress);
const CXzProps *props, ICompressProgress *progress);
SRes Xz_EncodeEmpty(ISeqOutStream *outStream);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif

View File

@@ -1,5 +1,5 @@
/* XzIn.c - Xz input
2009-06-19 : Igor Pavlov : Public domain */
2011-02-01 : Igor Pavlov : Public domain */
#include <string.h>
@@ -152,29 +152,31 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
{
Int64 i = 0;
UInt32 total = 0;
*startOffset += XZ_STREAM_FOOTER_SIZE;
for (;;)
{
int j;
size_t processedSize;
size_t i;
#define TEMP_BUF_SIZE (1 << 10)
Byte tempBuf[TEMP_BUF_SIZE];
if (*startOffset < XZ_STREAM_FOOTER_SIZE || i > (1 << 16))
if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
return SZ_ERROR_NO_ARCHIVE;
processedSize = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
i += processedSize;
*startOffset = -(Int64)processedSize;
i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
total += (UInt32)i;
*startOffset = -(Int64)i;
RINOK(SeekFromCur(stream, startOffset));
RINOK(LookInStream_Read2(stream, tempBuf, processedSize, SZ_ERROR_NO_ARCHIVE));
for (j = (int)processedSize; j >= 0; j--)
if (tempBuf[j -1] != 0)
RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
for (; i != 0; i--)
if (tempBuf[i - 1] != 0)
break;
if (j != 0)
if (i != 0)
{
if ((j & 3) != 0)
if ((i & 3) != 0)
return SZ_ERROR_NO_ARCHIVE;
*startOffset += j;
*startOffset += i;
break;
}
}
if (*startOffset < XZ_STREAM_FOOTER_SIZE)
return SZ_ERROR_NO_ARCHIVE;
*startOffset -= XZ_STREAM_FOOTER_SIZE;
@@ -182,9 +184,6 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
return SZ_ERROR_NO_ARCHIVE;
break;
}
}
}
p->flags = (CXzStreamFlags)GetBe16(buf + 8);

View File

@@ -3,19 +3,18 @@
#ifndef __7Z_COMPRESSION_MODE_H
#define __7Z_COMPRESSION_MODE_H
#include "../../../Common/MyString.h"
#include "../../../Windows/PropVariant.h"
#include "../../Common/MethodId.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
namespace N7z {
struct CMethodFull: public CMethod
struct CMethodFull: public CProps
{
CMethodId Id;
UInt32 NumInStreams;
UInt32 NumOutStreams;
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
};

View File

@@ -232,7 +232,7 @@ HRESULT CDecoder::Decode(
size_t size = props.GetCapacity();
if (size > 0xFFFFFFFF)
return E_NOTIMPL;
if (size > 0)
// if (size > 0)
{
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));
}

View File

@@ -49,6 +49,15 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindIn
folder.PackStreams.Add(bindInfo.InStreams[i]);
}
static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
{
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
if (setCoderProperties)
return props.SetCoderProps(setCoderProperties, dataSizeReduce);
return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
}
HRESULT CEncoder::CreateMixerCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce)
@@ -86,8 +95,7 @@ HRESULT CEncoder::CreateMixerCoder(
}
#endif
RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));
RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon));
/*
CMyComPtr<ICryptoResetSalt> resetSalt;
@@ -193,11 +201,9 @@ HRESULT CEncoder::Encode(
// UInt64 outStreamStartPos;
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
new CSequentialInStreamSizeCount2;
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
new CSequentialOutStreamSizeCount;
CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
inStreamSizeCountSpec->Init(inStream);
@@ -226,13 +232,11 @@ HRESULT CEncoder::Encode(
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
if (writeCoderProperties != NULL)
{
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init();
writeCoderProperties->WriteCoderProperties(outStream);
size_t size = outStreamSpec->GetSize();
encodingInfo.Props.SetCapacity(size);
memmove(encodingInfo.Props, outStreamSpec->GetBuffer(), size);
outStreamSpec->CopyToBuffer(encodingInfo.Props);
}
}
@@ -250,8 +254,7 @@ HRESULT CEncoder::Encode(
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
folderItem);
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
packSizes.Add(outStreamSizeCountSpec->GetSize());

View File

@@ -2,15 +2,14 @@
#include "StdAfx.h"
#include "7zHandler.h"
#include "7zFolderOutStream.h"
#include "../../../Common/ComTry.h"
#include "../../Common/ProgressUtils.h"
#include "7zDecode.h"
// #include "7z1Decode.h"
#include "../../../Common/ComTry.h"
#include "../../Common/StreamObjects.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h"
#include "7zFolderOutStream.h"
#include "7zHandler.h"
namespace NArchive {
namespace N7z {
@@ -73,13 +72,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
*/
CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
for(UInt32 ii = 0; ii < numItems; ii++)
for (UInt32 ii = 0; ii < numItems; ii++)
{
// UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
UInt32 ref2Index = allFilesMode ? ii : indices[ii];
// const CRef2 &ref2 = _refs[ref2Index];
// for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
// for (UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
{
#ifdef _7Z_VOL
// const CRef &ref = ref2.Refs[ri];
@@ -138,7 +137,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
}
extractCallback->SetTotal(importantTotalUnpacked);
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
CDecoder decoder(
#ifdef _ST_MODE
@@ -149,27 +148,26 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
);
// CDecoder1 decoder;
UInt64 currentTotalPacked = 0;
UInt64 currentTotalUnpacked = 0;
UInt64 totalFolderUnpacked;
UInt64 totalFolderPacked;
UInt64 totalPacked = 0;
UInt64 totalUnpacked = 0;
UInt64 curPacked, curUnpacked;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
currentTotalUnpacked += totalFolderUnpacked,
currentTotalPacked += totalFolderPacked)
for (int i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
{
lps->OutSize = currentTotalUnpacked;
lps->InSize = currentTotalPacked;
lps->OutSize = totalUnpacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
totalFolderUnpacked = efi.UnpackSize;
if (i >= extractFolderInfoVector.Size())
break;
totalFolderPacked = 0;
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
curUnpacked = efi.UnpackSize;
curPacked = 0;
CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
@@ -187,7 +185,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
HRESULT result = folderOutStream->Init(&db,
#ifdef _7Z_VOL
volume.StartRef2Index,
@@ -205,7 +202,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CNum folderIndex = efi.FolderIndex;
const CFolder &folderInfo = db.Folders[folderIndex];
totalFolderPacked = _db.GetFolderFullPackSize(folderIndex);
curPacked = _db.GetFolderFullPackSize(folderIndex);
CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);

View File

@@ -32,7 +32,6 @@ HRESULT CFolderInStream::OpenStream()
_filePos = 0;
while (_fileIndex < _numFiles)
{
_currentSizeIsDefined = false;
CMyComPtr<ISequentialInStream> stream;
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
if (result != S_OK && result != S_FALSE)
@@ -40,26 +39,22 @@ HRESULT CFolderInStream::OpenStream()
_fileIndex++;
_inStreamWithHashSpec->SetStream(stream);
_inStreamWithHashSpec->Init();
if (!stream)
if (stream)
{
_fileIsOpen = true;
CMyComPtr<IStreamGetSize> streamGetSize;
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
if (streamGetSize)
{
RINOK(streamGetSize->GetSize(&_currentSize));
_currentSizeIsDefined = true;
}
return S_OK;
}
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
Sizes.Add(0);
Processed.Add(result == S_OK);
AddDigest();
continue;
}
CMyComPtr<IStreamGetSize> streamGetSize;
if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK)
{
if(streamGetSize)
{
_currentSizeIsDefined = true;
RINOK(streamGetSize->GetSize(&_currentSize));
}
}
_fileIsOpen = true;
return S_OK;
}
return S_OK;
}
@@ -74,6 +69,7 @@ HRESULT CFolderInStream::CloseStream()
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
_inStreamWithHashSpec->ReleaseStream();
_fileIsOpen = false;
_currentSizeIsDefined = false;
Processed.Add(true);
Sizes.Add(_filePos);
AddDigest();
@@ -82,43 +78,40 @@ HRESULT CFolderInStream::CloseStream()
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize = 0;
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
if (processedSize != 0)
*processedSize = 0;
while (size > 0)
{
if (_fileIsOpen)
{
UInt32 localProcessedSize;
RINOK(_inStreamWithHash->Read(
((Byte *)data) + realProcessedSize, size, &localProcessedSize));
if (localProcessedSize == 0)
UInt32 processed2;
RINOK(_inStreamWithHash->Read(data, size, &processed2));
if (processed2 == 0)
{
RINOK(CloseStream());
continue;
}
realProcessedSize += localProcessedSize;
_filePos += localProcessedSize;
size -= localProcessedSize;
if (processedSize != 0)
*processedSize = processed2;
_filePos += processed2;
break;
}
else
{
if (_fileIndex >= _numFiles)
break;
RINOK(OpenStream());
}
}
if (processedSize != 0)
*processedSize = realProcessedSize;
return S_OK;
}
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
int subStreamIndex = (int)subStream;
if (subStreamIndex < 0 || subStream > Sizes.Size())
int index2 = (int)subStream;
if (index2 < 0 || subStream > Sizes.Size())
return E_FAIL;
if (subStreamIndex < Sizes.Size())
if (index2 < Sizes.Size())
{
*value= Sizes[subStreamIndex];
*value = Sizes[index2];
return S_OK;
}
if (!_currentSizeIsDefined)

View File

@@ -1,15 +1,13 @@
// 7z/FolderInStream.h
// 7zFolderInStream.h
#ifndef __7Z_FOLDERINSTREAM_H
#define __7Z_FOLDERINSTREAM_H
#include "7zItem.h"
#include "7zHeader.h"
#ifndef __7Z_FOLDER_IN_STREAM_H
#define __7Z_FOLDER_IN_STREAM_H
#include "../../ICoder.h"
#include "../IArchive.h"
#include "../Common/InStreamWithCRC.h"
#include "../../IStream.h"
#include "../../ICoder.h"
#include "7zItem.h"
namespace NArchive {
namespace N7z {
@@ -19,26 +17,14 @@ class CFolderInStream:
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
CFolderInStream();
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
private:
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
CMyComPtr<ISequentialInStream> _inStreamWithHash;
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
bool _currentSizeIsDefined;
UInt64 _currentSize;
bool _fileIsOpen;
UInt64 _currentSize;
UInt64 _filePos;
const UInt32 *_fileIndices;
UInt32 _numFiles;
UInt32 _fileIndex;
@@ -46,12 +32,18 @@ private:
HRESULT OpenStream();
HRESULT CloseStream();
void AddDigest();
public:
void Init(IArchiveUpdateCallback *updateCallback,
const UInt32 *fileIndices, UInt32 numFiles);
CRecordVector<bool> Processed;
CRecordVector<UInt32> CRCs;
CRecordVector<UInt64> Sizes;
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
CFolderInStream();
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles);
UInt64 GetFullSize() const
{
UInt64 size = 0;

View File

@@ -14,13 +14,13 @@ CFolderOutStream::CFolderOutStream()
}
HRESULT CFolderOutStream::Init(
const CArchiveDatabaseEx *archiveDatabase,
const CArchiveDatabaseEx *db,
UInt32 ref2Offset, UInt32 startIndex,
const CBoolVector *extractStatuses,
IArchiveExtractCallback *extractCallback,
bool testMode, bool checkCrc)
{
_db = archiveDatabase;
_db = db;
_ref2Offset = ref2Offset;
_startIndex = startIndex;
@@ -121,6 +121,15 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
return S_OK;
}
STDMETHODIMP CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
if ((int)subStream >= _extractStatuses->Size())
return S_FALSE;
*value = _db->Files[_startIndex + (int)subStream].Size;
return S_OK;
}
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
{
while (_currentIndex < _extractStatuses->Size())

View File

@@ -3,17 +3,18 @@
#ifndef __7Z_FOLDER_OUT_STREAM_H
#define __7Z_FOLDER_OUT_STREAM_H
#include "7zIn.h"
#include "../../IStream.h"
#include "../IArchive.h"
#include "../Common/OutStreamWithCRC.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
class CFolderOutStream:
public ISequentialOutStream,
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
COutStreamWithCRC *_crcStreamSpec;
@@ -34,14 +35,15 @@ class CFolderOutStream:
HRESULT CloseFileAndSetResult();
HRESULT ProcessEmptyFiles();
public:
MY_UNKNOWN_IMP
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
CFolderOutStream();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
HRESULT Init(
const CArchiveDatabaseEx *archiveDatabase,
const CArchiveDatabaseEx *db,
UInt32 ref2Offset, UInt32 startIndex,
const CBoolVector *extractStatuses,
IArchiveExtractCallback *extractCallback,

View File

@@ -24,25 +24,20 @@
using namespace NWindows;
extern UString ConvertMethodIdToString(UInt64 id);
namespace NArchive {
namespace N7z {
CHandler::CHandler()
{
_crcSize = 4;
#ifndef _NO_CRYPTO
_passwordIsDefined = false;
#endif
#ifdef EXTRACT_ONLY
_crcSize = 4;
#ifdef __7Z_SET_PROPERTIES
_numThreads = NSystem::GetNumberOfProcessors();
#endif
#else
Init();
#endif
}
@@ -70,7 +65,7 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
#else
STATPROPSTG kArcProps[] =
static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidMethod, VT_BSTR},
{ NULL, kpidSolid, VT_BOOL},
@@ -80,6 +75,25 @@ STATPROPSTG kArcProps[] =
{ NULL, kpidOffset, VT_UI8}
};
static inline wchar_t GetHex(Byte value)
{
return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
static UString ConvertMethodIdToString(UInt64 id)
{
wchar_t s[32];
int len = 32;
s[--len] = 0;
do
{
s[--len] = GetHex((Byte)id & 0xF); id >>= 4;
s[--len] = GetHex((Byte)id & 0xF); id >>= 4;
}
while (id != 0);
return s + len;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -172,22 +186,18 @@ static UString GetStringForSizeValue(UInt32 value)
return result;
}
static const UInt64 k_Copy = 0x0;
static const UInt64 k_Delta = 3;
static const UInt64 k_LZMA2 = 0x21;
static const UInt64 k_LZMA = 0x030101;
static const UInt64 k_PPMD = 0x030401;
static wchar_t GetHex(Byte value)
{
return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
}
static inline void AddHexToString(UString &res, Byte value)
{
res += GetHex((Byte)(value >> 4));
res += GetHex((Byte)(value & 0xF));
}
static void AddProp32(UString &s, const wchar_t *name, UInt32 v)
{
s += name;
s += ConvertUInt32ToString(v);
}
#endif
bool CHandler::IsEncrypted(UInt32 index2) const
@@ -283,6 +293,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
{
UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
propsString = GetStringForSizeValue(dicSize);
UInt32 d = coder.Props[0];
UInt32 lc = d % 9;
d /= 9;
UInt32 pb = d / 5;
UInt32 lp = d % 5;
if (lc != 3) AddProp32(propsString, L":lc", lc);
if (lp != 0) AddProp32(propsString, L":lp", lp);
if (pb != 2) AddProp32(propsString, L":pb", pb);
}
else if (coder.MethodID == k_LZMA2 && coder.Props.GetCapacity() == 1)
{

View File

@@ -18,6 +18,16 @@
namespace NArchive {
namespace N7z {
const UInt32 k_Copy = 0x0;
const UInt32 k_Delta = 3;
const UInt32 k_LZMA2 = 0x21;
const UInt32 k_LZMA = 0x030101;
const UInt32 k_PPMD = 0x030401;
const UInt32 k_BCJ = 0x03030103;
const UInt32 k_BCJ2 = 0x0303011B;
const UInt32 k_Deflate = 0x040108;
const UInt32 k_BZip2 = 0x040202;
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
@@ -31,9 +41,52 @@ namespace N7z {
#endif
#ifndef EXTRACT_ONLY
class COutHandler: public CMultiMethodProps
{
HRESULT SetSolidFromString(const UString &s);
HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
public:
bool _removeSfxBlock;
UInt64 _numSolidFiles;
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
bool _solidExtension;
bool _compressHeaders;
bool _encryptHeadersSpecified;
bool _encryptHeaders;
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
bool _volumeMode;
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
void InitSolid()
{
InitSolidFiles();
InitSolidSize();
_solidExtension = false;
_numSolidBytesDefined = false;
}
void InitProps();
COutHandler() { InitProps(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
#endif
class CHandler:
#ifndef EXTRACT_ONLY
public NArchive::COutHandler,
public COutHandler,
#endif
public IInArchive,
#ifdef __7Z_SET_PROPERTIES
@@ -90,16 +143,16 @@ private:
CRecordVector<CBind> _binds;
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
void AddDefaultMethod();
HRESULT SetMainMethod(CCompressionMethodMode &method,
CObjectVector<COneMethodInfo> &methodsInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
HRESULT SetCompressionMethod(
CCompressionMethodMode &method,
CCompressionMethodMode &headerMethod);
#endif

View File

@@ -2,13 +2,9 @@
#include "StdAfx.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Common/ComTry.h"
#include "../../../Common/StringToInt.h"
#include "../../ICoder.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"
@@ -21,24 +17,19 @@ using namespace NWindows;
namespace NArchive {
namespace N7z {
static const wchar_t *kLZMAMethodName = L"LZMA";
static const wchar_t *kCopyMethod = L"Copy";
static const wchar_t *kDefaultMethodName = kLZMAMethodName;
static const wchar_t *k_LZMA_Name = L"LZMA";
static const wchar_t *kDefaultMethodName = k_LZMA_Name;
static const wchar_t *k_Copy_Name = L"Copy";
static const UInt32 kLzmaAlgorithmX5 = 1;
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
static const UInt32 kDictionaryForHeaders =
static const wchar_t *k_MatchFinder_ForHeaders = L"BT2";
static const UInt32 k_NumFastBytes_ForHeaders = 273;
static const UInt32 k_Level_ForHeaders = 5;
static const UInt32 k_Dictionary_ForHeaders =
#ifdef UNDER_CE
1 << 18
1 << 18;
#else
1 << 20
1 << 20;
#endif
;
static const UInt32 kNumFastBytesForHeaders = 273;
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
static inline bool IsCopyMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kCopyMethod) == 0); }
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
@@ -46,123 +37,105 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
return S_OK;
}
HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode,
CCompressionMethodMode &headerMethod)
HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{
HRESULT res = SetCompressionMethod(methodMode, _methods
#ifndef _7ZIP_ST
, _numThreads
#endif
);
RINOK(res);
methodMode.Binds = _binds;
if (_compressHeaders)
{
// headerMethod.Methods.Add(methodMode.Methods.Back());
CObjectVector<COneMethodInfo> headerMethodInfoVector;
COneMethodInfo oneMethodInfo;
oneMethodInfo.MethodName = kLZMAMethodName;
{
CProp prop;
prop.Id = NCoderPropID::kMatchFinder;
prop.Value = kLzmaMatchFinderForHeaders;
oneMethodInfo.Props.Add(prop);
}
{
CProp prop;
prop.Id = NCoderPropID::kAlgorithm;
prop.Value = kAlgorithmForHeaders;
oneMethodInfo.Props.Add(prop);
}
{
CProp prop;
prop.Id = NCoderPropID::kNumFastBytes;
prop.Value = (UInt32)kNumFastBytesForHeaders;
oneMethodInfo.Props.Add(prop);
}
{
CProp prop;
prop.Id = NCoderPropID::kDictionarySize;
prop.Value = (UInt32)kDictionaryForHeaders;
oneMethodInfo.Props.Add(prop);
}
headerMethodInfoVector.Add(oneMethodInfo);
HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
#ifndef _7ZIP_ST
, 1
#endif
);
RINOK(res);
}
if (!FindMethod(
EXTERNAL_CODECS_VARS
m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
return E_INVALIDARG;
(CProps &)dest = (CProps &)m;
return S_OK;
}
HRESULT CHandler::SetCompressionMethod(
HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
{
if (!_compressHeaders)
return S_OK;
COneMethodInfo m;
m.MethodName = k_LZMA_Name;
m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
m.AddNumThreadsProp(1);
CMethodFull methodFull;
RINOK(PropsMethod_To_FullMethod(methodFull, m));
headerMethod.Methods.Add(methodFull);
return S_OK;
}
void CHandler::AddDefaultMethod()
{
for (int i = 0; i < _methods.Size(); i++)
{
UString &methodName = _methods[0].MethodName;
if (methodName.IsEmpty())
methodName = kDefaultMethodName;
}
if (_methods.IsEmpty())
{
COneMethodInfo m;
m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
_methods.Add(m);
}
}
HRESULT CHandler::SetMainMethod(
CCompressionMethodMode &methodMode,
CObjectVector<COneMethodInfo> &methodsInfo
CObjectVector<COneMethodInfo> &methods
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
UInt32 level = _level;
AddDefaultMethod();
if (methodsInfo.IsEmpty())
{
COneMethodInfo oneMethodInfo;
oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
methodsInfo.Add(oneMethodInfo);
}
const UInt64 kSolidBytes_Min = (1 << 24);
const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
bool needSolid = false;
for(int i = 0; i < methodsInfo.Size(); i++)
for (int i = 0; i < methods.Size(); i++)
{
COneMethodInfo &oneMethodInfo = methodsInfo[i];
SetCompressionMethod2(oneMethodInfo
COneMethodInfo &oneMethodInfo = methods[i];
SetGlobalLevelAndThreads(oneMethodInfo
#ifndef _7ZIP_ST
, numThreads
#endif
);
if (!IsCopyMethod(oneMethodInfo.MethodName))
needSolid = true;
CMethodFull methodFull;
if (!FindMethod(
EXTERNAL_CODECS_VARS
oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams))
return E_INVALIDARG;
methodFull.Props = oneMethodInfo.Props;
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
methodMode.Methods.Add(methodFull);
if (!_numSolidBytesDefined)
if (methodFull.Id != k_Copy)
needSolid = true;
if (_numSolidBytesDefined)
continue;
UInt32 dicSize;
switch (methodFull.Id)
{
for (int j = 0; j < methodFull.Props.Size(); j++)
{
const CProp &prop = methodFull.Props[j];
if ((prop.Id == NCoderPropID::kDictionarySize ||
prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
{
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
const UInt64 kMinSize = (1 << 24);
if (_numSolidBytes < kMinSize)
_numSolidBytes = kMinSize;
case k_LZMA:
case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
case k_Deflate: dicSize = (UInt32)1 << 15; break;
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
default: continue;
}
_numSolidBytes = (UInt64)dicSize << 7;
if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
_numSolidBytesDefined = true;
break;
}
}
}
}
if (!needSolid && !_numSolidBytesDefined)
{
_numSolidBytesDefined = true;
if (!_numSolidBytesDefined)
if (needSolid)
_numSolidBytes = kSolidBytes_Max;
else
_numSolidBytes = 0;
}
_numSolidBytesDefined = true;
return S_OK;
}
@@ -326,7 +299,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
CCompressionMethodMode methodMode, headerMethod;
RINOK(SetCompressionMethod(methodMode, headerMethod));
HRESULT res = SetMainMethod(methodMode, _methods
#ifndef _7ZIP_ST
, _numThreads
#endif
);
RINOK(res);
methodMode.Binds = _binds;
RINOK(SetHeaderMethod(headerMethod));
#ifndef _7ZIP_ST
methodMode.NumThreads = _numThreads;
headerMethod.NumThreads = 1;
@@ -373,8 +355,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CUpdateOptions options;
options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
options.UseFilters = _level != 0 && _autoFilter;
options.MaxFilter = _level >= 8;
int level = GetLevel();
options.UseFilters = level != 0 && _autoFilter;
options.MaxFilter = level >= 8;
options.HeaderOptions.CompressMainHeader = compressMainHeader;
options.HeaderOptions.WriteCTime = WriteCTime;
@@ -393,7 +376,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CMyComPtr<ICryptoGetTextPassword> getPassword;
updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
HRESULT res = Update(
res = Update(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
volume ? volume->Stream: 0,
@@ -437,25 +420,138 @@ static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream
return S_OK;
}
static HRESULT GetBindInfo(UString &srcString, CBind &bind)
void COutHandler::InitProps()
{
RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
if (srcString[0] != ':')
CMultiMethodProps::Init();
_removeSfxBlock = false;
_compressHeaders = true;
_encryptHeadersSpecified = false;
_encryptHeaders = false;
WriteCTime = false;
WriteATime = false;
WriteMTime = true;
_volumeMode = false;
InitSolid();
}
HRESULT COutHandler::SetSolidFromString(const UString &s)
{
UString s2 = s;
s2.MakeUpper();
for (int i = 0; i < s2.Length();)
{
const wchar_t *start = ((const wchar_t *)s2) + i;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(start, &end);
if (start == end)
{
if (s2[i++] != 'E')
return E_INVALIDARG;
srcString.Delete(0);
RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
if (!srcString.IsEmpty())
_solidExtension = true;
continue;
}
i += (int)(end - start);
if (i == s2.Length())
return E_INVALIDARG;
wchar_t c = s2[i++];
if (c == 'F')
{
if (v < 1)
v = 1;
_numSolidFiles = v;
}
else
{
unsigned numBits;
switch (c)
{
case 'B': numBits = 0; break;
case 'K': numBits = 10; break;
case 'M': numBits = 20; break;
case 'G': numBits = 30; break;
default: return E_INVALIDARG;
}
_numSolidBytes = (v << numBits);
_numSolidBytesDefined = true;
}
}
return S_OK;
}
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
{
bool isSolid;
switch (value.vt)
{
case VT_EMPTY: isSolid = true; break;
case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
case VT_BSTR:
if (StringToBool(value.bstrVal, isSolid))
break;
return SetSolidFromString(value.bstrVal);
default: return E_INVALIDARG;
}
if (isSolid)
InitSolid();
else
_numSolidFiles = 1;
return S_OK;
}
HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
if (name[0] == L'S')
{
name.Delete(0);
if (name.IsEmpty())
return SetSolidFromPROPVARIANT(value);
if (value.vt != VT_EMPTY)
return E_INVALIDARG;
return SetSolidFromString(name);
}
UInt32 number;
int index = ParseStringToUInt32(name, number);
UString realName = name.Mid(index);
if (index == 0)
{
if (name.CompareNoCase(L"RSFX") == 0) return PROPVARIANT_to_bool(value, _removeSfxBlock);
if (name.CompareNoCase(L"HC") == 0) return PROPVARIANT_to_bool(value, _compressHeaders);
if (name.CompareNoCase(L"HCF") == 0)
{
bool compressHeadersFull = true;
RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
return compressHeadersFull ? S_OK: E_INVALIDARG;
}
if (name.CompareNoCase(L"HE") == 0)
{
RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
_encryptHeadersSpecified = true;
return S_OK;
}
if (name.CompareNoCase(L"TC") == 0) return PROPVARIANT_to_bool(value, WriteCTime);
if (name.CompareNoCase(L"TA") == 0) return PROPVARIANT_to_bool(value, WriteATime);
if (name.CompareNoCase(L"TM") == 0) return PROPVARIANT_to_bool(value, WriteMTime);
if (name.CompareNoCase(L"V") == 0) return PROPVARIANT_to_bool(value, _volumeMode);
}
return CMultiMethodProps::SetProperty(name, value);
}
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
COM_TRY_BEGIN
_binds.Clear();
BeforeSetProperty();
InitProps();
for (int i = 0; i < numProperties; i++)
for (int i = 0; i < numProps; i++)
{
UString name = names[i];
name.MakeUpper();
@@ -466,9 +562,17 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
if (name[0] == 'B')
{
if (value.vt != VT_EMPTY)
return E_INVALIDARG;
name.Delete(0);
CBind bind;
RINOK(GetBindInfo(name, bind));
RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
if (name[0] != ':')
return E_INVALIDARG;
name.Delete(0);
RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream));
if (!name.IsEmpty())
return E_INVALIDARG;
_binds.Add(bind);
continue;
}
@@ -476,6 +580,47 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
RINOK(SetProperty(name, value));
}
int numEmptyMethods = GetNumEmptyMethods();
if (numEmptyMethods > 0)
{
int k;
for (k = 0; k < _binds.Size(); k++)
{
const CBind &bind = _binds[k];
if (bind.InCoder < (UInt32)numEmptyMethods ||
bind.OutCoder < (UInt32)numEmptyMethods)
return E_INVALIDARG;
}
for (k = 0; k < _binds.Size(); k++)
{
CBind &bind = _binds[k];
bind.InCoder -= (UInt32)numEmptyMethods;
bind.OutCoder -= (UInt32)numEmptyMethods;
}
_methods.Delete(0, numEmptyMethods);
}
AddDefaultMethod();
if (!_filterMethod.MethodName.IsEmpty())
{
for (int k = 0; k < _binds.Size(); k++)
{
CBind &bind = _binds[k];
bind.InCoder++;
bind.OutCoder++;
}
_methods.Insert(0, _filterMethod);
}
for (int k = 0; k < _binds.Size(); k++)
{
const CBind &bind = _binds[k];
if (bind.InCoder >= (UInt32)_methods.Size() ||
bind.OutCoder >= (UInt32)_methods.Size())
return E_INVALIDARG;
}
return S_OK;
COM_TRY_END
}

View File

@@ -120,7 +120,7 @@ public:
kUnsupportedVersion = 0,
kUnsupported,
kIncorrect,
kEndOfData,
kEndOfData
} Cause;
CInArchiveException(CCauseType cause): Cause(cause) {};
};
@@ -280,50 +280,60 @@ void CInByte2::ReadString(UString &s)
_pos += rem + 2;
}
static inline bool TestSignatureCandidate(const Byte *p)
static inline bool TestSignature(const Byte *p)
{
for (int i = 0; i < kSignatureSize; i++)
if (p[i] != kSignature[i])
return false;
return (p[0x1A] == 0 && p[0x1B] == 0);
return CrcCalc(p + 12, 20) == GetUi32(p + 8);
}
#ifdef FORMAT_7Z_RECOVERY
static inline bool TestSignature2(const Byte *p)
{
int i;
for (i = 0; i < kSignatureSize; i++)
if (p[i] != kSignature[i])
return false;
if (CrcCalc(p + 12, 20) == GetUi32(p + 8))
return true;
for (i = 8; i < kHeaderSize; i++)
if (p[i] != 0)
return false;
return (p[6] != 0 || p[7] != 0);
}
#else
#define TestSignature2(p) TestSignature(p)
#endif
HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));
if (TestSignatureCandidate(_header))
if (TestSignature2(_header))
return S_OK;
CByteBuffer byteBuffer;
const UInt32 kBufferSize = (1 << 16);
byteBuffer.SetCapacity(kBufferSize);
Byte *buffer = byteBuffer;
UInt32 numPrevBytes = kHeaderSize - 1;
memcpy(buffer, _header + 1, numPrevBytes);
UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
memcpy(buffer, _header, kHeaderSize);
UInt64 curTestPos = _arhiveBeginStreamPosition;
for (;;)
{
if (searchHeaderSizeLimit != NULL)
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
break;
do
{
UInt32 numReadBytes = kBufferSize - numPrevBytes;
UInt32 processedSize;
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
numPrevBytes += processedSize;
RINOK(stream->Read(buffer + kHeaderSize, kBufferSize - kHeaderSize, &processedSize));
if (processedSize == 0)
return S_FALSE;
}
while (numPrevBytes < kHeaderSize);
UInt32 numTests = numPrevBytes - kHeaderSize + 1;
for (UInt32 pos = 0; pos < numTests; pos++)
for (UInt32 pos = 1; pos <= processedSize; pos++)
{
for (; buffer[pos] != '7' && pos < numTests; pos++);
if (pos == numTests)
for (; buffer[pos] != '7' && pos <= processedSize; pos++);
if (pos > processedSize)
break;
if (TestSignatureCandidate(buffer + pos))
if (TestSignature(buffer + pos))
{
memcpy(_header, buffer + pos, kHeaderSize);
curTestPos += pos;
@@ -331,9 +341,8 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
}
}
curTestPos += numTests;
numPrevBytes -= numTests;
memmove(buffer, buffer + numTests, numPrevBytes);
curTestPos += processedSize;
memmove(buffer, buffer + processedSize, kHeaderSize);
}
return S_FALSE;
}
@@ -344,6 +353,8 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
HeadersSize = 0;
Close();
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition))
RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
_stream = stream;
return S_OK;
@@ -812,7 +823,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
ThrowUnsupported();
data.SetCapacity(unpackSize);
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unpackSize);
@@ -1164,23 +1175,26 @@ HRESULT CInArchive::ReadDatabase2(
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
}
else
#endif
#ifdef FORMAT_7Z_RECOVERY
crcFromArchive = crc;
#endif
db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
{
if (crc != crcFromArchive)
ThrowIncorrect();
}
db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
if (nextHeaderSize == 0)
return S_OK;
if (nextHeaderSize > (UInt64)0xFFFFFFFF)
if (nextHeaderSize > (UInt64)(UInt32)0xFFFFFFFF)
return S_FALSE;
if ((Int64)nextHeaderOffset < 0)
return S_FALSE;
if (db.ArchiveInfo.StartPositionAfterHeader + nextHeaderOffset > _fileEndPosition)
return S_FALSE;
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
CByteBuffer buffer2;

View File

@@ -133,6 +133,7 @@ class CInArchive
CInByte2 *_inByteBack;
UInt64 _arhiveBeginStreamPosition;
UInt64 _fileEndPosition;
Byte _header[kHeaderSize];

View File

@@ -19,32 +19,33 @@ struct CPropMap
CPropMap kPropMap[] =
{
{ NID::kName, NULL, kpidPath, VT_BSTR},
{ NID::kSize, NULL, kpidSize, VT_UI8},
{ NID::kPackInfo, NULL, kpidPackSize, VT_UI8},
{ NID::kName, { NULL, kpidPath, VT_BSTR } },
{ NID::kSize, { NULL, kpidSize, VT_UI8 } },
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
#ifdef _MULTI_PACK
{ 100, L"Pack0", kpidPackedSize0, VT_UI8},
{ 101, L"Pack1", kpidPackedSize1, VT_UI8},
{ 102, L"Pack2", kpidPackedSize2, VT_UI8},
{ 103, L"Pack3", kpidPackedSize3, VT_UI8},
{ 104, L"Pack4", kpidPackedSize4, VT_UI8},
{ 100, { L"Pack0", kpidPackedSize0, VT_UI8 } },
{ 101, { L"Pack1", kpidPackedSize1, VT_UI8 } },
{ 102, { L"Pack2", kpidPackedSize2, VT_UI8 } },
{ 103, { L"Pack3", kpidPackedSize3, VT_UI8 } },
{ 104, { L"Pack4", kpidPackedSize4, VT_UI8 } },
#endif
{ NID::kCTime, NULL, kpidCTime, VT_FILETIME},
{ NID::kMTime, NULL, kpidMTime, VT_FILETIME},
{ NID::kATime, NULL, kpidATime, VT_FILETIME},
{ NID::kWinAttributes, NULL, kpidAttrib, VT_UI4},
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
{ NID::kWinAttributes, { NULL, kpidAttrib, VT_UI4 } },
{ NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
{ NID::kAnti, NULL, kpidIsAnti, 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}
,
{ 97, { NULL,kpidEncrypted, VT_BOOL } },
{ 98, { NULL,kpidMethod, VT_BSTR } },
{ 99, { NULL,kpidBlock, VT_UI4 } }
#endif
};

View File

@@ -24,15 +24,6 @@
namespace NArchive {
namespace N7z {
static const UInt64 k_LZMA = 0x030101;
static const UInt64 k_BCJ = 0x03030103;
static const UInt64 k_BCJ2 = 0x0303011B;
static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
#ifdef MY_CPU_X86_OR_AMD64
#define USE_86_FILTER
#endif
@@ -339,84 +330,74 @@ static bool IsExeExt(const UString &ext)
return false;
}
#ifdef USE_86_FILTER
static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult)
static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &m)
{
methodResult.Id = methodID;
methodResult.NumInStreams = numInStreams;
methodResult.NumOutStreams = 1;
m.Id = methodID;
m.NumInStreams = numInStreams;
m.NumOutStreams = 1;
}
static void MakeExeMethod(const CCompressionMethodMode &method,
bool bcj2Filter, CCompressionMethodMode &exeMethod)
static void AddBcj2Methods(CCompressionMethodMode &mode)
{
exeMethod = method;
if (bcj2Filter)
{
CMethodFull methodFull;
GetMethodFull(k_BCJ2, 4, methodFull);
exeMethod.Methods.Insert(0, methodFull);
GetMethodFull(k_LZMA, 1, methodFull);
{
CProp prop;
prop.Id = NCoderPropID::kAlgorithm;
prop.Value = kAlgorithmForBCJ2_LZMA;
methodFull.Props.Add(prop);
}
{
CProp prop;
prop.Id = NCoderPropID::kMatchFinder;
prop.Value = kMatchFinderForBCJ2_LZMA;
methodFull.Props.Add(prop);
}
{
CProp prop;
prop.Id = NCoderPropID::kDictionarySize;
prop.Value = kDictionaryForBCJ2_LZMA;
methodFull.Props.Add(prop);
}
{
CProp prop;
prop.Id = NCoderPropID::kNumFastBytes;
prop.Value = kNumFastBytesForBCJ2_LZMA;
methodFull.Props.Add(prop);
}
CMethodFull m;
GetMethodFull(k_LZMA, 1, m);
m.AddProp32(NCoderPropID::kDictionarySize, 1 << 20);
m.AddProp32(NCoderPropID::kNumFastBytes, 128);
m.AddProp32(NCoderPropID::kNumThreads, 1);
m.AddProp32(NCoderPropID::kLitPosBits, 2);
m.AddProp32(NCoderPropID::kLitContextBits, 0);
// m.AddPropString(NCoderPropID::kMatchFinder, L"BT2");
mode.Methods.Add(m);
mode.Methods.Add(m);
exeMethod.Methods.Add(methodFull);
exeMethod.Methods.Add(methodFull);
CBind bind;
bind.OutCoder = 0;
bind.InStream = 0;
bind.InCoder = 1; bind.OutStream = 0; mode.Binds.Add(bind);
bind.InCoder = 2; bind.OutStream = 1; mode.Binds.Add(bind);
bind.InCoder = 3; bind.OutStream = 2; mode.Binds.Add(bind);
}
bind.InCoder = 1;
bind.OutStream = 0;
exeMethod.Binds.Add(bind);
bind.InCoder = 2;
bind.OutStream = 1;
exeMethod.Binds.Add(bind);
bind.InCoder = 3;
bind.OutStream = 2;
exeMethod.Binds.Add(bind);
static void MakeExeMethod(CCompressionMethodMode &mode,
bool useFilters, bool addFilter, bool bcj2Filter)
{
if (!mode.Binds.IsEmpty() || !useFilters || mode.Methods.Size() > 2)
return;
if (mode.Methods.Size() == 2)
{
if (mode.Methods[0].Id == k_BCJ2)
AddBcj2Methods(mode);
return;
}
if (!addFilter)
return;
bcj2Filter = bcj2Filter;
#ifdef USE_86_FILTER
if (bcj2Filter)
{
CMethodFull m;
GetMethodFull(k_BCJ2, 4, m);
mode.Methods.Insert(0, m);
AddBcj2Methods(mode);
}
else
{
CMethodFull methodFull;
GetMethodFull(k_BCJ, 1, methodFull);
exeMethod.Methods.Insert(0, methodFull);
CMethodFull m;
GetMethodFull(k_BCJ, 1, m);
mode.Methods.Insert(0, m);
CBind bind;
bind.OutCoder = 0;
bind.InStream = 0;
bind.InCoder = 1;
bind.OutStream = 0;
exeMethod.Binds.Add(bind);
mode.Binds.Add(bind);
}
#endif
}
#endif
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
CFileItem &file, CFileItem2 &file2)
@@ -595,6 +576,7 @@ public:
Fos = FosSpec;
Result = E_FAIL;
}
~CThreadDecoder() { CVirtThread::WaitThreadFinish(); }
virtual void Execute();
};
@@ -663,9 +645,7 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)
static const int kNumGroupsMax = 4;
#ifdef USE_86_FILTER
static bool Is86Group(int group) { return (group & 1) != 0; }
#endif
static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
static int GetGroupIndex(bool encrypted, int bcjFiltered)
{ return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
@@ -783,16 +763,15 @@ HRESULT Update(
if (inSizeForReduce2 > inSizeForReduce)
inSizeForReduce = inSizeForReduce2;
const UInt32 kMinReduceSize = (1 << 16);
if (inSizeForReduce < kMinReduceSize)
inSizeForReduce = kMinReduceSize;
RINOK(updateCallback->SetTotal(complexity));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
CStreamBinder sb;
RINOK(sb.CreateEvents());
CThreadDecoder threadDecoder;
if (!folderRefs.IsEmpty())
{
@@ -864,13 +843,8 @@ HRESULT Update(
{
const CSolidGroup &group = groups[groupIndex];
CCompressionMethodMode method;
#ifdef USE_86_FILTER
if (Is86Group(groupIndex))
MakeExeMethod(*options.Method, options.MaxFilter, method);
else
#endif
method = *options.Method;
CCompressionMethodMode method = *options.Method;
MakeExeMethod(method, options.UseFilters, Is86Group(groupIndex), options.MaxFilter);
if (IsEncryptedGroup(groupIndex))
{
@@ -917,11 +891,6 @@ HRESULT Update(
}
else
{
CStreamBinder sb;
RINOK(sb.CreateEvents());
CMyComPtr<ISequentialOutStream> sbOutStream;
CMyComPtr<ISequentialInStream> sbInStream;
sb.CreateStreams(&sbInStream, &sbOutStream);
CBoolVector extractStatuses;
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
@@ -940,8 +909,16 @@ HRESULT Update(
extractStatuses.Add(needExtract);
}
int startPackIndex = newDatabase.PackSizes.Size();
CFolder newFolder;
{
CMyComPtr<ISequentialInStream> sbInStream;
{
CMyComPtr<ISequentialOutStream> sbOutStream;
sb.CreateStreams(&sbInStream, &sbOutStream);
sb.ReInit();
RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));
sbOutStream.Release();
}
threadDecoder.InStream = inStream;
threadDecoder.Folder = &db->Folders[folderIndex];
@@ -950,14 +927,13 @@ HRESULT Update(
threadDecoder.Start();
int startPackIndex = newDatabase.PackSizes.Size();
CFolder newFolder;
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
sbInStream, NULL, &inSizeForReduce, newFolder,
archive.SeqStream, newDatabase.PackSizes, progress));
threadDecoder.WaitFinish();
threadDecoder.WaitExecuteFinish();
}
RINOK(threadDecoder.Result);
@@ -1128,6 +1104,8 @@ HRESULT Update(
if (folderRefIndex != folderRefs.Size())
return E_FAIL;
RINOK(lps->SetCur());
/*
folderRefs.ClearAndFree();
fileIndexToUpdateIndexMap.ClearAndFree();

View File

@@ -85,6 +85,7 @@ STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
if (formatIndex >= g_NumArcs)
return E_INVALIDARG;
const CArcInfo &arc = *g_Arcs[formatIndex];
@@ -119,6 +120,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)

View File

@@ -264,7 +264,7 @@ struct CInArchiveException
{
kUnexpectedEndOfArchive = 0,
kCRCError,
kIncorrectArchive,
kIncorrectArchive
}
Cause;
CInArchiveException(CCauseType cause): Cause(cause) {};

View File

@@ -4,13 +4,6 @@
#include "Common/ComTry.h"
#include "Windows/PropVariant.h"
#ifndef _7ZIP_ST
#include "../../Windows/System.h"
#endif
#include "../Common/CreateCoder.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
@@ -20,21 +13,13 @@
#include "../Compress/CopyCoder.h"
#include "Common/DummyOutStream.h"
#include "Common/ParseProperties.h"
#include "Common/HandlerOut.h"
using namespace NWindows;
namespace NArchive {
namespace NBz2 {
static const UInt32 kNumPassesX1 = 1;
static const UInt32 kNumPassesX7 = 2;
static const UInt32 kNumPassesX9 = 7;
static const UInt32 kDicSizeX1 = 100000;
static const UInt32 kDicSizeX3 = 500000;
static const UInt32 kDicSizeX5 = 900000;
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
@@ -48,22 +33,7 @@ class CHandler:
UInt64 _startPosition;
bool _packSizeDefined;
UInt32 _level;
UInt32 _dicSize;
UInt32 _numPasses;
#ifndef _7ZIP_ST
UInt32 _numThreads;
#endif
void InitMethodProperties()
{
_level = 5;
_dicSize =
_numPasses = 0xFFFFFFFF;
#ifndef _7ZIP_ST
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
#endif
}
CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
@@ -73,10 +43,10 @@ public:
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
CHandler() { InitMethodProperties(); }
CHandler() { }
};
STATPROPSTG kProps[] =
static const STATPROPSTG kProps[] =
{
{ NULL, kpidPackSize, VT_UI8}
};
@@ -87,7 +57,7 @@ IMP_IInArchive_ArcProps_NO_Table
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch(propID)
switch (propID)
{
case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
}
@@ -104,7 +74,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NWindows::NCOM::CPropVariant prop;
switch(propID)
switch (propID)
{
case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
}
@@ -188,7 +158,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
decoderSpec->SetInStream(_seqStream);
#ifndef _7ZIP_ST
RINOK(decoderSpec->SetNumberOfThreads(_numThreads));
RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads));
#endif
CDummyOutStream *outStreamSpec = new CDummyOutStream;
@@ -246,50 +216,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
static HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
int indexInClient,
UInt32 dictionary,
UInt32 numPasses,
#ifndef _7ZIP_ST
UInt32 numThreads,
#endif
const CProps &props,
IArchiveUpdateCallback *updateCallback)
{
RINOK(updateCallback->SetTotal(unpackSize));
UInt64 complexity = 0;
RINOK(updateCallback->SetCompleted(&complexity));
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(indexInClient, &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;
{
NWindows::NCOM::CPropVariant properties[] =
{
dictionary,
numPasses
#ifndef _7ZIP_ST
, numThreads
#endif
};
PROPID propIDs[] =
{
NCoderPropID::kDictionarySize,
NCoderPropID::kNumPasses
#ifndef _7ZIP_ST
, NCoderPropID::kNumThreads
#endif
};
RINOK(encoderSpec->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
}
RINOK(props.SetCoderProps(encoderSpec, NULL));
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
@@ -336,25 +275,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
UInt32 dicSize = _dicSize;
if (dicSize == 0xFFFFFFFF)
dicSize = (_level >= 5 ? kDicSizeX5 :
(_level >= 3 ? kDicSizeX3 :
kDicSizeX1));
UInt32 numPasses = _numPasses;
if (numPasses == 0xFFFFFFFF)
numPasses = (_level >= 9 ? kNumPassesX9 :
(_level >= 7 ? kNumPassesX7 :
kNumPassesX1));
return UpdateArchive(
size, outStream, 0, dicSize, numPasses,
#ifndef _7ZIP_ST
_numThreads,
#endif
updateCallback);
return UpdateArchive(size, outStream, _props, updateCallback);
}
if (indexInArchive != 0)
return E_INVALIDARG;
@@ -365,47 +286,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
InitMethodProperties();
#ifndef _7ZIP_ST
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
#endif
for (int i = 0; i < numProps; i++)
{
UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &prop = values[i];
if (name[0] == L'X')
{
UInt32 level = 9;
RINOK(ParsePropValue(name.Mid(1), prop, level));
_level = level;
}
else if (name[0] == L'D')
{
UInt32 dicSize = kDicSizeX5;
RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
_dicSize = dicSize;
}
else if (name.Left(4) == L"PASS")
{
UInt32 num = kNumPassesX9;
RINOK(ParsePropValue(name.Mid(4), prop, num));
_numPasses = num;
}
else if (name.Left(2) == L"MT")
{
#ifndef _7ZIP_ST
RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
#endif
}
else
return E_INVALIDARG;
}
return S_OK;
return _props.SetProperties(names, values, numProps);
}
static IInArchive *CreateArc() { return new CHandler; }

View File

@@ -2,9 +2,9 @@
#include "StdAfx.h"
#include "Common/Buffer.h"
#include "../../../../C/Alloc.h"
#include "Common/ComTry.h"
#include "Common/Defs.h"
#include "Common/IntToString.h"
#include "Common/StringConvert.h"
#include "Common/UTFConvert.h"
@@ -32,8 +32,6 @@ namespace NCab {
// #define _CAB_DETAILS
static const UInt32 kMaxTempBufSize = 1 << 20;
#ifdef _CAB_DETAILS
enum
{
@@ -41,7 +39,7 @@ enum
};
#endif
STATPROPSTG kProps[] =
static STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidSize, VT_UI8},
@@ -57,18 +55,18 @@ STATPROPSTG kProps[] =
#endif
};
static const wchar_t *kMethods[] =
static const char *kMethods[] =
{
L"None",
L"MSZip",
L"Quantum",
L"LZX"
"None",
"MSZip",
"Quantum",
"LZX"
};
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
static const wchar_t *kUnknownMethod = L"Unknown";
static const char *kUnknownMethod = "Unknown";
STATPROPSTG kArcProps[] =
static STATPROPSTG kArcProps[] =
{
{ NULL, kpidMethod, VT_BSTR},
// { NULL, kpidSolid, VT_BOOL},
@@ -87,7 +85,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
case kpidMethod:
{
UString resString;
AString resString;
CRecordVector<Byte> ids;
int i;
for (int v = 0; v < m_Database.Volumes.Size(); v++)
@@ -99,9 +97,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
for (i = 0; i < ids.Size(); i++)
{
Byte id = ids[i];
UString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
AString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
if (!resString.IsEmpty())
resString += L' ';
resString += ' ';
resString += method;
}
prop = resString;
@@ -171,12 +169,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
const CFolder &folder = db.Folders[realFolderIndex];
int methodIndex = folder.GetCompressionMethod();
UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
AString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
methodIndex == NHeader::NCompressionMethodMajor::kQuantum)
{
method += L":";
wchar_t temp[32];
method += ':';
char temp[32];
ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
method += temp;
}
@@ -344,9 +342,10 @@ private:
const CMvDatabaseEx *m_Database;
const CRecordVector<bool> *m_ExtractStatuses;
CByteBuffer TempBuf;
Byte *TempBuf;
UInt32 TempBufSize;
int NumIdenticalFiles;
bool TempBufMode;
bool IsSupported;
UInt32 m_BufStartFolderOffset;
int m_StartIndex;
@@ -362,12 +361,21 @@ private:
UInt64 m_FolderSize;
UInt64 m_PosInFolder;
void FreeTempBuf()
{
::MyFree(TempBuf);
TempBuf = NULL;
}
HRESULT OpenFile();
HRESULT CloseFileWithResOp(Int32 resOp);
HRESULT CloseFile();
HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
public:
HRESULT WriteEmptyFiles();
CFolderOutStream(): TempBuf(NULL) {}
~CFolderOutStream() { FreeTempBuf(); }
void Init(
const CMvDatabaseEx *database,
const CRecordVector<bool> *extractStatuses,
@@ -403,32 +411,33 @@ void CFolderOutStream::Init(
m_FileIsOpen = false;
m_IsOk = true;
TempBufMode = false;
NumIdenticalFiles = 0;
}
HRESULT CFolderOutStream::CloseFileWithResOp(Int32 resOp)
{
m_RealOutStream.Release();
m_FileIsOpen = false;
NumIdenticalFiles--;
return m_ExtractCallback->SetOperationResult(resOp);
}
HRESULT CFolderOutStream::CloseFile()
{
m_RealOutStream.Release();
HRESULT res = m_ExtractCallback->SetOperationResult(m_IsOk ?
return CloseFileWithResOp(m_IsOk ?
NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kDataError);
m_FileIsOpen = false;
return res;
}
HRESULT CFolderOutStream::OpenFile()
{
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
NExtract::NAskMode::kSkip;
if (!TempBufMode)
if (NumIdenticalFiles == 0)
{
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
int curIndex = m_CurrentIndex + 1;
for (; curIndex < m_ExtractStatuses->Size(); curIndex++)
if ((*m_ExtractStatuses)[curIndex])
int numExtractItems = 0;
int curIndex;
for (curIndex = m_CurrentIndex; curIndex < m_ExtractStatuses->Size(); curIndex++)
{
const CMvItem &mvItem2 = m_Database->Items[m_StartIndex + curIndex];
const CItem &item2 = m_Database->Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex];
@@ -436,21 +445,46 @@ HRESULT CFolderOutStream::OpenFile()
item.Size != item2.Size ||
item.Size == 0)
break;
if (!m_TestMode && (*m_ExtractStatuses)[curIndex])
numExtractItems++;
}
if (curIndex > m_CurrentIndex + 1)
NumIdenticalFiles = (curIndex - m_CurrentIndex);
if (NumIdenticalFiles == 0)
NumIdenticalFiles = 1;
TempBufMode = false;
if (numExtractItems > 1)
{
size_t oldCapacity = TempBuf.GetCapacity();
IsSupported = (item.Size <= kMaxTempBufSize);
if (item.Size > oldCapacity && IsSupported)
if (!TempBuf || item.Size > TempBufSize)
{
TempBuf.SetCapacity(0);
TempBuf.SetCapacity(item.Size);
FreeTempBuf();
TempBuf = (Byte *)MyAlloc(item.Size);
TempBufSize = item.Size;
if (TempBuf == NULL)
return E_OUTOFMEMORY;
}
TempBufMode = true;
m_BufStartFolderOffset = item.Offset;
}
else if (numExtractItems == 1)
{
while (NumIdenticalFiles && !(*m_ExtractStatuses)[m_CurrentIndex])
{
CMyComPtr<ISequentialOutStream> stream;
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &stream, NExtract::NAskMode::kSkip));
if (stream)
return E_FAIL;
RINOK(m_ExtractCallback->PrepareOperation(NExtract::NAskMode::kSkip));
m_CurrentIndex++;
m_FileIsOpen = true;
CloseFile();
}
}
}
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
NExtract::NAskMode::kSkip;
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
if (!m_RealOutStream && !m_TestMode)
askMode = NExtract::NAskMode::kSkip;
@@ -499,7 +533,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
numBytesToWrite = processedSizeLocal;
}
if (TempBufMode && IsSupported)
if (TempBufMode && TempBuf)
memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite);
}
realProcessed += numBytesToWrite;
@@ -513,39 +547,28 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
return res;
if (m_RemainFileSize == 0)
{
m_RealOutStream.Release();
RINOK(CloseFile());
if (TempBufMode)
while (NumIdenticalFiles)
{
while (m_CurrentIndex < m_ExtractStatuses->Size())
{
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.Offset != m_BufStartFolderOffset)
break;
HRESULT result = OpenFile();
m_FileIsOpen = true;
m_CurrentIndex++;
m_IsOk = true;
if (result == S_OK && m_RealOutStream && IsSupported)
result = WriteStream(m_RealOutStream, TempBuf, item.Size);
if (result == S_OK && m_RealOutStream && TempBuf)
result = WriteStream(m_RealOutStream, TempBuf, (size_t)(m_PosInFolder - m_BufStartFolderOffset));
if (IsSupported)
if (!TempBuf && TempBufMode && m_RealOutStream)
{
RINOK(CloseFile());
RINOK(result);
RINOK(CloseFileWithResOp(NExtract::NOperationResult::kUnSupportedMethod));
}
else
{
m_RealOutStream.Release();
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
m_FileIsOpen = false;
RINOK(CloseFile());
}
RINOK(result);
}
TempBufMode = false;
}
}
if (realProcessed > 0)
break; // with this break this function works as Write-Part
}
@@ -629,7 +652,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
bool allFilesMode = (numItems == (UInt32)-1);
if (allFilesMode)
numItems = m_Database.Items.Size();
if(numItems == 0)
if (numItems == 0)
return S_OK;
bool testMode = (testModeSpec != 0);
UInt64 totalUnPacked = 0;
@@ -755,12 +778,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curUnpack, extractCallback, testMode);
cabBlockInStreamSpec->MsZip = false;
HRESULT res = S_OK;
switch(folder.GetCompressionMethod())
{
case NHeader::NCompressionMethodMajor::kNone:
break;
case NHeader::NCompressionMethodMajor::kMSZip:
if(deflateDecoderSpec == NULL)
if (!deflateDecoder)
{
deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
deflateDecoder = deflateDecoderSpec;
@@ -768,33 +792,35 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
cabBlockInStreamSpec->MsZip = true;
break;
case NHeader::NCompressionMethodMajor::kLZX:
if(lzxDecoderSpec == NULL)
if (!lzxDecoder)
{
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
lzxDecoder = lzxDecoderSpec;
}
RINOK(lzxDecoderSpec->SetParams(folder.CompressionTypeMinor));
res = lzxDecoderSpec->SetParams(folder.CompressionTypeMinor);
break;
case NHeader::NCompressionMethodMajor::kQuantum:
if(quantumDecoderSpec == NULL)
if (!quantumDecoder)
{
quantumDecoderSpec = new NCompress::NQuantum::CDecoder;
quantumDecoder = quantumDecoderSpec;
}
quantumDecoderSpec->SetParams(folder.CompressionTypeMinor);
res = quantumDecoderSpec->SetParams(folder.CompressionTypeMinor);
break;
default:
res = E_INVALIDARG;
break;
}
if (res == E_INVALIDARG)
{
RINOK(cabFolderOutStream->Unsupported());
totalUnPacked += curUnpack;
continue;
}
}
RINOK(res);
cabBlockInStreamSpec->InitForNewFolder();
HRESULT res = S_OK;
{
int volIndex = mvItem.VolumeIndex;
int locFolderIndex = item.GetFolderIndex(db.Folders.Size());

View File

@@ -9,18 +9,15 @@
#include "ChmIn.h"
namespace NArchive{
namespace NChm{
namespace NArchive {
namespace NChm {
// define CHM_LOW, if you want to see low level items
// #define CHM_LOW
static const GUID kChmLzxGuid =
{ 0x7FC28940, 0x9D31, 0x11D0, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C };
static const GUID kHelp2LzxGuid =
{ 0x0A9007C6, 0x4076, 0x11D3, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 };
static const GUID kDesGuid =
{ 0x67F6E4A2, 0x60BF, 0x11D3, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF };
static const GUID kChmLzxGuid = { 0x7FC28940, 0x9D31, 0x11D0, { 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C } };
static const GUID kHelp2LzxGuid = { 0x0A9007C6, 0x4076, 0x11D3, { 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 } };
static const GUID kDesGuid = { 0x67F6E4A2, 0x60BF, 0x11D3, { 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF } };
static bool AreGuidsEqual(REFGUID g1, REFGUID g2)
{

View File

@@ -39,7 +39,7 @@ struct CItem
{
if (Name.Length() == 0)
return false;
return (Name[Name.Length() - 1] == '/');
return (Name.Back() == '/');
}
};

View File

@@ -87,7 +87,7 @@ CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
{
InSizes.Reserve(NumInStreams);
InSizePointers.Reserve(NumInStreams);
OutSizePointers.Reserve(NumOutStreams);
OutSizes.Reserve(NumOutStreams);
OutSizePointers.Reserve(NumOutStreams);
}

View File

@@ -54,7 +54,7 @@ static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
{
sizes.Clear();
sizePointers.Clear();
for(UInt32 i = 0; i < numItems; i++)
for (UInt32 i = 0; i < numItems; i++)
{
if (srcSizes == 0 || srcSizes[i] == NULL)
{
@@ -83,7 +83,7 @@ HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
{
_bindInfo = bindInfo;
_streamBinders.Clear();
for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
for (int i = 0; i < _bindInfo.BindPairs.Size(); i++)
{
_streamBinders.Add(CStreamBinder());
RINOK(_streamBinders.Back().CreateEvents());
@@ -113,7 +113,7 @@ void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
void CCoderMixer2MT::ReInit()
{
for(int i = 0; i < _streamBinders.Size(); i++)
for (int i = 0; i < _streamBinders.Size(); i++)
_streamBinders[i].ReInit();
}
@@ -125,20 +125,20 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre
throw 0;
*/
int i;
for(i = 0; i < _coders.Size(); i++)
for (i = 0; i < _coders.Size(); i++)
{
CCoder2 &coderInfo = _coders[i];
const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
coderInfo.InStreams.Clear();
UInt32 j;
for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
for (j = 0; j < coderStreamsInfo.NumInStreams; j++)
coderInfo.InStreams.Add(NULL);
coderInfo.OutStreams.Clear();
for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
for (j = 0; j < coderStreamsInfo.NumOutStreams; j++)
coderInfo.OutStreams.Add(NULL);
}
for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
for (i = 0; i < _bindInfo.BindPairs.Size(); i++)
{
const CBindPair &bindPair = _bindInfo.BindPairs[i];
UInt32 inCoderIndex, inCoderStreamIndex;
@@ -149,16 +149,26 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre
_streamBinders[i].CreateStreams(
&_coders[inCoderIndex].InStreams[inCoderStreamIndex],
&_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize;
_coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize);
_coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize);
if (inSetSize && outSetSize)
{
const UInt32 kBufSize = 1 << 19;
inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize);
outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize);
}
}
for(i = 0; i < _bindInfo.InStreams.Size(); i++)
for (i = 0; i < _bindInfo.InStreams.Size(); i++)
{
UInt32 inCoderIndex, inCoderStreamIndex;
_bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
_coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
}
for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
{
UInt32 outCoderIndex, outCoderStreamIndex;
_bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
@@ -204,7 +214,7 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
for (i = 0; i < _coders.Size(); i++)
if (i != _progressCoderIndex)
_coders[i].WaitFinish();
_coders[i].WaitExecuteFinish();
RINOK(ReturnIfError(E_ABORT));
RINOK(ReturnIfError(E_OUTOFMEMORY));

View File

@@ -19,6 +19,7 @@ struct CCoder2: public CCoderInfo2, public CVirtThread
CRecordVector<ISequentialOutStream*> OutStreamPointers;
CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
~CCoder2() { CVirtThread::WaitThreadFinish(); }
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
virtual void Execute();
void Code(ICompressProgressInfo *progress);

View File

@@ -4,7 +4,7 @@
#include "CoderMixer2ST.h"
namespace NCoderMixer2 {
namespace NCoderMixer {
CCoderMixer2ST::CCoderMixer2ST() {}
@@ -42,7 +42,7 @@ HRESULT CCoderMixer2ST::GetInStream(
{
CMyComPtr<ISequentialInStream> seqInStream;
int i;
for(i = 0; i < _bindInfo.InStreams.Size(); i++)
for (i = 0; i < _bindInfo.InStreams.Size(); i++)
if (_bindInfo.InStreams[i] == streamIndex)
{
seqInStream = inStreams[i];
@@ -57,7 +57,7 @@ HRESULT CCoderMixer2ST::GetInStream(
_bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
coderIndex, coderStreamIndex);
CCoderInfo &coder = _coders[coderIndex];
CCoderInfo2 &coder = _coders[coderIndex];
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
@@ -91,7 +91,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
{
CMyComPtr<ISequentialOutStream> seqOutStream;
int i;
for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
if (_bindInfo.OutStreams[i] == streamIndex)
{
seqOutStream = outStreams[i];
@@ -106,7 +106,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
coderIndex, coderStreamIndex);
CCoderInfo &coder = _coders[coderIndex];
CCoderInfo2 &coder = _coders[coderIndex];
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
@@ -169,7 +169,7 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
// _mainCoderIndex = 0;
// _mainCoderIndex = _coders.Size() - 1;
CCoderInfo &mainCoder = _coders[_mainCoderIndex];
CCoderInfo2 &mainCoder = _coders[_mainCoderIndex];
CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
@@ -198,7 +198,7 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
{
if (i == _mainCoderIndex)
continue;
CCoderInfo &coder = _coders[i];
CCoderInfo2 &coder = _coders[i];
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
if (setOutStreamSize)

View File

@@ -7,7 +7,7 @@
#include "../../../Common/MyCom.h"
#include "../../ICoder.h"
namespace NCoderMixer2 {
namespace NCoderMixer {
// SetBindInfo()
// for each coder
@@ -26,11 +26,11 @@ namespace NCoderMixer2 {
// Code
// }
struct CSTCoderInfo: public CCoderInfo
struct CSTCoderInfo: public CCoderInfo2
{
bool IsMain;
CSTCoderInfo(UInt32 numInStreams, UInt32 numOutStreams, bool isMain):
CCoderInfo(numInStreams, numOutStreams),IsMain(isMain) {}
CCoderInfo2(numInStreams, numOutStreams), IsMain(isMain) {}
};
class CCoderMixer2ST:
@@ -84,5 +84,5 @@ public:
};
}
#endif
#endif

View File

@@ -73,7 +73,7 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
for (i = 0; i < _coders.Size(); i++)
if (i != _progressCoderIndex)
_coders[i].WaitFinish();
_coders[i].WaitExecuteFinish();
RINOK(ReturnIfError(E_ABORT));
RINOK(ReturnIfError(E_OUTOFMEMORY));

View File

@@ -18,6 +18,7 @@ struct CCoder: public CCoderInfo, public CVirtThread
virtual void Execute();
void Code(ICompressProgressInfo *progress);
~CCoder() { CVirtThread::WaitThreadFinish(); }
};
/*

View File

@@ -2,16 +2,10 @@
#include "StdAfx.h"
#include "../../../Common/StringToInt.h"
#include "../../../Windows/PropVariant.h"
#ifndef _7ZIP_ST
#include "../../../Windows/System.h"
#endif
#include "../../ICoder.h"
#include "../Common/ParseProperties.h"
#include "HandlerOut.h"
@@ -20,487 +14,40 @@ using namespace NWindows;
namespace NArchive {
static const wchar_t *kCopyMethod = L"Copy";
static const wchar_t *kLZMAMethodName = L"LZMA";
static const wchar_t *kLZMA2MethodName = L"LZMA2";
static const wchar_t *kBZip2MethodName = L"BZip2";
static const wchar_t *kPpmdMethodName = L"PPMd";
static const wchar_t *kDeflateMethodName = L"Deflate";
static const wchar_t *kDeflate64MethodName = L"Deflate64";
static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
static const UInt32 kLzmaAlgoX1 = 0;
static const UInt32 kLzmaAlgoX5 = 1;
static const UInt32 kLzmaDicSizeX1 = 1 << 16;
static const UInt32 kLzmaDicSizeX3 = 1 << 20;
static const UInt32 kLzmaDicSizeX5 = 1 << 24;
static const UInt32 kLzmaDicSizeX7 = 1 << 25;
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
static const UInt32 kLzmaFastBytesX1 = 32;
static const UInt32 kLzmaFastBytesX7 = 64;
static const UInt32 kPpmdMemSizeX1 = (1 << 22);
static const UInt32 kPpmdMemSizeX5 = (1 << 24);
static const UInt32 kPpmdMemSizeX7 = (1 << 26);
static const UInt32 kPpmdMemSizeX9 = (192 << 20);
static const UInt32 kPpmdOrderX1 = 4;
static const UInt32 kPpmdOrderX5 = 6;
static const UInt32 kPpmdOrderX7 = 16;
static const UInt32 kPpmdOrderX9 = 32;
static const UInt32 kDeflateAlgoX1 = 0;
static const UInt32 kDeflateAlgoX5 = 1;
static const UInt32 kDeflateFastBytesX1 = 32;
static const UInt32 kDeflateFastBytesX7 = 64;
static const UInt32 kDeflateFastBytesX9 = 128;
static const UInt32 kDeflatePassesX1 = 1;
static const UInt32 kDeflatePassesX7 = 3;
static const UInt32 kDeflatePassesX9 = 10;
static const UInt32 kBZip2NumPassesX1 = 1;
static const UInt32 kBZip2NumPassesX7 = 2;
static const UInt32 kBZip2NumPassesX9 = 7;
static const UInt32 kBZip2DicSizeX1 = 100000;
static const UInt32 kBZip2DicSizeX3 = 500000;
static const UInt32 kBZip2DicSizeX5 = 900000;
static const wchar_t *kDefaultMethodName = kLZMAMethodName;
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
static const UInt32 kDictionaryForHeaders = 1 << 20;
static const UInt32 kNumFastBytesForHeaders = 273;
static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;
static bool AreEqual(const UString &methodName, const wchar_t *s)
{ return (methodName.CompareNoCase(s) == 0); }
bool COneMethodInfo::IsLzma() const
static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
{
return
AreEqual(MethodName, kLZMAMethodName) ||
AreEqual(MethodName, kLZMA2MethodName);
if (m.FindProp(propID) < 0)
m.AddProp32(propID, value);
}
static inline bool IsBZip2Method(const UString &methodName)
{ return AreEqual(methodName, kBZip2MethodName); }
static inline bool IsPpmdMethod(const UString &methodName)
{ return AreEqual(methodName, kPpmdMethodName); }
static inline bool IsDeflateMethod(const UString &methodName)
{
return
AreEqual(methodName, kDeflateMethodName) ||
AreEqual(methodName, kDeflate64MethodName);
}
struct CNameToPropID
{
PROPID PropID;
VARTYPE VarType;
const wchar_t *Name;
};
static CNameToPropID g_NameToPropID[] =
{
{ NCoderPropID::kBlockSize, VT_UI4, L"C" },
{ NCoderPropID::kDictionarySize, VT_UI4, L"D" },
{ NCoderPropID::kUsedMemorySize, VT_UI4, L"MEM" },
{ NCoderPropID::kOrder, VT_UI4, L"O" },
{ NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
{ NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
{ NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
{ NCoderPropID::kEndMarker, VT_BOOL, L"eos" },
{ NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
{ NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" },
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
{ NCoderPropID::kNumThreads, VT_UI4, L"mt" },
{ NCoderPropID::kDefaultProp, VT_UI4, L"" }
};
static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
{
if (varType == srcProp.vt)
{
destProp = srcProp;
return true;
}
if (varType == VT_UI1)
{
if (srcProp.vt == VT_UI4)
{
UInt32 value = srcProp.ulVal;
if (value > 0xFF)
return false;
destProp = (Byte)value;
return true;
}
}
else if (varType == VT_BOOL)
{
bool res;
if (SetBoolProperty(res, srcProp) != S_OK)
return false;
destProp = res;
return true;
}
return false;
}
static int FindPropIdExact(const UString &name)
{
for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
return i;
return -1;
}
static int FindPropIdStart(const UString &name)
{
for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
{
UString t = g_NameToPropID[i].Name;
if (t.CompareNoCase(name.Left(t.Length())) == 0)
return i;
}
return -1;
}
static void SetMethodProp(COneMethodInfo &m, PROPID propID, const NCOM::CPropVariant &value)
{
for (int j = 0; j < m.Props.Size(); j++)
if (m.Props[j].Id == propID)
return;
CProp prop;
prop.Id = propID;
prop.Value = value;
m.Props.Add(prop);
}
void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
UInt32 level = _level;
if (oneMethodInfo.MethodName.IsEmpty())
oneMethodInfo.MethodName = kDefaultMethodName;
if (oneMethodInfo.IsLzma())
{
UInt32 dicSize =
(level >= 9 ? kLzmaDicSizeX9 :
(level >= 7 ? kLzmaDicSizeX7 :
(level >= 5 ? kLzmaDicSizeX5 :
(level >= 3 ? kLzmaDicSizeX3 :
kLzmaDicSizeX1))));
UInt32 algo =
(level >= 5 ? kLzmaAlgoX5 :
kLzmaAlgoX1);
UInt32 fastBytes =
(level >= 7 ? kLzmaFastBytesX7 :
kLzmaFastBytesX1);
const wchar_t *matchFinder =
(level >= 5 ? kLzmaMatchFinderX5 :
kLzmaMatchFinderX1);
SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
SetMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
if (level != (UInt32)(UInt32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
#ifndef _7ZIP_ST
SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
}
else if (IsDeflateMethod(oneMethodInfo.MethodName))
{
UInt32 fastBytes =
(level >= 9 ? kDeflateFastBytesX9 :
(level >= 7 ? kDeflateFastBytesX7 :
kDeflateFastBytesX1));
}
UInt32 numPasses =
(level >= 9 ? kDeflatePassesX9 :
(level >= 7 ? kDeflatePassesX7 :
kDeflatePassesX1));
UInt32 algo =
(level >= 5 ? kDeflateAlgoX5 :
kDeflateAlgoX1);
SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
}
else if (IsBZip2Method(oneMethodInfo.MethodName))
{
UInt32 numPasses =
(level >= 9 ? kBZip2NumPassesX9 :
(level >= 7 ? kBZip2NumPassesX7 :
kBZip2NumPassesX1));
UInt32 dicSize =
(level >= 5 ? kBZip2DicSizeX5 :
(level >= 3 ? kBZip2DicSizeX3 :
kBZip2DicSizeX1));
SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
void CMultiMethodProps::Init()
{
#ifndef _7ZIP_ST
SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
}
else if (IsPpmdMethod(oneMethodInfo.MethodName))
{
UInt32 useMemSize =
(level >= 9 ? kPpmdMemSizeX9 :
(level >= 7 ? kPpmdMemSizeX7 :
(level >= 5 ? kPpmdMemSizeX5 :
kPpmdMemSizeX1)));
UInt32 order =
(level >= 9 ? kPpmdOrderX9 :
(level >= 7 ? kPpmdOrderX7 :
(level >= 5 ? kPpmdOrderX5 :
kPpmdOrderX1)));
SetMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
SetMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
}
}
static void SplitParams(const UString &srcString, UStringVector &subStrings)
{
subStrings.Clear();
UString name;
int len = srcString.Length();
if (len == 0)
return;
for (int i = 0; i < len; i++)
{
wchar_t c = srcString[i];
if (c == L':')
{
subStrings.Add(name);
name.Empty();
}
else
name += c;
}
subStrings.Add(name);
}
static void SplitParam(const UString &param, UString &name, UString &value)
{
int eqPos = param.Find(L'=');
if (eqPos >= 0)
{
name = param.Left(eqPos);
value = param.Mid(eqPos + 1);
return;
}
for(int i = 0; i < param.Length(); i++)
{
wchar_t c = param[i];
if (c >= L'0' && c <= L'9')
{
name = param.Left(i);
value = param.Mid(i);
return;
}
}
name = param;
}
HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
{
CProp prop;
int index = FindPropIdExact(name);
if (index < 0)
return E_INVALIDARG;
const CNameToPropID &nameToPropID = g_NameToPropID[index];
prop.Id = nameToPropID.PropID;
if (prop.Id == NCoderPropID::kBlockSize ||
prop.Id == NCoderPropID::kDictionarySize ||
prop.Id == NCoderPropID::kUsedMemorySize)
{
UInt32 dicSize;
RINOK(ParsePropDictionaryValue(value, dicSize));
prop.Value = dicSize;
}
else
{
NCOM::CPropVariant propValue;
if (nameToPropID.VarType == VT_BSTR)
propValue = value;
else if (nameToPropID.VarType == VT_BOOL)
{
bool res;
if (!StringToBool(value, res))
return E_INVALIDARG;
propValue = res;
}
else
{
UInt32 number;
if (ParseStringToUInt32(value, number) == value.Length())
propValue = number;
else
propValue = value;
}
if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
return E_INVALIDARG;
}
oneMethodInfo.Props.Add(prop);
return S_OK;
}
HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
{
UStringVector params;
SplitParams(srcString, params);
if (params.Size() > 0)
oneMethodInfo.MethodName = params[0];
for (int i = 1; i < params.Size(); i++)
{
const UString &param = params[i];
UString name, value;
SplitParam(param, name, value);
RINOK(SetParam(oneMethodInfo, name, value));
}
return S_OK;
}
HRESULT COutHandler::SetSolidSettings(const UString &s)
{
UString s2 = s;
s2.MakeUpper();
for (int i = 0; i < s2.Length();)
{
const wchar_t *start = ((const wchar_t *)s2) + i;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(start, &end);
if (start == end)
{
if (s2[i++] != 'E')
return E_INVALIDARG;
_solidExtension = true;
continue;
}
i += (int)(end - start);
if (i == s2.Length())
return E_INVALIDARG;
wchar_t c = s2[i++];
switch(c)
{
case 'F':
if (v < 1)
v = 1;
_numSolidFiles = v;
break;
case 'B':
_numSolidBytes = v;
_numSolidBytesDefined = true;
break;
case 'K':
_numSolidBytes = (v << 10);
_numSolidBytesDefined = true;
break;
case 'M':
_numSolidBytes = (v << 20);
_numSolidBytesDefined = true;
break;
case 'G':
_numSolidBytes = (v << 30);
_numSolidBytesDefined = true;
break;
default:
return E_INVALIDARG;
}
}
return S_OK;
}
HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)
{
bool isSolid;
switch(value.vt)
{
case VT_EMPTY:
isSolid = true;
break;
case VT_BOOL:
isSolid = (value.boolVal != VARIANT_FALSE);
break;
case VT_BSTR:
if (StringToBool(value.bstrVal, isSolid))
break;
return SetSolidSettings(value.bstrVal);
default:
return E_INVALIDARG;
}
if (isSolid)
InitSolid();
else
_numSolidFiles = 1;
return S_OK;
}
void COutHandler::Init()
{
_removeSfxBlock = false;
_compressHeaders = true;
_encryptHeadersSpecified = false;
_encryptHeaders = false;
WriteCTime = false;
WriteATime = false;
WriteMTime = true;
#ifndef _7ZIP_ST
_numThreads = NSystem::GetNumberOfProcessors();
_numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
#endif
_level = 5;
_level = (UInt32)(UInt32)-1;
_autoFilter = true;
_volumeMode = false;
_crcSize = 4;
InitSolid();
_filterMethod.Clear();
_methods.Clear();
}
void COutHandler::BeforeSetProperty()
{
Init();
#ifndef _7ZIP_ST
numProcessors = NSystem::GetNumberOfProcessors();
#endif
mainDicSize = 0xFFFFFFFF;
mainDicMethodIndex = 0xFFFFFFFF;
minNumber = 0;
_crcSize = 4;
}
HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
name.MakeUpper();
@@ -511,24 +58,14 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
{
name.Delete(0);
_level = 9;
return ParsePropValue(name, value, _level);
}
if (name[0] == L'S')
{
name.Delete(0);
if (name.IsEmpty())
return SetSolidSettings(value);
if (value.vt != VT_EMPTY)
return E_INVALIDARG;
return SetSolidSettings(name);
return ParsePropToUInt32(name, value, _level);
}
if (name == L"CRC")
{
_crcSize = 4;
name.Delete(0, 3);
return ParsePropValue(name, value, _crcSize);
_crcSize = 4;
return ParsePropToUInt32(name, value, _crcSize);
}
UInt32 number;
@@ -536,86 +73,67 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
UString realName = name.Mid(index);
if (index == 0)
{
if(name.Left(2).CompareNoCase(L"MT") == 0)
if (name.Left(2).CompareNoCase(L"MT") == 0)
{
#ifndef _7ZIP_ST
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
#endif
return S_OK;
}
if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value);
if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);
if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);
if (name.CompareNoCase(L"HCF") == 0)
{
bool compressHeadersFull = true;
RINOK(SetBoolProperty(compressHeadersFull, value));
if (!compressHeadersFull)
return E_INVALIDARG;
return S_OK;
}
if (name.CompareNoCase(L"HE") == 0)
{
RINOK(SetBoolProperty(_encryptHeaders, value));
_encryptHeadersSpecified = true;
return S_OK;
}
if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);
if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);
if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);
if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);
number = 0;
}
if (number > 10000)
return E_FAIL;
if (number < minNumber)
return E_INVALIDARG;
number -= minNumber;
for(int j = _methods.Size(); j <= (int)number; j++)
{
COneMethodInfo oneMethodInfo;
_methods.Add(oneMethodInfo);
}
COneMethodInfo &oneMethodInfo = _methods[number];
if (realName.Length() == 0)
if (name.CompareNoCase(L"F") == 0)
{
HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
if (res == S_OK)
return res;
if (value.vt != VT_BSTR)
return E_INVALIDARG;
return _filterMethod.ParseMethodFromPROPVARIANT(L"", 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);
}
RINOK(SetParams(oneMethodInfo, value.bstrVal));
void CSingleMethodProps::Init()
{
Clear();
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
AddNumThreadsProp(_numThreads);
#endif
_level = (UInt32)(UInt32)-1;
}
HRESULT CSingleMethodProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
Init();
for (int i = 0; i < numProps; i++)
{
UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
if (name[0] == L'X')
{
UInt32 a = 9;
RINOK(ParsePropToUInt32(name.Mid(1), value, a));
_level = a;
AddLevelProp(a);
}
else if (name.Left(2).CompareNoCase(L"MT") == 0)
{
#ifndef _7ZIP_ST
RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
AddNumThreadsProp(_numThreads);
#endif
}
else
{
int index = FindPropIdStart(realName);
if (index < 0)
return E_INVALIDARG;
const CNameToPropID &nameToPropID = g_NameToPropID[index];
CProp prop;
prop.Id = nameToPropID.PropID;
if (prop.Id == NCoderPropID::kBlockSize ||
prop.Id == NCoderPropID::kDictionarySize ||
prop.Id == NCoderPropID::kUsedMemorySize)
{
UInt32 dicSize;
RINOK(ParsePropDictionaryValue(realName.Mid(MyStringLen(nameToPropID.Name)), value, dicSize));
prop.Value = dicSize;
if (number <= mainDicMethodIndex)
mainDicSize = dicSize;
}
else
{
int index = FindPropIdExact(realName);
if (index < 0)
return E_INVALIDARG;
const CNameToPropID &nameToPropID = g_NameToPropID[index];
prop.Id = nameToPropID.PropID;
if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
return E_INVALIDARG;
}
oneMethodInfo.Props.Add(prop);
return ParseParamsFromPROPVARIANT(name, value);
}
return S_OK;
}

View File

@@ -3,83 +3,61 @@
#ifndef __HANDLER_OUT_H
#define __HANDLER_OUT_H
#include "../../../Common/MyString.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
struct COneMethodInfo
{
CObjectVector<CProp> Props;
UString MethodName;
bool IsLzma() const;
};
class COutHandler
class CMultiMethodProps
{
UInt32 _level;
public:
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
HRESULT SetSolidSettings(const UString &s);
HRESULT SetSolidSettings(const PROPVARIANT &value);
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
UInt32 _crcSize;
CObjectVector<COneMethodInfo> _methods;
bool _removeSfxBlock;
UInt64 _numSolidFiles;
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
bool _solidExtension;
bool _compressHeaders;
bool _encryptHeadersSpecified;
bool _encryptHeaders;
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
COneMethodInfo _filterMethod;
bool _autoFilter;
UInt32 _level;
bool _volumeMode;
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
void SetCompressionMethod2(COneMethodInfo &oneMethodInfo
void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
void InitSolid()
int GetNumEmptyMethods() const
{
InitSolidFiles();
InitSolidSize();
_solidExtension = false;
_numSolidBytesDefined = false;
int i;
for (i = 0; i < _methods.Size(); i++)
if (!_methods[i].IsEmpty())
break;
return i;
}
int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
void Init();
COutHandler() { Init(); }
CMultiMethodProps() { Init(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
void BeforeSetProperty();
class CSingleMethodProps: public CMethodProps
{
UInt32 _level;
UInt32 minNumber;
UInt32 numProcessors;
UInt32 mainDicSize;
UInt32 mainDicMethodIndex;
void Init();
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
CSingleMethodProps() { Init(); }
int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
};
}

View File

@@ -21,8 +21,10 @@ STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSi
{
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
/*
if (size > 0 && realProcessedSize == 0)
_wasFinished = true;
*/
_size += realProcessedSize;
_crc = CrcUpdate(_crc, data, realProcessedSize);
if(processedSize != NULL)

View File

@@ -49,19 +49,19 @@ private:
CMyComPtr<IInStream> _stream;
UInt64 _size;
UInt32 _crc;
bool _wasFinished;
// bool _wasFinished;
public:
void SetStream(IInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
_wasFinished = false;
// _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; }
// bool WasFinished() const { return _wasFinished; }
};
#endif

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
#include "../../../../C/Types.h"
#include "ItemNameUtils.h"
namespace NArchive {
@@ -29,8 +31,8 @@ UString GetOSName2(const UString &name)
if (name.IsEmpty())
return UString();
UString newName = GetOSName(name);
if (newName[newName.Length() - 1] == kOSDirDelimiter)
newName.Delete(newName.Length() - 1);
if (newName.Back() == kOSDirDelimiter)
newName.DeleteBack();
return newName;
}

View File

@@ -6,72 +6,61 @@
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if(processedSize != NULL)
if (processedSize)
*processedSize = 0;
while(_streamIndex < Streams.Size() && size > 0)
if (size == 0)
return S_OK;
if (_pos >= _totalLength)
return (_pos == _totalLength) ? S_OK : E_FAIL;
{
CSubStreamInfo &s = Streams[_streamIndex];
if (_pos == s.Size)
int left = 0, mid = _streamIndex, right = Streams.Size();
for (;;)
{
_streamIndex++;
_pos = 0;
continue;
}
RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
UInt32 realProcessed;
HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
data = (void *)((Byte *)data + realProcessed);
size -= realProcessed;
if(processedSize != NULL)
*processedSize += realProcessed;
_pos += realProcessed;
_seekPos += realProcessed;
RINOK(result);
CSubStreamInfo &m = Streams[mid];
if (_pos < m.GlobalOffset)
right = mid;
else if (_pos >= m.GlobalOffset + m.Size)
left = mid + 1;
else
{
_streamIndex = mid;
break;
}
return S_OK;
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)
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
UInt64 newPos;
switch(seekOrigin)
{
case STREAM_SEEK_SET:
newPos = offset;
break;
case STREAM_SEEK_CUR:
newPos = _seekPos + offset;
break;
case STREAM_SEEK_END:
newPos = _totalLength + offset;
break;
default:
return STG_E_INVALIDFUNCTION;
case STREAM_SEEK_SET: _pos = offset; break;
case STREAM_SEEK_CUR: _pos = _pos + offset; break;
case STREAM_SEEK_END: _pos = _totalLength + offset; break;
default: return STG_E_INVALIDFUNCTION;
}
_seekPos = 0;
for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
{
UInt64 size = Streams[_streamIndex].Size;
if (newPos < _seekPos + size)
{
_pos = newPos - _seekPos;
_seekPos += _pos;
if (newPosition != 0)
*newPosition = newPos;
*newPosition = _pos;
return S_OK;
}
_seekPos += size;
}
if (newPos == _seekPos)
{
if (newPosition != 0)
*newPosition = newPos;
return S_OK;
}
return E_FAIL;
}

View File

@@ -1,36 +1,44 @@
// MultiStream.h
#ifndef __MULTISTREAM_H
#define __MULTISTREAM_H
#ifndef __MULTI_STREAM_H
#define __MULTI_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../Archive/IArchive.h"
#include "../../IStream.h"
class CMultiStream:
public IInStream,
public CMyUnknownImp
{
int _streamIndex;
UInt64 _pos;
UInt64 _seekPos;
UInt64 _totalLength;
int _streamIndex;
public:
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
UInt64 Pos;
UInt64 Size;
UInt64 GlobalOffset;
UInt64 LocalPos;
};
CObjectVector<CSubStreamInfo> Streams;
void Init()
HRESULT Init()
{
_streamIndex = 0;
_pos = 0;
_seekPos = 0;
_totalLength = 0;
UInt64 total = 0;
for (int i = 0; i < Streams.Size(); i++)
_totalLength += Streams[i].Size;
{
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)

View File

@@ -1,177 +1,3 @@
// ParseProperties.cpp
#include "StdAfx.h"
#include "ParseProperties.h"
#include "Common/StringToInt.h"
#include "Common/MyCom.h"
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
{
if (prop.vt == VT_UI4)
{
if (!name.IsEmpty())
return E_INVALIDARG;
resValue = prop.ulVal;
}
else if (prop.vt == VT_EMPTY)
{
if(!name.IsEmpty())
{
const wchar_t *start = name;
const wchar_t *end;
UInt64 v = ConvertStringToUInt64(start, &end);
if (end - start != name.Length())
return E_INVALIDARG;
resValue = (UInt32)v;
}
}
else
return E_INVALIDARG;
return S_OK;
}
static const int kLogarithmicSizeLimit = 32;
static const wchar_t kByteSymbol = L'B';
static const wchar_t kKiloByteSymbol = L'K';
static const wchar_t kMegaByteSymbol = L'M';
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
{
UString srcString = srcStringSpec;
srcString.MakeUpper();
const wchar_t *start = srcString;
const wchar_t *end;
UInt64 number = ConvertStringToUInt64(start, &end);
int numDigits = (int)(end - start);
if (numDigits == 0 || srcString.Length() > numDigits + 1)
return E_INVALIDARG;
if (srcString.Length() == numDigits)
{
if (number >= kLogarithmicSizeLimit)
return E_INVALIDARG;
dicSize = (UInt32)1 << (int)number;
return S_OK;
}
switch (srcString[numDigits])
{
case kByteSymbol:
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
return E_INVALIDARG;
dicSize = (UInt32)number;
break;
case kKiloByteSymbol:
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
return E_INVALIDARG;
dicSize = (UInt32)(number << 10);
break;
case kMegaByteSymbol:
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
return E_INVALIDARG;
dicSize = (UInt32)(number << 20);
break;
default:
return E_INVALIDARG;
}
return S_OK;
}
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
{
if (name.IsEmpty())
{
if (prop.vt == VT_UI4)
{
UInt32 logDicSize = prop.ulVal;
if (logDicSize >= 32)
return E_INVALIDARG;
resValue = (UInt32)1 << logDicSize;
return S_OK;
}
if (prop.vt == VT_BSTR)
return ParsePropDictionaryValue(prop.bstrVal, resValue);
return E_INVALIDARG;
}
return ParsePropDictionaryValue(name, resValue);
}
bool StringToBool(const UString &s, bool &res)
{
if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
{
res = true;
return true;
}
if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
{
res = false;
return true;
}
return false;
}
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
{
switch(value.vt)
{
case VT_EMPTY:
dest = true;
return S_OK;
case VT_BOOL:
dest = (value.boolVal != VARIANT_FALSE);
return S_OK;
/*
case VT_UI4:
dest = (value.ulVal != 0);
break;
*/
case VT_BSTR:
return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG;
}
return E_INVALIDARG;
}
int ParseStringToUInt32(const UString &srcString, UInt32 &number)
{
const wchar_t *start = srcString;
const wchar_t *end;
UInt64 number64 = ConvertStringToUInt64(start, &end);
if (number64 > 0xFFFFFFFF)
{
number = 0;
return 0;
}
number = (UInt32)number64;
return (int)(end - start);
}
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
{
if (name.IsEmpty())
{
switch(prop.vt)
{
case VT_UI4:
numThreads = prop.ulVal;
break;
default:
{
bool val;
RINOK(SetBoolProperty(val, prop));
numThreads = (val ? defaultNumThreads : 1);
break;
}
}
}
else
{
UInt32 number;
int index = ParseStringToUInt32(name, number);
if (index != name.Length())
return E_INVALIDARG;
numThreads = number;
}
return S_OK;
}

View File

@@ -1,18 +1,6 @@
// ParseProperties.h
#ifndef __PARSEPROPERTIES_H
#define __PARSEPROPERTIES_H
#include "Common/MyString.h"
#include "Common/Types.h"
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
bool StringToBool(const UString &s, bool &res);
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
int ParseStringToUInt32(const UString &srcString, UInt32 &number);
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
#ifndef __PARSE_PROPERTIES_H
#define __PARSE_PROPERTIES_H
#endif

View File

@@ -3,8 +3,8 @@
#include "StdAfx.h"
#include "Common/ComTry.h"
#include "Common/StringToInt.h"
#include "Common/StringConvert.h"
#include "Common/StringToInt.h"
#include "Windows/PropVariant.h"
#include "Windows/Time.h"
@@ -25,10 +25,10 @@ namespace NFileHeader
{
namespace NMagic
{
extern const char *kMagic1 = "070701";
extern const char *kMagic2 = "070702";
extern const char *kMagic3 = "070707";
extern const char *kEndName = "TRAILER!!!";
const char *kMagic1 = "070701";
const char *kMagic2 = "070702";
const char *kMagic3 = "070707";
const char *kEndName = "TRAILER!!!";
const Byte kMagicForRecord2[2] = { 0xC7, 0x71 };
}

View File

@@ -0,0 +1,644 @@
// CramfsHandler.cpp
#include "StdAfx.h"
#include "../../../C/7zCrc.h"
#include "../../../C/CpuArch.h"
#include "../../../C/Alloc.h"
#include "Common/ComTry.h"
#include "Common/StringConvert.h"
#include "Windows/PropVariantUtils.h"
#include "../Common/LimitedStreams.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamObjects.h"
#include "../Common/StreamUtils.h"
#include "../Compress/CopyCoder.h"
#include "../Compress/ZlibDecoder.h"
namespace NArchive {
namespace NCramfs {
#define SIGNATURE { 'C','o','m','p','r','e','s','s','e','d',' ','R','O','M','F','S' }
static const UInt32 kSignatureSize = 16;
static const char kSignature[kSignatureSize] = SIGNATURE;
static const UInt32 kArcSizeMax = (256 + 16) << 20;
static const UInt32 kNumFilesMax = (1 << 19);
static const unsigned kNumDirLevelsMax = (1 << 8);
static const UInt32 kHeaderSize = 0x40;
static const unsigned kHeaderNameSize = 16;
static const UInt32 kNodeSize = 12;
static const UInt32 kFlag_FsVer2 = (1 << 0);
static const CUInt32PCharPair k_Flags[] =
{
{ 0, "Ver2" },
{ 1, "SortedDirs" },
{ 8, "Holes" },
{ 9, "WrongSignature" },
{ 10, "ShiftedRootOffset" }
};
static const unsigned kBlockSizeLog = 12;
static const UInt32 kBlockSize = 1 << kBlockSizeLog;
/*
struct CNode
{
UInt16 Mode;
UInt16 Uid;
UInt32 Size;
Byte Gid;
UInt32 NameLen;
UInt32 Offset;
void Parse(const Byte *p)
{
Mode = GetUi16(p);
Uid = GetUi16(p + 2);
Size = Get32(p + 4) & 0xFFFFFF;
Gid = p[7];
NameLen = p[8] & 0x3F;
Offset = Get32(p + 8) >> 6;
}
};
*/
#define Get32(p) (be ? GetBe32(p) : GetUi32(p))
static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); }
static bool IsDir(const Byte *p, bool be) { return (GetMode(p, be) & 0xF000) == 0x4000; }
static UInt32 GetSize(const Byte *p, bool be)
{
if (be)
return GetBe32(p + 4) >> 8;
else
return GetUi32(p + 4) & 0xFFFFFF;
}
static UInt32 GetNameLen(const Byte *p, bool be)
{
if (be)
return (p[8] & 0xFC);
else
return (p[8] & 0x3F) << 2;
}
static UInt32 GetOffset(const Byte *p, bool be)
{
if (be)
return (GetBe32(p + 8) & 0x03FFFFFF) << 2;
else
return GetUi32(p + 8) >> 6 << 2;
}
struct CItem
{
UInt32 Offset;
int Parent;
};
struct CHeader
{
bool be;
UInt32 Size;
UInt32 Flags;
// UInt32 Future;
UInt32 Crc;
// UInt32 Edition;
UInt32 NumBlocks;
UInt32 NumFiles;
char Name[kHeaderNameSize];
bool Parse(const Byte *p)
{
if (memcmp(p + 16, kSignature, kSignatureSize) != 0)
return false;
switch(GetUi32(p))
{
case 0x28CD3D45: be = false; break;
case 0x453DCD28: be = true; break;
default: return false;
}
Size = Get32(p + 4);
Flags = Get32(p + 8);
// Future = Get32(p + 0xC);
Crc = Get32(p + 0x20);
// Edition = Get32(p + 0x24);
NumBlocks = Get32(p + 0x28);
NumFiles = Get32(p + 0x2C);
memcpy(Name, p + 0x30, kHeaderNameSize);
return true;
}
bool IsVer2() const { return (Flags & kFlag_FsVer2) != 0; }
};
class CHandler:
public IInArchive,
public IInArchiveGetStream,
public CMyUnknownImp
{
CRecordVector<CItem> _items;
CMyComPtr<IInStream> _stream;
Byte *_data;
UInt32 _size;
UInt32 _headersSize;
AString _errorMessage;
CHeader _h;
// Current file
NCompress::NZlib::CDecoder *_zlibDecoderSpec;
CMyComPtr<ICompressCoder> _zlibDecoder;
CBufInStream *_inStreamSpec;
CMyComPtr<ISequentialInStream> _inStream;
CBufPtrSeqOutStream *_outStreamSpec;
CMyComPtr<ISequentialOutStream> _outStream;
UInt32 _curBlocksOffset;
UInt32 _curNumBlocks;
HRESULT OpenDir(int parent, UInt32 baseOffsetBase, unsigned level);
HRESULT Open2(IInStream *inStream);
AString GetPath(int index) const;
bool GetPackSize(int index, UInt32 &res) const;
void Free();
public:
CHandler(): _data(0) {}
~CHandler() { Free(); }
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive(;)
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize);
};
static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
{ NULL, kpidSize, VT_UI4},
{ NULL, kpidPackSize, VT_UI4},
{ NULL, kpidPosixAttrib, VT_UI4}
// { NULL, kpidOffset, VT_UI4}
};
static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidName, VT_BSTR},
{ NULL, kpidBigEndian, VT_BOOL},
{ NULL, kpidCharacts, VT_BSTR},
{ NULL, kpidPhySize, VT_UI4},
{ NULL, kpidHeadersSize, VT_UI4},
{ NULL, kpidNumSubFiles, VT_UI4},
{ NULL, kpidNumBlocks, VT_UI4}
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
HRESULT CHandler::OpenDir(int parent, UInt32 baseOffset, unsigned level)
{
const Byte *p = _data + baseOffset;
bool be = _h.be;
if (!IsDir(p, be))
return S_OK;
UInt32 offset = GetOffset(p, be);
UInt32 size = GetSize(p, be);
if (offset == 0 && size == 0)
return S_OK;
UInt32 end = offset + size;
if (offset < kHeaderSize || end > _size || level > kNumDirLevelsMax)
return S_FALSE;
if (end > _headersSize)
_headersSize = end;
int startIndex = _items.Size();
while (size != 0)
{
if (size < kNodeSize || (UInt32)_items.Size() >= kNumFilesMax)
return S_FALSE;
CItem item;
item.Parent = parent;
item.Offset = offset;
_items.Add(item);
UInt32 nodeLen = kNodeSize + GetNameLen(_data + offset, be);
if (size < nodeLen)
return S_FALSE;
offset += nodeLen;
size -= nodeLen;
}
int endIndex = _items.Size();
for (int i = startIndex; i < endIndex; i++)
{
RINOK(OpenDir(i, _items[i].Offset, level + 1));
}
return S_OK;
}
HRESULT CHandler::Open2(IInStream *inStream)
{
Byte buf[kHeaderSize];
RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize));
if (!_h.Parse(buf))
return S_FALSE;
if (_h.IsVer2())
{
if (_h.Size < kHeaderSize || _h.Size > kArcSizeMax || _h.NumFiles > kNumFilesMax)
return S_FALSE;
}
else
{
UInt64 size;
RINOK(inStream->Seek(0, STREAM_SEEK_END, &size));
if (size > kArcSizeMax)
return S_FALSE;
_h.Size = (UInt32)size;
RINOK(inStream->Seek(kHeaderSize, STREAM_SEEK_SET, NULL));
}
_data = (Byte *)MidAlloc(_h.Size);
if (_data == 0)
return E_OUTOFMEMORY;
memcpy(_data, buf, kHeaderSize);
size_t processed = _h.Size - kHeaderSize;
RINOK(ReadStream(inStream, _data + kHeaderSize, &processed));
if (processed < kNodeSize)
return S_FALSE;
_size = kHeaderSize + (UInt32)processed;
if (_size != _h.Size)
_errorMessage = "Unexpected end of archive";
else
{
SetUi32(_data + 0x20, 0);
if (_h.IsVer2())
if (CrcCalc(_data, _h.Size) != _h.Crc)
_errorMessage = "CRC error";
}
if (_h.IsVer2())
_items.Reserve(_h.NumFiles - 1);
return OpenDir(-1, kHeaderSize, 0);
}
AString CHandler::GetPath(int index) const
{
unsigned len = 0;
int indexMem = index;
do
{
const CItem &item = _items[index];
index = item.Parent;
const Byte *p = _data + item.Offset;
unsigned size = GetNameLen(p, _h.be);
p += kNodeSize;
unsigned i;
for (i = 0; i < size && p[i]; i++);
len += i + 1;
}
while (index >= 0);
len--;
AString path;
char *dest = path.GetBuffer(len) + len;
index = indexMem;
for (;;)
{
const CItem &item = _items[index];
index = item.Parent;
const Byte *p = _data + item.Offset;
unsigned size = GetNameLen(p, _h.be);
p += kNodeSize;
unsigned i;
for (i = 0; i < size && p[i]; i++);
dest -= i;
memcpy(dest, p, i);
if (index < 0)
break;
*(--dest) = CHAR_PATH_SEPARATOR;
}
path.ReleaseBuffer(len);
return path;
}
bool CHandler::GetPackSize(int index, UInt32 &res) const
{
const CItem &item = _items[index];
const Byte *p = _data + item.Offset;
bool be = _h.be;
UInt32 offset = GetOffset(p, be);
if (offset < kHeaderSize)
return false;
UInt32 numBlocks = (GetSize(p, be) + kBlockSize - 1) >> kBlockSizeLog;
UInt32 start = offset + numBlocks * 4;
if (start > _size)
return false;
UInt32 end = Get32(_data + start - 4);
if (end < start)
return false;
res = end - start;
return true;
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)
{
COM_TRY_BEGIN
{
Close();
RINOK(Open2(stream));
_stream = stream;
}
return S_OK;
COM_TRY_END
}
void CHandler::Free()
{
MidFree(_data);
_data = 0;
}
STDMETHODIMP CHandler::Close()
{
_headersSize = 0;
_items.Clear();
_stream.Release();
_errorMessage.Empty();
Free();
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidName:
{
char dest[kHeaderNameSize + 4];
memcpy(dest, _h.Name, kHeaderNameSize);
dest[kHeaderNameSize] = 0;
prop = dest;
break;
}
case kpidBigEndian: prop = _h.be; break;
case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break;
case kpidNumBlocks: if (_h.IsVer2()) prop = _h.NumBlocks; break;
case kpidNumSubFiles: if (_h.IsVer2()) prop = _h.NumFiles; break;
case kpidPhySize: if (_h.IsVer2()) prop = _h.Size; break;
case kpidHeadersSize: prop = _headersSize; break;
case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
const CItem &item = _items[index];
const Byte *p = _data + item.Offset;
bool be = _h.be;
bool isDir = IsDir(p, be);
switch(propID)
{
case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
case kpidIsDir: prop = isDir; break;
// case kpidOffset: prop = (UInt32)GetOffset(p, be); break;
case kpidSize: if (!isDir) prop = GetSize(p, be); break;
case kpidPackSize:
if (!isDir)
{
UInt32 size;
if (GetPackSize(index, size))
prop = size;
}
break;
case kpidPosixAttrib: prop = (UInt32)GetMode(p, be); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
class CCramfsInStream: public CCachedInStream
{
HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize);
public:
CHandler *Handler;
};
HRESULT CCramfsInStream::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
{
return Handler->ReadBlock(blockIndex, dest, blockSize);
}
HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
{
if (!_zlibDecoder)
{
_zlibDecoderSpec = new NCompress::NZlib::CDecoder();
_zlibDecoder = _zlibDecoderSpec;
}
if (!_inStream)
{
_inStreamSpec = new CBufInStream();
_inStream = _inStreamSpec;
}
if (!_outStream)
{
_outStreamSpec = new CBufPtrSeqOutStream();
_outStream = _outStreamSpec;
}
bool be = _h.be;
const Byte *p = _data + (_curBlocksOffset + (UInt32)blockIndex * 4);
UInt32 start = (blockIndex == 0 ? _curBlocksOffset + _curNumBlocks * 4: Get32(p - 4));
UInt32 end = Get32(p);
if (end < start || end > _size)
return S_FALSE;
UInt32 inSize = end - start;
_inStreamSpec->Init(_data + start, inSize);
_outStreamSpec->Init(dest, blockSize);
RINOK(_zlibDecoder->Code(_inStream, _outStream, NULL, NULL, NULL));
return (_zlibDecoderSpec->GetInputProcessedSize() == inSize &&
_outStreamSpec->GetPos() == blockSize) ? S_OK : S_FALSE;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool allFilesMode = (numItems == (UInt32)-1);
if (allFilesMode)
numItems = _items.Size();
if (numItems == 0)
return S_OK;
bool be = _h.be;
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
const Byte *p = _data + _items[allFilesMode ? i : indices[i]].Offset;
if (!IsDir(p, be))
totalSize += GetSize(p, be);
}
extractCallback->SetTotal(totalSize);
UInt64 totalPackSize;
totalSize = totalPackSize = 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 = totalPackSize;
lps->OutSize = totalSize;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> outStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
UInt32 index = allFilesMode ? i : indices[i];
const CItem &item = _items[index];
RINOK(extractCallback->GetStream(index, &outStream, askMode));
const Byte *p = _data + item.Offset;
if (IsDir(p, be))
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
continue;
}
UInt32 curSize = GetSize(p, be);
totalSize += curSize;
UInt32 packSize;
if (GetPackSize(index, packSize))
totalPackSize += packSize;
if (!testMode && !outStream)
continue;
RINOK(extractCallback->PrepareOperation(askMode));
UInt32 offset = GetOffset(p, be);
if (offset < kHeaderSize)
curSize = 0;
int res = NExtract::NOperationResult::kDataError;
{
CMyComPtr<ISequentialInStream> inSeqStream;
CMyComPtr<IInStream> inStream;
HRESULT hres = GetStream(index, &inSeqStream);
if (inSeqStream)
inSeqStream.QueryInterface(IID_IInStream, &inStream);
if (hres == E_OUTOFMEMORY)
return E_OUTOFMEMORY;
if (hres == S_FALSE || !inStream)
res = NExtract::NOperationResult::kUnSupportedMethod;
else
{
RINOK(hres);
if (inStream)
{
HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
if (hres != S_OK && hres != S_FALSE)
{
RINOK(hres);
}
if (copyCoderSpec->TotalSize == curSize && hres == S_OK)
res = NExtract::NOperationResult::kOK;
}
}
}
RINOK(extractCallback->SetOperationResult(res));
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
COM_TRY_BEGIN
const CItem &item = _items[index];
const Byte *p = _data + item.Offset;
bool be = _h.be;
if (IsDir(p, be))
return E_FAIL;
UInt32 size = GetSize(p, be);
UInt32 numBlocks = (size + kBlockSize - 1) >> kBlockSizeLog;
UInt32 offset = GetOffset(p, be);
if (offset < kHeaderSize)
{
if (offset != 0)
return S_FALSE;
CBufInStream *streamSpec = new CBufInStream;
CMyComPtr<IInStream> streamTemp = streamSpec;
streamSpec->Init(NULL, 0);
*stream = streamTemp.Detach();
return S_OK;
}
if (offset + numBlocks * 4 > _size)
return S_FALSE;
UInt32 prev = offset;
for (UInt32 i = 0; i < numBlocks; i++)
{
UInt32 next = Get32(_data + offset + i * 4);
if (next < prev || next > _size)
return S_FALSE;
prev = next;
}
CCramfsInStream *streamSpec = new CCramfsInStream;
CMyComPtr<IInStream> streamTemp = streamSpec;
_curNumBlocks = numBlocks;
_curBlocksOffset = offset;
streamSpec->Handler = this;
if (!streamSpec->Alloc(kBlockSizeLog, 21 - kBlockSizeLog))
return E_OUTOFMEMORY;
streamSpec->Init(size);
*stream = streamTemp.Detach();
return S_OK;
COM_TRY_END
}
static IInArchive *CreateArc() { return new NArchive::NCramfs::CHandler; }
static CArcInfo g_ArcInfo =
{ L"CramFS", L"cramfs", 0, 0xD3, SIGNATURE, kSignatureSize, false, CreateArc, 0 };
REGISTER_ARC(Cramfs)
}}

View File

@@ -3,8 +3,6 @@
#include "StdAfx.h"
#include "Common/ComTry.h"
#include "Common/Defs.h"
#include "Common/NewHandler.h"
#include "Common/StringConvert.h"
#include "Common/StringToInt.h"

View File

@@ -1,118 +1,3 @@
// DeflateProps.cpp
#include "StdAfx.h"
#include "Windows/PropVariant.h"
#include "Common/ParseProperties.h"
#include "DeflateProps.h"
namespace NArchive {
static const UInt32 kAlgo1 = 0;
static const UInt32 kAlgo5 = 1;
static const UInt32 kPasses1 = 1;
static const UInt32 kPasses7 = 3;
static const UInt32 kPasses9 = 10;
static const UInt32 kFb1 = 32;
static const UInt32 kFb7 = 64;
static const UInt32 kFb9 = 128;
void CDeflateProps::Normalize()
{
UInt32 level = Level;
if (level == 0xFFFFFFFF)
level = 5;
if (Algo == 0xFFFFFFFF)
Algo = (level >= 5 ?
kAlgo5 :
kAlgo1);
if (NumPasses == 0xFFFFFFFF)
NumPasses =
(level >= 9 ? kPasses9 :
(level >= 7 ? kPasses7 :
kPasses1));
if (Fb == 0xFFFFFFFF)
Fb =
(level >= 9 ? kFb9 :
(level >= 7 ? kFb7 :
kFb1));
}
HRESULT CDeflateProps::SetCoderProperties(ICompressSetCoderProperties *setCoderProperties)
{
Normalize();
NWindows::NCOM::CPropVariant props[] =
{
Algo,
NumPasses,
Fb,
Mc
};
PROPID propIDs[] =
{
NCoderPropID::kAlgorithm,
NCoderPropID::kNumPasses,
NCoderPropID::kNumFastBytes,
NCoderPropID::kMatchFinderCycles
};
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
if (!McDefined)
numProps--;
return setCoderProperties->SetCoderProperties(propIDs, props, numProps);
}
HRESULT CDeflateProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
Init();
for (int i = 0; i < numProps; i++)
{
UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &prop = values[i];
if (name[0] == L'X')
{
UInt32 a = 9;
RINOK(ParsePropValue(name.Mid(1), prop, a));
Level = a;
}
else if (name.Left(1) == L"A")
{
UInt32 a = kAlgo5;
RINOK(ParsePropValue(name.Mid(1), prop, a));
Algo = a;
}
else if (name.Left(4) == L"PASS")
{
UInt32 a = kPasses9;
RINOK(ParsePropValue(name.Mid(4), prop, a));
NumPasses = a;
}
else if (name.Left(2) == L"FB")
{
UInt32 a = kFb9;
RINOK(ParsePropValue(name.Mid(2), prop, a));
Fb = a;
}
else if (name.Left(2) == L"MC")
{
UInt32 a = 0xFFFFFFFF;
RINOK(ParsePropValue(name.Mid(2), prop, a));
Mc = a;
McDefined = true;
}
else
return E_INVALIDARG;
}
return S_OK;
}
}

View File

@@ -3,33 +3,4 @@
#ifndef __DEFLATE_PROPS_H
#define __DEFLATE_PROPS_H
#include "../ICoder.h"
namespace NArchive {
class CDeflateProps
{
UInt32 Level;
UInt32 NumPasses;
UInt32 Fb;
UInt32 Algo;
UInt32 Mc;
bool McDefined;
void Init()
{
Level = NumPasses = Fb = Algo = Mc = 0xFFFFFFFF;
McDefined = false;
}
void Normalize();
public:
CDeflateProps() { Init(); }
bool IsMaximum() const { return Algo > 0; }
HRESULT SetCoderProperties(ICompressSetCoderProperties *setCoderProperties);
HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
};
}
#endif

View File

@@ -277,9 +277,9 @@ static const CUInt32PCharPair g_AbiOS[] =
static const CUInt32PCharPair g_SegmentFlags[] =
{
{ 1 << 0, "Execute" },
{ 1 << 1, "Write" },
{ 1 << 2, "Read" }
{ 0, "Execute" },
{ 1, "Write" },
{ 2, "Read" }
};
static const char *g_Types[] =

View File

@@ -526,7 +526,14 @@ HRESULT CDatabase::ReadDir(Int32 parent, UInt32 cluster, int level)
item.Attrib = attrib;
item.Flags = p[12];
item.Size = Get32(p + 28);
item.Cluster = Get16(p + 26) | ((UInt32)Get16(p + 20) << 16);
item.Cluster = Get16(p + 26);
if (Header.NumFatBits > 16)
item.Cluster |= ((UInt32)Get16(p + 20) << 16);
else
{
// OS/2 and WinNT probably can store EA (extended atributes) in that field.
}
item.CTime = Get32(p + 14);
item.CTime2 = p[13];
item.ADate = Get16(p + 18);
@@ -578,8 +585,12 @@ HRESULT CDatabase::Open()
return S_FALSE;
UInt64 fileSize;
RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize));
/* we comment that check to support truncated images */
/*
if (fileSize < Header.GetPhySize())
return S_FALSE;
*/
if (Header.IsFat32())
{

View File

@@ -18,11 +18,10 @@
#include "../Compress/DeflateDecoder.h"
#include "../Compress/DeflateEncoder.h"
#include "Common/HandlerOut.h"
#include "Common/InStreamWithCRC.h"
#include "Common/OutStreamWithCRC.h"
#include "DeflateProps.h"
#define Get32(p) GetUi32(p)
using namespace NWindows;
@@ -305,7 +304,7 @@ class CHandler:
CMyComPtr<ICompressCoder> _decoder;
NCompress::NDeflate::NDecoder::CCOMCoder *_decoderSpec;
CDeflateProps _method;
CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
@@ -321,7 +320,7 @@ public:
}
};
STATPROPSTG kProps[] =
static STATPROPSTG const kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidSize, VT_UI8},
@@ -545,7 +544,7 @@ static HRESULT UpdateArchive(
ISequentialOutStream *outStream,
UInt64 unpackSize,
const CItem &newItem,
CDeflateProps &deflateProps,
const CSingleMethodProps &props,
IArchiveUpdateCallback *updateCallback)
{
UInt64 complexity = 0;
@@ -567,7 +566,7 @@ static HRESULT UpdateArchive(
CItem item = newItem;
item.Method = NHeader::NCompressionMethod::kDeflate;
item.ExtraFlags = deflateProps.IsMaximum() ?
item.ExtraFlags = props.GetLevel() >= 7 ?
NHeader::NExtraFlags::kMaximum :
NHeader::NExtraFlags::kFastest;
@@ -577,7 +576,7 @@ static HRESULT UpdateArchive(
NCompress::NDeflate::NEncoder::CCOMCoder *deflateEncoderSpec = new NCompress::NDeflate::NEncoder::CCOMCoder;
CMyComPtr<ICompressCoder> deflateEncoder = deflateEncoderSpec;
RINOK(deflateProps.SetCoderProperties(deflateEncoderSpec));
RINOK(props.SetCoderProps(deflateEncoderSpec, NULL));
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
item.Crc = inStreamSpec->GetCRC();
@@ -616,8 +615,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (prop.vt != VT_FILETIME)
return E_INVALIDARG;
utcTime = prop.filetime;
if (!NTime::FileTimeToUnixTime(utcTime, newItem.Time))
return E_INVALIDARG;
NTime::FileTimeToUnixTime(utcTime, newItem.Time);
}
{
NCOM::CPropVariant prop;
@@ -658,8 +656,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
return UpdateArchive(outStream, size, newItem, _method, updateCallback);
return UpdateArchive(outStream, size, newItem, _props, updateCallback);
}
if (indexInArchive != 0)
@@ -680,7 +677,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
return _method.SetProperties(names, values, numProps);
return _props.SetProperties(names, values, numProps);
}
static IInArchive *CreateArc() { return new CHandler; }

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -3,9 +3,7 @@
#include "StdAfx.h"
#include "Common/ComTry.h"
#include "Common/Defs.h"
#include "Common/IntToString.h"
#include "Common/NewHandler.h"
#include "Common/StringConvert.h"
#include "Windows/PropVariant.h"
@@ -26,7 +24,7 @@ using namespace NTime;
namespace NArchive {
namespace NIso {
STATPROPSTG kProps[] =
static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -35,8 +33,17 @@ STATPROPSTG kProps[] =
{ NULL, kpidMTime, VT_FILETIME}
};
static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidComment, VT_BSTR},
{ NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidMTime, VT_FILETIME}
// { NULL, kpidPhySize, VT_UI8},
// { NULL, kpidHeadersSize, VT_UI8}
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
@@ -68,6 +75,58 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
static void AddString(AString &s, const char *name, const Byte *p, int size)
{
int i;
for (i = 0; i < size && p[i]; i++);
for (; i > 0 && p[i - 1] == ' '; i--);
if (i != 0)
{
AString d;
memcpy(d.GetBuffer(i), p, i);
d.ReleaseBuffer(i);
s += '\n';
s += name;
s += ": ";
s += d;
}
}
#define ADD_STRING(n, v) AddString(s, n, vol. ## v, sizeof(vol. ## v))
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
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; }
// case kpidPhySize: break;
// case kpidHeadersSize: break;
case kpidError: if (_archive.IncorrectBigEndian) prop = "Incorrect big-endian headers"; break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -89,9 +148,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = (const wchar_t *)s;
break;
}
case kpidIsDir:
prop = false;
break;
case kpidIsDir: prop = false; break;
case kpidSize:
case kpidPackSize:
prop = (UInt64)_archive.GetBootItemSize(index);
@@ -115,17 +172,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
int pos = s.ReverseFind(L';');
if (pos >= 0 && pos == s.Length() - 2)
if (s[s.Length() - 1] == L'1')
if (s.Back() == L'1')
s = s.Left(pos);
if (!s.IsEmpty())
if (s[s.Length() - 1] == L'.')
s = s.Left(s.Length() - 1);
if (s.Back() == L'.')
s.DeleteBack();
prop = (const wchar_t *)NItemName::GetOSName2(s);
}
break;
case kpidIsDir:
prop = item.IsDir();
break;
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize:
case kpidPackSize:
if (!item.IsDir())
@@ -133,16 +188,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
case kpidMTime:
{
FILETIME utcFileTime;
if (item.DateTime.GetFileTime(utcFileTime))
prop = utcFileTime;
/*
else
{
utcFileTime.dwLowDateTime = 0;
utcFileTime.dwHighDateTime = 0;
}
*/
FILETIME utc;
if (item.DateTime.GetFileTime(utc))
prop = utc;
break;
}
}
@@ -163,20 +211,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
for(i = 0; i < numItems; 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 += item.DataLength;
}
else
{
totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
}
}
extractCallback->SetTotal(totalSize);
UInt64 currentTotalSize = 0;

View File

@@ -65,7 +65,7 @@ UInt16 CInArchive::ReadUInt16()
for (int i = 0; i < 2; i++)
{
if (b[i] != b[3 - i])
throw 1;
IncorrectBigEndian = true;
value |= ((UInt16)(b[i]) << (8 * i));
}
return (UInt16)value;
@@ -440,6 +440,7 @@ HRESULT CInArchive::Open(IInStream *inStream)
void CInArchive::Clear()
{
IncorrectBigEndian = false;
Refs.Clear();
_rootDir.Clear();
VolDescs.Clear();

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