Compare commits

...

7 Commits
15.07 ... 15.14

Author SHA1 Message Date
Igor Pavlov
c20d013055 15.14 2016-05-28 00:16:58 +01:00
Igor Pavlov
9608215ad8 15.13 2016-05-28 00:16:58 +01:00
Igor Pavlov
5de23c1deb 15.12 2016-05-28 00:16:58 +01:00
Igor Pavlov
e24f7fba53 15.11 2016-05-28 00:16:57 +01:00
Igor Pavlov
7c8a265a15 15.10 2016-05-28 00:16:57 +01:00
Igor Pavlov
a663a6deb7 15.09 2016-05-28 00:16:56 +01:00
Igor Pavlov
6543c28020 15.08 2016-05-28 00:16:56 +01:00
260 changed files with 8368 additions and 2816 deletions

82
C/7z.h
View File

@@ -1,5 +1,5 @@
/* 7z.h -- 7z interface /* 7z.h -- 7z interface
2014-02-08 : Igor Pavlov : Public domain */ 2015-11-18 : Igor Pavlov : Public domain */
#ifndef __7Z_H #ifndef __7Z_H
#define __7Z_H #define __7Z_H
@@ -48,21 +48,10 @@ typedef struct
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX]; UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX]; CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX]; CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
UInt64 CodersUnpackSizes[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder; } CSzFolder;
/*
typedef struct
{
size_t CodersDataOffset;
size_t UnpackSizeDataOffset;
// UInt32 StartCoderUnpackSizesIndex;
UInt32 StartPackStreamIndex;
// UInt32 IndexOfMainOutStream;
} CSzFolder2;
*/
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes); SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct typedef struct
{ {
@@ -92,47 +81,25 @@ typedef struct
UInt32 NumPackStreams; UInt32 NumPackStreams;
UInt32 NumFolders; UInt32 NumFolders;
UInt64 *PackPositions; // NumPackStreams + 1 UInt64 *PackPositions; // NumPackStreams + 1
CSzBitUi32s FolderCRCs; CSzBitUi32s FolderCRCs; // NumFolders
size_t *FoCodersOffsets; size_t *FoCodersOffsets; // NumFolders + 1
size_t *FoSizesOffsets; UInt32 *FoStartPackStreamIndex; // NumFolders + 1
// UInt32 StartCoderUnpackSizesIndex; UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
UInt32 *FoStartPackStreamIndex; Byte *FoToMainUnpackSizeIndex; // NumFolders
UInt64 *CoderUnpackSizes; // for all coders in all folders
// CSzFolder2 *Folders; // +1 item for sum values
Byte *CodersData; Byte *CodersData;
Byte *UnpackSizesData;
size_t UnpackSizesDataSize;
// UInt64 *CoderUnpackSizes;
} CSzAr; } CSzAr;
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos, ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain); ISzAlloc *allocMain);
/*
SzExtract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
typedef struct typedef struct
{ {
CSzAr db; CSzAr db;
@@ -142,7 +109,7 @@ typedef struct
UInt32 NumFiles; UInt32 NumFiles;
UInt64 *UnpackPositions; UInt64 *UnpackPositions; // NumFiles + 1
// Byte *IsEmptyFiles; // Byte *IsEmptyFiles;
Byte *IsDirs; Byte *IsDirs;
CSzBitUi32s CRCs; CSzBitUi32s CRCs;
@@ -152,9 +119,8 @@ typedef struct
CSzBitUi64s MTime; CSzBitUi64s MTime;
CSzBitUi64s CTime; CSzBitUi64s CTime;
// UInt32 *FolderStartPackStreamIndex; UInt32 *FolderToFile; // NumFolders + 1
UInt32 *FolderStartFileIndex; // + 1 UInt32 *FileToFolder; // NumFiles
UInt32 *FileIndexToFolderIndexMap;
size_t *FileNameOffsets; /* in 2-byte steps */ size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */ Byte *FileNames; /* UTF-16-LE */
@@ -182,6 +148,28 @@ size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest); UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/ */
/*
SzArEx_Extract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
SRes SzArEx_Extract( SRes SzArEx_Extract(
const CSzArEx *db, const CSzArEx *db,
ILookInStream *inStream, ILookInStream *inStream,

View File

@@ -1,5 +1,5 @@
/* 7zAlloc.c -- Allocation functions /* 7zAlloc.c -- Allocation functions
2015-02-21 : Igor Pavlov : Public domain */ 2015-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -26,7 +26,7 @@ void *SzAlloc(void *p, size_t size)
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount);
g_allocCount++; g_allocCount++;
#endif #endif
return malloc(size); return malloc(size);
@@ -51,7 +51,7 @@ void *SzAllocTemp(void *p, size_t size)
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp);
g_allocCountTemp++; g_allocCountTemp++;
#ifdef _WIN32 #ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size); return HeapAlloc(GetProcessHeap(), 0, size);

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder /* 7zDec.c -- Decoding from 7z folder
2015-08-01 : Igor Pavlov : Public domain */ 2015-11-18 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -8,6 +8,7 @@
/* #define _7ZIP_PPMD_SUPPPORT */ /* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h" #include "7z.h"
#include "7zCrc.h"
#include "Bcj2.h" #include "Bcj2.h"
#include "Bra.h" #include "Bra.h"
@@ -160,14 +161,23 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
inSize -= inProcessed; inSize -= inProcessed;
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{ {
if (state.dicBufSize != outSize || lookahead != 0 || if (outSize != state.dicPos || inSize != 0)
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
break; break;
} }
if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
break;
if (inProcessed == 0 && dicPos == state.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed); res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@@ -213,13 +223,20 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
inSize -= inProcessed; inSize -= inProcessed;
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{ {
if (state.decoder.dicBufSize != outSize || lookahead != 0 || if (outSize != state.decoder.dicPos || inSize != 0)
(status != LZMA_STATUS_FINISHED_WITH_MARK))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
break; break;
} }
if (inProcessed == 0 && dicPos == state.decoder.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed); res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@@ -537,33 +554,38 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
SRes res; SRes res;
CSzFolder folder; CSzFolder folder;
CSzData sd; CSzData sd;
CSzData sdSizes;
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data; sd.Data = data;
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex]; sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
sdSizes.Data = p->UnpackSizesData + p->FoSizesOffsets[folderIndex]; res = SzGetNextFolderItem(&folder, &sd);
sdSizes.Size =
p->FoSizesOffsets[folderIndex + 1] -
p->FoSizesOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd, &sdSizes);
if (res != SZ_OK) if (res != SZ_OK)
return res; return res;
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.UnpackStream]) if (sd.Size != 0
|| folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
|| outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
{ {
unsigned i; unsigned i;
Byte *tempBuf[3] = { 0, 0, 0}; Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes,
res = SzFolder_Decode2(&folder, data,
&p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
p->PackPositions + p->FoStartPackStreamIndex[folderIndex], p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
inStream, startPos, inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf); outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]); IAlloc_Free(allocMain, tempBuf[i]);
if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
return res; return res;
} }
} }

View File

@@ -1,9 +1,9 @@
#define MY_VER_MAJOR 15 #define MY_VER_MAJOR 15
#define MY_VER_MINOR 07 #define MY_VER_MINOR 14
#define MY_VER_BUILD 00 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "15.07" #define MY_VERSION_NUMBERS "15.14"
#define MY_VERSION "15.07 beta" #define MY_VERSION "15.14"
#define MY_DATE "2015-09-17" #define MY_DATE "2015-12-31"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov" #define MY_AUTHOR_NAME "Igor Pavlov"

View File

@@ -513,4 +513,3 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
#endif #endif
return Groups[0]; return Groups[0];
} }

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2015-08-02: Igor Pavlov : Public domain */ 2015-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
@@ -10,14 +10,18 @@ EXTERN_C_BEGIN
/* /*
MY_CPU_LE means that CPU is LITTLE ENDIAN. MY_CPU_LE means that CPU is LITTLE ENDIAN.
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). MY_CPU_BE means that CPU is BIG ENDIAN.
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
*/ */
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) #if defined(_M_X64) \
#define MY_CPU_AMD64 || defined(_M_AMD64) \
|| defined(__x86_64__) \
|| defined(__AMD64__) \
|| defined(__amd64__)
#define MY_CPU_AMD64
#endif #endif
#if defined(MY_CPU_AMD64) \ #if defined(MY_CPU_AMD64) \
@@ -52,10 +56,6 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_IA64_LE #define MY_CPU_IA64_LE
#endif #endif
#if defined(MY_CPU_X86_OR_AMD64)
#define MY_CPU_LE_UNALIGN
#endif
#if defined(MY_CPU_X86_OR_AMD64) \ #if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \ || defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_IA64_LE) \ || defined(MY_CPU_IA64_LE) \
@@ -65,7 +65,8 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|| defined(__AARCH64EL__) \ || defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \ || defined(__MIPSEL__) \
|| defined(__MIPSEL) \ || defined(__MIPSEL) \
|| defined(_MIPSEL) || defined(_MIPSEL) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE #define MY_CPU_LE
#endif #endif
@@ -76,7 +77,11 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|| defined(__MIPSEB__) \ || defined(__MIPSEB__) \
|| defined(__MIPSEB) \ || defined(__MIPSEB) \
|| defined(_MIPSEB) \ || defined(_MIPSEB) \
|| defined(__m68k__) || defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE #define MY_CPU_BE
#endif #endif
@@ -85,6 +90,14 @@ Stop_Compiling_Bad_Endian
#endif #endif
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
/* || defined(__AARCH64EL__) */
#define MY_CPU_LE_UNALIGN
#endif
#endif
#ifdef MY_CPU_LE_UNALIGN #ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) #define GetUi16(p) (*(const UInt16 *)(const void *)(p))
@@ -128,6 +141,8 @@ Stop_Compiling_Bad_Endian
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300) #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
/* Note: we use bswap instruction, that is unsupported in 386 cpu */
#include <stdlib.h> #include <stdlib.h>
#pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_ulong)
@@ -137,6 +152,13 @@ Stop_Compiling_Bad_Endian
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
#else #else
#define GetBe32(p) ( \ #define GetBe32(p) ( \

View File

@@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms /* LzFind.c -- Match finder for LZ algorithms
2015-05-15 : Igor Pavlov : Public domain */ 2015-10-15 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -11,7 +11,7 @@
#define kEmptyHashValue 0 #define kEmptyHashValue 0
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) #define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ #define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
#define kNormalizeMask (~(kNormalizeStepMin - 1)) #define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
#define kMaxHistorySize ((UInt32)7 << 29) #define kMaxHistorySize ((UInt32)7 << 29)
#define kStartMaxLen 3 #define kStartMaxLen 3
@@ -60,9 +60,11 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
if (p->streamEndWasReached || p->result != SZ_OK) if (p->streamEndWasReached || p->result != SZ_OK)
return; return;
/* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */
if (p->directInput) if (p->directInput)
{ {
UInt32 curSize = 0xFFFFFFFF - p->streamPos; UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos);
if (curSize > p->directInputRem) if (curSize > p->directInputRem)
curSize = (UInt32)p->directInputRem; curSize = (UInt32)p->directInputRem;
p->directInputRem -= curSize; p->directInputRem -= curSize;
@@ -97,7 +99,7 @@ void MatchFinder_MoveBlock(CMatchFinder *p)
{ {
memmove(p->bufferBase, memmove(p->bufferBase,
p->buffer - p->keepSizeBefore, p->buffer - p->keepSizeBefore,
(size_t)(p->streamPos - p->pos + p->keepSizeBefore)); (size_t)(p->streamPos - p->pos) + p->keepSizeBefore);
p->buffer = p->bufferBase + p->keepSizeBefore; p->buffer = p->bufferBase + p->keepSizeBefore;
} }
@@ -290,7 +292,7 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
p->posLimit = p->pos + limit; p->posLimit = p->pos + limit;
} }
void MatchFinder_Init(CMatchFinder *p) void MatchFinder_Init_2(CMatchFinder *p, int readData)
{ {
UInt32 i; UInt32 i;
UInt32 *hash = p->hash; UInt32 *hash = p->hash;
@@ -303,10 +305,18 @@ void MatchFinder_Init(CMatchFinder *p)
p->pos = p->streamPos = p->cyclicBufferSize; p->pos = p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK; p->result = SZ_OK;
p->streamEndWasReached = 0; p->streamEndWasReached = 0;
MatchFinder_ReadBlock(p);
if (readData)
MatchFinder_ReadBlock(p);
MatchFinder_SetLimits(p); MatchFinder_SetLimits(p);
} }
void MatchFinder_Init(CMatchFinder *p)
{
MatchFinder_Init_2(p, True);
}
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
{ {
return (p->pos - p->historySize - 1) & kNormalizeMask; return (p->pos - p->historySize - 1) & kNormalizeMask;

View File

@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2015-05-01 : Igor Pavlov : Public domain */ 2015-10-15 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H #ifndef __LZ_FIND_H
#define __LZ_FIND_H #define __LZ_FIND_H
@@ -53,6 +53,11 @@ typedef struct _CMatchFinder
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
#define Inline_MatchFinder_IsFinishedOK(p) \
((p)->streamEndWasReached \
&& (p)->streamPos == (p)->pos \
&& (!(p)->directInput || (p)->directInputRem == 0))
int MatchFinder_NeedMove(CMatchFinder *p); int MatchFinder_NeedMove(CMatchFinder *p);
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
void MatchFinder_MoveBlock(CMatchFinder *p); void MatchFinder_MoveBlock(CMatchFinder *p);
@@ -98,9 +103,12 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init_2(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p); void MatchFinder_Init(CMatchFinder *p);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);

View File

@@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms /* LzFindMt.c -- multithreaded Match finder for LZ algorithms
2015-05-03 : Igor Pavlov : Public domain */ 2015-10-15 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -173,12 +173,12 @@ static void HashThreadFunc(CMatchFinderMt *mt)
CriticalSection_Enter(&mt->btSync.cs); CriticalSection_Enter(&mt->btSync.cs);
CriticalSection_Enter(&mt->hashSync.cs); CriticalSection_Enter(&mt->hashSync.cs);
{ {
const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf); const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
const Byte *afterPtr; ptrdiff_t offset;
MatchFinder_MoveBlock(mf); MatchFinder_MoveBlock(mf);
afterPtr = MatchFinder_GetPointerToCurrentPos(mf); offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
mt->pointerToCurPos -= beforePtr - afterPtr; mt->pointerToCurPos -= offset;
mt->buffer -= beforePtr - afterPtr; mt->buffer -= offset;
} }
CriticalSection_Leave(&mt->btSync.cs); CriticalSection_Leave(&mt->btSync.cs);
CriticalSection_Leave(&mt->hashSync.cs); CriticalSection_Leave(&mt->hashSync.cs);
@@ -501,8 +501,11 @@ void MatchFinderMt_Init(CMatchFinderMt *p)
CMatchFinder *mf = p->MatchFinder; CMatchFinder *mf = p->MatchFinder;
p->btBufPos = p->btBufPosLimit = 0; p->btBufPos = p->btBufPosLimit = 0;
p->hashBufPos = p->hashBufPosLimit = 0; p->hashBufPos = p->hashBufPosLimit = 0;
MatchFinder_Init(mf);
p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf); /* Init without data reading. We don't want to read data in this thread */
MatchFinder_Init_2(mf, False);
p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
p->btNumAvailBytes = 0; p->btNumAvailBytes = 0;
p->lzPos = p->historySize + 1; p->lzPos = p->historySize + 1;

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2014-10-29 : Igor Pavlov : Public domain */ 2015-11-09 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
@@ -103,8 +103,8 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{ {
case LZMA2_STATE_CONTROL: case LZMA2_STATE_CONTROL:
p->control = b; p->control = b;
PRF(printf("\n %4X ", p->decoder.dicPos)); PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", b)); PRF(printf(" %2X", (unsigned)b));
if (p->control == 0) if (p->control == 0)
return LZMA2_STATE_FINISHED; return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
@@ -124,7 +124,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_UNPACK1: case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b; p->unpackSize |= (UInt32)b;
p->unpackSize++; p->unpackSize++;
PRF(printf(" %8d", p->unpackSize)); PRF(printf(" %8u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0: case LZMA2_STATE_PACK0:
@@ -134,7 +134,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_PACK1: case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b; p->packSize |= (UInt32)b;
p->packSize++; p->packSize++;
PRF(printf(" %8d", p->packSize)); PRF(printf(" %8u", (unsigned)p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);

View File

@@ -1,5 +1,5 @@
/* Lzma2Enc.c -- LZMA2 Encoder /* Lzma2Enc.c -- LZMA2 Encoder
2015-09-16 : Igor Pavlov : Public domain */ 2015-10-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -479,7 +479,7 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
for (i = 0; i < p->props.numBlockThreads; i++) for (i = 0; i < p->props.numBlockThreads; i++)
{ {
CLzma2EncInt *t = &p->coders[i]; CLzma2EncInt *t = &p->coders[(unsigned)i];
if (!t->enc) if (!t->enc)
{ {
t->enc = LzmaEnc_Create(p->alloc); t->enc = LzmaEnc_Create(p->alloc);
@@ -489,11 +489,7 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
} }
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
if (p->props.numBlockThreads <= 1) if (p->props.numBlockThreads > 1)
#endif
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
#ifndef _7ZIP_ST
{ {
CMtCallbackImp mtCallback; CMtCallbackImp mtCallback;
@@ -508,9 +504,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
p->mtCoder.blockSize = p->props.blockSize; p->mtCoder.blockSize = p->props.blockSize;
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16; p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
if (p->mtCoder.destBlockSize < p->props.blockSize)
{
p->mtCoder.destBlockSize = (size_t)0 - 1;
if (p->mtCoder.destBlockSize < p->props.blockSize)
return SZ_ERROR_FAIL;
}
p->mtCoder.numThreads = p->props.numBlockThreads; p->mtCoder.numThreads = p->props.numBlockThreads;
return MtCoder_Code(&p->mtCoder); return MtCoder_Code(&p->mtCoder);
} }
#endif #endif
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
} }

View File

@@ -1,5 +1,7 @@
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder /* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
2009-08-14 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Lzma86.h" #include "Lzma86.h"
@@ -7,8 +9,8 @@
#include "Bra.h" #include "Bra.h"
#include "LzmaDec.h" #include "LzmaDec.h"
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); } static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
{ {

View File

@@ -1,5 +1,7 @@
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
2009-08-14 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
@@ -11,8 +13,8 @@
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); } static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
int level, UInt32 dictSize, int filterMode) int level, UInt32 dictSize, int filterMode)

View File

@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder /* LzmaEnc.c -- LZMA Encoder
2015-05-15 Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -505,8 +505,8 @@ static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11,
static void RangeEnc_Construct(CRangeEnc *p) static void RangeEnc_Construct(CRangeEnc *p)
{ {
p->outStream = 0; p->outStream = NULL;
p->bufBase = 0; p->bufBase = NULL;
} }
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) #define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
@@ -514,10 +514,10 @@ static void RangeEnc_Construct(CRangeEnc *p)
#define RC_BUF_SIZE (1 << 16) #define RC_BUF_SIZE (1 << 16)
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
{ {
if (p->bufBase == 0) if (!p->bufBase)
{ {
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
if (p->bufBase == 0) if (!p->bufBase)
return 0; return 0;
p->bufLim = p->bufBase + RC_BUF_SIZE; p->bufLim = p->bufBase + RC_BUF_SIZE;
} }
@@ -854,7 +854,7 @@ static void MovePos(CLzmaEnc *p, UInt32 num)
{ {
#ifdef SHOW_STAT #ifdef SHOW_STAT
g_STAT_OFFSET += num; g_STAT_OFFSET += num;
printf("\n MovePos %d", num); printf("\n MovePos %u", num);
#endif #endif
if (num != 0) if (num != 0)
@@ -871,12 +871,12 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
#ifdef SHOW_STAT #ifdef SHOW_STAT
printf("\n i = %d numPairs = %d ", g_STAT_OFFSET, numPairs / 2); printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
g_STAT_OFFSET++; g_STAT_OFFSET++;
{ {
UInt32 i; UInt32 i;
for (i = 0; i < numPairs; i += 2) for (i = 0; i < numPairs; i += 2)
printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
} }
#endif #endif
@@ -1167,12 +1167,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
cur = 0; cur = 0;
#ifdef SHOW_STAT2 #ifdef SHOW_STAT2
if (position >= 0) /* if (position >= 0) */
{ {
unsigned i; unsigned i;
printf("\n pos = %4X", position); printf("\n pos = %4X", position);
for (i = cur; i <= lenEnd; i++) for (i = cur; i <= lenEnd; i++)
printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
} }
#endif #endif
@@ -1397,13 +1397,13 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{ {
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes; UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice;
if (limit > numAvailFull) if (limit > numAvailFull)
limit = numAvailFull; limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1; lenTest2 -= lenTest + 1;
if (lenTest2 >= 2) if (lenTest2 >= 2)
{ {
UInt32 nextRepMatchPrice;
UInt32 state2 = kRepNextStates[state]; UInt32 state2 = kRepNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = UInt32 curAndLenCharPrice =
@@ -1487,13 +1487,13 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
const Byte *data2 = data - curBack - 1; const Byte *data2 = data - curBack - 1;
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes; UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice;
if (limit > numAvailFull) if (limit > numAvailFull)
limit = numAvailFull; limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1; lenTest2 -= lenTest + 1;
if (lenTest2 >= 2) if (lenTest2 >= 2)
{ {
UInt32 nextRepMatchPrice;
UInt32 state2 = kMatchNextStates[state]; UInt32 state2 = kMatchNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = curAndLenPrice + UInt32 curAndLenCharPrice = curAndLenPrice +
@@ -1749,15 +1749,15 @@ void LzmaEnc_Construct(CLzmaEnc *p)
#endif #endif
LzmaEnc_InitPriceTables(p->ProbPrices); LzmaEnc_InitPriceTables(p->ProbPrices);
p->litProbs = 0; p->litProbs = NULL;
p->saveState.litProbs = 0; p->saveState.litProbs = NULL;
} }
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
{ {
void *p; void *p;
p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
if (p != 0) if (p)
LzmaEnc_Construct((CLzmaEnc *)p); LzmaEnc_Construct((CLzmaEnc *)p);
return p; return p;
} }
@@ -1766,8 +1766,8 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
{ {
alloc->Free(alloc, p->litProbs); alloc->Free(alloc, p->litProbs);
alloc->Free(alloc, p->saveState.litProbs); alloc->Free(alloc, p->saveState.litProbs);
p->litProbs = 0; p->litProbs = NULL;
p->saveState.litProbs = 0; p->saveState.litProbs = NULL;
} }
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
@@ -1829,7 +1829,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
len = GetOptimum(p, nowPos32, &pos); len = GetOptimum(p, nowPos32, &pos);
#ifdef SHOW_STAT2 #ifdef SHOW_STAT2
printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);
#endif #endif
posState = nowPos32 & p->pbMask; posState = nowPos32 & p->pbMask;
@@ -1963,12 +1963,12 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
{ {
unsigned lclp = p->lc + p->lp; unsigned lclp = p->lc + p->lp;
if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
{ {
LzmaEnc_FreeLits(p, alloc); LzmaEnc_FreeLits(p, alloc);
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
if (p->litProbs == 0 || p->saveState.litProbs == 0) if (!p->litProbs || !p->saveState.litProbs)
{ {
LzmaEnc_FreeLits(p, alloc); LzmaEnc_FreeLits(p, alloc);
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
@@ -2140,6 +2140,7 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
#endif #endif
} }
typedef struct typedef struct
{ {
ISeqOutStream funcTable; ISeqOutStream funcTable;
@@ -2169,12 +2170,14 @@ UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
} }
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
{ {
const CLzmaEnc *p = (CLzmaEnc *)pp; const CLzmaEnc *p = (CLzmaEnc *)pp;
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
} }
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
{ {
@@ -2209,6 +2212,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
return res; return res;
} }
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
@@ -2222,9 +2226,9 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
for (;;) for (;;)
{ {
res = LzmaEnc_CodeOneBlock(p, False, 0, 0); res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
if (res != SZ_OK || p->finished != 0) if (res != SZ_OK || p->finished)
break; break;
if (progress != 0) if (progress)
{ {
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
if (res != SZ_OK) if (res != SZ_OK)
@@ -2234,10 +2238,19 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
} }
} }
} }
LzmaEnc_Finish(p); LzmaEnc_Finish(p);
/*
if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
res = SZ_ERROR_FAIL;
}
*/
return res; return res;
} }
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
ISzAlloc *alloc, ISzAlloc *allocBig) ISzAlloc *alloc, ISzAlloc *allocBig)
{ {
@@ -2245,6 +2258,7 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
} }
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -2272,6 +2286,7 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
return SZ_OK; return SZ_OK;
} }
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{ {
@@ -2280,19 +2295,22 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
CSeqOutStreamBuf outStream; CSeqOutStreamBuf outStream;
LzmaEnc_SetInputBuf(p, src, srcLen);
outStream.funcTable.Write = MyWrite; outStream.funcTable.Write = MyWrite;
outStream.data = dest; outStream.data = dest;
outStream.rem = *destLen; outStream.rem = *destLen;
outStream.overflow = False; outStream.overflow = False;
p->writeEndMark = writeEndMark; p->writeEndMark = writeEndMark;
p->rc.outStream = &outStream.funcTable; p->rc.outStream = &outStream.funcTable;
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
if (res == SZ_OK) if (res == SZ_OK)
{
res = LzmaEnc_Encode2(p, progress); res = LzmaEnc_Encode2(p, progress);
if (res == SZ_OK && p->nowPos64 != srcLen)
res = SZ_ERROR_FAIL;
}
*destLen -= outStream.rem; *destLen -= outStream.rem;
if (outStream.overflow) if (outStream.overflow)
@@ -2300,13 +2318,14 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
return res; return res;
} }
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{ {
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
SRes res; SRes res;
if (p == 0) if (!p)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
res = LzmaEnc_SetProps(p, props); res = LzmaEnc_SetProps(p, props);

View File

@@ -1,10 +1,8 @@
/* MtCoder.c -- Multi-thread Coder /* MtCoder.c -- Multi-thread Coder
2010-09-24 : Igor Pavlov : Public domain */ 2015-10-13 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <stdio.h>
#include "MtCoder.h" #include "MtCoder.h"
void LoopThread_Construct(CLoopThread *p) void LoopThread_Construct(CLoopThread *p)
@@ -120,7 +118,7 @@ void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
LoopThread_Construct(&p->thread); LoopThread_Construct(&p->thread);
} }
#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; } #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
static void CMtThread_CloseEvents(CMtThread *p) static void CMtThread_CloseEvents(CMtThread *p)
{ {

View File

@@ -1,5 +1,5 @@
/* Ppmd7.c -- PPMdH codec /* Ppmd7.c -- PPMdH codec
2010-03-12 : Igor Pavlov : Public domain 2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -66,7 +66,7 @@ void Ppmd7_Construct(CPpmd7 *p)
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{ {
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
do { p->Units2Indx[k++] = (Byte)i; } while(--step); do { p->Units2Indx[k++] = (Byte)i; } while (--step);
p->Indx2Units[i] = (Byte)k; p->Indx2Units[i] = (Byte)k;
} }
@@ -257,7 +257,7 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
#define MyMem12Cpy(dest, src, num) \ #define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{ {

View File

@@ -1,5 +1,5 @@
/* Ppmd7Enc.c -- PPMdH Encoder /* Ppmd7Enc.c -- PPMdH Encoder
2010-03-12 : Igor Pavlov : Public domain 2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -26,7 +26,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
temp = 0xFF; temp = 0xFF;
} }
while(--p->CacheSize != 0); while (--p->CacheSize != 0);
p->Cache = (Byte)((UInt32)p->Low >> 24); p->Cache = (Byte)((UInt32)p->Low >> 24);
} }
p->CacheSize++; p->CacheSize++;

View File

@@ -1,5 +1,5 @@
/* Ppmd8.c -- PPMdI codec /* Ppmd8.c -- PPMdI codec
2013-11-12 : Igor Pavlov : Public domain 2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */ This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -67,7 +67,7 @@ void Ppmd8_Construct(CPpmd8 *p)
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{ {
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
do { p->Units2Indx[k++] = (Byte)i; } while(--step); do { p->Units2Indx[k++] = (Byte)i; } while (--step);
p->Indx2Units[i] = (Byte)k; p->Indx2Units[i] = (Byte)k;
} }
@@ -241,7 +241,7 @@ static void *AllocUnits(CPpmd8 *p, unsigned indx)
#define MyMem12Cpy(dest, src, num) \ #define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU) static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{ {

View File

@@ -1,5 +1,5 @@
/* Crypto/Sha256.c -- SHA-256 Hash /* Crypto/Sha256.c -- SHA-256 Hash
2015-03-02 : Igor Pavlov : Public domain 2015-11-14 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */ This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Precomp.h" #include "Precomp.h"
@@ -113,10 +113,26 @@ static void Sha256_WriteByteBlock(CSha256 *p)
{ {
UInt32 W[16]; UInt32 W[16];
unsigned j; unsigned j;
UInt32 *state = p->state; UInt32 *state;
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
UInt32 a,b,c,d,e,f,g,h; UInt32 a,b,c,d,e,f,g,h;
#else
UInt32 T[8];
#endif
for (j = 0; j < 16; j += 4)
{
const Byte *ccc = p->buffer + j * 4;
W[j ] = GetBe32(ccc);
W[j + 1] = GetBe32(ccc + 4);
W[j + 2] = GetBe32(ccc + 8);
W[j + 3] = GetBe32(ccc + 12);
}
state = p->state;
#ifdef _SHA256_UNROLL2
a = state[0]; a = state[0];
b = state[1]; b = state[1];
c = state[2]; c = state[2];
@@ -126,17 +142,10 @@ static void Sha256_WriteByteBlock(CSha256 *p)
g = state[6]; g = state[6];
h = state[7]; h = state[7];
#else #else
UInt32 T[8];
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
T[j] = state[j]; T[j] = state[j];
#endif #endif
for (j = 0; j < 16; j += 2)
{
W[j ] = GetBe32(p->buffer + j * 4);
W[j + 1] = GetBe32(p->buffer + j * 4 + 4);
}
for (j = 0; j < 64; j += 16) for (j = 0; j < 64; j += 16)
{ {
RX_16 RX_16
@@ -226,11 +235,13 @@ void Sha256_Final(CSha256 *p, Byte *digest)
Sha256_WriteByteBlock(p); Sha256_WriteByteBlock(p);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i += 2)
{ {
UInt32 v = p->state[i]; UInt32 v0 = p->state[i];
SetBe32(digest, v); UInt32 v1 = p->state[i + 1];
digest += 4; SetBe32(digest , v0);
SetBe32(digest + 4, v1);
digest += 8;
} }
Sha256_Init(p); Sha256_Init(p);

View File

@@ -73,4 +73,3 @@ Ppmd7Dec.o: ../../Ppmd7Dec.c
clean: clean:
-$(RM) $(PROG) $(OBJS) -$(RM) $(PROG) $(OBJS)

View File

@@ -1,5 +1,5 @@
/* 7zipInstall.c - 7-Zip Installer /* 7zipInstall.c - 7-Zip Installer
2015-08-04 : Igor Pavlov : Public domain */ 2015-12-09 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -261,7 +261,7 @@ static LONG MyRegistry_CreateKeyAndVal(HKEY parentKey, LPCWSTR keyName, LPCWSTR
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
res = MyRegistry_SetString(destKey, valName, val); res = MyRegistry_SetString(destKey, valName, val);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
return res; return res;
} }
@@ -284,7 +284,7 @@ static LONG MyRegistry_CreateKeyAndVal_32(HKEY parentKey, LPCWSTR keyName, LPCWS
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
res = MyRegistry_SetString(destKey, valName, val); res = MyRegistry_SetString(destKey, valName, val);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
return res; return res;
} }
@@ -322,7 +322,7 @@ static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
processed -= k7zStartHeaderSize; processed -= k7zStartHeaderSize;
for (pos = 0; pos <= processed; pos++) for (pos = 0; pos <= processed; pos++)
{ {
for (; buf[pos] != '7' && pos <= processed; pos++); for (; pos <= processed && buf[pos] != '7'; pos++);
if (pos > processed) if (pos > processed)
break; break;
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0) if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
@@ -571,6 +571,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
#endif #endif
break; break;
} }
default: return FALSE;
} }
break; break;
@@ -598,8 +600,8 @@ static LONG SetRegKey_Path2(HKEY parentKey)
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
res = MyRegistry_SetString(destKey, k_Reg_Path32, path); res = MyRegistry_SetString(destKey, k_Reg_Path32, path);
res = MyRegistry_SetString(destKey, k_Reg_Path, path); /* res = */ MyRegistry_SetString(destKey, k_Reg_Path, path);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
return res; return res;
} }
@@ -718,10 +720,10 @@ static void WriteCLSID()
WCHAR destPath[MAX_PATH + 10]; WCHAR destPath[MAX_PATH + 10];
wcscpy(destPath, path); wcscpy(destPath, path);
wcscat(destPath, L"7-zip32.dll"); wcscat(destPath, L"7-zip32.dll");
res = MyRegistry_SetString(destKey, NULL, destPath); /* res = */ MyRegistry_SetString(destKey, NULL, destPath);
res = MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment"); /* res = */ MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment");
// DeleteRegValue(destKey, L"InprocServer32"); // DeleteRegValue(destKey, L"InprocServer32");
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
#endif #endif
@@ -737,10 +739,10 @@ static void WriteCLSID()
WCHAR destPath[MAX_PATH + 10]; WCHAR destPath[MAX_PATH + 10];
wcscpy(destPath, path); wcscpy(destPath, path);
wcscat(destPath, L"7-zip.dll"); wcscat(destPath, L"7-zip.dll");
res = MyRegistry_SetString(destKey, NULL, destPath); /* res = */ MyRegistry_SetString(destKey, NULL, destPath);
res = MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment"); /* res = */ MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment");
// DeleteRegValue(destKey, L"InprocServer32"); // DeleteRegValue(destKey, L"InprocServer32");
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
} }
@@ -1011,7 +1013,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
BOOL bRet; BOOL bRet;
MSG msg; MSG msg;
while ((bRet = GetMessage(&msg, g_HWND, 0, 0)) != 0) // we need messages for all thread windows (including EDITTEXT window in dialog)
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{ {
if (bRet == -1) if (bRet == -1)
return retCode; return retCode;
@@ -1083,7 +1086,6 @@ static int Install()
WCHAR sfxPath[MAX_PATH + 2]; WCHAR sfxPath[MAX_PATH + 2];
Bool needReboot = False; Bool needReboot = False;
size_t pathLen;
allocImp.Alloc = SzAlloc; allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree; allocImp.Free = SzFree;
@@ -1116,6 +1118,7 @@ static int Install()
if (res == SZ_OK) if (res == SZ_OK)
{ {
size_t pathLen;
if (!g_SilentMode) if (!g_SilentMode)
{ {
GetDlgItemTextW(g_HWND, IDE_EXTRACT_PATH, path, MAX_PATH); GetDlgItemTextW(g_HWND, IDE_EXTRACT_PATH, path, MAX_PATH);
@@ -1161,9 +1164,9 @@ if (res == SZ_OK)
if (res == SZ_OK) if (res == SZ_OK)
{ {
UInt32 i; UInt32 i;
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call, if(!outBuf) */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call, if (!outBuf) */
Byte *outBuf = NULL; /* it must be NULL before first call for each new archive. */ Byte *outBuf = NULL; /* it must be NULL before first call for each new archive. */
size_t outBufSize = 0; /* it can have any value before first call, if(!outBuf) */ size_t outBufSize = 0; /* it can have any value before first call, if (!outBuf) */
g_TotalSize = 0; g_TotalSize = 0;

View File

@@ -1,5 +1,5 @@
/* 7zipUninstall.c - 7-Zip Uninstaller /* 7zipUninstall.c - 7-Zip Uninstaller
2015-08-09 : Igor Pavlov : Public domain */ 2015-12-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -384,7 +384,7 @@ static void WriteCLSID()
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
RegDeleteValueW(destKey, k_7zip_CLSID); RegDeleteValueW(destKey, k_7zip_CLSID);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
} }
} }
@@ -419,7 +419,7 @@ static void WriteCLSID()
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
RegDeleteValueW(destKey, k_7zip_CLSID); RegDeleteValueW(destKey, k_7zip_CLSID);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
} }
} }
@@ -542,7 +542,7 @@ static BOOL RemoveDir()
#define k_Lang L"Lang" #define k_Lang L"Lang"
// NUM_LANG_TXT_FILES files are placed before en.ttt // NUM_LANG_TXT_FILES files are placed before en.ttt
#define NUM_LANG_TXT_FILES 86 #define NUM_LANG_TXT_FILES 87
#ifdef _64BIT_INSTALLER #ifdef _64BIT_INSTALLER
#define NUM_EXTRA_FILES_64BIT 1 #define NUM_EXTRA_FILES_64BIT 1
@@ -556,7 +556,7 @@ static const char *k_Names =
"af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext" "af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext"
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky" " fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky"
" lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru" " lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru"
" sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi zh-cn zh-tw" " sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi yo zh-cn zh-tw"
" en.ttt" " en.ttt"
" descript.ion" " descript.ion"
" History.txt" " History.txt"
@@ -771,6 +771,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
OnClose(); OnClose();
break; break;
} }
default: return FALSE;
} }
break; break;
@@ -1033,7 +1035,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
BOOL bRet; BOOL bRet;
MSG msg; MSG msg;
while ((bRet = GetMessage(&msg, g_HWND, 0, 0)) != 0) while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{ {
if (bRet == -1) if (bRet == -1)
return retCode; return retCode;

View File

@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression /* LzmaUtil.c -- Test application for LZMA compression
2015-06-13 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "../../Precomp.h" #include "../../Precomp.h"
@@ -133,7 +133,7 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
SRes res; SRes res;
CLzmaEncProps props; CLzmaEncProps props;
rs = rs; UNUSED_VAR(rs);
enc = LzmaEnc_Create(&g_Alloc); enc = LzmaEnc_Create(&g_Alloc);
if (enc == 0) if (enc == 0)

View File

@@ -1,12 +1,14 @@
/* LzmaLibExports.c -- LZMA library DLL Entry point /* LzmaLibExports.c -- LZMA library DLL Entry point
2008-10-04 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "../../Precomp.h"
#include <windows.h> #include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{ {
hInstance = hInstance; UNUSED_VAR(hInstance);
dwReason = dwReason; UNUSED_VAR(dwReason);
lpReserved = lpReserved; UNUSED_VAR(lpReserved);
return TRUE; return TRUE;
} }

View File

@@ -1,5 +1,5 @@
/* SfxSetup.c - 7z SFX Setup /* SfxSetup.c - 7z SFX Setup
2015-03-25 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -88,7 +88,7 @@ static unsigned FindItem(const char * const *items, unsigned num, const wchar_t
#ifdef _CONSOLE #ifdef _CONSOLE
static BOOL WINAPI HandlerRoutine(DWORD ctrlType) static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
{ {
ctrlType = ctrlType; UNUSED_VAR(ctrlType);
return TRUE; return TRUE;
} }
#endif #endif
@@ -144,7 +144,7 @@ static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
processed -= k7zStartHeaderSize; processed -= k7zStartHeaderSize;
for (pos = 0; pos <= processed; pos++) for (pos = 0; pos <= processed; pos++)
{ {
for (; buf[pos] != '7' && pos <= processed; pos++); for (; pos <= processed && buf[pos] != '7'; pos++);
if (pos > processed) if (pos > processed)
break; break;
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0) if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
@@ -257,10 +257,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
#ifdef _CONSOLE #ifdef _CONSOLE
SetConsoleCtrlHandler(HandlerRoutine, TRUE); SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#else #else
hInstance = hInstance; UNUSED_VAR(hInstance);
hPrevInstance = hPrevInstance; UNUSED_VAR(hPrevInstance);
lpCmdLine = lpCmdLine; UNUSED_VAR(lpCmdLine);
nCmdShow = nCmdShow; UNUSED_VAR(nCmdShow);
#endif #endif
CrcGenerateTable(); CrcGenerateTable();

View File

@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode /* XzDec.c -- Xz Decode
2015-05-01 : Igor Pavlov : Public domain */ 2015-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -74,7 +74,7 @@ static void BraState_Free(void *pp, ISzAlloc *alloc)
static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{ {
CBraState *p = ((CBraState *)pp); CBraState *p = ((CBraState *)pp);
alloc = alloc; UNUSED_VAR(alloc);
p->ip = 0; p->ip = 0;
if (p->methodId == XZ_ID_Delta) if (p->methodId == XZ_ID_Delta)
{ {
@@ -129,9 +129,9 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
CBraState *p = ((CBraState *)pp); CBraState *p = ((CBraState *)pp);
SizeT destLenOrig = *destLen; SizeT destLenOrig = *destLen;
SizeT srcLenOrig = *srcLen; SizeT srcLenOrig = *srcLen;
UNUSED_VAR(finishMode);
*destLen = 0; *destLen = 0;
*srcLen = 0; *srcLen = 0;
finishMode = finishMode;
*wasFinished = 0; *wasFinished = 0;
while (destLenOrig > 0) while (destLenOrig > 0)
{ {
@@ -236,8 +236,8 @@ static void SbState_Free(void *pp, ISzAlloc *alloc)
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{ {
UNUSED_VAR(pp); UNUSED_VAR(pp);
props = props; UNUSED_VAR(props);
alloc = alloc; UNUSED_VAR(alloc);
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
} }
@@ -251,7 +251,7 @@ static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
{ {
CSbDec *p = (CSbDec *)pp; CSbDec *p = (CSbDec *)pp;
SRes res; SRes res;
srcWasFinished = srcWasFinished; UNUSED_VAR(srcWasFinished);
p->dest = dest; p->dest = dest;
p->destLen = *destLen; p->destLen = *destLen;
p->src = src; p->src = src;
@@ -308,7 +308,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
ELzmaStatus status; ELzmaStatus status;
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status); SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status);
srcWasFinished = srcWasFinished; UNUSED_VAR(srcWasFinished);
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK); *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
return res; return res;
} }
@@ -555,7 +555,7 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
pos += (unsigned)size; pos += (unsigned)size;
#ifdef XZ_DUMP #ifdef XZ_DUMP
printf("\nf[%d] = %2X: ", i, filter->id); printf("\nf[%u] = %2X: ", i, (unsigned)filter->id);
{ {
unsigned i; unsigned i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)

View File

@@ -1,5 +1,5 @@
/* XzIn.c - Xz input /* XzIn.c - Xz input
2015-04-21 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -72,7 +72,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc) static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
{ {
size_t i, numBlocks, pos = 1; size_t numBlocks, pos = 1;
UInt32 crc; UInt32 crc;
if (size < 5 || buf[0] != 0) if (size < 5 || buf[0] != 0)
@@ -94,6 +94,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
Xz_Free(p, alloc); Xz_Free(p, alloc);
if (numBlocks != 0) if (numBlocks != 0)
{ {
size_t i;
p->numBlocks = numBlocks; p->numBlocks = numBlocks;
p->numBlocksAllocated = numBlocks; p->numBlocksAllocated = numBlocks;
p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);

View File

@@ -158,14 +158,6 @@ SOURCE=.\7zFolderInStream.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\7zFolderOutStream.cpp
# End Source File
# Begin Source File
SOURCE=.\7zFolderOutStream.h
# End Source File
# Begin Source File
SOURCE=.\7zHandler.cpp SOURCE=.\7zHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -350,14 +342,6 @@ SOURCE=..\Common\CoderMixer2.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\Common\CrossThreadProgress.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CrossThreadProgress.h
# End Source File
# Begin Source File
SOURCE=..\Common\HandlerOut.cpp SOURCE=..\Common\HandlerOut.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -254,8 +254,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
lps->Init(extractCallback, false); lps->Init(extractCallback, false);
CDecoder decoder( CDecoder decoder(
#ifndef USE_MIXER_ST #if !defined(USE_MIXER_MT)
false false
#elif !defined(USE_MIXER_ST)
true
#elif !defined(__7Z_SET_PROPERTIES)
#ifdef _7ZIP_ST
false
#else
true
#endif
#else #else
_useMultiThreadMixer _useMultiThreadMixer
#endif #endif

View File

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

View File

@@ -1,6 +0,0 @@
// 7zFolderOutStream.h
#ifndef __7Z_FOLDER_OUT_STREAM_H
#define __7Z_FOLDER_OUT_STREAM_H
#endif

View File

@@ -36,10 +36,14 @@ CHandler::CHandler()
#endif #endif
#ifdef EXTRACT_ONLY #ifdef EXTRACT_ONLY
_crcSize = 4; _crcSize = 4;
#ifdef __7Z_SET_PROPERTIES #ifdef __7Z_SET_PROPERTIES
_numThreads = NSystem::GetNumberOfProcessors(); _numThreads = NSystem::GetNumberOfProcessors();
_useMultiThreadMixer = true;
#endif #endif
#endif #endif
} }
@@ -722,10 +726,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return E_INVALIDARG; return E_INVALIDARG;
const PROPVARIANT &value = values[i]; const PROPVARIANT &value = values[i];
UInt32 number; UInt32 number;
int index = ParseStringToUInt32(name, number); unsigned index = ParseStringToUInt32(name, number);
if (index == 0) if (index == 0)
{ {
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer); if (name.IsEqualTo("mtf"))
{
RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer));
continue;
}
if (name.IsPrefixedBy_Ascii_NoCase("mt")) if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{ {
RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads)); RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads));

View File

@@ -21,11 +21,11 @@ namespace N7z {
#ifndef __7Z_SET_PROPERTIES #ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY #ifdef EXTRACT_ONLY
#if !defined(_7ZIP_ST) && !defined(_SFX) #if !defined(_7ZIP_ST) && !defined(_SFX)
#define __7Z_SET_PROPERTIES #define __7Z_SET_PROPERTIES
#endif #endif
#else #else
#define __7Z_SET_PROPERTIES #define __7Z_SET_PROPERTIES
#endif #endif
#endif #endif

View File

@@ -1180,7 +1180,7 @@ HRESULT CInArchive::ReadHeader(
bool isKnownType = true; bool isKnownType = true;
if (type > ((UInt32)1 << 30)) if (type > ((UInt32)1 << 30))
isKnownType = false; isKnownType = false;
else switch((UInt32)type) else switch ((UInt32)type)
{ {
case NID::kName: case NID::kName:
{ {
@@ -1338,7 +1338,7 @@ HRESULT CInArchive::ReadHeader(
db.UnsupportedFeatureWarning = true; db.UnsupportedFeatureWarning = true;
_inByteBack->SkipRem(); _inByteBack->SkipRem();
} }
// SkipData worked incorrectly in some versions before v4.59 (7zVer <= 00.02) // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02)
if (_inByteBack->GetRem() != 0) if (_inByteBack->GetRem() != 0)
ThrowIncorrect(); ThrowIncorrect();
} }

View File

@@ -87,6 +87,8 @@ struct CFolders
return PackPositions[index + 1] - PackPositions[index]; return PackPositions[index + 1] - PackPositions[index];
} }
CFolders(): NumPackStreams(0), NumFolders(0) {}
void Clear() void Clear()
{ {
NumPackStreams = 0; NumPackStreams = 0;

View File

@@ -14,7 +14,7 @@ namespace N7z {
struct CPropMap struct CPropMap
{ {
UInt32 FilePropID; UInt32 FilePropID;
STATPROPSTG StatPROPSTG; CStatProp StatProp;
}; };
static const CPropMap kPropMap[] = static const CPropMap kPropMap[] =
@@ -24,11 +24,11 @@ static const CPropMap kPropMap[] =
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } }, { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
#ifdef _MULTI_PACK #ifdef _MULTI_PACK
{ 100, { L"Pack0", kpidPackedSize0, VT_UI8 } }, { 100, { "Pack0", kpidPackedSize0, VT_UI8 } },
{ 101, { L"Pack1", kpidPackedSize1, VT_UI8 } }, { 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
{ 102, { L"Pack2", kpidPackedSize2, VT_UI8 } }, { 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
{ 103, { L"Pack3", kpidPackedSize3, VT_UI8 } }, { 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
{ 104, { L"Pack4", kpidPackedSize4, VT_UI8 } }, { 104, { "Pack4", kpidPackedSize4, VT_UI8 } },
#endif #endif
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } }, { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
@@ -90,7 +90,7 @@ void CHandler::FillPopIDs()
_fileInfoPopIDs.Clear(); _fileInfoPopIDs.Clear();
#ifdef _7Z_VOL #ifdef _7Z_VOL
if(_volumes.Size() < 1) if (_volumes.Size() < 1)
return; return;
const CVolume &volume = _volumes.Front(); const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_db = volume.Database; const CArchiveDatabaseEx &_db = volume.Database;
@@ -156,8 +156,8 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID,
const CPropMap &pr = kPropMap[i]; const CPropMap &pr = kPropMap[i];
if (pr.FilePropID == id) if (pr.FilePropID == id)
{ {
const STATPROPSTG &st = pr.StatPROPSTG; const CStatProp &st = pr.StatProp;
*propID = st.propid; *propID = st.PropID;
*varType = st.vt; *varType = st.vt;
/* /*
if (st.lpwstrName) if (st.lpwstrName)

View File

@@ -567,14 +567,17 @@ static const char *g_Exts =
" iso bin nrg mdf img pdi tar cpio xpi" " iso bin nrg mdf img pdi tar cpio xpi"
" vfd vhd vud vmc vsv" " vfd vhd vud vmc vsv"
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm" " vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def" " inl inc idl acf asa"
" h hpp hxx c cpp cxx m mm go swift"
" rc java cs rs pas bas vb cls ctl frm dlg def"
" f77 f f90 f95" " f77 f f90 f95"
" asm sql manifest dep" " asm s"
" sql manifest dep"
" mak clw csproj vcproj sln dsp dsw" " mak clw csproj vcproj sln dsp dsw"
" class" " class"
" bat cmd" " bat cmd bash sh"
" xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml" " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
" awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs" " awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs"
" text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf" " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
" sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf" " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
" abw afp cwk lwp wpd wps wpt wrf wri" " abw afp cwk lwp wpd wps wpt wrf wri"

View File

@@ -13,7 +13,6 @@ AR_OBJS = \
$O\7zEncode.obj \ $O\7zEncode.obj \
$O\7zExtract.obj \ $O\7zExtract.obj \
$O\7zFolderInStream.obj \ $O\7zFolderInStream.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \ $O\7zHandler.obj \
$O\7zHandlerOut.obj \ $O\7zHandlerOut.obj \
$O\7zHeader.obj \ $O\7zHeader.obj \
@@ -65,7 +64,6 @@ COMPRESS_OBJS = \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
$O\CrossThreadProgress.obj \
$O\HandlerOut.obj \ $O\HandlerOut.obj \
$O\InStreamWithCRC.obj \ $O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \ $O\ItemNameUtils.obj \

View File

@@ -83,8 +83,14 @@ class CHandler: public CHandlerCont
HRESULT ReadTables(IInStream *stream); HRESULT ReadTables(IInStream *stream);
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; } UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
virtual UInt64 GetItemPos(UInt32 index) const { return BlocksToBytes(_items[index].StartBlock); } virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
virtual UInt64 GetItemSize(UInt32 index) const { return BlocksToBytes(_items[index].NumBlocks); } {
const CItem &item = _items[index];
pos = BlocksToBytes(item.StartBlock);
size = BlocksToBytes(item.NumBlocks);
return NExtract::NOperationResult::kOK;
}
public: public:
INTERFACE_IInArchive_Cont(;) INTERFACE_IInArchive_Cont(;)
}; };

View File

@@ -572,6 +572,7 @@ public:
HRESULT FlushCorrupted(unsigned folderIndex); HRESULT FlushCorrupted(unsigned folderIndex);
HRESULT Unsupported(); HRESULT Unsupported();
bool NeedMoreWrite() const { return (m_FolderSize > m_PosInFolder); }
UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; } UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; }
UInt64 GetPosInFolder() const { return m_PosInFolder; } UInt64 GetPosInFolder() const { return m_PosInFolder; }
}; };
@@ -781,6 +782,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
realProcessed += size; realProcessed += size;
if (processedSize) if (processedSize)
*processedSize = realProcessed; *processedSize = realProcessed;
m_PosInFolder += size;
return S_OK; return S_OK;
// return E_FAIL; // return E_FAIL;
} }
@@ -830,9 +832,7 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex) HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
{ {
UInt64 remain = GetRemain(); if (!NeedMoreWrite())
if (remain == 0)
{ {
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage; CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage); m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
@@ -843,16 +843,16 @@ HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
return S_OK; return S_OK;
} }
const unsigned kBufSize = (1 << 10); const unsigned kBufSize = (1 << 12);
Byte buf[kBufSize]; Byte buf[kBufSize];
for (unsigned i = 0; i < kBufSize; i++) for (unsigned i = 0; i < kBufSize; i++)
buf[i] = 0; buf[i] = 0;
for (;;) for (;;)
{ {
UInt64 remain = GetRemain(); if (!NeedMoreWrite())
if (remain == 0)
return S_OK; return S_OK;
UInt64 remain = GetRemain();
UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize); UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize);
UInt32 processedSizeLocal = 0; UInt32 processedSizeLocal = 0;
RINOK(Write2(buf, size, &processedSizeLocal, false)); RINOK(Write2(buf, size, &processedSizeLocal, false));
@@ -937,8 +937,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CRecordVector<bool> extractStatuses; CRecordVector<bool> extractStatuses;
for (i = 0; i < numItems;) for (i = 0;;)
{ {
lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
if (i >= numItems)
break;
unsigned index = allFilesMode ? i : indices[i]; unsigned index = allFilesMode ? i : indices[i];
const CMvItem &mvItem = m_Database.Items[index]; const CMvItem &mvItem = m_Database.Items[index];
@@ -1003,10 +1010,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curUnpack = item.GetEndOffset(); curUnpack = item.GetEndOffset();
} }
lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
CFolderOutStream *cabFolderOutStream = new CFolderOutStream; CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream); CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
@@ -1071,7 +1074,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
bool keepInputBuffer = false; bool keepInputBuffer = false;
bool thereWasNotAlignedChunk = false; bool thereWasNotAlignedChunk = false;
for (UInt32 bl = 0; cabFolderOutStream->GetRemain() != 0;) for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();)
{ {
if (volIndex >= m_Database.Volumes.Size()) if (volIndex >= m_Database.Volumes.Size())
{ {
@@ -1213,7 +1216,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
} }
if (res != S_OK || cabFolderOutStream->GetRemain() != 0) if (res != S_OK || cabFolderOutStream->NeedMoreWrite())
{ {
RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2)); RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2));
} }

View File

@@ -67,6 +67,7 @@ void CInArchive::ReadOtherArc(COtherArc &oa)
ReadName(oa.DiskName); ReadName(oa.DiskName);
} }
struct CSignatureFinder struct CSignatureFinder
{ {
Byte *Buf; Byte *Buf;
@@ -100,6 +101,7 @@ struct CSignatureFinder
HRESULT Find(); HRESULT Find();
}; };
HRESULT CSignatureFinder::Find() HRESULT CSignatureFinder::Find()
{ {
for (;;) for (;;)
@@ -156,6 +158,7 @@ HRESULT CSignatureFinder::Find()
} }
} }
bool CInArcInfo::Parse(const Byte *p) bool CInArcInfo::Parse(const Byte *p)
{ {
if (Get32(p + 0x0C) != 0 || if (Get32(p + 0x0C) != 0 ||
@@ -177,6 +180,7 @@ bool CInArcInfo::Parse(const Byte *p)
return true; return true;
} }
HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit) HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{ {
IsArc = false; IsArc = false;
@@ -286,7 +290,9 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
if (ai.IsThereNext()) ReadOtherArc(ai.NextArc); if (ai.IsThereNext()) ReadOtherArc(ai.NextArc);
UInt32 i; UInt32 i;
db.Folders.ClearAndReserve(ai.NumFolders); db.Folders.ClearAndReserve(ai.NumFolders);
for (i = 0; i < ai.NumFolders; i++) for (i = 0; i < ai.NumFolders; i++)
{ {
Read(p, 8); Read(p, 8);
@@ -311,6 +317,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
} }
db.Items.ClearAndReserve(ai.NumFiles); db.Items.ClearAndReserve(ai.NumFiles);
for (i = 0; i < ai.NumFiles; i++) for (i = 0; i < ai.NumFiles; i++)
{ {
Read(p, 16); Read(p, 16);
@@ -324,6 +331,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
item.Attributes = Get16(p + 14); item.Attributes = Get16(p + 14);
ReadName(item.Name); ReadName(item.Name);
if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size()) if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size())
{ {
HeaderError = true; HeaderError = true;
@@ -336,6 +344,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
return S_OK; return S_OK;
} }
HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit) HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{ {
try try
@@ -370,6 +379,7 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
return MyCompare(p1->ItemIndex, p2->ItemIndex); return MyCompare(p1->ItemIndex, p2->ItemIndex);
} }
bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2) bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
{ {
const CMvItem *p1 = &Items[i1]; const CMvItem *p1 = &Items[i1];
@@ -384,12 +394,15 @@ bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
&& item1.Name == item2.Name; && item1.Name == item2.Name;
} }
void CMvDatabaseEx::FillSortAndShrink() void CMvDatabaseEx::FillSortAndShrink()
{ {
Items.Clear(); Items.Clear();
StartFolderOfVol.Clear(); StartFolderOfVol.Clear();
FolderStartFileIndex.Clear(); FolderStartFileIndex.Clear();
int offset = 0; int offset = 0;
FOR_VECTOR (v, Volumes) FOR_VECTOR (v, Volumes)
{ {
const CDatabaseEx &db = Volumes[v]; const CDatabaseEx &db = Volumes[v];
@@ -422,11 +435,12 @@ void CMvDatabaseEx::FillSortAndShrink()
FOR_VECTOR (i, Items) FOR_VECTOR (i, Items)
{ {
int folderIndex = GetFolderIndex(&Items[i]); int folderIndex = GetFolderIndex(&Items[i]);
if (folderIndex >= (int)FolderStartFileIndex.Size()) while (folderIndex >= (int)FolderStartFileIndex.Size())
FolderStartFileIndex.Add(i); FolderStartFileIndex.Add(i);
} }
} }
bool CMvDatabaseEx::Check() bool CMvDatabaseEx::Check()
{ {
for (unsigned v = 1; v < Volumes.Size(); v++) for (unsigned v = 1; v < Volumes.Size(); v++)
@@ -444,9 +458,11 @@ bool CMvDatabaseEx::Check()
return false; return false;
} }
} }
UInt32 beginPos = 0; UInt32 beginPos = 0;
UInt64 endPos = 0; UInt64 endPos = 0;
int prevFolder = -2; int prevFolder = -2;
FOR_VECTOR (i, Items) FOR_VECTOR (i, Items)
{ {
const CMvItem &mvItem = Items[i]; const CMvItem &mvItem = Items[i];
@@ -456,15 +472,19 @@ bool CMvDatabaseEx::Check()
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDir()) if (item.IsDir())
continue; continue;
int folderIndex = GetFolderIndex(&mvItem); int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder) if (folderIndex != prevFolder)
prevFolder = folderIndex; prevFolder = folderIndex;
else if (item.Offset < endPos && else if (item.Offset < endPos &&
(item.Offset != beginPos || item.GetEndOffset() != endPos)) (item.Offset != beginPos || item.GetEndOffset() != endPos))
return false; return false;
beginPos = item.Offset; beginPos = item.Offset;
endPos = item.GetEndOffset(); endPos = item.GetEndOffset();
} }
return true; return true;
} }

View File

@@ -25,6 +25,7 @@ struct COtherArc
} }
}; };
struct CArchInfo struct CArchInfo
{ {
Byte VersionMinor; // cabinet file format version, minor Byte VersionMinor; // cabinet file format version, minor
@@ -65,6 +66,7 @@ struct CArchInfo
} }
}; };
struct CInArcInfo: public CArchInfo struct CInArcInfo: public CArchInfo
{ {
UInt32 Size; // size of this cabinet file in bytes UInt32 Size; // size of this cabinet file in bytes
@@ -105,17 +107,20 @@ struct CDatabase
} }
}; };
struct CDatabaseEx: public CDatabase struct CDatabaseEx: public CDatabase
{ {
CMyComPtr<IInStream> Stream; CMyComPtr<IInStream> Stream;
}; };
struct CMvItem struct CMvItem
{ {
unsigned VolumeIndex; unsigned VolumeIndex;
unsigned ItemIndex; unsigned ItemIndex;
}; };
class CMvDatabaseEx class CMvDatabaseEx
{ {
bool AreItemsEqual(unsigned i1, unsigned i2); bool AreItemsEqual(unsigned i1, unsigned i2);

View File

@@ -101,9 +101,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
if (m_Database.NewFormat) if (m_Database.NewFormat)
{ {
switch(propID) switch (propID)
{ {
case kpidSize: case kpidSize:
prop = (UInt64)m_Database.NewFormatString.Len(); prop = (UInt64)m_Database.NewFormatString.Len();
@@ -112,12 +113,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
} }
int entryIndex;
unsigned entryIndex;
if (m_Database.LowLevel) if (m_Database.LowLevel)
entryIndex = index; entryIndex = index;
else else
entryIndex = m_Database.Indices[index]; entryIndex = m_Database.Indices[index];
const CItem &item = m_Database.Items[entryIndex]; const CItem &item = m_Database.Items[entryIndex];
switch (propID) switch (propID)
{ {
case kpidPath: case kpidPath:
@@ -161,6 +165,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
#endif #endif
} }
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
@@ -244,9 +249,9 @@ public:
UInt64 m_PosInFolder; UInt64 m_PosInFolder;
UInt64 m_PosInSection; UInt64 m_PosInSection;
const CRecordVector<bool> *m_ExtractStatuses; const CRecordVector<bool> *m_ExtractStatuses;
int m_StartIndex; unsigned m_StartIndex;
int m_CurrentIndex; unsigned m_CurrentIndex;
int m_NumFiles; unsigned m_NumFiles;
private: private:
const CFilesDatabase *m_Database; const CFilesDatabase *m_Database;
@@ -298,7 +303,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
{ {
if (m_FileIsOpen) if (m_FileIsOpen)
return S_OK; return S_OK;
for (;m_CurrentIndex < m_NumFiles; m_CurrentIndex++) for (; m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
{ {
UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex);
if (fileSize != 0) if (fileSize != 0)
@@ -318,7 +323,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
if (processedSize) if (processedSize)
*processedSize = 0; *processedSize = 0;
while(size != 0) while (size != 0)
{ {
if (m_FileIsOpen) if (m_FileIsOpen)
{ {
@@ -368,7 +373,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
// return E_FAIL; // return E_FAIL;
} }
int fullIndex = m_StartIndex + m_CurrentIndex; unsigned fullIndex = m_StartIndex + m_CurrentIndex;
m_RemainFileSize = m_Database->GetFileSize(fullIndex); m_RemainFileSize = m_Database->GetFileSize(fullIndex);
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex); UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
if (fileOffset < m_PosInSection) if (fileOffset < m_PosInSection)
@@ -408,7 +413,7 @@ HRESULT CChmFolderOutStream::FlushCorrupted(UInt64 maxSize)
{ {
const UInt32 kBufferSize = (1 << 10); const UInt32 kBufferSize = (1 << 10);
Byte buffer[kBufferSize]; Byte buffer[kBufferSize];
for (int i = 0; i < kBufferSize; i++) for (unsigned i = 0; i < kBufferSize; i++)
buffer[i] = 0; buffer[i] = 0;
if (maxSize > m_FolderSize) if (maxSize > m_FolderSize)
maxSize = m_FolderSize; maxSize = m_FolderSize;
@@ -531,9 +536,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
{ {
UInt32 index = allFilesMode ? i : indices[i]; UInt32 index = allFilesMode ? i : indices[i];
int entryIndex = m_Database.Indices[index]; const CItem &item = m_Database.Items[m_Database.Indices[index]];
const CItem &item = m_Database.Items[entryIndex]; const UInt64 sectionIndex = item.Section;
UInt64 sectionIndex = item.Section;
if (item.IsDir() || item.Size == 0) if (item.IsDir() || item.Size == 0)
continue; continue;
if (sectionIndex == 0) if (sectionIndex == 0)
@@ -567,14 +571,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CByteBuffer packBuf; CByteBuffer packBuf;
for (i = 0; i < numItems;) for (i = 0;;)
{ {
RINOK(extractCallback->SetCompleted(&currentTotalSize)); RINOK(extractCallback->SetCompleted(&currentTotalSize));
if (i >= numItems)
break;
UInt32 index = allFilesMode ? i : indices[i]; UInt32 index = allFilesMode ? i : indices[i];
i++; i++;
int entryIndex = m_Database.Indices[index]; const CItem &item = m_Database.Items[m_Database.Indices[index]];
const CItem &item = m_Database.Items[entryIndex]; const UInt64 sectionIndex = item.Section;
UInt64 sectionIndex = item.Section;
Int32 askMode= testMode ? Int32 askMode= testMode ?
NExtract::NAskMode::kTest : NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract; NExtract::NAskMode::kExtract;
@@ -645,7 +652,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 folderIndex = m_Database.GetFolder(index); UInt64 folderIndex = m_Database.GetFolder(index);
UInt64 compressedPos = m_Database.ContentOffset + section.Offset; const UInt64 compressedPos = m_Database.ContentOffset + section.Offset;
RINOK(lzxDecoderSpec->SetParams_and_Alloc(lzxInfo.GetNumDictBits())); RINOK(lzxDecoderSpec->SetParams_and_Alloc(lzxInfo.GetNumDictBits()));
const CItem *lastItem = &item; const CItem *lastItem = &item;
@@ -673,9 +680,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
for (; i < numItems; i++) for (; i < numItems; i++)
{ {
UInt32 nextIndex = allFilesMode ? i : indices[i]; const UInt32 nextIndex = allFilesMode ? i : indices[i];
int entryIndex = m_Database.Indices[nextIndex]; const CItem &nextItem = m_Database.Items[m_Database.Indices[nextIndex]];
const CItem &nextItem = m_Database.Items[entryIndex];
if (nextItem.Section != sectionIndex) if (nextItem.Section != sectionIndex)
break; break;
UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex); UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex);

View File

@@ -656,7 +656,7 @@ static AString GetSectionPrefix(const AString &name)
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } #define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
static int CompareFiles(const int *p1, const int *p2, void *param) static int CompareFiles(const unsigned *p1, const unsigned *p2, void *param)
{ {
const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param; const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param;
const CItem &item1 = items[*p1]; const CItem &item1 = items[*p1];
@@ -731,7 +731,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
RINOK(DecompressStream(inStream, database, kNameList)); RINOK(DecompressStream(inStream, database, kNameList));
/* UInt16 length = */ ReadUInt16(); /* UInt16 length = */ ReadUInt16();
UInt16 numSections = ReadUInt16(); UInt16 numSections = ReadUInt16();
for (int i = 0; i < numSections; i++) for (unsigned i = 0; i < numSections; i++)
{ {
CSectionInfo section; CSectionInfo section;
UInt16 nameLen = ReadUInt16(); UInt16 nameLen = ReadUInt16();
@@ -766,10 +766,10 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList)); RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList));
if ((_chunkSize & 0xF) != 0) if ((_chunkSize & 0xF) != 0)
return S_FALSE; return S_FALSE;
int numGuids = (int)(_chunkSize / 0x10); unsigned numGuids = (unsigned)(_chunkSize / 0x10);
if (numGuids < 1) if (numGuids < 1)
return S_FALSE; return S_FALSE;
for (int i = 0; i < numGuids; i++) for (unsigned i = 0; i < numGuids; i++)
{ {
CMethodInfo method; CMethodInfo method;
ReadGUID(method.Guid); ReadGUID(method.Guid);
@@ -803,14 +803,17 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
return S_FALSE; return S_FALSE;
{ {
int n = GetLog(ReadUInt32()); // There is bug in VC6, if we use function call as parameter for inline function
UInt32 val32 = ReadUInt32();
int n = GetLog(val32);
if (n < 0 || n > 16) if (n < 0 || n > 16)
return S_FALSE; return S_FALSE;
li.ResetIntervalBits = n; li.ResetIntervalBits = n;
} }
{ {
int n = GetLog(ReadUInt32()); UInt32 val32 = ReadUInt32();
int n = GetLog(val32);
if (n < 0 || n > 16) if (n < 0 || n > 16)
return S_FALSE; return S_FALSE;
li.WindowSizeBits = n; li.WindowSizeBits = n;

View File

@@ -177,25 +177,25 @@ class CFilesDatabase: public CDatabase
{ {
public: public:
bool LowLevel; bool LowLevel;
CRecordVector<int> Indices; CUIntVector Indices;
CObjectVector<CSectionInfo> Sections; CObjectVector<CSectionInfo> Sections;
UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; } UInt64 GetFileSize(unsigned fileIndex) const { return Items[Indices[fileIndex]].Size; }
UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; } UInt64 GetFileOffset(unsigned fileIndex) const { return Items[Indices[fileIndex]].Offset; }
UInt64 GetFolder(int fileIndex) const UInt64 GetFolder(unsigned fileIndex) const
{ {
const CItem &item = Items[Indices[fileIndex]]; const CItem &item = Items[Indices[fileIndex]];
const CSectionInfo &section = Sections[(int)item.Section]; const CSectionInfo &section = Sections[(unsigned)item.Section];
if (section.IsLzx()) if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset); return section.Methods[0].LzxInfo.GetFolder(item.Offset);
return 0; return 0;
} }
UInt64 GetLastFolder(int fileIndex) const UInt64 GetLastFolder(unsigned fileIndex) const
{ {
const CItem &item = Items[Indices[fileIndex]]; const CItem &item = Items[Indices[fileIndex]];
const CSectionInfo &section = Sections[(int)item.Section]; const CSectionInfo &section = Sections[(unsigned)item.Section];
if (section.IsLzx()) if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1); return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);
return 0; return 0;

View File

@@ -433,9 +433,9 @@ HRESULT CDatabase::Open(IInStream *inStream)
SectorSizeBits = sectorSizeBits; SectorSizeBits = sectorSizeBits;
MiniSectorSizeBits = miniSectorSizeBits; MiniSectorSizeBits = miniSectorSizeBits;
if (sectorSizeBits > 28 || if (sectorSizeBits > 24 ||
sectorSizeBits < 7 || sectorSizeBits < 7 ||
miniSectorSizeBits > 28 || miniSectorSizeBits > 24 ||
miniSectorSizeBits < 2 || miniSectorSizeBits < 2 ||
miniSectorSizeBits > sectorSizeBits) miniSectorSizeBits > sectorSizeBits)
return S_FALSE; return S_FALSE;
@@ -571,6 +571,7 @@ HRESULT CDatabase::Open(IInStream *inStream)
RINOK(AddNode(-1, root.SonDid)); RINOK(AddNode(-1, root.SonDid));
unsigned numCabs = 0; unsigned numCabs = 0;
FOR_VECTOR (i, Refs) FOR_VECTOR (i, Refs)
{ {
const CItem &item = Items[Refs[i].Did]; const CItem &item = Items[Refs[i].Did];
@@ -578,27 +579,31 @@ HRESULT CDatabase::Open(IInStream *inStream)
continue; continue;
bool isMsiName; bool isMsiName;
UString msiName = ConvertName(item.Name, isMsiName); UString msiName = ConvertName(item.Name, isMsiName);
if (isMsiName) if (isMsiName && !msiName.IsEmpty())
{ {
bool isThereExt = (msiName.Find(L'.') >= 0);
bool isMsiSpec = (msiName[0] == k_Msi_SpecChar);
if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab") if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
|| msiName.Len() >= 3 && msiName[0] != k_Msi_SpecChar && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")) || !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")
|| !isMsiSpec && !isThereExt)
{ {
numCabs++; numCabs++;
MainSubfile = i; MainSubfile = i;
} }
} }
} }
if (numCabs > 1) if (numCabs > 1)
MainSubfile = -1; MainSubfile = -1;
{ {
FOR_VECTOR(t, Items) FOR_VECTOR (t, Items)
{ {
Update_PhySize_WithItem(t); Update_PhySize_WithItem(t);
} }
} }
{ {
FOR_VECTOR(t, Items) FOR_VECTOR (t, Items)
{ {
const CItem &item = Items[t]; const CItem &item = Items[t];
@@ -739,7 +744,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
return S_OK; return S_OK;
UInt32 i; UInt32 i;
UInt64 totalSize = 0; UInt64 totalSize = 0;
for(i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
{ {
const CItem &item = _db.Items[_db.Refs[allFilesMode ? i : indices[i]].Did]; const CItem &item = _db.Items[_db.Refs[allFilesMode ? i : indices[i]].Did];
if (!item.IsDir()) if (!item.IsDir())

View File

@@ -1,15 +0,0 @@
// CrossThreadProgress.cpp
#include "StdAfx.h"
#include "CrossThreadProgress.h"
STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
{
InSize = inSize;
OutSize = outSize;
ProgressEvent.Set();
WaitEvent.Lock();
return Result;
}

View File

@@ -1,37 +0,0 @@
// CrossThreadProgress.h
#ifndef __CROSSTHREADPROGRESS_H
#define __CROSSTHREADPROGRESS_H
#include "../../ICoder.h"
#include "../../../Windows/Synchronization.h"
#include "../../../Common/MyCom.h"
class CCrossThreadProgress:
public ICompressProgressInfo,
public CMyUnknownImp
{
public:
const UInt64 *InSize;
const UInt64 *OutSize;
HRESULT Result;
NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
NWindows::NSynchronization::CAutoResetEvent WaitEvent;
HRes Create()
{
RINOK(ProgressEvent.CreateIfNotCreated());
return WaitEvent.CreateIfNotCreated();
}
void Init()
{
ProgressEvent.Reset();
WaitEvent.Reset();
}
MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
#endif

View File

@@ -147,7 +147,9 @@ HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PR
#endif #endif
} }
else else
return ParseMethodFromPROPVARIANT(names[i], value); {
RINOK(ParseMethodFromPROPVARIANT(names[i], value));
}
} }
return S_OK; return S_OK;
} }

View File

@@ -119,9 +119,9 @@ HRESULT COutVolumeStream::Flush()
/* /*
STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{ {
if(processedSize != NULL) if (processedSize)
*processedSize = 0; *processedSize = 0;
while(size > 0) while (size > 0)
{ {
if (_streamIndex >= Streams.Size()) if (_streamIndex >= Streams.Size())
{ {
@@ -157,7 +157,7 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
_absPos += realProcessed; _absPos += realProcessed;
if (_absPos > _length) if (_absPos > _length)
_length = _absPos; _length = _absPos;
if(processedSize != NULL) if (processedSize)
*processedSize += realProcessed; *processedSize += realProcessed;
if (subStream.Pos == subStream.Size) if (subStream.Pos == subStream.Size)
{ {

View File

@@ -5,6 +5,7 @@
#include "../../../C/CpuArch.h" #include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h" #include "../../Common/ComTry.h"
#include "../../Common/MyLinux.h"
#include "../../Common/StringConvert.h" #include "../../Common/StringConvert.h"
#include "../../Common/StringToInt.h" #include "../../Common/StringToInt.h"
#include "../../Common/UTFConvert.h" #include "../../Common/UTFConvert.h"
@@ -121,7 +122,7 @@ struct CItem
bool IsBin() const { return Type == k_Type_BinLe || Type == k_Type_BinBe; } bool IsBin() const { return Type == k_Type_BinLe || Type == k_Type_BinBe; }
bool IsCrcFormat() const { return Type == k_Type_HexCrc; } bool IsCrcFormat() const { return Type == k_Type_HexCrc; }
bool IsDir() const { return (Mode & 0170000) == 0040000; } bool IsDir() const { return MY_LIN_S_ISDIR(Mode); }
bool IsTrailer() const { return strcmp(Name, kName_TRAILER) == 0; } bool IsTrailer() const { return strcmp(Name, kName_TRAILER) == 0; }
UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; } UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; }
}; };

View File

@@ -8,6 +8,7 @@
#include "../../../C/LzmaDec.h" #include "../../../C/LzmaDec.h"
#include "../../Common/ComTry.h" #include "../../Common/ComTry.h"
#include "../../Common/MyLinux.h"
#include "../../Common/StringConvert.h" #include "../../Common/StringConvert.h"
#include "../../Windows/PropVariantUtils.h" #include "../../Windows/PropVariantUtils.h"
@@ -98,7 +99,7 @@ struct CNode
#define Get32(p) (be ? GetBe32(p) : GetUi32(p)) #define Get32(p) (be ? GetBe32(p) : GetUi32(p))
static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(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 bool IsDir(const Byte *p, bool be) { return MY_LIN_S_ISDIR(GetMode(p, be)); }
static UInt32 GetSize(const Byte *p, bool be) static UInt32 GetSize(const Byte *p, bool be)
{ {
@@ -146,7 +147,7 @@ struct CHeader
{ {
if (memcmp(p + 16, kSignature, ARRAY_SIZE(kSignature)) != 0) if (memcmp(p + 16, kSignature, ARRAY_SIZE(kSignature)) != 0)
return false; return false;
switch(GetUi32(p)) switch (GetUi32(p))
{ {
case 0x28CD3D45: be = false; break; case 0x28CD3D45: be = false; break;
case 0x453DCD28: be = true; break; case 0x453DCD28: be = true; break;
@@ -354,7 +355,7 @@ HRESULT CHandler::Open2(IInStream *inStream)
if (!_h.IsVer2()) if (!_h.IsVer2())
{ {
FOR_VECTOR(i, _items) FOR_VECTOR (i, _items)
{ {
const CItem &item = _items[i]; const CItem &item = _items[i];
const Byte *p = _data + item.Offset; const Byte *p = _data + item.Offset;
@@ -530,7 +531,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
const Byte *p = _data + item.Offset; const Byte *p = _data + item.Offset;
bool be = _h.be; bool be = _h.be;
bool isDir = IsDir(p, be); bool isDir = IsDir(p, be);
switch(propID) switch (propID)
{ {
case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break; case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
case kpidIsDir: prop = isDir; break; case kpidIsDir: prop = isDir; break;
@@ -660,10 +661,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps; CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false); lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_stream);
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
{ {
lps->InSize = totalPackSize; lps->InSize = totalPackSize;
@@ -701,20 +698,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
int res = NExtract::NOperationResult::kDataError; int res = NExtract::NOperationResult::kDataError;
{ {
CMyComPtr<ISequentialInStream> inSeqStream; CMyComPtr<ISequentialInStream> inSeqStream;
CMyComPtr<IInStream> inStream;
HRESULT hres = GetStream(index, &inSeqStream); HRESULT hres = GetStream(index, &inSeqStream);
if (inSeqStream)
inSeqStream.QueryInterface(IID_IInStream, &inStream);
if (hres == E_OUTOFMEMORY) if (hres == E_OUTOFMEMORY)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if (hres == S_FALSE || !inStream) if (hres == S_FALSE || !inSeqStream)
res = NExtract::NOperationResult::kUnsupportedMethod; res = NExtract::NOperationResult::kUnsupportedMethod;
else else
{ {
RINOK(hres); RINOK(hres);
if (inStream)
{ {
HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress); HRESULT hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress);
if (hres == S_OK) if (hres == S_OK)
{ {
if (copyCoderSpec->TotalSize == curSize) if (copyCoderSpec->TotalSize == curSize)
@@ -729,6 +722,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
RINOK(extractCallback->SetOperationResult(res)); RINOK(extractCallback->SetOperationResult(res));
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }

View File

@@ -26,6 +26,7 @@ HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE; #define NT_CHECK_FAIL_ACTION return FALSE;
#ifdef _WIN32
extern "C" extern "C"
BOOL WINAPI DllMain( BOOL WINAPI DllMain(
#ifdef UNDER_CE #ifdef UNDER_CE
@@ -49,6 +50,7 @@ BOOL WINAPI DllMain(
*/ */
return TRUE; return TRUE;
} }
#endif
DEFINE_GUID(CLSID_CArchiveHandler, DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1, k_7zip_GUID_Data1,

View File

@@ -632,7 +632,7 @@ enum
kpidInfoSection kpidInfoSection
}; };
static const STATPROPSTG kProps[] = static const CStatProp kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR }, { NULL, kpidPath, VT_BSTR },
{ NULL, kpidSize, VT_UI8 }, { NULL, kpidSize, VT_UI8 },
@@ -641,8 +641,8 @@ static const STATPROPSTG kProps[] =
{ NULL, kpidVa, VT_UI8 }, { NULL, kpidVa, VT_UI8 },
{ NULL, kpidType, VT_BSTR }, { NULL, kpidType, VT_BSTR },
{ NULL, kpidCharacts, VT_BSTR } { NULL, kpidCharacts, VT_BSTR }
, { (LPOLESTR)L"Link Section", kpidLinkSection, VT_BSTR} , { "Link Section", kpidLinkSection, VT_BSTR}
, { (LPOLESTR)L"Info Section", kpidInfoSection, VT_BSTR} , { "Info Section", kpidInfoSection, VT_BSTR}
}; };
IMP_IInArchive_Props_WITH_NAME IMP_IInArchive_Props_WITH_NAME

View File

File diff suppressed because it is too large Load Diff

View File

@@ -133,15 +133,23 @@ bool CHeader::Parse(const Byte *p)
default: return false; default: return false;
} }
{ {
int s = GetLog(Get16(p + 11)); {
if (s < 9 || s > 12) UInt32 val32 = Get16(p + 11);
return false; int s = GetLog(val32);
SectorSizeLog = (Byte)s; if (s < 9 || s > 12)
s = GetLog(p[13]); return false;
if (s < 0) SectorSizeLog = (Byte)s;
return false; }
SectorsPerClusterLog = (Byte)s; {
UInt32 val32 = p[13];
int s = GetLog(val32);
if (s < 0)
return false;
SectorsPerClusterLog = (Byte)s;
}
ClusterSizeLog = (Byte)(SectorSizeLog + SectorsPerClusterLog); ClusterSizeLog = (Byte)(SectorSizeLog + SectorsPerClusterLog);
if (ClusterSizeLog > 24)
return false;
} }
NumReservedSectors = Get16(p + 14); NumReservedSectors = Get16(p + 14);
@@ -152,10 +160,13 @@ bool CHeader::Parse(const Byte *p)
if (NumFats < 1 || NumFats > 4) if (NumFats < 1 || NumFats > 4)
return false; return false;
// we also support images that contain 0 in offset field.
bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0));
UInt16 numRootDirEntries = Get16(p + 17); UInt16 numRootDirEntries = Get16(p + 17);
if (numRootDirEntries == 0) if (numRootDirEntries == 0)
{ {
if (codeOffset < 90) if (codeOffset < 90 && !isOkOffset)
return false; return false;
NumFatBits = 32; NumFatBits = 32;
NumRootDirSectors = 0; NumRootDirSectors = 0;
@@ -163,7 +174,7 @@ bool CHeader::Parse(const Byte *p)
else else
{ {
// Some FAT12s don't contain VolFields // Some FAT12s don't contain VolFields
if (codeOffset < 62 - 24) if (codeOffset < 62 - 24 && !isOkOffset)
return false; return false;
NumFatBits = 0; NumFatBits = 0;
UInt32 mask = (1 << (SectorSizeLog - 5)) - 1; UInt32 mask = (1 << (SectorSizeLog - 5)) - 1;
@@ -805,7 +816,7 @@ enum
// kpidFileSysType // kpidFileSysType
}; };
static const STATPROPSTG kArcProps[] = static const CStatProp kArcProps[] =
{ {
{ NULL, kpidFileSystem, VT_BSTR}, { NULL, kpidFileSystem, VT_BSTR},
{ NULL, kpidClusterSize, VT_UI4}, { NULL, kpidClusterSize, VT_UI4},
@@ -814,12 +825,12 @@ static const STATPROPSTG kArcProps[] =
{ NULL, kpidMTime, VT_FILETIME}, { NULL, kpidMTime, VT_FILETIME},
{ NULL, kpidVolumeName, VT_BSTR}, { NULL, kpidVolumeName, VT_BSTR},
{ (LPOLESTR)L"FATs", kpidNumFats, VT_UI4}, { "FATs", kpidNumFats, VT_UI4},
{ NULL, kpidSectorSize, VT_UI4}, { NULL, kpidSectorSize, VT_UI4},
{ NULL, kpidId, VT_UI4}, { NULL, kpidId, VT_UI4},
// { (LPOLESTR)L"OEM Name", kpidOemName, VT_BSTR}, // { "OEM Name", kpidOemName, VT_BSTR},
// { (LPOLESTR)L"Volume Name", kpidVolName, VT_BSTR}, // { "Volume Name", kpidVolName, VT_BSTR},
// { (LPOLESTR)L"File System Type", kpidFileSysType, VT_BSTR} // { "File System Type", kpidFileSysType, VT_BSTR}
// { NULL, kpidSectorsPerTrack, VT_UI4}, // { NULL, kpidSectorsPerTrack, VT_UI4},
// { NULL, kpidNumHeads, VT_UI4}, // { NULL, kpidNumHeads, VT_UI4},
// { NULL, kpidHiddenSectors, VT_UI4} // { NULL, kpidHiddenSectors, VT_UI4}
@@ -858,7 +869,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
switch(propID) switch (propID)
{ {
case kpidFileSystem: case kpidFileSystem:
{ {
@@ -897,7 +908,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
const CItem &item = Items[index]; const CItem &item = Items[index];
switch(propID) switch (propID)
{ {
case kpidPath: prop = GetItemPath(index); break; case kpidPath: prop = GetItemPath(index); break;
case kpidShortName: prop = item.GetShortName(); break; case kpidShortName: prop = item.GetShortName(); break;

View File

@@ -145,7 +145,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
const CItem2 &item = _items2[index]; const CItem2 &item = _items2[index];
switch(propID) switch (propID)
{ {
case kpidExtension: case kpidExtension:
prop = _isRaw ? prop = _isRaw ?
@@ -209,7 +209,7 @@ AString CHandler::GetComment()
Byte type = *p++; Byte type = *p++;
size--; size--;
bool ok = false; bool ok = false;
switch(type) switch (type)
{ {
case 0: case 0:
{ {
@@ -256,7 +256,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
// COM_TRY_BEGIN // COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
switch(propID) switch (propID)
{ {
// case kpidComment: prop = GetComment(); break; // case kpidComment: prop = GetComment(); break;
case kpidPhySize: prop = (UInt64)_phySize; break; case kpidPhySize: prop = (UInt64)_phySize; break;

View File

@@ -156,8 +156,15 @@ class CHandler: public CHandlerCont
CByteBuffer _buffer; CByteBuffer _buffer;
HRESULT Open2(IInStream *stream); HRESULT Open2(IInStream *stream);
virtual UInt64 GetItemPos(UInt32 index) const { return _items[index].GetPos(); }
virtual UInt64 GetItemSize(UInt32 index) const { return _items[index].GetSize(); } virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CPartition &item = _items[index];
pos = item.GetPos();
size = item.GetSize();
return NExtract::NOperationResult::kOK;
}
public: public:
INTERFACE_IInArchive_Cont(;) INTERFACE_IInArchive_Cont(;)
}; };

View File

@@ -28,7 +28,11 @@ STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 totalSize = 0; UInt64 totalSize = 0;
UInt32 i; UInt32 i;
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
totalSize += GetItemSize(allFilesMode ? i : indices[i]); {
UInt64 pos, size;
GetItem_ExtractInfo(allFilesMode ? i : indices[i], pos, size);
totalSize += size;
}
extractCallback->SetTotal(totalSize); extractCallback->SetTotal(totalSize);
totalSize = 0; totalSize = 0;
@@ -56,21 +60,31 @@ STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
Int32 index = allFilesMode ? i : indices[i]; Int32 index = allFilesMode ? i : indices[i];
RINOK(extractCallback->GetStream(index, &outStream, askMode)); RINOK(extractCallback->GetStream(index, &outStream, askMode));
UInt64 size = GetItemSize(index);
UInt64 pos, size;
int opRes = GetItem_ExtractInfo(index, pos, size);
totalSize += size; totalSize += size;
if (!testMode && !outStream) if (!testMode && !outStream)
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
RINOK(_stream->Seek(GetItemPos(index), STREAM_SEEK_SET, NULL)); if (opRes == NExtract::NOperationResult::kOK)
streamSpec->Init(size); {
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); RINOK(_stream->Seek(pos, STREAM_SEEK_SET, NULL));
streamSpec->Init(size);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
opRes = NExtract::NOperationResult::kDataError;
if (copyCoderSpec->TotalSize == size)
opRes = NExtract::NOperationResult::kOK;
else if (copyCoderSpec->TotalSize < size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
}
outStream.Release(); outStream.Release();
int opRes = NExtract::NOperationResult::kDataError;
if (copyCoderSpec->TotalSize == size)
opRes = NExtract::NOperationResult::kOK;
else if (copyCoderSpec->TotalSize < size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
RINOK(extractCallback->SetOperationResult(opRes)); RINOK(extractCallback->SetOperationResult(opRes));
} }
@@ -81,13 +95,22 @@ STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream) STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
// const CPartition &item = _items[index]; *stream = NULL;
return CreateLimitedInStream(_stream, GetItemPos(index), GetItemSize(index), stream); UInt64 pos, size;
if (GetItem_ExtractInfo(index, pos, size) != NExtract::NOperationResult::kOK)
return S_FALSE;
return CreateLimitedInStream(_stream, pos, size, stream);
COM_TRY_END COM_TRY_END
} }
CHandlerImg::CHandlerImg():
_imgExt(NULL)
{
ClearStreamVars();
}
STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{ {
switch (seekOrigin) switch (seekOrigin)
@@ -190,6 +213,8 @@ STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
int opRes = NExtract::NOperationResult::kDataError; int opRes = NExtract::NOperationResult::kDataError;
ClearStreamVars();
CMyComPtr<ISequentialInStream> inStream; CMyComPtr<ISequentialInStream> inStream;
HRESULT hres = GetStream(0, &inStream); HRESULT hres = GetStream(0, &inStream);
if (hres == S_FALSE) if (hres == S_FALSE)
@@ -205,6 +230,13 @@ STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
{ {
if (copyCoderSpec->TotalSize == _size) if (copyCoderSpec->TotalSize == _size)
opRes = NExtract::NOperationResult::kOK; opRes = NExtract::NOperationResult::kOK;
if (_stream_unavailData)
opRes = NExtract::NOperationResult::kUnavailable;
else if (_stream_unsupportedMethod)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
else if (_stream_dataError)
opRes = NExtract::NOperationResult::kDataError;
else if (copyCoderSpec->TotalSize < _size) else if (copyCoderSpec->TotalSize < _size)
opRes = NExtract::NOperationResult::kUnexpectedEnd; opRes = NExtract::NOperationResult::kUnexpectedEnd;
} }
@@ -227,4 +259,30 @@ STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
COM_TRY_END COM_TRY_END
} }
HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize)
{
areThereNonZeros = false;
numZeros = 0;
const size_t kBufSize = 1 << 11;
Byte buf[kBufSize];
for (;;)
{
UInt32 size = 0;
HRESULT(stream->Read(buf, kBufSize, &size));
if (size == 0)
return S_OK;
for (UInt32 i = 0; i < size; i++)
if (buf[i] != 0)
{
areThereNonZeros = true;
numZeros += i;
return S_OK;
}
numZeros += size;
if (numZeros > maxSize)
return S_OK;
}
}
} }

View File

@@ -30,8 +30,8 @@ class CHandlerCont:
protected: protected:
CMyComPtr<IInStream> _stream; CMyComPtr<IInStream> _stream;
virtual UInt64 GetItemPos(UInt32 index) const = 0; virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const = 0;
virtual UInt64 GetItemSize(UInt32 index) const = 0;
public: public:
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive_Cont(PURE) INTERFACE_IInArchive_Cont(PURE)
@@ -39,6 +39,9 @@ public:
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY; STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY;
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
// destructor must be virtual for this class
virtual ~CHandlerCont() {}
}; };
@@ -68,6 +71,22 @@ protected:
UInt64 _size; UInt64 _size;
CMyComPtr<IInStream> Stream; CMyComPtr<IInStream> Stream;
const char *_imgExt; const char *_imgExt;
bool _stream_unavailData;
bool _stream_unsupportedMethod;
bool _stream_dataError;
// bool _stream_UsePackSize;
// UInt64 _stream_PackSize;
void ClearStreamVars()
{
_stream_unavailData = false;
_stream_unsupportedMethod = false;
_stream_dataError = false;
// _stream_UsePackSize = false;
// _stream_PackSize = 0;
}
virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0; virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0;
virtual void CloseAtError(); virtual void CloseAtError();
@@ -83,8 +102,15 @@ public:
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0; STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0;
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
CHandlerImg();
// destructor must be virtual for this class
virtual ~CHandlerImg() {}
}; };
HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize);
} }
#endif #endif

View File

@@ -293,12 +293,14 @@ namespace NPropDataType
const UInt32 kMask_ZeroEnd = 1 << 4; const UInt32 kMask_ZeroEnd = 1 << 4;
// const UInt32 kMask_BigEndian = 1 << 5; // const UInt32 kMask_BigEndian = 1 << 5;
const UInt32 kMask_Utf = 1 << 6; const UInt32 kMask_Utf = 1 << 6;
// const UInt32 kMask_Utf8 = kMask_Utf | 0; const UInt32 kMask_Utf8 = kMask_Utf | 0;
const UInt32 kMask_Utf16 = kMask_Utf | 1; const UInt32 kMask_Utf16 = kMask_Utf | 1;
// const UInt32 kMask_Utf32 = kMask_Utf | 2; // const UInt32 kMask_Utf32 = kMask_Utf | 2;
const UInt32 kNotDefined = 0; const UInt32 kNotDefined = 0;
const UInt32 kRaw = 1; const UInt32 kRaw = 1;
const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd;
const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd; const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd;
}; };
@@ -512,12 +514,26 @@ ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05)
{ if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
*propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \ *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \
struct CStatProp
{
const char *Name;
UInt32 PropID;
VARTYPE vt;
};
namespace NWindows {
namespace NCOM {
// PropVariant.cpp
BSTR AllocBstrFromAscii(const char *s) throw();
}}
#define IMP_IInArchive_GetProp_WITH_NAME(k) \ #define IMP_IInArchive_GetProp_WITH_NAME(k) \
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
{ if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
const STATPROPSTG &srcItem = k[index]; \ const CStatProp &prop = k[index]; \
*propID = srcItem.propid; *varType = srcItem.vt; \ *propID = (PROPID)prop.PropID; *varType = prop.vt; \
if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \ *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \
#define IMP_IInArchive_Props \ #define IMP_IInArchive_Props \
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \

View File

@@ -323,7 +323,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
lps->InSize = lps->OutSize = currentTotalSize + offset; lps->InSize = lps->OutSize = currentTotalSize + offset;
const CDir &item2 = ref.Dir->_subItems[ref.Index + e]; const CDir &item2 = ref.Dir->_subItems[ref.Index + e];
RINOK(_stream->Seek((UInt64)item2.ExtentLocation * _archive.BlockSize, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek((UInt64)item2.ExtentLocation * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(item2.Size); streamSpec->Init(item2.Size);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != item2.Size) if (copyCoderSpec->TotalSize != item2.Size)
@@ -336,7 +336,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
else else
{ {
RINOK(_stream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek((UInt64)blockIndex * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(currentItemSize); streamSpec->Init(currentItemSize);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != currentItemSize) if (copyCoderSpec->TotalSize != currentItemSize)
@@ -379,7 +379,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
if (item.Size == 0) if (item.Size == 0)
continue; continue;
CSeekExtent se; CSeekExtent se;
se.Phy = (UInt64)item.ExtentLocation * _archive.BlockSize; se.Phy = (UInt64)item.ExtentLocation * kBlockSize;
se.Virt = virtOffset; se.Virt = virtOffset;
extentStreamSpec->Extents.Add(se); extentStreamSpec->Extents.Add(se);
virtOffset += item.Size; virtOffset += item.Size;
@@ -405,7 +405,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
blockIndex = be.LoadRBA; blockIndex = be.LoadRBA;
} }
return CreateLimitedInStream(_stream, blockIndex * _archive.BlockSize, currentItemSize, stream); return CreateLimitedInStream(_stream, (UInt64)blockIndex * kBlockSize, currentItemSize, stream);
COM_TRY_END COM_TRY_END
} }

View File

@@ -8,6 +8,8 @@
#include "../../Common/StreamUtils.h" #include "../../Common/StreamUtils.h"
#include "../HandlerCont.h"
#include "IsoIn.h" #include "IsoIn.h"
namespace NArchive { namespace NArchive {
@@ -86,15 +88,15 @@ AString CBootInitialEntry::GetName() const
Byte CInArchive::ReadByte() Byte CInArchive::ReadByte()
{ {
if (m_BufferPos >= BlockSize) if (m_BufferPos >= kBlockSize)
m_BufferPos = 0; m_BufferPos = 0;
if (m_BufferPos == 0) if (m_BufferPos == 0)
{ {
size_t processed = BlockSize; size_t processed = kBlockSize;
HRESULT res = ReadStream(_stream, m_Buffer, &processed); HRESULT res = ReadStream(_stream, m_Buffer, &processed);
if (res != S_OK) if (res != S_OK)
throw CSystemException(res); throw CSystemException(res);
if (processed != BlockSize) if (processed != kBlockSize)
throw CUnexpectedEndException(); throw CUnexpectedEndException();
UInt64 end = _position + processed; UInt64 end = _position + processed;
if (PhySize < end) if (PhySize < end)
@@ -292,7 +294,11 @@ void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d)
d.FileStructureVersion = ReadByte(); // = 1 d.FileStructureVersion = ReadByte(); // = 1
SkipZeros(1); SkipZeros(1);
ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse)); ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse));
SkipZeros(653);
// Most ISO contains zeros in the following field (reserved for future standardization).
// But some ISO programs write some data to that area.
// So we disable check for zeros.
Skip(653); // SkipZeros(653);
} }
static const Byte kSig_CD001[5] = { 'C', 'D', '0', '0', '1' }; static const Byte kSig_CD001[5] = { 'C', 'D', '0', '0', '1' };
@@ -509,7 +515,7 @@ HRESULT CInArchive::Open2()
PhySize = _position; PhySize = _position;
m_BufferPos = 0; m_BufferPos = 0;
BlockSize = kBlockSize; // BlockSize = kBlockSize;
for (;;) for (;;)
{ {
@@ -596,7 +602,7 @@ HRESULT CInArchive::Open2()
ReadBootInfo(); ReadBootInfo();
{ {
FOR_VECTOR(i, Refs) FOR_VECTOR (i, Refs)
{ {
const CRef &ref = Refs[i]; const CRef &ref = Refs[i];
for (UInt32 j = 0; j < ref.NumExtents; j++) for (UInt32 j = 0; j < ref.NumExtents; j++)
@@ -608,12 +614,28 @@ HRESULT CInArchive::Open2()
} }
} }
{ {
FOR_VECTOR(i, BootEntries) FOR_VECTOR (i, BootEntries)
{ {
const CBootInitialEntry &be = BootEntries[i]; const CBootInitialEntry &be = BootEntries[i];
UpdatePhySize(be.LoadRBA, GetBootItemSize(i)); UpdatePhySize(be.LoadRBA, GetBootItemSize(i));
} }
} }
if (PhySize < _fileSize)
{
UInt64 rem = _fileSize - PhySize;
const UInt64 kRemMax = 1 << 21;
if (rem <= kRemMax)
{
RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL));
bool areThereNonZeros = false;
UInt64 numZeros = 0;
RINOK(ReadZeroTail(_stream, areThereNonZeros, numZeros, kRemMax));
if (!areThereNonZeros)
PhySize += numZeros;
}
}
return S_OK; return S_OK;
} }

View File

@@ -170,7 +170,7 @@ struct CBootInitialEntry
// Partition Table found in the boot image. // Partition Table found in the boot image.
UInt16 SectorCount; // This is the number of virtual/emulated sectors the system UInt16 SectorCount; // This is the number of virtual/emulated sectors the system
// will store at Load Segment during the initial boot procedure. // will store at Load Segment during the initial boot procedure.
UInt32 LoadRBA; // This is the start address of the virtual disk. CD<EFBFBD>s use UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use
// Relative/Logical block addressing. // Relative/Logical block addressing.
Byte VendorSpec[20]; Byte VendorSpec[20];
@@ -282,7 +282,7 @@ public:
CRecordVector<CRef> Refs; CRecordVector<CRef> Refs;
CObjectVector<CVolumeDescriptor> VolDescs; CObjectVector<CVolumeDescriptor> VolDescs;
int MainVolDescIndex; int MainVolDescIndex;
UInt32 BlockSize; // UInt32 BlockSize;
CObjectVector<CBootInitialEntry> BootEntries; CObjectVector<CBootInitialEntry> BootEntries;
bool IsArc; bool IsArc;
@@ -297,8 +297,8 @@ public:
void UpdatePhySize(UInt32 blockIndex, UInt64 size) void UpdatePhySize(UInt32 blockIndex, UInt64 size)
{ {
UInt64 alignedSize = (size + BlockSize - 1) & ~((UInt64)BlockSize - 1); const UInt64 alignedSize = (size + kBlockSize - 1) & ~((UInt64)kBlockSize - 1);
UInt64 end = blockIndex * BlockSize + alignedSize; const UInt64 end = (UInt64)blockIndex * kBlockSize + alignedSize;
if (PhySize < end) if (PhySize < end)
PhySize = end; PhySize = end;
} }
@@ -315,7 +315,7 @@ public:
size = (1440 << 10); size = (1440 << 10);
else if (be.BootMediaType == NBootMediaType::k2d88Floppy) else if (be.BootMediaType == NBootMediaType::k2d88Floppy)
size = (2880 << 10); size = (2880 << 10);
UInt64 startPos = (UInt64)be.LoadRBA * BlockSize; UInt64 startPos = (UInt64)be.LoadRBA * kBlockSize;
if (startPos < _fileSize) if (startPos < _fileSize)
{ {
if (_fileSize - startPos < size) if (_fileSize - startPos < size)

View File

@@ -158,6 +158,7 @@ static const CPartType kPartTypes[] =
{ 0x1E, kFat, "FAT16-LBA-WIN95-Hidden" }, { 0x1E, kFat, "FAT16-LBA-WIN95-Hidden" },
{ 0x82, 0, "Solaris x86 / Linux swap" }, { 0x82, 0, "Solaris x86 / Linux swap" },
{ 0x83, 0, "Linux" }, { 0x83, 0, "Linux" },
{ 0x8E, "lvm", "Linux LVM" },
{ 0xA5, 0, "BSD slice" }, { 0xA5, 0, "BSD slice" },
{ 0xBE, 0, "Solaris 8 boot" }, { 0xBE, 0, "Solaris 8 boot" },
{ 0xBF, 0, "New Solaris x86" }, { 0xBF, 0, "New Solaris x86" },
@@ -189,8 +190,14 @@ class CHandler: public CHandlerCont
UInt64 _totalSize; UInt64 _totalSize;
CByteBuffer _buffer; CByteBuffer _buffer;
virtual UInt64 GetItemPos(UInt32 index) const { return _items[index].Part.GetPos(); } virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
virtual UInt64 GetItemSize(UInt32 index) const { return _items[index].Size; } {
const CItem &item = _items[index];
pos = item.Part.GetPos();
size = item.Size;
return NExtract::NOperationResult::kOK;
}
HRESULT ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level); HRESULT ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level);
public: public:
INTERFACE_IInArchive_Cont(;) INTERFACE_IInArchive_Cont(;)
@@ -332,15 +339,15 @@ enum
kpidEndChs kpidEndChs
}; };
static const STATPROPSTG kProps[] = static const CStatProp kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidFileSystem, VT_BSTR}, { NULL, kpidFileSystem, VT_BSTR},
{ NULL, kpidOffset, VT_UI8}, { NULL, kpidOffset, VT_UI8},
{ (LPOLESTR)L"Primary", kpidPrimary, VT_BOOL}, { "Primary", kpidPrimary, VT_BOOL},
{ (LPOLESTR)L"Begin CHS", kpidBegChs, VT_BSTR}, { "Begin CHS", kpidBegChs, VT_BSTR},
{ (LPOLESTR)L"End CHS", kpidEndChs, VT_BSTR} { "End CHS", kpidEndChs, VT_BSTR}
}; };
IMP_IInArchive_Props_WITH_NAME IMP_IInArchive_Props_WITH_NAME

View File

@@ -56,8 +56,15 @@ class CHandler: public CHandlerCont
CItem _items[kNumFilesMax]; CItem _items[kNumFilesMax];
HRESULT Open2(IInStream *stream); HRESULT Open2(IInStream *stream);
virtual UInt64 GetItemPos(UInt32 index) const { return _items[index].Offset; }
virtual UInt64 GetItemSize(UInt32 index) const { return _items[index].Size; } virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CItem &item = _items[index];
pos = item.Offset;
size = item.Size;
return NExtract::NOperationResult::kOK;
}
public: public:
INTERFACE_IInArchive_Cont(;) INTERFACE_IInArchive_Cont(;)
}; };

View File

@@ -519,7 +519,7 @@ bool CAttr::ParseExtents(CRecordVector<CExtent> &extents, UInt64 numClustersMax,
UInt64 vSize = 0; UInt64 vSize = 0;
{ {
unsigned i = num; unsigned i = num;
do vSize = (vSize << 8) | p[--i]; while(i); do vSize = (vSize << 8) | p[--i]; while (i);
} }
if (vSize == 0) if (vSize == 0)
return false; return false;
@@ -576,20 +576,20 @@ class CInStream:
UInt64 _physPos; UInt64 _physPos;
UInt64 _curRem; UInt64 _curRem;
bool _sparseMode; bool _sparseMode;
size_t _compressedPos;
UInt64 _tags[kNumCacheChunks];
unsigned _chunkSizeLog; unsigned _chunkSizeLog;
UInt64 _tags[kNumCacheChunks];
CByteBuffer _inBuf; CByteBuffer _inBuf;
CByteBuffer _outBuf; CByteBuffer _outBuf;
public: public:
CMyComPtr<IInStream> Stream;
UInt64 Size; UInt64 Size;
UInt64 InitializedSize; UInt64 InitializedSize;
unsigned BlockSizeLog; unsigned BlockSizeLog;
unsigned CompressionUnit; unsigned CompressionUnit;
bool InUse;
CRecordVector<CExtent> Extents; CRecordVector<CExtent> Extents;
bool InUse;
CMyComPtr<IInStream> Stream;
HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
@@ -597,11 +597,11 @@ public:
HRESULT InitAndSeek(unsigned compressionUnit) HRESULT InitAndSeek(unsigned compressionUnit)
{ {
CompressionUnit = compressionUnit; CompressionUnit = compressionUnit;
_chunkSizeLog = BlockSizeLog + CompressionUnit;
if (compressionUnit != 0) if (compressionUnit != 0)
{ {
UInt32 cuSize = GetCuSize(); UInt32 cuSize = GetCuSize();
_inBuf.Alloc(cuSize); _inBuf.Alloc(cuSize);
_chunkSizeLog = BlockSizeLog + CompressionUnit;
_outBuf.Alloc(kNumCacheChunks << _chunkSizeLog); _outBuf.Alloc(kNumCacheChunks << _chunkSizeLog);
} }
for (size_t i = 0; i < kNumCacheChunks; i++) for (size_t i = 0; i < kNumCacheChunks; i++)
@@ -1835,7 +1835,7 @@ HRESULT CDatabase::Open()
int indexOfUnnamedStream = -1; int indexOfUnnamedStream = -1;
if (!rec.IsDir()) if (!rec.IsDir())
{ {
FOR_VECTOR(di, rec.DataRefs) FOR_VECTOR (di, rec.DataRefs)
if (rec.DataAttrs[rec.DataRefs[di].Start].Name.IsEmpty()) if (rec.DataAttrs[rec.DataRefs[di].Start].Name.IsEmpty())
{ {
indexOfUnnamedStream = di; indexOfUnnamedStream = di;
@@ -1849,7 +1849,7 @@ HRESULT CDatabase::Open()
if (i < kNumSysRecs) if (i < kNumSysRecs)
{ {
needShow = false; needShow = false;
FOR_VECTOR(di, rec.DataRefs) FOR_VECTOR (di, rec.DataRefs)
if (rec.GetSize(di) != 0) if (rec.GetSize(di) != 0)
{ {
needShow = true; needShow = true;
@@ -1905,7 +1905,7 @@ HRESULT CDatabase::Open()
unsigned numAltStreams = 0; unsigned numAltStreams = 0;
FOR_VECTOR(di, rec.DataRefs) FOR_VECTOR (di, rec.DataRefs)
{ {
if (!rec.IsDir() && (int)di == indexOfUnnamedStream) if (!rec.IsDir() && (int)di == indexOfUnnamedStream)
continue; continue;
@@ -2173,7 +2173,7 @@ enum
kpidATime2 kpidATime2
}; };
static const STATPROPSTG kProps[] = static const CStatProp kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
@@ -2181,20 +2181,20 @@ static const STATPROPSTG kProps[] =
// { NULL, kpidLink, VT_BSTR}, // { NULL, kpidLink, VT_BSTR},
// { (LPOLESTR)L"Link 2", kpidLink2, VT_BSTR}, // { "Link 2", kpidLink2, VT_BSTR},
// { (LPOLESTR)L"Link Type", kpidLinkType, VT_UI2}, // { "Link Type", kpidLinkType, VT_UI2},
{ NULL, kpidINode, VT_UI8}, { NULL, kpidINode, VT_UI8},
{ NULL, kpidMTime, VT_FILETIME}, { NULL, kpidMTime, VT_FILETIME},
{ NULL, kpidCTime, VT_FILETIME}, { NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidATime, VT_FILETIME}, { NULL, kpidATime, VT_FILETIME},
// { (LPOLESTR)L"Record Modified", kpidRecMTime, VT_FILETIME}, // { "Record Modified", kpidRecMTime, VT_FILETIME},
// { (LPOLESTR)L"Modified 2", kpidMTime2, VT_FILETIME}, // { "Modified 2", kpidMTime2, VT_FILETIME},
// { (LPOLESTR)L"Created 2", kpidCTime2, VT_FILETIME}, // { "Created 2", kpidCTime2, VT_FILETIME},
// { (LPOLESTR)L"Accessed 2", kpidATime2, VT_FILETIME}, // { "Accessed 2", kpidATime2, VT_FILETIME},
// { (LPOLESTR)L"Record Modified 2", kpidRecMTime2, VT_FILETIME}, // { "Record Modified 2", kpidRecMTime2, VT_FILETIME},
{ NULL, kpidAttrib, VT_UI4}, { NULL, kpidAttrib, VT_UI4},
{ NULL, kpidNumBlocks, VT_UI4}, { NULL, kpidNumBlocks, VT_UI4},
@@ -2226,13 +2226,13 @@ enum
kpidRecordSize = kpidUserDefined kpidRecordSize = kpidUserDefined
}; };
static const STATPROPSTG kArcProps[] = static const CStatProp kArcProps[] =
{ {
{ NULL, kpidVolumeName, VT_BSTR}, { NULL, kpidVolumeName, VT_BSTR},
{ NULL, kpidFileSystem, VT_BSTR}, { NULL, kpidFileSystem, VT_BSTR},
{ NULL, kpidClusterSize, VT_UI4}, { NULL, kpidClusterSize, VT_UI4},
{ NULL, kpidSectorSize, VT_UI4}, { NULL, kpidSectorSize, VT_UI4},
{ (LPOLESTR)L"Record Size", kpidRecordSize, VT_UI4}, { "Record Size", kpidRecordSize, VT_UI4},
{ NULL, kpidHeadersSize, VT_UI8}, { NULL, kpidHeadersSize, VT_UI8},
{ NULL, kpidCTime, VT_FILETIME}, { NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidId, VT_UI8}, { NULL, kpidId, VT_UI8},

View File

@@ -347,18 +347,24 @@ struct CSection
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {} CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
// const UInt32 GetSize() const { return PSize; }
const UInt32 GetSize() const { return MyMin(PSize, VSize); }
void UpdateTotalSize(UInt32 &totalSize) const void UpdateTotalSize(UInt32 &totalSize) const
{ {
UInt32 t = Pa + PSize; UInt32 t = Pa + PSize;
if (totalSize < t) if (totalSize < t)
totalSize = t; totalSize = t;
} }
void Parse(const Byte *p); void Parse(const Byte *p);
int Compare(const CSection &s) const int Compare(const CSection &s) const
{ {
RINOZ(MyCompare(Pa, s.Pa)); RINOZ(MyCompare(Pa, s.Pa));
return MyCompare(PSize, s.PSize); UInt32 size1 = GetSize();
UInt32 size2 = s.GetSize();
return MyCompare(size1, size2);
} }
}; };
@@ -765,7 +771,7 @@ enum
// kpidBaseOfData32, // kpidBaseOfData32,
}; };
static const STATPROPSTG kArcProps[] = static const CStatProp kArcProps[] =
{ {
// { NULL, kpidWarning, VT_BSTR}, // { NULL, kpidWarning, VT_BSTR},
{ NULL, kpidCpu, VT_BSTR}, { NULL, kpidCpu, VT_BSTR},
@@ -776,28 +782,28 @@ static const STATPROPSTG kArcProps[] =
{ NULL, kpidChecksum, VT_UI4}, { NULL, kpidChecksum, VT_UI4},
{ NULL, kpidName, VT_BSTR}, { NULL, kpidName, VT_BSTR},
{ (LPOLESTR)L"Image Size", kpidImageSize, VT_UI4}, { "Image Size", kpidImageSize, VT_UI4},
{ (LPOLESTR)L"Section Alignment", kpidSectAlign, VT_UI4}, { "Section Alignment", kpidSectAlign, VT_UI4},
{ (LPOLESTR)L"File Alignment", kpidFileAlign, VT_UI4}, { "File Alignment", kpidFileAlign, VT_UI4},
{ (LPOLESTR)L"Code Size", kpidCodeSize, VT_UI4}, { "Code Size", kpidCodeSize, VT_UI4},
{ (LPOLESTR)L"Initialized Data Size", kpidInitDataSize, VT_UI4}, { "Initialized Data Size", kpidInitDataSize, VT_UI4},
{ (LPOLESTR)L"Uninitialized Data Size", kpidUnInitDataSize, VT_UI4}, { "Uninitialized Data Size", kpidUnInitDataSize, VT_UI4},
{ (LPOLESTR)L"Linker Version", kpidLinkerVer, VT_BSTR}, { "Linker Version", kpidLinkerVer, VT_BSTR},
{ (LPOLESTR)L"OS Version", kpidOsVer, VT_BSTR}, { "OS Version", kpidOsVer, VT_BSTR},
{ (LPOLESTR)L"Image Version", kpidImageVer, VT_BSTR}, { "Image Version", kpidImageVer, VT_BSTR},
{ (LPOLESTR)L"Subsystem Version", kpidSubsysVer, VT_BSTR}, { "Subsystem Version", kpidSubsysVer, VT_BSTR},
{ (LPOLESTR)L"Subsystem", kpidSubSystem, VT_BSTR}, { "Subsystem", kpidSubSystem, VT_BSTR},
{ (LPOLESTR)L"DLL Characteristics", kpidDllCharacts, VT_BSTR}, { "DLL Characteristics", kpidDllCharacts, VT_BSTR},
{ (LPOLESTR)L"Stack Reserve", kpidStackReserve, VT_UI8}, { "Stack Reserve", kpidStackReserve, VT_UI8},
{ (LPOLESTR)L"Stack Commit", kpidStackCommit, VT_UI8}, { "Stack Commit", kpidStackCommit, VT_UI8},
{ (LPOLESTR)L"Heap Reserve", kpidHeapReserve, VT_UI8}, { "Heap Reserve", kpidHeapReserve, VT_UI8},
{ (LPOLESTR)L"Heap Commit", kpidHeapCommit, VT_UI8}, { "Heap Commit", kpidHeapCommit, VT_UI8},
{ (LPOLESTR)L"Image Base", kpidImageBase, VT_UI8}, { "Image Base", kpidImageBase, VT_UI8},
{ NULL, kpidComment, VT_BSTR}, { NULL, kpidComment, VT_BSTR},
// { (LPOLESTR)L"Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8}, // { "Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8},
// { (LPOLESTR)L"Base Of Code", kpidBaseOfCode, VT_UI8}, // { "Base Of Code", kpidBaseOfCode, VT_UI8},
// { (LPOLESTR)L"Base Of Data", kpidBaseOfData32, VT_UI8}, // { "Base Of Data", kpidBaseOfData32, VT_UI8},
}; };
static const Byte kProps[] = static const Byte kProps[] =
@@ -1039,7 +1045,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch (propID) switch (propID)
{ {
case kpidPath: prop = MultiByteToUnicodeString(item.Name); break; case kpidPath: prop = MultiByteToUnicodeString(item.Name); break;
case kpidSize: prop = (UInt64)MyMin(item.PSize, item.VSize); break; case kpidSize: prop = (UInt64)item.GetSize(); break;
case kpidPackSize: prop = (UInt64)item.PSize; break; case kpidPackSize: prop = (UInt64)item.PSize; break;
case kpidVirtualSize: prop = (UInt64)item.VSize; break; case kpidVirtualSize: prop = (UInt64)item.VSize; break;
case kpidOffset: prop = item.Pa; break; case kpidOffset: prop = item.Pa; break;
@@ -1883,14 +1889,17 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
} }
f.CloseBlock(2); f.CloseBlock(2);
} }
f.CloseBlock(0); f.CloseBlock(0);
return true; return true;
} }
HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback) HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback)
{ {
const CSection &sect = _sections[sectionIndex]; const CSection &sect = _sections[sectionIndex];
size_t fileSize = sect.PSize; // Maybe we need sect.VSize here !!! const size_t fileSize = sect.GetSize();
if (fileSize > kFileSizeMax) if (fileSize > kFileSizeMax)
return S_FALSE; return S_FALSE;
{ {
@@ -2031,8 +2040,8 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
{ {
UInt32 mask = (1 << numBits) - 1; UInt32 mask = (1 << numBits) - 1;
size_t end = ((maxOffset + mask) & ~mask); size_t end = ((maxOffset + mask) & ~mask);
// 9.29: we use only PSize. PSize can be larger than VSize
if (/* end < sect.VSize && */ end <= sect.PSize) if (/* end < sect.VSize && */ end <= sect.GetSize())
{ {
CSection sect2; CSection sect2;
sect2.Flags = 0; sect2.Flags = 0;
@@ -2050,7 +2059,8 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
// 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX // 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX
// the code for .rsrc_2 is commented. // the code for .rsrc_2 is commented.
sect2.PSize = sect.PSize - (UInt32)maxOffset; sect2.PSize = sect.GetSize() - (UInt32)maxOffset;
if (sect2.PSize != 0) if (sect2.PSize != 0)
{ {
sect2.VSize = sect2.PSize; sect2.VSize = sect2.PSize;
@@ -2233,7 +2243,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
sections.Sort(); sections.Sort();
UInt32 limit = (1 << 12); UInt32 limit = (1 << 12);
unsigned num = 0; unsigned num = 0;
FOR_VECTOR(i, sections) FOR_VECTOR (i, sections)
{ {
const CSection &s = sections[i]; const CSection &s = sections[i];
if (s.Pa > limit) if (s.Pa > limit)
@@ -2463,7 +2473,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else if (mixItem.ResourceIndex >= 0) else if (mixItem.ResourceIndex >= 0)
size = _items[mixItem.ResourceIndex].GetSize(); size = _items[mixItem.ResourceIndex].GetSize();
else else
size = _sections[mixItem.SectionIndex].PSize; size = _sections[mixItem.SectionIndex].GetSize();
totalSize += size; totalSize += size;
} }
extractCallback->SetTotal(totalSize); extractCallback->SetTotal(totalSize);
@@ -2539,7 +2549,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
else else
{ {
currentItemSize = sect.PSize; currentItemSize = sect.GetSize();
if (!testMode && !outStream) if (!testMode && !outStream)
continue; continue;
@@ -2798,12 +2808,12 @@ enum
// , kpidImageBase // , kpidImageBase
}; };
static const STATPROPSTG kArcProps[] = static const CStatProp kArcProps[] =
{ {
// { NULL, kpidHeadersSize, VT_UI4 }, // { NULL, kpidHeadersSize, VT_UI4 },
{ NULL, kpidCpu, VT_BSTR}, { NULL, kpidCpu, VT_BSTR},
{ (LPOLESTR)L"Subsystem", kpidSubSystem, VT_BSTR }, { "Subsystem", kpidSubSystem, VT_BSTR },
// { (LPOLESTR)L"Image Base", kpidImageBase, VT_UI8 } // { "Image Base", kpidImageBase, VT_UI8 }
}; };
IMP_IInArchive_Props IMP_IInArchive_Props

View File

@@ -1,5 +1,5 @@
/* PpmdHandler.c -- PPMd format handler /* PpmdHandler.cpp -- PPMd format handler
2010-03-10 : Igor Pavlov : Public domain 2015-11-30 : Igor Pavlov : Public domain
This code is based on: This code is based on:
PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -349,6 +349,7 @@ struct CPpmdCpp
} }
}; };
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback) Int32 testMode, IArchiveExtractCallback *extractCallback)
{ {
@@ -386,13 +387,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CPpmdCpp ppmd(_item.Ver); CPpmdCpp ppmd(_item.Ver);
if (!ppmd.Alloc(_item.MemInMB)) if (!ppmd.Alloc(_item.MemInMB))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod; Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod;
if (_item.IsSupported()) if (_item.IsSupported())
{ {
opRes = NExtract::NOperationResult::kDataError; opRes = NExtract::NOperationResult::kDataError;
ppmd.Init(_item.Order, _item.Restor); ppmd.Init(_item.Order, _item.Restor);
inBuf.Init(); inBuf.Init();
UInt64 outSize = 0; UInt64 outSize = 0;
if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK) if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK)
for (;;) for (;;)
{ {
@@ -431,6 +436,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
RINOK(WriteStream(realOutStream, outBuf.Buf, i)); RINOK(WriteStream(realOutStream, outBuf.Buf, i));
} }
if (inBuf.Extra)
{
opRes = NExtract::NOperationResult::kUnexpectedEnd;
break;
}
if (sym < 0) if (sym < 0)
{ {
if (sym == -1 && ppmd.IsFinishedOK()) if (sym == -1 && ppmd.IsFinishedOK())
@@ -438,12 +450,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
break; break;
} }
} }
RINOK(inBuf.Res); RINOK(inBuf.Res);
} }
realOutStream.Release(); realOutStream.Release();
return extractCallback->SetOperationResult(opRes); return extractCallback->SetOperationResult(opRes);
} }
static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 }; static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 };
REGISTER_ARC_I( REGISTER_ARC_I(

View File

@@ -30,6 +30,8 @@
#include "../Common/FindSignature.h" #include "../Common/FindSignature.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
#include "../HandlerCont.h"
#include "RarVol.h" #include "RarVol.h"
#include "Rar5Handler.h" #include "Rar5Handler.h"
@@ -38,13 +40,6 @@ using namespace NWindows;
#define Get32(p) GetUi32(p) #define Get32(p) GetUi32(p)
namespace NArchive { namespace NArchive {
namespace NRar {
HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize);
}
namespace NRar5 { namespace NRar5 {
static const unsigned kMarkerSize = 8; static const unsigned kMarkerSize = 8;
@@ -1297,6 +1292,18 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break; break;
} }
case kpidError:
{
if (/* &_missingVol || */ !_missingVolName.IsEmpty())
{
UString s;
s.SetFromAscii("Missing volume : ");
s += _missingVolName;
prop = s;
}
break;
}
case kpidErrorFlags: case kpidErrorFlags:
{ {
UInt32 v = _errorFlags; UInt32 v = _errorFlags;
@@ -1818,6 +1825,8 @@ HRESULT CHandler::Open2(IInStream *stream,
int prevSplitFile = -1; int prevSplitFile = -1;
int prevMainFile = -1; int prevMainFile = -1;
bool nextVol_is_Required = false;
CInArchive arch; CInArchive arch;
for (;;) for (;;)
@@ -1845,13 +1854,19 @@ HRESULT CHandler::Open2(IInStream *stream,
break; break;
} }
HRESULT result = openVolumeCallback->GetStream(seqName.GetNextName(), &inStream); const UString volName = seqName.GetNextName();
if (result == S_FALSE)
break; HRESULT result = openVolumeCallback->GetStream(volName, &inStream);
if (result != S_OK)
if (result != S_OK && result != S_FALSE)
return result; return result;
if (!inStream)
if (!inStream || result != S_OK)
{
if (nextVol_is_Required)
_missingVolName = volName;
break; break;
}
} }
UInt64 endPos = 0; UInt64 endPos = 0;
@@ -1938,7 +1953,7 @@ HRESULT CHandler::Open2(IInStream *stream,
bool areThereNonZeros; bool areThereNonZeros;
UInt64 numZeros; UInt64 numZeros;
const UInt64 maxSize = 1 << 12; const UInt64 maxSize = 1 << 12;
RINOK(NRar::ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)); RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize));
if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize) if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize)
arcInfo.EndPos += numZeros; arcInfo.EndPos += numZeros;
} }
@@ -2099,11 +2114,18 @@ HRESULT CHandler::Open2(IInStream *stream,
} }
curBytes += endPos; curBytes += endPos;
nextVol_is_Required = false;
if (!arcInfo.IsVolume()) if (!arcInfo.IsVolume())
break; break;
if (arcInfo.EndOfArchive_was_Read
&& !arcInfo.AreMoreVolumes()) if (arcInfo.EndOfArchive_was_Read)
break; {
if (!arcInfo.AreMoreVolumes())
break;
nextVol_is_Required = true;
}
} }
FillLinks(); FillLinks();
@@ -2125,6 +2147,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
STDMETHODIMP CHandler::Close() STDMETHODIMP CHandler::Close()
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
_missingVolName.Empty();
_errorFlags = 0; _errorFlags = 0;
// _warningFlags = 0; // _warningFlags = 0;
_isArc = false; _isArc = false;

View File

@@ -381,6 +381,7 @@ private:
// UInt32 _warningFlags; // UInt32 _warningFlags;
bool _isArc; bool _isArc;
CByteBuffer _comment; CByteBuffer _comment;
UString _missingVolName;
DECL_EXTERNAL_CODECS_VARS DECL_EXTERNAL_CODECS_VARS

View File

@@ -30,6 +30,8 @@
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
#include "../Common/OutStreamWithCRC.h" #include "../Common/OutStreamWithCRC.h"
#include "../HandlerCont.h"
#include "RarVol.h" #include "RarVol.h"
#include "RarHandler.h" #include "RarHandler.h"
@@ -638,6 +640,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
{ {
ArcInfo.EndFlags = m_BlockHeader.Flags; ArcInfo.EndFlags = m_BlockHeader.Flags;
UInt32 offset = 7; UInt32 offset = 7;
if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC)
{ {
if (processed < offset + 4) if (processed < offset + 4)
@@ -646,6 +649,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
ArcInfo.DataCRC = Get32(m_FileHeaderData + offset); ArcInfo.DataCRC = Get32(m_FileHeaderData + offset);
offset += 4; offset += 4;
} }
if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber)
{ {
if (processed < offset + 2) if (processed < offset + 2)
@@ -655,6 +659,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
ArcInfo.EndOfArchive_was_Read = true; ArcInfo.EndOfArchive_was_Read = true;
} }
m_Position += processed; m_Position += processed;
FinishCryptoBlock(); FinishCryptoBlock();
ArcInfo.EndPos = m_Position; ArcInfo.EndPos = m_Position;
@@ -697,11 +702,13 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
continue; continue;
*/ */
} }
if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10)) if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10))
{ {
error = k_ErrorType_DecryptionError; error = k_ErrorType_DecryptionError;
return S_OK; return S_OK;
} }
if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
{ {
if (m_FileHeaderData.Size() < 7 + 4) if (m_FileHeaderData.Size() < 7 + 4)
@@ -853,8 +860,21 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break; break;
} }
// case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
case kpidError:
{
// if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
if (/* &_missingVol || */ !_missingVolName.IsEmpty())
{
UString s;
s.SetFromAscii("Missing volume : ");
s += _missingVolName;
prop = s;
}
break;
}
case kpidErrorFlags: case kpidErrorFlags:
{ {
UInt32 v = _errorFlags; UInt32 v = _errorFlags;
@@ -938,7 +958,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.BaseFileIndex >= 0) if (item.BaseFileIndex >= 0)
mainItem = &_items[_refItems[item.BaseFileIndex].ItemIndex]; mainItem = &_items[_refItems[item.BaseFileIndex].ItemIndex];
*/ */
switch(propID) switch (propID)
{ {
case kpidPath: case kpidPath:
{ {
@@ -998,31 +1018,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
} }
HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize)
{
areThereNonZeros = false;
numZeros = 0;
const size_t kBufSize = 1 << 9;
Byte buf[kBufSize];
for (;;)
{
UInt32 size = 0;
HRESULT(stream->Read(buf, kBufSize, &size));
if (size == 0)
return S_OK;
for (UInt32 i = 0; i < size; i++)
if (buf[i] != 0)
{
areThereNonZeros = true;
numZeros += i;
return S_OK;
}
numZeros += size;
if (numZeros > maxSize)
return S_OK;
}
}
HRESULT CHandler::Open2(IInStream *stream, HRESULT CHandler::Open2(IInStream *stream,
const UInt64 *maxCheckStartPosition, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openCallback) IArchiveOpenCallback *openCallback)
@@ -1042,7 +1037,10 @@ HRESULT CHandler::Open2(IInStream *stream,
openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword);
} }
bool nextVol_is_Required = false;
CInArchive archive; CInArchive archive;
for (;;) for (;;)
{ {
CMyComPtr<IInStream> inStream; CMyComPtr<IInStream> inStream;
@@ -1073,14 +1071,19 @@ HRESULT CHandler::Open2(IInStream *stream,
*/ */
} }
UString fullName = seqName.GetNextName(); const UString volName = seqName.GetNextName();
HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
if (result == S_FALSE) HRESULT result = openVolumeCallback->GetStream(volName, &inStream);
break;
if (result != S_OK) if (result != S_OK && result != S_FALSE)
return result; return result;
if (!inStream)
if (!inStream || result != S_OK)
{
if (nextVol_is_Required)
_missingVolName = volName;
break; break;
}
} }
else else
inStream = stream; inStream = stream;
@@ -1197,6 +1200,18 @@ HRESULT CHandler::Open2(IInStream *stream,
arc.PhySize = archive.ArcInfo.GetPhySize(); arc.PhySize = archive.ArcInfo.GetPhySize();
arc.Stream = inStream; arc.Stream = inStream;
} }
nextVol_is_Required = false;
if (!archive.ArcInfo.IsVolume())
break;
if (archive.ArcInfo.EndOfArchive_was_Read)
{
if (!archive.ArcInfo.AreMoreVolumes())
break;
nextVol_is_Required = true;
}
} }
} }
@@ -1239,6 +1254,7 @@ STDMETHODIMP CHandler::Close()
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
// _errorMessage.Empty(); // _errorMessage.Empty();
_missingVolName.Empty();
_errorFlags = 0; _errorFlags = 0;
_warningFlags = 0; _warningFlags = 0;
_isArc = false; _isArc = false;
@@ -1593,7 +1609,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressCoder> commonCoder; CMyComPtr<ICompressCoder> commonCoder;
switch(item.Method) switch (item.Method)
{ {
case '0': case '0':
{ {

View File

@@ -45,6 +45,7 @@ struct CInArcInfo
bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); }
bool AreMoreVolumes() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_NextVol) != 0; }
bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; } bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; }
bool Is_DataCRC_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; } bool Is_DataCRC_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; }
}; };
@@ -79,6 +80,7 @@ class CHandler:
UInt32 _errorFlags; UInt32 _errorFlags;
UInt32 _warningFlags; UInt32 _warningFlags;
bool _isArc; bool _isArc;
UString _missingVolName;
DECL_EXTERNAL_CODECS_VARS DECL_EXTERNAL_CODECS_VARS

View File

@@ -226,8 +226,13 @@ class CHandler: public CHandlerCont
HRESULT ReadHeader(ISequentialInStream *stream, bool isMainHeader); HRESULT ReadHeader(ISequentialInStream *stream, bool isMainHeader);
HRESULT Open2(ISequentialInStream *stream); HRESULT Open2(ISequentialInStream *stream);
virtual UInt64 GetItemPos(UInt32) const { return _headersSize; } virtual int GetItem_ExtractInfo(UInt32 /* index */, UInt64 &pos, UInt64 &size) const
virtual UInt64 GetItemSize(UInt32) const { return _size; } {
pos = _headersSize;
size = _size;
return NExtract::NOperationResult::kOK;
}
public: public:
INTERFACE_IInArchive_Cont(;) INTERFACE_IInArchive_Cont(;)
}; };

View File

@@ -8,6 +8,7 @@
#include "../../../C/Xz.h" #include "../../../C/Xz.h"
#include "../../Common/ComTry.h" #include "../../Common/ComTry.h"
#include "../../Common/MyLinux.h"
#include "../../Common/IntToString.h" #include "../../Common/IntToString.h"
#include "../../Common/StringConvert.h" #include "../../Common/StringConvert.h"
@@ -76,14 +77,6 @@ static const char * const k_Methods[] =
static const UInt32 kMetadataBlockSizeLog = 13; static const UInt32 kMetadataBlockSizeLog = 13;
static const UInt32 kMetadataBlockSize = (1 << kMetadataBlockSizeLog); static const UInt32 kMetadataBlockSize = (1 << kMetadataBlockSizeLog);
#define MY_S_IFIFO 0x1000
#define MY_S_IFCHR 0x2000
#define MY_S_IFDIR 0x4000
#define MY_S_IFBLK 0x6000
#define MY_S_IFREG 0x8000
#define MY_S_IFLNK 0xA000
#define MY_S_IFSOCK 0xC000
enum enum
{ {
kType_IPC, kType_IPC,
@@ -99,8 +92,8 @@ enum
static const UInt32 k_TypeToMode[] = static const UInt32 k_TypeToMode[] =
{ {
0, 0,
MY_S_IFDIR, MY_S_IFREG, MY_S_IFLNK, MY_S_IFBLK, MY_S_IFCHR, MY_S_IFIFO, MY_S_IFSOCK, MY_LIN_S_IFDIR, MY_LIN_S_IFREG, MY_LIN_S_IFLNK, MY_LIN_S_IFBLK, MY_LIN_S_IFCHR, MY_LIN_S_IFIFO, MY_LIN_S_IFSOCK,
MY_S_IFDIR, MY_S_IFREG, MY_S_IFLNK, MY_S_IFBLK, MY_S_IFCHR, MY_S_IFIFO, MY_S_IFSOCK MY_LIN_S_IFDIR, MY_LIN_S_IFREG, MY_LIN_S_IFLNK, MY_LIN_S_IFBLK, MY_LIN_S_IFCHR, MY_LIN_S_IFIFO, MY_LIN_S_IFSOCK
}; };
@@ -754,7 +747,7 @@ UInt32 CNode::Parse4(const Byte *p, UInt32 size, const CHeader &_h)
} }
unsigned offset = 20; unsigned offset = 20;
switch(Type) switch (Type)
{ {
case kType_FIFO: case kType_FIFO + 7: case kType_FIFO: case kType_FIFO + 7:
case kType_SOCK: case kType_SOCK + 7: case kType_SOCK: case kType_SOCK + 7:
@@ -939,7 +932,7 @@ static const Byte kArcProps[] =
kpidHeadersSize, kpidHeadersSize,
kpidFileSystem, kpidFileSystem,
kpidMethod, kpidMethod,
kpidBlock, kpidClusterSize,
kpidBigEndian, kpidBigEndian,
kpidCTime, kpidCTime,
kpidCharacts kpidCharacts
@@ -1552,7 +1545,7 @@ HRESULT CHandler::Open2(IInStream *inStream)
const Byte *p = _inodesData.Data + pos; const Byte *p = _inodesData.Data + pos;
UInt32 size = totalSize - pos; UInt32 size = totalSize - pos;
switch(_h.Major) switch (_h.Major)
{ {
case 1: size = n.Parse1(p, size, _h); break; case 1: size = n.Parse1(p, size, _h); break;
case 2: size = n.Parse2(p, size, _h); break; case 2: size = n.Parse2(p, size, _h); break;
@@ -1817,7 +1810,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
switch(propID) switch (propID)
{ {
case kpidMethod: case kpidMethod:
{ {
@@ -1850,7 +1843,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = res; prop = res;
break; break;
} }
case kpidBlock: prop = _h.BlockSize; break; case kpidClusterSize: prop = _h.BlockSize; break;
case kpidBigEndian: prop = _h.be; break; case kpidBigEndian: prop = _h.be; break;
case kpidCTime: case kpidCTime:
if (_h.CTime != 0) if (_h.CTime != 0)
@@ -1882,7 +1875,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
bool isDir = node.IsDir(); bool isDir = node.IsDir();
bool be = _h.be; bool be = _h.be;
switch(propID) switch (propID)
{ {
case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break; case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
case kpidIsDir: prop = isDir; break; case kpidIsDir: prop = isDir; break;
@@ -1899,7 +1892,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMTime: case kpidMTime:
{ {
UInt32 offset = 0; UInt32 offset = 0;
switch(_h.Major) switch (_h.Major)
{ {
case 1: case 1:
if (node.Type == kType_FILE) if (node.Type == kType_FILE)
@@ -2111,11 +2104,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
int res = NExtract::NOperationResult::kDataError; int res = NExtract::NOperationResult::kDataError;
{ {
CMyComPtr<ISequentialInStream> inSeqStream; CMyComPtr<ISequentialInStream> inSeqStream;
CMyComPtr<IInStream> inStream;
HRESULT hres = GetStream(index, &inSeqStream); HRESULT hres = GetStream(index, &inSeqStream);
if (inSeqStream) if (hres == S_FALSE || !inSeqStream)
inSeqStream.QueryInterface(IID_IInStream, &inStream);
if (hres == S_FALSE || !inStream)
{ {
if (hres == E_OUTOFMEMORY) if (hres == E_OUTOFMEMORY)
return hres; return hres;
@@ -2124,9 +2114,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else else
{ {
RINOK(hres); RINOK(hres);
if (inStream)
{ {
HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress); HRESULT hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress);
if (hres == S_OK) if (hres == S_OK)
{ {
if (copyCoderSpec->TotalSize == unpackSize) if (copyCoderSpec->TotalSize == unpackSize)
@@ -2136,15 +2125,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
res = NExtract::NOperationResult::kUnsupportedMethod; res = NExtract::NOperationResult::kUnsupportedMethod;
} }
else if(hres != S_FALSE) else if (hres != S_FALSE)
{ {
RINOK(hres); RINOK(hres);
} }
} }
} }
} }
RINOK(extractCallback->SetOperationResult(res)); RINOK(extractCallback->SetOperationResult(res));
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }

View File

@@ -639,6 +639,7 @@ void CHandler::Init()
_forceCodePage = false; _forceCodePage = false;
// _codePage = CP_OEMCP; // _codePage = CP_OEMCP;
_curCodePage = _specifiedCodePage = CP_UTF8; // CP_OEMCP; _curCodePage = _specifiedCodePage = CP_UTF8; // CP_OEMCP;
_thereIsPaxExtendedHeader = false;
} }
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)

View File

@@ -4,6 +4,7 @@
#include "../../../Common/ComTry.h" #include "../../../Common/ComTry.h"
#include "../../../Common/Defs.h" #include "../../../Common/Defs.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h" #include "../../../Common/StringConvert.h"
#include "../../../Common/UTFConvert.h" #include "../../../Common/UTFConvert.h"
@@ -113,7 +114,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop)); RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop));
if (prop.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
ui.Mode = 0777 | (ui.IsDir ? 0040000 : 0100000); ui.Mode =
MY_LIN_S_IRWXO
| MY_LIN_S_IRWXG
| MY_LIN_S_IRWXU
| (ui.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG);
else if (prop.vt != VT_UI4) else if (prop.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
else else

View File

@@ -58,7 +58,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
switch(propID) switch (propID)
{ {
case kpidPhySize: prop = _archive.PhySize; break; case kpidPhySize: prop = _archive.PhySize; break;
@@ -98,6 +98,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc;
if (_archive.Unsupported) v |= kpv_ErrorFlags_UnsupportedFeature; if (_archive.Unsupported) v |= kpv_ErrorFlags_UnsupportedFeature;
if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_archive.NoEndAnchor) v |= kpv_ErrorFlags_HeadersError;
prop = v; prop = v;
break; break;
} }

View File

@@ -564,7 +564,7 @@ HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &la
return S_OK; return S_OK;
} }
HRESULT CInArchive::FillRefs(CFileSet &fs, int fileIndex, int parent, int numRecurseAllowed) HRESULT CInArchive::FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed)
{ {
if ((_numRefs & 0xFFF) == 0) if ((_numRefs & 0xFFF) == 0)
{ {
@@ -610,6 +610,7 @@ API_FUNC_IsArc IsArc_Udf(const Byte *p, size_t size)
} }
} }
HRESULT CInArchive::Open2() HRESULT CInArchive::Open2()
{ {
Clear(); Clear();
@@ -644,8 +645,10 @@ HRESULT CInArchive::Open2()
CExtent extentVDS; CExtent extentVDS;
extentVDS.Parse(buf + i + 16); extentVDS.Parse(buf + i + 16);
*/ */
const size_t kBufSize = 1 << 11; const size_t kBufSize = 1 << 11;
Byte buf[kBufSize]; Byte buf[kBufSize];
for (SecLogSize = 11;; SecLogSize -= 3) for (SecLogSize = 11;; SecLogSize -= 3)
{ {
if (SecLogSize < 8) if (SecLogSize < 8)
@@ -665,6 +668,7 @@ HRESULT CInArchive::Open2()
break; break;
} }
} }
PhySize = (UInt32)(256 + 1) << SecLogSize; PhySize = (UInt32)(256 + 1) << SecLogSize;
IsArc = true; IsArc = true;
@@ -946,28 +950,63 @@ HRESULT CInArchive::Open2()
} }
{ {
UInt32 secMask = ((UInt32)1 << SecLogSize) - 1; const UInt32 secMask = ((UInt32)1 << SecLogSize) - 1;
PhySize = (PhySize + secMask) & ~(UInt64)secMask; PhySize = (PhySize + secMask) & ~(UInt64)secMask;
} }
NoEndAnchor = true;
if (PhySize < fileSize) if (PhySize < fileSize)
{ {
UInt64 rem = fileSize - PhySize;
const size_t secSize = (size_t)1 << SecLogSize;
RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL));
size_t bufSize = (UInt32)1 << SecLogSize;
size_t readSize = bufSize; // some UDF images contain ZEROs before "Anchor Volume Descriptor Pointer" at the end
RINOK(ReadStream(_stream, buf, &readSize));
if (readSize == bufSize) for (unsigned sec = 0; sec < 1024; sec++)
{ {
CTag tag; if (rem == 0)
if (tag.Parse(buf, readSize) == S_OK) break;
if (tag.Id == DESC_TYPE_AnchorVolPtr)
size_t readSize = secSize;
if (readSize > rem)
readSize = (size_t)rem;
RINOK(ReadStream(_stream, buf, &readSize));
if (readSize == 0)
break;
if (readSize == secSize && NoEndAnchor)
{
CTag tag;
if (tag.Parse(buf, readSize) == S_OK &&
tag.Id == DESC_TYPE_AnchorVolPtr)
{ {
PhySize += bufSize; NoEndAnchor = false;
rem -= readSize;
PhySize = fileSize - rem;
continue;
} }
}
size_t i;
for (i = 0; i < readSize && buf[i] == 0; i++);
if (i != readSize)
break;
rem -= readSize;
} }
if (rem == 0)
PhySize = fileSize;
} }
return S_OK; return S_OK;
} }
HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress) HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress)
{ {
_progress = progress; _progress = progress;
@@ -1000,6 +1039,7 @@ void CInArchive::Clear()
IsArc = false; IsArc = false;
Unsupported = false; Unsupported = false;
UnexpectedEnd = false; UnexpectedEnd = false;
NoEndAnchor = false;
PhySize = 0; PhySize = 0;
FileSize = 0; FileSize = 0;

View File

@@ -252,7 +252,7 @@ struct CItem
bool IsInline; bool IsInline;
CByteBuffer InlineData; CByteBuffer InlineData;
CRecordVector<CMyExtent> Extents; CRecordVector<CMyExtent> Extents;
CRecordVector<int> SubFiles; CUIntVector SubFiles;
void Parse(const Byte *buf); void Parse(const Byte *buf);
@@ -282,7 +282,7 @@ struct CItem
struct CRef struct CRef
{ {
int Parent; int Parent;
int FileIndex; unsigned FileIndex;
}; };
@@ -346,7 +346,7 @@ class CInArchive
HRESULT ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed); HRESULT ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed);
HRESULT Open2(); HRESULT Open2();
HRESULT FillRefs(CFileSet &fs, int fileIndex, int parent, int numRecurseAllowed); HRESULT FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed);
UInt64 _processedProgressBytes; UInt64 _processedProgressBytes;
@@ -370,6 +370,7 @@ public:
bool IsArc; bool IsArc;
bool Unsupported; bool Unsupported;
bool UnexpectedEnd; bool UnexpectedEnd;
bool NoEndAnchor;
void UpdatePhySize(UInt64 val) void UpdatePhySize(UInt64 val)
{ {

View File

@@ -694,7 +694,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
const CItem2 &item2 = _items2[index]; const CItem2 &item2 = _items2[index];
const CItem &item = _items[item2.MainIndex]; const CItem &item = _items[item2.MainIndex];
switch(propID) switch (propID)
{ {
case kpidPath: case kpidPath:
{ {
@@ -754,7 +754,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
switch(propID) switch (propID)
{ {
case kpidMethod: case kpidMethod:
{ {
@@ -1039,7 +1039,7 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p
else else
{ {
bool needAdd = true; bool needAdd = true;
switch(type) switch (type)
{ {
case SECTION_RAW: case SECTION_RAW:
{ {

View File

@@ -599,17 +599,17 @@ enum
kpidSavedState kpidSavedState
}; };
static const STATPROPSTG kArcProps[] = static const CStatProp kArcProps[] =
{ {
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidOffset, VT_UI8}, { NULL, kpidOffset, VT_UI8},
{ NULL, kpidCTime, VT_FILETIME}, { NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidClusterSize, VT_UI8}, { NULL, kpidClusterSize, VT_UI8},
{ NULL, kpidMethod, VT_BSTR}, { NULL, kpidMethod, VT_BSTR},
{ (LPOLESTR)L"Parent", kpidParent, VT_BSTR}, { "Parent", kpidParent, VT_BSTR},
{ NULL, kpidCreatorApp, VT_BSTR}, { NULL, kpidCreatorApp, VT_BSTR},
{ NULL, kpidHostOS, VT_BSTR}, { NULL, kpidHostOS, VT_BSTR},
{ (LPOLESTR)L"Saved State", kpidSavedState, VT_BOOL}, { "Saved State", kpidSavedState, VT_BOOL},
{ NULL, kpidId, VT_BSTR} { NULL, kpidId, VT_BSTR}
}; };
@@ -682,9 +682,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
s += " -> "; s += " -> ";
const CHandler *p = this; const CHandler *p = this;
while (p != 0 && p->NeedParent()) while (p && p->NeedParent())
p = p->Parent; p = p->Parent;
if (p == 0) if (!p)
s += '?'; s += '?';
else else
s += p->Footer.GetTypeString(); s += p->Footer.GetTypeString();
@@ -750,26 +750,24 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END COM_TRY_END
} }
HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback *openArchiveCallback, unsigned level) HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback *openArchiveCallback, unsigned level)
{ {
Close(); Close();
Stream = stream; Stream = stream;
if (level > (1 << 12)) // Maybe we need to increase that limit if (level > (1 << 12)) // Maybe we need to increase that limit
return S_FALSE; return S_FALSE;
RINOK(Open3()); RINOK(Open3());
if (child && memcmp(child->Dyn.ParentId, Footer.Id, 16) != 0) if (child && memcmp(child->Dyn.ParentId, Footer.Id, 16) != 0)
return S_FALSE; return S_FALSE;
if (Footer.Type != kDiskType_Diff) if (Footer.Type != kDiskType_Diff)
return S_OK; return S_OK;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
if (openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback) != S_OK)
{
// return S_FALSE;
}
CMyComPtr<IInStream> nextStream;
bool useRelative; bool useRelative;
UString name; UString name;
if (!Dyn.RelativeParentNameFromLocator.IsEmpty()) if (!Dyn.RelativeParentNameFromLocator.IsEmpty())
{ {
useRelative = true; useRelative = true;
@@ -780,11 +778,17 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
useRelative = false; useRelative = false;
name = Dyn.ParentName; name = Dyn.ParentName;
} }
Dyn.RelativeNameWasUsed = useRelative; Dyn.RelativeNameWasUsed = useRelative;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
if (openVolumeCallback) if (openVolumeCallback)
{ {
CMyComPtr<IInStream> nextStream;
HRESULT res = openVolumeCallback->GetStream(name, &nextStream); HRESULT res = openVolumeCallback->GetStream(name, &nextStream);
if (res == S_FALSE) if (res == S_FALSE)
{ {
if (useRelative && Dyn.ParentName != Dyn.RelativeParentNameFromLocator) if (useRelative && Dyn.ParentName != Dyn.RelativeParentNameFromLocator)
@@ -793,19 +797,35 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
if (res == S_OK) if (res == S_OK)
Dyn.RelativeNameWasUsed = false; Dyn.RelativeNameWasUsed = false;
} }
if (res == S_FALSE)
return S_OK;
} }
RINOK(res);
if (res != S_OK && res != S_FALSE)
return res;
if (res == S_FALSE || !nextStream)
{
UString s;
s.SetFromAscii("Missing volume : ");
s += name;
AddErrorMessage(s);
return S_OK;
}
Parent = new CHandler; Parent = new CHandler;
ParentStream = Parent; ParentStream = Parent;
res = Parent->Open2(nextStream, this, openArchiveCallback, level + 1); res = Parent->Open2(nextStream, this, openArchiveCallback, level + 1);
if (res == S_FALSE)
if (res != S_OK)
{ {
Parent = NULL; Parent = NULL;
ParentStream.Release(); ParentStream.Release();
if (res == E_ABORT)
return res;
if (res != S_FALSE)
{
// we must show that error code
}
} }
} }
{ {
@@ -813,7 +833,7 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
while (p->NeedParent()) while (p->NeedParent())
{ {
p = p->Parent; p = p->Parent;
if (p == 0) if (!p)
{ {
AddErrorMessage(L"Can't open parent VHD file:"); AddErrorMessage(L"Can't open parent VHD file:");
AddErrorMessage(Dyn.ParentName); AddErrorMessage(Dyn.ParentName);
@@ -824,12 +844,13 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
return S_OK; return S_OK;
} }
void CHandler::CloseAtError() void CHandler::CloseAtError()
{ {
_phySize = 0; _phySize = 0;
Bat.Clear(); Bat.Clear();
NumUsedBlocks = 0; NumUsedBlocks = 0;
Parent = 0; Parent = NULL;
Stream.Release(); Stream.Release();
ParentStream.Release(); ParentStream.Release();
Dyn.Clear(); Dyn.Clear();

View File

File diff suppressed because it is too large Load Diff

View File

@@ -56,7 +56,7 @@ enum
kpidBootImage kpidBootImage
}; };
static const STATPROPSTG kArcProps[] = static const CStatProp kArcProps[] =
{ {
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidPackSize, VT_UI8}, { NULL, kpidPackSize, VT_UI8},
@@ -69,8 +69,8 @@ static const STATPROPSTG kArcProps[] =
{ NULL, kpidIsVolume, VT_BOOL}, { NULL, kpidIsVolume, VT_BOOL},
{ NULL, kpidVolume, VT_UI4}, { NULL, kpidVolume, VT_UI4},
{ NULL, kpidNumVolumes, VT_UI4}, { NULL, kpidNumVolumes, VT_UI4},
{ (LPOLESTR)L"Images", kpidNumImages, VT_UI4}, { "Images", kpidNumImages, VT_UI4},
{ (LPOLESTR)L"Boot Image", kpidBootImage, VT_UI4} { "Boot Image", kpidBootImage, VT_UI4}
}; };
@@ -1028,6 +1028,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
COM_TRY_END COM_TRY_END
} }
STDMETHODIMP CHandler::Close() STDMETHODIMP CHandler::Close()
{ {
_firstVolumeIndex = -1; _firstVolumeIndex = -1;
@@ -1093,7 +1094,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps; CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false); lps->Init(extractCallback, false);
for (i = 0; i < numItems; for (i = 0;; i++,
currentTotalUnPacked += currentItemUnPacked) currentTotalUnPacked += currentItemUnPacked)
{ {
currentItemUnPacked = 0; currentItemUnPacked = 0;
@@ -1102,14 +1103,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
lps->OutSize = currentTotalUnPacked; lps->OutSize = currentTotalUnPacked;
RINOK(lps->SetCur()); RINOK(lps->SetCur());
if (i >= numItems)
break;
UInt32 index = allFilesMode ? i : indices[i]; UInt32 index = allFilesMode ? i : indices[i];
i++;
Int32 askMode = testMode ? Int32 askMode = testMode ?
NExtract::NAskMode::kTest : NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract; NExtract::NAskMode::kExtract;
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if (index >= _db.SortedItems.Size()) if (index >= _db.SortedItems.Size())
{ {
if (!testMode && !realOutStream) if (!testMode && !realOutStream)
@@ -1153,13 +1158,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
Int32 opRes = NExtract::NOperationResult::kOK; Int32 opRes = NExtract::NOperationResult::kOK;
if (streamIndex != prevSuccessStreamIndex || realOutStream) if (streamIndex != prevSuccessStreamIndex || realOutStream)
{ {
Byte digest[kHashSize]; Byte digest[kHashSize];
const CVolume &vol = _volumes[si.PartNumber]; const CVolume &vol = _volumes[si.PartNumber];
bool needDigest = !si.IsEmptyHash(); bool needDigest = !si.IsEmptyHash();
HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header, &_db, HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header, &_db,
realOutStream, progress, needDigest ? digest : NULL); realOutStream, progress, needDigest ? digest : NULL);
if (res == S_OK) if (res == S_OK)
{ {
if (!needDigest || memcmp(digest, si.Hash, kHashSize) == 0) if (!needDigest || memcmp(digest, si.Hash, kHashSize) == 0)
@@ -1174,13 +1182,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else else
return res; return res;
} }
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(opRes)); RINOK(extractCallback->SetOperationResult(opRes));
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
*numItems = _db.SortedItems.Size() + *numItems = _db.SortedItems.Size() +

View File

@@ -21,7 +21,7 @@
#include "../../Common/StreamObjects.h" #include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h" #include "../../Common/StreamUtils.h"
#include "../../Compress/XPressDecoder.h" #include "../../Compress/XpressDecoder.h"
#include "../Common/OutStreamWithSha1.h" #include "../Common/OutStreamWithSha1.h"
@@ -255,7 +255,12 @@ HRESULT CUnpacker::Unpack2(
_solidIndex = resource.SolidIndex; _solidIndex = resource.SolidIndex;
_unpackedChunkIndex = chunkIndex; _unpackedChunkIndex = chunkIndex;
if (cur < offsetInChunk)
return E_FAIL;
cur -= offsetInChunk;
if (cur > rem) if (cur > rem)
cur = (size_t)rem; cur = (size_t)rem;

View File

@@ -221,6 +221,7 @@ namespace NHeaderFlags
const UInt32 kXPRESS = (UInt32)1 << 17; const UInt32 kXPRESS = (UInt32)1 << 17;
const UInt32 kLZX = (UInt32)1 << 18; const UInt32 kLZX = (UInt32)1 << 18;
const UInt32 kLZMS = (UInt32)1 << 19; const UInt32 kLZMS = (UInt32)1 << 19;
const UInt32 kXPRESS2 = (UInt32)1 << 21; // XPRESS with nonstandard chunk size ?
const UInt32 kMethodMask = 0xFFFE0000; const UInt32 kMethodMask = 0xFFFE0000;
} }
@@ -277,7 +278,8 @@ struct CHeader
return (!IsCompressed() return (!IsCompressed()
|| (Flags & NHeaderFlags::kLZX) != 0 || (Flags & NHeaderFlags::kLZX) != 0
|| (Flags & NHeaderFlags::kXPRESS) != 0 || (Flags & NHeaderFlags::kXPRESS) != 0
|| (Flags & NHeaderFlags::kLZMS) != 0); || (Flags & NHeaderFlags::kLZMS) != 0
|| (Flags & NHeaderFlags::kXPRESS2) != 0);
} }
unsigned GetMethod() const unsigned GetMethod() const
@@ -289,6 +291,7 @@ struct CHeader
if (mask == NHeaderFlags::kXPRESS) return NMethod::kXPRESS; if (mask == NHeaderFlags::kXPRESS) return NMethod::kXPRESS;
if (mask == NHeaderFlags::kLZX) return NMethod::kLZX; if (mask == NHeaderFlags::kLZX) return NMethod::kLZX;
if (mask == NHeaderFlags::kLZMS) return NMethod::kLZMS; if (mask == NHeaderFlags::kLZMS) return NMethod::kLZMS;
if (mask == NHeaderFlags::kXPRESS2) return NMethod::kXPRESS;
return mask; return mask;
} }

View File

@@ -5,6 +5,7 @@
#include "../../../C/CpuArch.h" #include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h" #include "../../Common/ComTry.h"
#include "../../Common/MyLinux.h"
#include "../../Common/MyXml.h" #include "../../Common/MyXml.h"
#include "../../Common/StringToInt.h" #include "../../Common/StringToInt.h"
#include "../../Common/UTFConvert.h" #include "../../Common/UTFConvert.h"
@@ -360,7 +361,7 @@ HRESULT CHandler::Open2(IInStream *stream)
UInt64 totalPackSize = 0; UInt64 totalPackSize = 0;
unsigned numMainFiles = 0; unsigned numMainFiles = 0;
FOR_VECTOR(i, _files) FOR_VECTOR (i, _files)
{ {
const CFile &file = _files[i]; const CFile &file = _files[i];
file.UpdateTotalPackSize(totalPackSize); file.UpdateTotalPackSize(totalPackSize);
@@ -511,10 +512,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.ModeDefined) if (item.ModeDefined)
{ {
UInt32 mode = item.Mode; UInt32 mode = item.Mode;
const UInt32 k_PosixAttrib_Dir = (1 << 14); if ((mode & MY_LIN_S_IFMT) == 0)
const UInt32 k_PosixAttrib_RegFile = (1 << 15); mode |= (item.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG);
if ((mode & 0xF000) == 0)
mode |= (item.IsDir ? k_PosixAttrib_Dir : k_PosixAttrib_RegFile);
prop = mode; prop = mode;
} }
break; break;

View File

@@ -271,7 +271,7 @@ HRESULT CAddCommon::Compress(
else else
{ {
CMethodId methodId; CMethodId methodId;
switch(method) switch (method)
{ {
case NFileHeader::NCompressionMethod::kBZip2: case NFileHeader::NCompressionMethod::kBZip2:
methodId = kMethodId_BZip2; methodId = kMethodId_BZip2;

View File

@@ -4,6 +4,7 @@
#include "../../../Common/ComTry.h" #include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h" #include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h" #include "../../../Windows/PropVariant.h"
#include "../../../Windows/TimeUtils.h" #include "../../../Windows/TimeUtils.h"
@@ -241,12 +242,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
const CItemEx &item = m_Items[index]; const CItemEx &item = m_Items[index];
const CExtraBlock &extra = item.GetMainExtra();
switch (propID) switch (propID)
{ {
case kpidPath: case kpidPath:
{ {
UString res; UString res;
item.GetUnicodeString(item.Name, res, _forceCodePage, _specifiedCodePage); item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ConvertToOSName2(res); NItemName::ConvertToOSName2(res);
prop = res; prop = res;
break; break;
@@ -261,9 +264,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
FILETIME ft; FILETIME ft;
UInt32 unixTime; UInt32 unixTime;
UInt32 type; UInt32 type;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft)) if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
type = NFileTimeType::kWindows; type = NFileTimeType::kWindows;
else if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime)) else if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
type = NFileTimeType::kUnix; type = NFileTimeType::kUnix;
else else
type = NFileTimeType::kDOS; type = NFileTimeType::kDOS;
@@ -274,7 +277,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime: case kpidCTime:
{ {
FILETIME ft; FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft)) if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
prop = ft; prop = ft;
break; break;
} }
@@ -282,7 +285,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidATime: case kpidATime:
{ {
FILETIME ft; FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft)) if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
prop = ft; prop = ft;
break; break;
} }
@@ -291,10 +294,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
FILETIME utc; FILETIME utc;
bool defined = true; bool defined = true;
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc)) if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
{ {
UInt32 unixTime = 0; UInt32 unixTime = 0;
if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime)) if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
NTime::UnixTimeToFileTime(unixTime, utc); NTime::UnixTimeToFileTime(unixTime, utc);
else else
{ {
@@ -328,7 +331,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.Comment.Size() != 0) if (item.Comment.Size() != 0)
{ {
UString res; UString res;
item.GetUnicodeString(BytesToString(item.Comment), res, _forceCodePage, _specifiedCodePage); item.GetUnicodeString(res, BytesToString(item.Comment), true, _forceCodePage, _specifiedCodePage);
prop = res; prop = res;
} }
break; break;
@@ -347,7 +350,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
m += kMethod_AES; m += kMethod_AES;
CWzAesExtra aesField; CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField)) if (extra.GetWzAes(aesField))
{ {
char s[16]; char s[16];
s[0] = '-'; s[0] = '-';
@@ -360,7 +363,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
CStrongCryptoExtra f; CStrongCryptoExtra f;
f.AlgId = 0; f.AlgId = 0;
if (item.CentralExtra.GetStrongCrypto(f)) if (extra.GetStrongCrypto(f))
{ {
const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId); const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
if (s) if (s)
@@ -373,6 +376,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
ConvertUInt32ToString(f.AlgId, temp + 1); ConvertUInt32ToString(f.AlgId, temp + 1);
m += temp; m += temp;
} }
if (f.CertificateIsUsed())
m += "-Cert";
} }
else else
m += kMethod_StrongCrypto; m += kMethod_StrongCrypto;
@@ -425,6 +430,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = (UInt32)item.ExtractVersion.Version; prop = (UInt32)item.ExtractVersion.Version;
break; break;
} }
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
@@ -615,7 +621,7 @@ HRESULT CZipDecoder::Decode(
if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES) if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES)
{ {
CWzAesExtra aesField; CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField)) if (item.GetMainExtra().GetWzAes(aesField))
{ {
wzAesMode = true; wzAesMode = true;
needCRC = aesField.NeedCrc(); needCRC = aesField.NeedCrc();
@@ -651,7 +657,7 @@ HRESULT CZipDecoder::Decode(
if (wzAesMode) if (wzAesMode)
{ {
CWzAesExtra aesField; CWzAesExtra aesField;
if (!item.CentralExtra.GetWzAes(aesField)) if (!item.GetMainExtra().GetWzAes(aesField))
return S_OK; return S_OK;
id = aesField.Method; id = aesField.Method;
if (!_wzAesDecoder) if (!_wzAesDecoder)
@@ -929,7 +935,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
bool allFilesMode = (numItems == (UInt32)(Int32)-1); bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode) if (allFilesMode)
numItems = m_Items.Size(); numItems = m_Items.Size();
if(numItems == 0) if (numItems == 0)
return S_OK; return S_OK;
UInt32 i; UInt32 i;
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)

View File

@@ -84,6 +84,8 @@ namespace NFileHeader
kNTFS = 0x0A, kNTFS = 0x0A,
kStrongEncrypt = 0x17, kStrongEncrypt = 0x17,
kUnixTime = 0x5455, kUnixTime = 0x5455,
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
kWzAES = 0x9901 kWzAES = 0x9901
}; };
} }
@@ -153,36 +155,7 @@ namespace NFileHeader
}; };
} }
namespace NUnixAttrib
{
const UInt32 kIFMT = 0170000; // file type mask
const UInt32 kIFDIR = 0040000; // directory
const UInt32 kIFREG = 0100000; // regular file
const UInt32 kIFSOCK = 0140000; // socket (BSD, not SysV or Amiga)
const UInt32 kIFLNK = 0120000; // symbolic link (not SysV, Amiga)
const UInt32 kIFBLK = 0060000; // block special (not Amiga)
const UInt32 kIFCHR = 0020000; // character special (not Amiga)
const UInt32 kIFIFO = 0010000; // fifo (BCC, not MSC or Amiga)
const UInt32 kISUID = 04000; // set user id on execution
const UInt32 kISGID = 02000; // set group id on execution
const UInt32 kISVTX = 01000; // directory permissions control
const UInt32 kENFMT = kISGID; // record locking enforcement flag
const UInt32 kIRWXU = 00700; // read, write, execute: owner
const UInt32 kIRUSR = 00400; // read permission: owner
const UInt32 kIWUSR = 00200; // write permission: owner
const UInt32 kIXUSR = 00100; // execute permission: owner
const UInt32 kIRWXG = 00070; // read, write, execute: group
const UInt32 kIRGRP = 00040; // read permission: group
const UInt32 kIWGRP = 00020; // write permission: group
const UInt32 kIXGRP = 00010; // execute permission: group
const UInt32 kIRWXO = 00007; // read, write, execute: other
const UInt32 kIROTH = 00004; // read permission: other
const UInt32 kIWOTH = 00002; // write permission: other
const UInt32 kIXOTH = 00001; // execute permission: other
}
namespace NAmigaAttrib namespace NAmigaAttrib
{ {
const UInt32 kIFMT = 06000; // Amiga file type mask const UInt32 kIFMT = 06000; // Amiga file type mask

View File

@@ -188,9 +188,9 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
// Crc = Get32(p + 10); // Crc = Get32(p + 10);
// PackSize = Get32(p + 14); // PackSize = Get32(p + 14);
// Size = Get32(p + 18); // Size = Get32(p + 18);
unsigned nameSize = Get16(p + 22); const unsigned nameSize = Get16(p + 22);
unsigned extraSize = Get16(p + 24); unsigned extraSize = Get16(p + 24);
UInt32 extraOffset = kLocalHeaderSize + (UInt32)nameSize; const UInt32 extraOffset = kLocalHeaderSize + (UInt32)nameSize;
if (extraOffset + extraSize > (1 << 16)) if (extraOffset + extraSize > (1 << 16))
return k_IsArc_Res_NO; return k_IsArc_Res_NO;
@@ -203,7 +203,8 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
const Byte *p2 = p + kLocalHeaderSize; const Byte *p2 = p + kLocalHeaderSize;
for (size_t i = 0; i < rem; i++) for (size_t i = 0; i < rem; i++)
if (p2[i] == 0) if (p2[i] == 0)
return k_IsArc_Res_NO; if (i != nameSize - 1)
return k_IsArc_Res_NO;
} }
if (size < extraOffset) if (size < extraOffset)
@@ -562,13 +563,21 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
// return false; // return false;
} }
} }
if (!CheckDosTime(item.Time)) if (!CheckDosTime(item.Time))
{ {
HeadersWarning = true; HeadersWarning = true;
// return false; // return false;
} }
if (item.Name.Len() != nameSize) if (item.Name.Len() != nameSize)
return false; {
// we support "bad" archives with null-terminated name.
if (item.Name.Len() + 1 != nameSize)
return false;
HeadersWarning = true;
}
return item.LocalFullHeaderSize <= ((UInt32)1 << 16); return item.LocalFullHeaderSize <= ((UInt32)1 << 16);
} }
@@ -579,7 +588,7 @@ static bool FlagsAreSame(const CItem &i1, const CItem &i2)
if (i1.Flags == i2.Flags) if (i1.Flags == i2.Flags)
return true; return true;
UInt32 mask = 0xFFFF; UInt32 mask = 0xFFFF;
switch(i1.Method) switch (i1.Method)
{ {
case NFileHeader::NCompressionMethod::kDeflated: case NFileHeader::NCompressionMethod::kDeflated:
mask = 0x7FF9; mask = 0x7FF9;
@@ -782,9 +791,9 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
item.Crc = Get32(p + 12); item.Crc = Get32(p + 12);
item.PackSize = Get32(p + 16); item.PackSize = Get32(p + 16);
item.Size = Get32(p + 20); item.Size = Get32(p + 20);
unsigned nameSize = Get16(p + 24); const unsigned nameSize = Get16(p + 24);
UInt16 extraSize = Get16(p + 26); const unsigned extraSize = Get16(p + 26);
UInt16 commentSize = Get16(p + 28); const unsigned commentSize = Get16(p + 28);
UInt32 diskNumberStart = Get16(p + 30); UInt32 diskNumberStart = Get16(p + 30);
item.InternalAttrib = Get16(p + 32); item.InternalAttrib = Get16(p + 32);
item.ExternalAttrib = Get32(p + 34); item.ExternalAttrib = Get32(p + 34);
@@ -961,7 +970,7 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UI
CItemEx cdItem; CItemEx cdItem;
RINOK(ReadCdItem(cdItem)); RINOK(ReadCdItem(cdItem));
items.Add(cdItem); items.Add(cdItem);
if (progress && items.Size() % 1 == 0) if (progress && (items.Size() & 0xFFF) == 0)
RINOK(progress->SetCompletedCD(items.Size())); RINOK(progress->SetCompletedCD(items.Size()));
} }
return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE; return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE;
@@ -1009,6 +1018,7 @@ bool IsStrangeItem(const CItem &item)
return item.Name.Len() > (1 << 14) || item.Method > (1 << 8); return item.Name.Len() > (1 << 14) || item.Method > (1 << 8);
} }
HRESULT CInArchive::ReadLocals( HRESULT CInArchive::ReadLocals(
CObjectVector<CItemEx> &items, CProgressVirt *progress) CObjectVector<CItemEx> &items, CProgressVirt *progress)
{ {
@@ -1037,7 +1047,8 @@ HRESULT CInArchive::ReadLocals(
return S_FALSE; return S_FALSE;
throw; throw;
} }
if (progress && items.Size() % 1 == 0)
if (progress && (items.Size() & 0xFF) == 0)
RINOK(progress->SetCompletedLocal(items.Size(), item.LocalHeaderPos)); RINOK(progress->SetCompletedLocal(items.Size(), item.LocalHeaderPos));
} }
@@ -1154,15 +1165,17 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
HeadersError = true; HeadersError = true;
return S_OK; return S_OK;
} }
_inBufMode = true; _inBufMode = true;
_inBuffer.Init(); _inBuffer.Init();
cdAbsOffset = m_Position - 4; cdAbsOffset = m_Position - 4;
for (;;) for (;;)
{ {
CItemEx cdItem; CItemEx cdItem;
RINOK(ReadCdItem(cdItem)); RINOK(ReadCdItem(cdItem));
cdItems.Add(cdItem); cdItems.Add(cdItem);
if (progress && cdItems.Size() % 1 == 0) if (progress && (cdItems.Size() & 0xFFF) == 0)
RINOK(progress->SetCompletedCD(items.Size())); RINOK(progress->SetCompletedCD(items.Size()));
m_Signature = ReadUInt32(); m_Signature = ReadUInt32();
if (m_Signature != NSignature::kCentralFileHeader) if (m_Signature != NSignature::kCentralFileHeader)
@@ -1183,6 +1196,7 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
CEcd64 ecd64; CEcd64 ecd64;
bool isZip64 = false; bool isZip64 = false;
UInt64 ecd64AbsOffset = m_Position - 4; UInt64 ecd64AbsOffset = m_Position - 4;
if (m_Signature == NSignature::kEcd64) if (m_Signature == NSignature::kEcd64)
{ {
IsZip64 = isZip64 = true; IsZip64 = isZip64 = true;
@@ -1213,6 +1227,7 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
(!items.IsEmpty()))) (!items.IsEmpty())))
return S_FALSE; return S_FALSE;
} }
if (m_Signature == NSignature::kEcd64Locator) if (m_Signature == NSignature::kEcd64Locator)
{ {
if (!isZip64) if (!isZip64)
@@ -1224,6 +1239,7 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
return S_FALSE; return S_FALSE;
m_Signature = ReadUInt32(); m_Signature = ReadUInt32();
} }
if (m_Signature != NSignature::kEcd) if (m_Signature != NSignature::kEcd)
return S_FALSE; return S_FALSE;
@@ -1323,6 +1339,7 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
return S_OK; return S_OK;
} }
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress) HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
{ {
HRESULT res; HRESULT res;

View File

@@ -2,10 +2,15 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "ZipHeader.h"
#include "ZipItem.h"
#include "../Common/ItemNameUtils.h"
#include "../../../../C/CpuArch.h" #include "../../../../C/CpuArch.h"
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
#include "../Common/ItemNameUtils.h"
#include "ZipItem.h"
namespace NArchive { namespace NArchive {
namespace NZip { namespace NZip {
@@ -77,6 +82,30 @@ bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res
return false; return false;
} }
bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
bool CLocalItem::IsDir() const bool CLocalItem::IsDir() const
{ {
return NItemName::HasTailSlash(Name, GetCodePage()); return NItemName::HasTailSlash(Name, GetCodePage());
@@ -86,12 +115,29 @@ bool CItem::IsDir() const
{ {
if (NItemName::HasTailSlash(Name, GetCodePage())) if (NItemName::HasTailSlash(Name, GetCodePage()))
return true; return true;
Byte hostOS = GetHostOS();
if (Size == 0 && PackSize == 0 && !Name.IsEmpty() && Name.Back() == '\\')
{
// do we need to use CharPrevExA?
// .NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers?
// so we support that case
switch (hostOS)
{
case NHostOS::kFAT:
case NHostOS::kNTFS:
case NHostOS::kHPFS:
case NHostOS::kVFAT:
return true;
}
}
if (!FromCentral) if (!FromCentral)
return false; return false;
UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF); UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF);
Byte hostOS = GetHostOS();
switch (hostOS) switch (hostOS)
{ {
case NHostOS::kAMIGA: case NHostOS::kAMIGA:
@@ -114,7 +160,7 @@ bool CItem::IsDir() const
case NHostOS::kMVS: case NHostOS::kMVS:
return false; // change it throw kUnknownAttributes; return false; // change it throw kUnknownAttributes;
case NHostOS::kUnix: case NHostOS::kUnix:
return ((highAttrib & NUnixAttrib::kIFMT) == NUnixAttrib::kIFDIR); return MY_LIN_S_ISDIR(highAttrib);
default: default:
return false; return false;
} }
@@ -151,8 +197,57 @@ bool CItem::GetPosixAttrib(UInt32 &attrib) const
} }
attrib = 0; attrib = 0;
if (IsDir()) if (IsDir())
attrib = NUnixAttrib::kIFDIR; attrib = MY_LIN_S_IFDIR;
return false; return false;
} }
void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const
{
bool isUtf8 = IsUtf8();
bool ignore_Utf8_Errors = true;
if (!isUtf8)
{
{
const unsigned id = isComment ?
NFileHeader::NExtraID::kIzUnicodeComment:
NFileHeader::NExtraID::kIzUnicodeName;
const CObjectVector<CExtraSubBlock> &subBlocks = GetMainExtra().SubBlocks;
FOR_VECTOR (i, subBlocks)
{
const CExtraSubBlock &sb = subBlocks[i];
if (sb.ID == id)
{
AString utf;
if (sb.ExtractIzUnicode(CrcCalc(s, s.Len()), utf))
if (ConvertUTF8ToUnicode(utf, res))
return;
break;
}
}
}
if (useSpecifiedCodePage)
isUtf8 = (codePage == CP_UTF8);
#ifdef _WIN32
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
ignore_Utf8_Errors = false;
}
#endif
}
if (isUtf8)
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
}} }}

View File

@@ -7,7 +7,6 @@
#include "../../../Common/MyBuffer.h" #include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h" #include "../../../Common/MyString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/UTFConvert.h" #include "../../../Common/UTFConvert.h"
#include "ZipHeader.h" #include "ZipHeader.h"
@@ -28,6 +27,23 @@ struct CExtraSubBlock
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const; bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const; bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
bool ExtractIzUnicode(UInt32 crc, AString &name) const
{
unsigned size = (unsigned)Data.Size();
if (size < 1 + 4)
return false;
const Byte *p = (const Byte *)Data;
if (p[0] > 1)
return false;
if (crc != GetUi32(p + 1))
return false;
size -= 5;
name.SetFrom_CalcLen((const char *)p + 5, size);
if (size != name.Len())
return false;
return CheckUTF8(name, false);
}
}; };
const unsigned k_WzAesExtra_Size = 7; const unsigned k_WzAesExtra_Size = 7;
@@ -109,6 +125,8 @@ struct CStrongCryptoExtra
Flags = GetUi16(p + 6); Flags = GetUi16(p + 6);
return (Format == 2); return (Format == 2);
} }
bool CertificateIsUsed() const { return (Flags > 0x0001); }
}; };
struct CExtraBlock struct CExtraBlock
@@ -155,27 +173,8 @@ struct CExtraBlock
} }
*/ */
bool GetNtfsTime(unsigned index, FILETIME &ft) const bool GetNtfsTime(unsigned index, FILETIME &ft) const;
{ bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
void RemoveUnknownSubBlocks() void RemoveUnknownSubBlocks()
{ {
@@ -272,45 +271,22 @@ public:
MadeByVersion.HostOS = 0; MadeByVersion.HostOS = 0;
} }
const CExtraBlock &GetMainExtra() const { return *(FromCentral ? &CentralExtra : &LocalExtra); }
bool IsDir() const; bool IsDir() const;
UInt32 GetWinAttrib() const; UInt32 GetWinAttrib() const;
bool GetPosixAttrib(UInt32 &attrib) const; bool GetPosixAttrib(UInt32 &attrib) const;
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; } Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; }
void GetUnicodeString(const AString &s, UString &res, bool useSpecifiedCodePage, UINT codePage) const void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const;
{
bool isUtf8 = IsUtf8();
bool ignore_Utf8_Errors = true;
#ifdef _WIN32
if (!isUtf8)
{
if (useSpecifiedCodePage)
isUtf8 = (codePage == CP_UTF8);
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
ignore_Utf8_Errors = false;
}
}
#endif
if (isUtf8)
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
bool IsThereCrc() const bool IsThereCrc() const
{ {
if (Method == NFileHeader::NCompressionMethod::kWzAES) if (Method == NFileHeader::NCompressionMethod::kWzAES)
{ {
CWzAesExtra aesField; CWzAesExtra aesField;
if (CentralExtra.GetWzAes(aesField)) if (GetMainExtra().GetWzAes(aesField))
return aesField.NeedCrc(); return aesField.NeedCrc();
} }
return (Crc != 0 || !IsDir()); return (Crc != 0 || !IsDir());
@@ -320,8 +296,10 @@ public:
{ {
Byte hostOS = GetHostOS(); Byte hostOS = GetHostOS();
return (UINT)(( return (UINT)((
hostOS == NFileHeader::NHostOS::kFAT || hostOS == NFileHeader::NHostOS::kFAT
hostOS == NFileHeader::NHostOS::kNTFS) ? CP_OEMCP : CP_ACP); || hostOS == NFileHeader::NHostOS::kNTFS
|| hostOS == NFileHeader::NHostOS::kUnix // do we need it?
) ? CP_OEMCP : CP_ACP);
} }
}; };

View File

@@ -723,7 +723,7 @@ static HRESULT Update2(
CThreads threads; CThreads threads;
CRecordVector<HANDLE> compressingCompletedEvents; CRecordVector<HANDLE> compressingCompletedEvents;
CRecordVector<int> threadIndices; // list threads in order of updateItems CUIntVector threadIndices; // list threads in order of updateItems
{ {
RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize))); RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize)));
@@ -759,7 +759,7 @@ static HRESULT Update2(
while (itemIndex < updateItems.Size()) while (itemIndex < updateItems.Size())
{ {
if ((UInt32)threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size()) if (threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size())
{ {
CUpdateItem &ui = updateItems[mtItemIndex++]; CUpdateItem &ui = updateItems[mtItemIndex++];
if (!ui.NewData) if (!ui.NewData)

View File

@@ -554,14 +554,6 @@ SOURCE=..\..\Common\CreateCoder.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\Common\CrossThreadProgress.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\CWrappers.cpp SOURCE=..\..\Common\CWrappers.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1285,14 +1277,6 @@ SOURCE=..\..\Archive\7z\7zFolderInStream.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zFolderOutStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHandler.cpp SOURCE=..\..\Archive\7z\7zHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -77,7 +77,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
$O\CrossThreadProgress.obj \
$O\DummyOutStream.obj \ $O\DummyOutStream.obj \
$O\FindSignature.obj \ $O\FindSignature.obj \
$O\HandlerOut.obj \ $O\HandlerOut.obj \
@@ -94,7 +93,6 @@ AR_COMMON_OBJS = \
$O\7zEncode.obj \ $O\7zEncode.obj \
$O\7zExtract.obj \ $O\7zExtract.obj \
$O\7zFolderInStream.obj \ $O\7zFolderInStream.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \ $O\7zHandler.obj \
$O\7zHandlerOut.obj \ $O\7zHandlerOut.obj \
$O\7zHeader.obj \ $O\7zHeader.obj \

View File

@@ -546,14 +546,6 @@ SOURCE=..\..\Common\CreateCoder.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\Common\CrossThreadProgress.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\CWrappers.cpp SOURCE=..\..\Common\CWrappers.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -812,14 +804,6 @@ SOURCE=..\..\Compress\LzmaEncoder.h
SOURCE=..\..\Compress\LzmaRegister.cpp SOURCE=..\..\Compress\LzmaRegister.cpp
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\Compress\RangeCoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\RangeCoderBit.h
# End Source File
# End Group # End Group
# Begin Group "Archive" # Begin Group "Archive"
@@ -865,14 +849,6 @@ SOURCE=..\..\Archive\7z\7zFolderInStream.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zFolderOutStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHandler.cpp SOURCE=..\..\Archive\7z\7zHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -67,7 +67,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
$O\CrossThreadProgress.obj \
$O\DummyOutStream.obj \ $O\DummyOutStream.obj \
$O\HandlerOut.obj \ $O\HandlerOut.obj \
$O\InStreamWithCRC.obj \ $O\InStreamWithCRC.obj \
@@ -83,7 +82,6 @@ AR_COMMON_OBJS = \
$O\7zEncode.obj \ $O\7zEncode.obj \
$O\7zExtract.obj \ $O\7zExtract.obj \
$O\7zFolderInStream.obj \ $O\7zFolderInStream.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \ $O\7zHandler.obj \
$O\7zHandlerOut.obj \ $O\7zHandlerOut.obj \
$O\7zHeader.obj \ $O\7zHeader.obj \

View File

@@ -211,122 +211,6 @@ SOURCE=..\..\UI\FileManager\Test.bmp
# Begin Group "Archive" # Begin Group "Archive"
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Group "7z"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Archive\7z\7zCompressionMode.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zCompressionMode.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zDecode.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zDecode.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zEncode.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zEncode.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zExtract.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zFolderInStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zFolderInStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zFolderOutStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHandler.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHandler.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHandlerOut.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHeader.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHeader.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zIn.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zIn.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zItem.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zOut.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zOut.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zProperties.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zProperties.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zRegister.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zSpecStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zSpecStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zUpdate.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zUpdate.h
# End Source File
# End Group
# Begin Group "Archive Common" # Begin Group "Archive Common"
# PROP Default_Filter "" # PROP Default_Filter ""
@@ -403,6 +287,114 @@ SOURCE=..\..\Archive\Common\ParseProperties.cpp
SOURCE=..\..\Archive\Common\ParseProperties.h SOURCE=..\..\Archive\Common\ParseProperties.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "7z"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Archive\7z\7zCompressionMode.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zCompressionMode.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zDecode.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zDecode.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zEncode.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zEncode.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zExtract.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zFolderInStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zFolderInStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHandler.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHandler.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHandlerOut.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHeader.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zHeader.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zIn.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zIn.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zItem.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zOut.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zOut.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zProperties.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zProperties.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zRegister.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zSpecStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zSpecStream.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zUpdate.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\7z\7zUpdate.h
# End Source File
# End Group
# Begin Source File # Begin Source File
SOURCE=..\..\Archive\IArchive.h SOURCE=..\..\Archive\IArchive.h

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