Compare commits

...

4 Commits
15.09 ... 15.13

Author SHA1 Message Date
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
170 changed files with 3758 additions and 2018 deletions

80
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
{ {
@@ -93,46 +82,24 @@ typedef struct
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

@@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions /* 7zArcIn.c -- 7z Input functions
2015-09-28 : Igor Pavlov : Public domain */ 2015-11-18 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -11,15 +11,15 @@
#include "CpuArch.h" #include "CpuArch.h"
#define MY_ALLOC(T, p, size, alloc) { \ #define MY_ALLOC(T, p, size, alloc) { \
if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = 0; else MY_ALLOC(T, p, size, alloc) } #define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
#define MY_ALLOC_AND_CPY(to, size, from, alloc) \ #define MY_ALLOC_AND_CPY(to, size, from, alloc) \
{ MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); } { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); }
#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \ #define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \
{ if ((size) == 0) p = 0; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } } { if ((size) == 0) p = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }
#define k7zMajorVersion 0 #define k7zMajorVersion 0
@@ -58,26 +58,14 @@ enum EIdEnum
const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
/*
static int SzFolder_FindBondForInStream(const CSzFolder *p, UInt32 inStreamIndex)
{
UInt32 i;
for (i = 0; i < p->NumBonds; i++)
if (p->Bonds[i].InIndex == inStreamIndex)
return i;
return -1;
}
*/
#define SzBitUi32s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; }
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc) static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
{ {
if (num == 0) if (num == 0)
{ {
p->Defs = 0; p->Defs = NULL;
p->Vals = 0; p->Vals = NULL;
} }
else else
{ {
@@ -89,49 +77,49 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc) void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
{ {
IAlloc_Free(alloc, p->Defs); p->Defs = 0; IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
IAlloc_Free(alloc, p->Vals); p->Vals = 0; IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
} }
#define SzBitUi64s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; } #define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc) void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
{ {
IAlloc_Free(alloc, p->Defs); p->Defs = 0; IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
IAlloc_Free(alloc, p->Vals); p->Vals = 0; IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
} }
static void SzAr_Init(CSzAr *p) static void SzAr_Init(CSzAr *p)
{ {
p->NumPackStreams = 0; p->NumPackStreams = 0;
p->NumFolders = 0; p->NumFolders = 0;
p->PackPositions = 0;
SzBitUi32s_Init(&p->FolderCRCs);
// p->Folders = 0;
p->FoCodersOffsets = 0;
p->FoSizesOffsets = 0;
p->FoStartPackStreamIndex = 0;
p->CodersData = 0; p->PackPositions = NULL;
// p->CoderUnpackSizes = 0; SzBitUi32s_Init(&p->FolderCRCs);
p->UnpackSizesData = 0;
p->FoCodersOffsets = NULL;
p->FoStartPackStreamIndex = NULL;
p->FoToCoderUnpackSizes = NULL;
p->FoToMainUnpackSizeIndex = NULL;
p->CoderUnpackSizes = NULL;
p->CodersData = NULL;
} }
static void SzAr_Free(CSzAr *p, ISzAlloc *alloc) static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
{ {
IAlloc_Free(alloc, p->UnpackSizesData);
IAlloc_Free(alloc, p->CodersData);
// IAlloc_Free(alloc, p->CoderUnpackSizes);
IAlloc_Free(alloc, p->PackPositions); IAlloc_Free(alloc, p->PackPositions);
// IAlloc_Free(alloc, p->Folders);
IAlloc_Free(alloc, p->FoCodersOffsets);
IAlloc_Free(alloc, p->FoSizesOffsets);
IAlloc_Free(alloc, p->FoStartPackStreamIndex);
SzBitUi32s_Free(&p->FolderCRCs, alloc); SzBitUi32s_Free(&p->FolderCRCs, alloc);
IAlloc_Free(alloc, p->FoCodersOffsets);
IAlloc_Free(alloc, p->FoStartPackStreamIndex);
IAlloc_Free(alloc, p->FoToCoderUnpackSizes);
IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
IAlloc_Free(alloc, p->CoderUnpackSizes);
IAlloc_Free(alloc, p->CodersData);
SzAr_Init(p); SzAr_Init(p);
} }
@@ -139,18 +127,19 @@ static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
void SzArEx_Init(CSzArEx *p) void SzArEx_Init(CSzArEx *p)
{ {
SzAr_Init(&p->db); SzAr_Init(&p->db);
p->NumFiles = 0; p->NumFiles = 0;
p->dataPos = 0; p->dataPos = 0;
// p->Files = 0;
p->UnpackPositions = 0; p->UnpackPositions = NULL;
// p->IsEmptyFiles = 0; p->IsDirs = NULL;
p->IsDirs = 0;
// p->FolderStartPackStreamIndex = 0; p->FolderToFile = NULL;
// p->PackStreamStartPositions = 0; p->FileToFolder = NULL;
p->FolderStartFileIndex = 0;
p->FileIndexToFolderIndexMap = 0; p->FileNameOffsets = NULL;
p->FileNameOffsets = 0; p->FileNames = NULL;
p->FileNames = 0;
SzBitUi32s_Init(&p->CRCs); SzBitUi32s_Init(&p->CRCs);
SzBitUi32s_Init(&p->Attribs); SzBitUi32s_Init(&p->Attribs);
// SzBitUi32s_Init(&p->Parents); // SzBitUi32s_Init(&p->Parents);
@@ -160,29 +149,27 @@ void SzArEx_Init(CSzArEx *p)
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
{ {
// IAlloc_Free(alloc, p->FolderStartPackStreamIndex); IAlloc_Free(alloc, p->UnpackPositions);
// IAlloc_Free(alloc, p->PackStreamStartPositions); IAlloc_Free(alloc, p->IsDirs);
IAlloc_Free(alloc, p->FolderStartFileIndex);
IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); IAlloc_Free(alloc, p->FolderToFile);
IAlloc_Free(alloc, p->FileToFolder);
IAlloc_Free(alloc, p->FileNameOffsets); IAlloc_Free(alloc, p->FileNameOffsets);
IAlloc_Free(alloc, p->FileNames); IAlloc_Free(alloc, p->FileNames);
SzBitUi64s_Free(&p->CTime, alloc);
SzBitUi64s_Free(&p->MTime, alloc);
SzBitUi32s_Free(&p->CRCs, alloc); SzBitUi32s_Free(&p->CRCs, alloc);
// SzBitUi32s_Free(&p->Parents, alloc);
SzBitUi32s_Free(&p->Attribs, alloc); SzBitUi32s_Free(&p->Attribs, alloc);
IAlloc_Free(alloc, p->IsDirs); // SzBitUi32s_Free(&p->Parents, alloc);
// IAlloc_Free(alloc, p->IsEmptyFiles); SzBitUi64s_Free(&p->MTime, alloc);
IAlloc_Free(alloc, p->UnpackPositions); SzBitUi64s_Free(&p->CTime, alloc);
// IAlloc_Free(alloc, p->Files);
SzAr_Free(&p->db, alloc); SzAr_Free(&p->db, alloc);
SzArEx_Init(p); SzArEx_Init(p);
} }
static int TestSignatureCandidate(Byte *testBytes)
static int TestSignatureCandidate(const Byte *testBytes)
{ {
unsigned i; unsigned i;
for (i = 0; i < k7zSignatureSize; i++) for (i = 0; i < k7zSignatureSize; i++)
@@ -191,16 +178,7 @@ static int TestSignatureCandidate(Byte *testBytes)
return 1; return 1;
} }
#define SzData_Clear(p) { (p)->Data = 0; (p)->Size = 0; } #define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; }
static SRes SzReadByte(CSzData *sd, Byte *b)
{
if (sd->Size == 0)
return SZ_ERROR_ARCHIVE;
sd->Size--;
*b = *sd->Data++;
return SZ_OK;
}
#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++; #define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++;
#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest) #define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest)
@@ -249,57 +227,6 @@ static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
return SZ_OK; return SZ_OK;
} }
/*
static MY_NO_INLINE const Byte *SzReadNumbers(const Byte *data, const Byte *dataLim, UInt64 *values, UInt32 num)
{
for (; num != 0; num--)
{
Byte firstByte;
Byte mask;
unsigned i;
UInt32 v;
UInt64 value;
if (data == dataLim)
return NULL;
firstByte = *data++;
if ((firstByte & 0x80) == 0)
{
*values++ = firstByte;
continue;
}
if (data == dataLim)
return NULL;
v = *data++;
if ((firstByte & 0x40) == 0)
{
*values++ = (((UInt32)firstByte & 0x3F) << 8) | v;
continue;
}
if (data == dataLim)
return NULL;
value = v | ((UInt32)*data++ << 8);
mask = 0x20;
for (i = 2; i < 8; i++)
{
if ((firstByte & mask) == 0)
{
UInt64 highPart = firstByte & (mask - 1);
value |= (highPart << (8 * i));
break;
}
if (data == dataLim)
return NULL;
value |= ((UInt64)*data++ << (8 * i));
mask >>= 1;
}
*values++ = value;
}
return data;
}
*/
static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)
{ {
@@ -336,7 +263,7 @@ static SRes SkipData(CSzData *sd)
return SZ_OK; return SZ_OK;
} }
static SRes WaitId(CSzData *sd, UInt64 id) static SRes WaitId(CSzData *sd, UInt32 id)
{ {
for (;;) for (;;)
{ {
@@ -384,7 +311,7 @@ static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, I
Byte *v2; Byte *v2;
UInt32 numBytes = (numItems + 7) >> 3; UInt32 numBytes = (numItems + 7) >> 3;
*v = NULL; *v = NULL;
RINOK(SzReadByte(sd, &allAreDefined)); SZ_READ_BYTE(allAreDefined);
if (numBytes == 0) if (numBytes == 0)
return SZ_OK; return SZ_OK;
if (allAreDefined == 0) if (allAreDefined == 0)
@@ -438,7 +365,7 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
{ {
Byte allAreDefined; Byte allAreDefined;
UInt32 numDefined = numItems; UInt32 numDefined = numItems;
RINOK(SzReadByte(sd, &allAreDefined)); SZ_READ_BYTE(allAreDefined);
if (!allAreDefined) if (!allAreDefined)
{ {
size_t numBytes = (numItems + 7) >> 3; size_t numBytes = (numItems + 7) >> 3;
@@ -502,7 +429,7 @@ static SRes SzReadSwitch(CSzData *sd)
#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX) #define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes) SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
{ {
UInt32 numCoders, i; UInt32 numCoders, i;
UInt32 numInStreams = 0; UInt32 numInStreams = 0;
@@ -524,7 +451,7 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
unsigned idSize, j; unsigned idSize, j;
UInt64 id; UInt64 id;
RINOK(SzReadByte(sd, &mainByte)); SZ_READ_BYTE(mainByte);
if ((mainByte & 0xC0) != 0) if ((mainByte & 0xC0) != 0)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
@@ -663,16 +590,12 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
} }
} }
for (i = 0; i < numCoders; i++)
{
RINOK(ReadNumber(sdSizes, f->CodersUnpackSizes + i));
}
f->NumCoders = numCoders; f->NumCoders = numCoders;
return SZ_OK; return SZ_OK;
} }
static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
{ {
CSzData sd; CSzData sd;
@@ -703,9 +626,11 @@ static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
return SZ_OK; return SZ_OK;
} }
#define k_Scan_NumCoders_MAX 64 #define k_Scan_NumCoders_MAX 64
#define k_Scan_NumCodersStreams_in_Folder_MAX 64 #define k_Scan_NumCodersStreams_in_Folder_MAX 64
static SRes ReadUnpackInfo(CSzAr *p, static SRes ReadUnpackInfo(CSzAr *p,
CSzData *sd2, CSzData *sd2,
UInt32 numFoldersMax, UInt32 numFoldersMax,
@@ -739,8 +664,9 @@ static SRes ReadUnpackInfo(CSzAr *p,
} }
MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc); MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc);
MY_ALLOC(size_t, p->FoSizesOffsets, (size_t)numFolders + 1, alloc);
MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc); MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc);
MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc);
MY_ALLOC(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc);
startBufPtr = sd.Data; startBufPtr = sd.Data;
@@ -857,7 +783,8 @@ static SRes ReadUnpackInfo(CSzAr *p,
} }
p->FoStartPackStreamIndex[fo] = packStreamIndex; p->FoStartPackStreamIndex[fo] = packStreamIndex;
p->FoSizesOffsets[fo] = (numCoders << 8) | indexOfMainStream; p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
numCodersOutStreams += numCoders; numCodersOutStreams += numCoders;
if (numCodersOutStreams < numCoders) if (numCodersOutStreams < numCoders)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
@@ -871,6 +798,8 @@ static SRes ReadUnpackInfo(CSzAr *p,
} }
} }
p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
{ {
size_t dataSize = sd.Data - startBufPtr; size_t dataSize = sd.Data - startBufPtr;
p->FoStartPackStreamIndex[fo] = packStreamIndex; p->FoStartPackStreamIndex[fo] = packStreamIndex;
@@ -887,27 +816,13 @@ static SRes ReadUnpackInfo(CSzAr *p,
RINOK(WaitId(&sd, k7zIdCodersUnpackSize)); RINOK(WaitId(&sd, k7zIdCodersUnpackSize));
// MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc); MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
{ {
size_t dataSize = sd.Size;
/*
UInt32 i; UInt32 i;
for (i = 0; i < numCodersOutStreams; i++) for (i = 0; i < numCodersOutStreams; i++)
{ {
RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)); RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i));
} }
*/
RINOK(SkipNumbers(&sd, numCodersOutStreams));
dataSize -= sd.Size;
MY_ALLOC_ZE_AND_CPY(p->UnpackSizesData, dataSize, sd.Data - dataSize, alloc);
p->UnpackSizesDataSize = dataSize;
/*
const Byte *data = SzReadNumbers(sd.Data, sd.Data + sd.Size, p->CoderUnpackSizes, numCodersOutStreams);
if (data == NULL)
return SZ_ERROR_ARCHIVE;
sd.Size = sd.Data + sd.Size - data;
sd.Data = data;
*/
} }
for (;;) for (;;)
@@ -928,6 +843,13 @@ static SRes ReadUnpackInfo(CSzAr *p,
} }
} }
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
{
return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]];
}
typedef struct typedef struct
{ {
UInt32 NumTotalSubStreams; UInt32 NumTotalSubStreams;
@@ -937,12 +859,10 @@ typedef struct
CSzData sdCRCs; CSzData sdCRCs;
} CSubStreamInfo; } CSubStreamInfo;
#define SzUi32IndexMax (((UInt32)1 << 31) - 2)
static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
{ {
UInt64 type = 0; UInt64 type = 0;
UInt32 i;
UInt32 numSubDigests = 0; UInt32 numSubDigests = 0;
UInt32 numFolders = p->NumFolders; UInt32 numFolders = p->NumFolders;
UInt32 numUnpackStreams = numFolders; UInt32 numUnpackStreams = numFolders;
@@ -953,6 +873,7 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
RINOK(ReadID(sd, &type)); RINOK(ReadID(sd, &type));
if (type == k7zIdNumUnpackStream) if (type == k7zIdNumUnpackStream)
{ {
UInt32 i;
ssi->sdNumSubStreams.Data = sd->Data; ssi->sdNumSubStreams.Data = sd->Data;
numUnpackStreams = 0; numUnpackStreams = 0;
numSubDigests = 0; numSubDigests = 0;
@@ -1064,7 +985,6 @@ static SRes SzReadAndDecodePackedStreams(
UInt64 dataStartPos; UInt64 dataStartPos;
UInt32 fo; UInt32 fo;
CSubStreamInfo ssi; CSubStreamInfo ssi;
CSzData sdCodersUnpSizes;
RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp)); RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp));
@@ -1072,51 +992,24 @@ static SRes SzReadAndDecodePackedStreams(
if (p->NumFolders == 0) if (p->NumFolders == 0)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
sdCodersUnpSizes.Data = p->UnpackSizesData;
sdCodersUnpSizes.Size = p->UnpackSizesDataSize;
for (fo = 0; fo < p->NumFolders; fo++) for (fo = 0; fo < p->NumFolders; fo++)
Buf_Init(tempBufs + fo); Buf_Init(tempBufs + fo);
for (fo = 0; fo < p->NumFolders; fo++) for (fo = 0; fo < p->NumFolders; fo++)
{ {
CBuf *tempBuf = tempBufs + fo; CBuf *tempBuf = tempBufs + fo;
// folder = p->Folders; UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo);
// unpackSize = SzAr_GetFolderUnpackSize(p, 0);
UInt32 mix = (UInt32)p->FoSizesOffsets[fo];
UInt32 mainIndex = mix & 0xFF;
UInt32 numOutStreams = mix >> 8;
UInt32 si;
UInt64 unpackSize = 0;
p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
for (si = 0; si < numOutStreams; si++)
{
UInt64 curSize;
RINOK(ReadNumber(&sdCodersUnpSizes, &curSize));
if (si == mainIndex)
{
unpackSize = curSize;
break;
}
}
if (si == numOutStreams)
return SZ_ERROR_FAIL;
if ((size_t)unpackSize != unpackSize) if ((size_t)unpackSize != unpackSize)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp)) if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
} }
p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
for (fo = 0; fo < p->NumFolders; fo++) for (fo = 0; fo < p->NumFolders; fo++)
{ {
const CBuf *tempBuf = tempBufs + fo; const CBuf *tempBuf = tempBufs + fo;
RINOK(LookInStream_SeekTo(inStream, dataStartPos)); RINOK(LookInStream_SeekTo(inStream, dataStartPos));
RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp)); RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp));
if (SzBitWithVals_Check(&p->FolderCRCs, fo))
if (CrcCalc(tempBuf->data, tempBuf->size) != p->FolderCRCs.Vals[fo])
return SZ_ERROR_CRC;
} }
return SZ_OK; return SZ_OK;
@@ -1164,7 +1057,7 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)); RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
RINOK(SzReadByte(sd2, &external)); SZ_READ_BYTE_SD(sd2, external);
if (external == 0) if (external == 0)
sd = *sd2; sd = *sd2;
else else
@@ -1198,14 +1091,13 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
return SZ_OK; return SZ_OK;
} }
#define NUM_ADDITIONAL_STREAMS_MAX 8 #define NUM_ADDITIONAL_STREAMS_MAX 8
static SRes SzReadHeader2( static SRes SzReadHeader2(
CSzArEx *p, /* allocMain */ CSzArEx *p, /* allocMain */
CSzData *sd, CSzData *sd,
// Byte **emptyStreamVector, /* allocTemp */
// Byte **emptyFileVector, /* allocTemp */
// Byte **lwtVector, /* allocTemp */
ILookInStream *inStream, ILookInStream *inStream,
CBuf *tempBufs, UInt32 *numTempBufs, CBuf *tempBufs, UInt32 *numTempBufs,
ISzAlloc *allocMain, ISzAlloc *allocMain,
@@ -1215,10 +1107,9 @@ static SRes SzReadHeader2(
UInt64 type; UInt64 type;
UInt32 numFiles = 0; UInt32 numFiles = 0;
UInt32 numEmptyStreams = 0; UInt32 numEmptyStreams = 0;
UInt32 i;
CSubStreamInfo ssi; CSubStreamInfo ssi;
const Byte *emptyStreams = 0; const Byte *emptyStreams = NULL;
const Byte *emptyFiles = 0; const Byte *emptyFiles = NULL;
SzData_Clear(&ssi.sdSizes); SzData_Clear(&ssi.sdSizes);
SzData_Clear(&ssi.sdCRCs); SzData_Clear(&ssi.sdCRCs);
@@ -1242,22 +1133,19 @@ static SRes SzReadHeader2(
RINOK(ReadID(sd, &type)); RINOK(ReadID(sd, &type));
} }
// if (type == k7zIdAdditionalStreamsInfo) return SZ_ERROR_UNSUPPORTED;
if (type == k7zIdAdditionalStreamsInfo) if (type == k7zIdAdditionalStreamsInfo)
{ {
CSzAr tempAr; CSzAr tempAr;
SRes res; SRes res;
UInt32 numTempFolders;
SzAr_Init(&tempAr); SzAr_Init(&tempAr);
res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX, res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX,
p->startPosAfterHeader, &tempAr, allocTemp); p->startPosAfterHeader, &tempAr, allocTemp);
numTempFolders = tempAr.NumFolders; *numTempBufs = tempAr.NumFolders;
SzAr_Free(&tempAr, allocTemp); SzAr_Free(&tempAr, allocTemp);
if (res != SZ_OK) if (res != SZ_OK)
return res; return res;
*numTempBufs = numTempFolders;
RINOK(ReadID(sd, &type)); RINOK(ReadID(sd, &type));
} }
@@ -1271,9 +1159,9 @@ static SRes SzReadHeader2(
if (type == k7zIdEnd) if (type == k7zIdEnd)
{ {
// *sd2 = sd;
return SZ_OK; return SZ_OK;
} }
if (type != k7zIdFilesInfo) if (type != k7zIdFilesInfo)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
@@ -1334,6 +1222,7 @@ static SRes SzReadHeader2(
{ {
RINOK(RememberBitVector(sd, numFiles, &emptyStreams)); RINOK(RememberBitVector(sd, numFiles, &emptyStreams));
numEmptyStreams = CountDefinedBits(emptyStreams, numFiles); numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);
emptyFiles = NULL;
break; break;
} }
case k7zIdEmptyFile: case k7zIdEmptyFile:
@@ -1397,27 +1286,23 @@ static SRes SzReadHeader2(
} }
{ {
UInt32 i;
UInt32 emptyFileIndex = 0; UInt32 emptyFileIndex = 0;
UInt32 folderIndex = 0; UInt32 folderIndex = 0;
UInt32 indexInFolder = 0; UInt32 remSubStreams = 0;
UInt32 numSubStreams = 0;
UInt64 unpackPos = 0; UInt64 unpackPos = 0;
const Byte *digestsDefs = 0; const Byte *digestsDefs = NULL;
const Byte *digestsVals = 0; const Byte *digestsVals = NULL;
UInt32 digestsValsIndex = 0; UInt32 digestsValsIndex = 0;
UInt32 digestIndex; UInt32 digestIndex;
Byte allDigestsDefined = 0; Byte allDigestsDefined = 0;
UInt32 curNumSubStreams = (UInt32)(Int32)-1;
Byte isDirMask = 0; Byte isDirMask = 0;
Byte crcMask = 0; Byte crcMask = 0;
Byte mask = 0x80; Byte mask = 0x80;
// size_t unpSizesOffset = 0;
CSzData sdCodersUnpSizes;
sdCodersUnpSizes.Data = p->db.UnpackSizesData;
sdCodersUnpSizes.Size = p->db.UnpackSizesDataSize;
MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders + 1, allocMain); MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain);
MY_ALLOC_ZE(UInt32, p->FileIndexToFolderIndexMap, p->NumFiles, allocMain); MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain);
MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain); MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain);
MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain); MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
@@ -1425,7 +1310,7 @@ static SRes SzReadHeader2(
if (ssi.sdCRCs.Size != 0) if (ssi.sdCRCs.Size != 0)
{ {
RINOK(SzReadByte(&ssi.sdCRCs, &allDigestsDefined)); SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined);
if (allDigestsDefined) if (allDigestsDefined)
digestsVals = ssi.sdCRCs.Data; digestsVals = ssi.sdCRCs.Data;
else else
@@ -1437,6 +1322,7 @@ static SRes SzReadHeader2(
} }
digestIndex = 0; digestIndex = 0;
for (i = 0; i < numFiles; i++, mask >>= 1) for (i = 0; i < numFiles; i++, mask >>= 1)
{ {
if (mask == 0) if (mask == 0)
@@ -1451,79 +1337,66 @@ static SRes SzReadHeader2(
p->UnpackPositions[i] = unpackPos; p->UnpackPositions[i] = unpackPos;
p->CRCs.Vals[i] = 0; p->CRCs.Vals[i] = 0;
// p->CRCs.Defs[i] = 0;
if (emptyStreams && SzBitArray_Check(emptyStreams, i)) if (emptyStreams && SzBitArray_Check(emptyStreams, i))
{ {
if (!emptyFiles || !SzBitArray_Check(emptyFiles, emptyFileIndex)) if (emptyFiles)
{
if (!SzBitArray_Check(emptyFiles, emptyFileIndex))
isDirMask |= mask; isDirMask |= mask;
emptyFileIndex++; emptyFileIndex++;
if (indexInFolder == 0) }
else
isDirMask |= mask;
if (remSubStreams == 0)
{ {
p->FileIndexToFolderIndexMap[i] = (UInt32)-1; p->FileToFolder[i] = (UInt32)-1;
continue; continue;
} }
} }
if (indexInFolder == 0)
if (remSubStreams == 0)
{ {
/*
v3.13 incorrectly worked with empty folders
v4.07: Loop for skipping empty folders
*/
for (;;) for (;;)
{ {
if (folderIndex >= p->db.NumFolders) if (folderIndex >= p->db.NumFolders)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
p->FolderStartFileIndex[folderIndex] = i; p->FolderToFile[folderIndex] = i;
if (curNumSubStreams == (UInt32)(Int32)-1); numSubStreams = 1;
if (ssi.sdNumSubStreams.Data)
{ {
curNumSubStreams = 1; RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
if (ssi.sdNumSubStreams.Data != 0)
{
RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &curNumSubStreams));
} }
} remSubStreams = numSubStreams;
if (curNumSubStreams != 0) if (numSubStreams != 0)
break; break;
curNumSubStreams = (UInt32)(Int32)-1; {
folderIndex++; // check it UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
unpackPos += folderUnpackSize;
if (unpackPos < folderUnpackSize)
return SZ_ERROR_ARCHIVE;
}
folderIndex++;
} }
} }
p->FileIndexToFolderIndexMap[i] = folderIndex;
p->FileToFolder[i] = folderIndex;
if (emptyStreams && SzBitArray_Check(emptyStreams, i)) if (emptyStreams && SzBitArray_Check(emptyStreams, i))
continue; continue;
indexInFolder++; if (--remSubStreams == 0)
if (indexInFolder >= curNumSubStreams)
{ {
UInt64 folderUnpackSize = 0; UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
UInt64 startFolderUnpackPos; UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]];
{
UInt32 mix = (UInt32)p->db.FoSizesOffsets[folderIndex];
UInt32 mainIndex = mix & 0xFF;
UInt32 numOutStreams = mix >> 8;
UInt32 si;
p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData;
for (si = 0; si < numOutStreams; si++)
{
UInt64 curSize;
RINOK(ReadNumber(&sdCodersUnpSizes, &curSize));
if (si == mainIndex)
{
folderUnpackSize = curSize;
break;
}
}
if (si == numOutStreams)
return SZ_ERROR_FAIL;
}
// UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
startFolderUnpackPos = p->UnpackPositions[p->FolderStartFileIndex[folderIndex]];
if (folderUnpackSize < unpackPos - startFolderUnpackPos) if (folderUnpackSize < unpackPos - startFolderUnpackPos)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
unpackPos = startFolderUnpackPos + folderUnpackSize; unpackPos = startFolderUnpackPos + folderUnpackSize;
if (unpackPos < folderUnpackSize)
return SZ_ERROR_ARCHIVE;
if (curNumSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i)) if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i))
{ {
p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex]; p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex];
crcMask |= mask; crcMask |= mask;
@@ -1534,14 +1407,16 @@ static SRes SzReadHeader2(
digestsValsIndex++; digestsValsIndex++;
crcMask |= mask; crcMask |= mask;
} }
folderIndex++; folderIndex++;
indexInFolder = 0;
} }
else else
{ {
UInt64 v; UInt64 v;
RINOK(ReadNumber(&ssi.sdSizes, &v)); RINOK(ReadNumber(&ssi.sdSizes, &v));
unpackPos += v; unpackPos += v;
if (unpackPos < v)
return SZ_ERROR_ARCHIVE;
if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))
{ {
p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
@@ -1550,30 +1425,55 @@ static SRes SzReadHeader2(
} }
} }
} }
if (mask != 0x80) if (mask != 0x80)
{ {
UInt32 byteIndex = (i - 1) >> 3; UInt32 byteIndex = (i - 1) >> 3;
p->IsDirs[byteIndex] = isDirMask; p->IsDirs[byteIndex] = isDirMask;
p->CRCs.Defs[byteIndex] = crcMask; p->CRCs.Defs[byteIndex] = crcMask;
} }
p->UnpackPositions[i] = unpackPos; p->UnpackPositions[i] = unpackPos;
p->FolderStartFileIndex[folderIndex] = i;
p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData; if (remSubStreams != 0)
return SZ_ERROR_ARCHIVE;
for (;;)
{
p->FolderToFile[folderIndex] = i;
if (folderIndex >= p->db.NumFolders)
break;
if (!ssi.sdNumSubStreams.Data)
return SZ_ERROR_ARCHIVE;
RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
if (numSubStreams != 0)
return SZ_ERROR_ARCHIVE;
/*
{
UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
unpackPos += folderUnpackSize;
if (unpackPos < folderUnpackSize)
return SZ_ERROR_ARCHIVE;
} }
*/
folderIndex++;
}
if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
return SZ_ERROR_ARCHIVE;
}
return SZ_OK; return SZ_OK;
} }
static SRes SzReadHeader( static SRes SzReadHeader(
CSzArEx *p, CSzArEx *p,
CSzData *sd, CSzData *sd,
ILookInStream *inStream, ILookInStream *inStream,
ISzAlloc *allocMain ISzAlloc *allocMain,
,ISzAlloc *allocTemp ISzAlloc *allocTemp)
)
{ {
// Byte *emptyStreamVector = 0;
// Byte *emptyFileVector = 0;
// Byte *lwtVector = 0;
UInt32 i; UInt32 i;
UInt32 numTempBufs = 0; UInt32 numTempBufs = 0;
SRes res; SRes res;
@@ -1581,55 +1481,22 @@ static SRes SzReadHeader(
for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
Buf_Init(tempBufs + i); Buf_Init(tempBufs + i);
// SzBitUi32s_Init(&digests);
res = SzReadHeader2(p, sd, res = SzReadHeader2(p, sd, inStream,
// &emptyStreamVector,
// &emptyFileVector,
// &lwtVector,
inStream,
tempBufs, &numTempBufs, tempBufs, &numTempBufs,
allocMain, allocTemp allocMain, allocTemp);
);
for (i = 0; i < numTempBufs; i++) for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
Buf_Free(tempBufs + i, allocTemp); Buf_Free(tempBufs + i, allocTemp);
// IAlloc_Free(allocTemp, emptyStreamVector);
// IAlloc_Free(allocTemp, emptyFileVector);
// IAlloc_Free(allocTemp, lwtVector);
RINOK(res); RINOK(res);
{
if (sd->Size != 0) if (sd->Size != 0)
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
}
return res; return res;
} }
/*
static UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
{
const CSzFolder2 *f = p->Folders + folderIndex;
// return p->CoderUnpackSizes[f->StartCoderUnpackSizesIndex + f->IndexOfMainOutStream];
UInt32 si;
CSzData sdCodersUnpSizes;
sdCodersUnpSizes.Data = p->UnpackSizesData + f->UnpackSizeDataOffset;
sdCodersUnpSizes.Size = p->UnpackSizesDataSize - f->UnpackSizeDataOffset;
for (si = 0; si < numOutStreams; si++)
{
UInt64 curSize;
ReadNumber(&sdCodersUnpSizes, &curSize);
if (si == mainIndex)
return curSize;
}
return 0;
}
*/
static SRes SzArEx_Open2( static SRes SzArEx_Open2(
CSzArEx *p, CSzArEx *p,
ILookInStream *inStream, ILookInStream *inStream,
@@ -1687,6 +1554,7 @@ static SRes SzArEx_Open2(
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT); res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT);
if (res == SZ_OK) if (res == SZ_OK)
{ {
res = SZ_ERROR_ARCHIVE; res = SZ_ERROR_ARCHIVE;
@@ -1696,7 +1564,9 @@ static SRes SzArEx_Open2(
UInt64 type; UInt64 type;
sd.Data = buf.data; sd.Data = buf.data;
sd.Size = buf.size; sd.Size = buf.size;
res = ReadID(&sd, &type); res = ReadID(&sd, &type);
if (res == SZ_OK && type == k7zIdEncodedHeader) if (res == SZ_OK && type == k7zIdEncodedHeader)
{ {
CSzAr tempAr; CSzAr tempAr;
@@ -1721,6 +1591,7 @@ static SRes SzArEx_Open2(
res = ReadID(&sd, &type); res = ReadID(&sd, &type);
} }
} }
if (res == SZ_OK) if (res == SZ_OK)
{ {
if (type == k7zIdHeader) if (type == k7zIdHeader)
@@ -1744,11 +1615,11 @@ static SRes SzArEx_Open2(
} }
} }
} }
Buf_Free(&buf, allocTemp); Buf_Free(&buf, allocTemp);
return res; return res;
} }
// #include <stdio.h>
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAlloc *allocTemp) ISzAlloc *allocMain, ISzAlloc *allocTemp)
@@ -1756,10 +1627,10 @@ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
if (res != SZ_OK) if (res != SZ_OK)
SzArEx_Free(p, allocMain); SzArEx_Free(p, allocMain);
// printf ("\nrrr=%d\n", rrr);
return res; return res;
} }
SRes SzArEx_Extract( SRes SzArEx_Extract(
const CSzArEx *p, const CSzArEx *p,
ILookInStream *inStream, ILookInStream *inStream,
@@ -1772,34 +1643,36 @@ SRes SzArEx_Extract(
ISzAlloc *allocMain, ISzAlloc *allocMain,
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
{ {
UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; UInt32 folderIndex = p->FileToFolder[fileIndex];
SRes res = SZ_OK; SRes res = SZ_OK;
*offset = 0; *offset = 0;
*outSizeProcessed = 0; *outSizeProcessed = 0;
if (folderIndex == (UInt32)-1) if (folderIndex == (UInt32)-1)
{ {
IAlloc_Free(allocMain, *tempBuf); IAlloc_Free(allocMain, *tempBuf);
*blockIndex = folderIndex; *blockIndex = folderIndex;
*tempBuf = 0; *tempBuf = NULL;
*outBufferSize = 0; *outBufferSize = 0;
return SZ_OK; return SZ_OK;
} }
if (*tempBuf == 0 || *blockIndex != folderIndex) if (*tempBuf == NULL || *blockIndex != folderIndex)
{ {
// UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
/*
UInt64 unpackSizeSpec = UInt64 unpackSizeSpec =
p->UnpackPositions[p->FolderStartFileIndex[folderIndex + 1]] - p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -
p->UnpackPositions[p->FolderStartFileIndex[folderIndex]]; p->UnpackPositions[p->FolderToFile[folderIndex]];
*/
size_t unpackSize = (size_t)unpackSizeSpec; size_t unpackSize = (size_t)unpackSizeSpec;
if (unpackSize != unpackSizeSpec) if (unpackSize != unpackSizeSpec)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
*blockIndex = folderIndex; *blockIndex = folderIndex;
IAlloc_Free(allocMain, *tempBuf); IAlloc_Free(allocMain, *tempBuf);
*tempBuf = 0; *tempBuf = NULL;
// RINOK(LookInStream_SeekTo(inStream, startOffset));
if (res == SZ_OK) if (res == SZ_OK)
{ {
@@ -1807,36 +1680,30 @@ SRes SzArEx_Extract(
if (unpackSize != 0) if (unpackSize != 0)
{ {
*tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize); *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
if (*tempBuf == 0) if (*tempBuf == NULL)
res = SZ_ERROR_MEM; res = SZ_ERROR_MEM;
} }
if (res == SZ_OK) if (res == SZ_OK)
{ {
res = SzAr_DecodeFolder(&p->db, folderIndex, res = SzAr_DecodeFolder(&p->db, folderIndex,
inStream, inStream, p->dataPos, *tempBuf, unpackSize, allocTemp);
p->dataPos,
*tempBuf, unpackSize, allocTemp);
if (res == SZ_OK)
{
if (SzBitWithVals_Check(&p->db.FolderCRCs, folderIndex))
{
if (CrcCalc(*tempBuf, unpackSize) != p->db.FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
}
}
} }
} }
} }
if (res == SZ_OK) if (res == SZ_OK)
{ {
UInt64 unpackPos = p->UnpackPositions[fileIndex]; UInt64 unpackPos = p->UnpackPositions[fileIndex];
*offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderStartFileIndex[folderIndex]]); *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
*outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos); *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
if (*offset + *outSizeProcessed > *outBufferSize) if (*offset + *outSizeProcessed > *outBufferSize)
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
if (SzBitWithVals_Check(&p->CRCs, fileIndex) && CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex]) if (SzBitWithVals_Check(&p->CRCs, fileIndex))
if (CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])
res = SZ_ERROR_CRC; res = SZ_ERROR_CRC;
} }
return res; return res;
} }

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 9 #define MY_VER_MINOR 13
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "15.09" #define MY_VERSION_NUMBERS "15.13"
#define MY_VERSION "15.09 beta" #define MY_VERSION "15.13"
#define MY_DATE "2015-10-16" #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,13 +10,17 @@ 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) \
|| defined(_M_AMD64) \
|| defined(__x86_64__) \
|| defined(__AMD64__) \
|| defined(__amd64__)
#define MY_CPU_AMD64 #define MY_CPU_AMD64
#endif #endif
@@ -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 @@
/* 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,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-10-15 Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -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 +
@@ -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;

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-09-28 : 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);

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

@@ -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

@@ -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

@@ -781,6 +781,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;
} }
@@ -843,7 +844,7 @@ 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;
@@ -937,8 +938,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 +1011,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);

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

@@ -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,16 +579,20 @@ 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;

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

@@ -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

@@ -1118,7 +1118,7 @@ HRESULT CHandler::SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, siz
{ {
if (block == 0 || block >= _h.NumBlocks) if (block == 0 || block >= _h.NumBlocks)
return S_FALSE; return S_FALSE;
if (((size + (1 << _h.BlockBits) + 1) >> _h.BlockBits) > _h.NumBlocks - block) if (((size + ((size_t)1 << _h.BlockBits) - 1) >> _h.BlockBits) > _h.NumBlocks - block)
return S_FALSE; return S_FALSE;
RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL)); RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL));
_totalRead += size; _totalRead += size;
@@ -1167,6 +1167,9 @@ HRESULT CHandler::Open2(IInStream *inStream)
RINOK(_openCallback->SetTotal(NULL, &_phySize)); RINOK(_openCallback->SetTotal(NULL, &_phySize));
} }
UInt64 fileSize = 0;
RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize));
CRecordVector<CGroupDescriptor> groups; CRecordVector<CGroupDescriptor> groups;
{ {
@@ -1214,6 +1217,21 @@ HRESULT CHandler::Open2(IInStream *inStream)
if (_h.NumInodes < _h.NumFreeInodes) if (_h.NumInodes < _h.NumFreeInodes)
return S_FALSE; return S_FALSE;
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
size_t nodesDataSize = (size_t)numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
// that code to reduce false detecting cases
if (nodesDataSize > fileSize)
{
if (numNodes > (1 << 24))
return S_FALSE;
}
UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1; UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1;
// numReserveInodes = _h.NumInodes + 1; // numReserveInodes = _h.NumInodes + 1;
if (numReserveInodes != 0) if (numReserveInodes != 0)
@@ -1222,13 +1240,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
_refs.Reserve(numReserveInodes); _refs.Reserve(numReserveInodes);
} }
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
size_t nodesDataSize = numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
CByteBuffer nodesData; CByteBuffer nodesData;
nodesData.Alloc(nodesDataSize); nodesData.Alloc(nodesDataSize);

View File

@@ -160,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;
@@ -171,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;

View File

@@ -294,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' };

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];

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);
} }
}; };
@@ -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;
@@ -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;

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

@@ -1292,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;
@@ -1813,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 (;;)
@@ -1840,14 +1854,20 @@ 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;
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &arch.StreamStartPosition)); RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &arch.StreamStartPosition));
@@ -2094,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)
{
if (!arcInfo.AreMoreVolumes())
break; break;
nextVol_is_Required = true;
}
} }
FillLinks(); FillLinks();
@@ -2120,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

@@ -640,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)
@@ -648,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)
@@ -657,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;
@@ -699,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)
@@ -855,7 +860,20 @@ 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:
{ {
@@ -1019,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;
@@ -1050,15 +1071,20 @@ 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;
@@ -1174,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;
}
} }
} }
@@ -1216,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;

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

@@ -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

@@ -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
for (unsigned sec = 0; sec < 1024; sec++)
{
if (rem == 0)
break;
size_t readSize = secSize;
if (readSize > rem)
readSize = (size_t)rem;
RINOK(ReadStream(_stream, buf, &readSize)); RINOK(ReadStream(_stream, buf, &readSize));
if (readSize == bufSize)
if (readSize == 0)
break;
if (readSize == secSize && NoEndAnchor)
{ {
CTag tag; CTag tag;
if (tag.Parse(buf, readSize) == S_OK) if (tag.Parse(buf, readSize) == S_OK &&
if (tag.Id == DESC_TYPE_AnchorVolPtr) 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

@@ -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

@@ -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) }
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; return S_OK;
} }
RINOK(res);
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

@@ -451,6 +451,8 @@ class CHandler: public CHandlerImg
CByteBuffer _descriptorBuf; CByteBuffer _descriptorBuf;
CDescriptor _descriptor; CDescriptor _descriptor;
UString _missingVolName;
void InitAndSeekMain() void InitAndSeekMain()
{ {
_virtPos = 0; _virtPos = 0;
@@ -882,6 +884,19 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidNumVolumes: if (_isMultiVol) prop = (UInt32)_extents.Size(); break; case kpidNumVolumes: if (_isMultiVol) prop = (UInt32)_extents.Size(); break;
case kpidError:
{
if (_missingVol || !_missingVolName.IsEmpty())
{
UString s;
s.SetFromAscii("Missing volume : ");
if (!_missingVolName.IsEmpty())
s += _missingVolName;
prop = s;
}
break;
}
case kpidErrorFlags: case kpidErrorFlags:
{ {
UInt32 v = 0; UInt32 v = 0;
@@ -889,7 +904,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
if (_unsupportedSome) v |= kpv_ErrorFlags_UnsupportedMethod; if (_unsupportedSome) v |= kpv_ErrorFlags_UnsupportedMethod;
if (_headerError) v |= kpv_ErrorFlags_HeadersError; if (_headerError) v |= kpv_ErrorFlags_HeadersError;
if (_missingVol) v |= kpv_ErrorFlags_UnexpectedEnd; // if (_missingVol) v |= kpv_ErrorFlags_UnexpectedEnd;
if (v != 0) if (v != 0)
prop = v; prop = v;
break; break;
@@ -1081,15 +1096,14 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
} }
HRESULT result = volumeCallback->GetStream(u, &nextStream); HRESULT result = volumeCallback->GetStream(u, &nextStream);
if (result == S_FALSE)
{ if (result != S_OK && result != S_FALSE)
_missingVol = true;
continue;
}
if (result != S_OK)
return result; return result;
if (!nextStream)
if (!nextStream || result != S_OK)
{ {
if (_missingVolName.IsEmpty())
_missingVolName = u;
_missingVol = true; _missingVol = true;
continue; continue;
} }
@@ -1431,6 +1445,8 @@ STDMETHODIMP CHandler::Close()
_isMultiVol = false; _isMultiVol = false;
_needDeflate = false; _needDeflate = false;
_missingVolName.Empty();
_descriptorBuf.Free(); _descriptorBuf.Free();
_descriptor.Clear(); _descriptor.Clear();

View File

@@ -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

@@ -256,6 +256,11 @@ 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

@@ -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)

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
}; };
} }

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,6 +203,7 @@ 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)
if (i != nameSize - 1)
return k_IsArc_Res_NO; return k_IsArc_Res_NO;
} }
@@ -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)
{
// we support "bad" archives with null-terminated name.
if (item.Name.Len() + 1 != nameSize)
return false; return false;
HeadersWarning = true;
}
return item.LocalFullHeaderSize <= ((UInt32)1 << 16); return item.LocalFullHeaderSize <= ((UInt32)1 << 16);
} }
@@ -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

@@ -3,8 +3,10 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../../C/CpuArch.h" #include "../../../../C/CpuArch.h"
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyLinux.h" #include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
@@ -80,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());
@@ -89,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:
@@ -158,4 +201,53 @@ bool CItem::GetPosixAttrib(UInt32 &attrib) const
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

@@ -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

View File

@@ -49,7 +49,6 @@ AR_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 \
@@ -63,7 +62,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

@@ -7,12 +7,12 @@ COMMON_OBJS = \
$O\CRC.obj \ $O\CRC.obj \
$O\CrcReg.obj \ $O\CrcReg.obj \
$O\IntToString.obj \ $O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \ $O\MyString.obj \
$O\MyVector.obj \
$O\NewHandler.obj \
$O\Sha256Reg.obj \ $O\Sha256Reg.obj \
$O\StringConvert.obj \ $O\StringConvert.obj \
$O\StringToInt.obj \ $O\StringToInt.obj \
$O\MyVector.obj \
$O\Wildcard.obj \ $O\Wildcard.obj \
WIN_OBJS = \ WIN_OBJS = \
@@ -42,7 +42,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
$O\CrossThreadProgress.obj \
$O\ItemNameUtils.obj \ $O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \ $O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \ $O\ParseProperties.obj \
@@ -51,7 +50,6 @@ AR_COMMON_OBJS = \
$O\7zCompressionMode.obj \ $O\7zCompressionMode.obj \
$O\7zDecode.obj \ $O\7zDecode.obj \
$O\7zExtract.obj \ $O\7zExtract.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \ $O\7zHandler.obj \
$O\7zHeader.obj \ $O\7zHeader.obj \
$O\7zIn.obj \ $O\7zIn.obj \

View File

@@ -42,7 +42,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
$O\CrossThreadProgress.obj \
$O\HandlerOut.obj \ $O\HandlerOut.obj \
$O\ItemNameUtils.obj \ $O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \ $O\OutStreamWithCRC.obj \
@@ -53,7 +52,6 @@ AR_COMMON_OBJS = \
$O\7zCompressionMode.obj \ $O\7zCompressionMode.obj \
$O\7zDecode.obj \ $O\7zDecode.obj \
$O\7zExtract.obj \ $O\7zExtract.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \ $O\7zHandler.obj \
$O\7zHeader.obj \ $O\7zHeader.obj \
$O\7zIn.obj \ $O\7zIn.obj \

View File

@@ -93,7 +93,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\InStreamWithCRC.obj \ $O\InStreamWithCRC.obj \
@@ -111,7 +110,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

@@ -47,7 +47,6 @@ AR_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 \
@@ -61,7 +60,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

@@ -18,7 +18,6 @@ FILE_IO =FileIO
FILE_IO_2 =Windows/$(FILE_IO) FILE_IO_2 =Windows/$(FILE_IO)
MT_FILES = \ MT_FILES = \
System.o \
LzFindMt.o \ LzFindMt.o \
Threads.o \ Threads.o \
@@ -60,6 +59,7 @@ OBJS = \
StringConvert.o \ StringConvert.o \
StringToInt.o \ StringToInt.o \
PropVariant.o \ PropVariant.o \
System.o \
7zCrc.o \ 7zCrc.o \
7zCrcOpt.o \ 7zCrcOpt.o \
Alloc.o \ Alloc.o \
@@ -150,10 +150,8 @@ StringToInt.o: ../../../Common/StringToInt.cpp
PropVariant.o: ../../../Windows/PropVariant.cpp PropVariant.o: ../../../Windows/PropVariant.cpp
$(CXX) $(CFLAGS) ../../../Windows/PropVariant.cpp $(CXX) $(CFLAGS) ../../../Windows/PropVariant.cpp
ifdef MT_FILES
System.o: ../../../Windows/System.cpp System.o: ../../../Windows/System.cpp
$(CXX) $(CFLAGS) ../../../Windows/System.cpp $(CXX) $(CFLAGS) ../../../Windows/System.cpp
endif
7zCrc.o: ../../../../C/7zCrc.c 7zCrc.o: ../../../../C/7zCrc.c
$(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c $(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c
@@ -195,4 +193,3 @@ Lzma86Enc.o: ../../../../C/Lzma86Enc.c
clean: clean:
-$(RM) $(PROG) $(OBJS) -$(RM) $(PROG) $(OBJS)

View File

@@ -117,14 +117,6 @@ SOURCE=..\..\Archive\Common\CoderMixer2.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=..\..\Archive\Common\ItemNameUtils.cpp SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -221,14 +213,6 @@ SOURCE=..\..\Archive\7z\7zExtract.cpp
# 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

@@ -72,7 +72,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
$O\CrossThreadProgress.obj \
$O\ItemNameUtils.obj \ $O\ItemNameUtils.obj \
$O\MultiStream.obj \ $O\MultiStream.obj \
$O\OutStreamWithCRC.obj \ $O\OutStreamWithCRC.obj \
@@ -81,7 +80,6 @@ AR_COMMON_OBJS = \
7Z_OBJS = \ 7Z_OBJS = \
$O\7zDecode.obj \ $O\7zDecode.obj \
$O\7zExtract.obj \ $O\7zExtract.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \ $O\7zHandler.obj \
$O\7zIn.obj \ $O\7zIn.obj \
$O\7zRegister.obj \ $O\7zRegister.obj \

View File

@@ -157,14 +157,6 @@ SOURCE=..\..\Archive\7z\7zExtract.cpp
# 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
@@ -205,14 +197,6 @@ SOURCE=..\..\Archive\Common\CoderMixer2.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=..\..\Archive\Common\ItemNameUtils.cpp SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -67,14 +67,12 @@ FM_OBJS = \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
$O\CrossThreadProgress.obj \
$O\ItemNameUtils.obj \ $O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \ $O\OutStreamWithCRC.obj \
7Z_OBJS = \ 7Z_OBJS = \
$O\7zDecode.obj \ $O\7zDecode.obj \
$O\7zExtract.obj \ $O\7zExtract.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \ $O\7zHandler.obj \
$O\7zIn.obj \ $O\7zIn.obj \
$O\7zRegister.obj \ $O\7zRegister.obj \

View File

@@ -149,14 +149,6 @@ SOURCE=..\..\Archive\7z\7zExtract.cpp
# 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
@@ -197,14 +189,6 @@ SOURCE=..\..\Archive\Common\CoderMixer2.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=..\..\Archive\Common\ItemNameUtils.cpp SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -341,14 +325,6 @@ SOURCE=..\..\UI\FileManager\ComboDialog.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\UI\FileManager\MessagesDialog.cpp
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\MessagesDialog.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -92,7 +92,6 @@ AR_OBJS = \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
$O\CrossThreadProgress.obj \
$O\ItemNameUtils.obj \ $O\ItemNameUtils.obj \
$O\MultiStream.obj \ $O\MultiStream.obj \
$O\OutStreamWithCRC.obj \ $O\OutStreamWithCRC.obj \
@@ -100,7 +99,6 @@ AR_COMMON_OBJS = \
7Z_OBJS = \ 7Z_OBJS = \
$O\7zDecode.obj \ $O\7zDecode.obj \
$O\7zExtract.obj \ $O\7zExtract.obj \
$O\7zFolderOutStream.obj \
$O\7zHandler.obj \ $O\7zHandler.obj \
$O\7zIn.obj \ $O\7zIn.obj \
$O\7zRegister.obj \ $O\7zRegister.obj \

View File

@@ -73,8 +73,10 @@ void CRandomGenerator::Init()
HASH_UPD(v2); HASH_UPD(v2);
#endif #endif
#ifdef _WIN32
DWORD tickCount = ::GetTickCount(); DWORD tickCount = ::GetTickCount();
HASH_UPD(tickCount); HASH_UPD(tickCount);
#endif
for (unsigned j = 0; j < 100; j++) for (unsigned j = 0; j < 100; j++)
{ {

View File

@@ -112,25 +112,87 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
if (algId * 64 + 128 != bitLen) if (algId * 64 + 128 != bitLen)
return E_NOTIMPL; return E_NOTIMPL;
_key.KeySize = 16 + algId * 8; _key.KeySize = 16 + algId * 8;
if ((flags & 1) == 0) bool cert = ((flags & 2) != 0);
return E_NOTIMPL;
if ((flags & 0x4000) != 0) if ((flags & 0x4000) != 0)
{ {
// Use 3DES // Use 3DES
return E_NOTIMPL; return E_NOTIMPL;
} }
if (cert)
{
return E_NOTIMPL;
}
else
{
if ((flags & 1) == 0)
return E_NOTIMPL;
}
UInt32 rdSize = GetUi16(p + 8); UInt32 rdSize = GetUi16(p + 8);
if ((rdSize & 0xF) != 0 || rdSize + 16 > _remSize)
return E_NOTIMPL; if (rdSize + 16 > _remSize)
memmove(p, p + 10, rdSize);
Byte *validData = p + rdSize + 16;
if (GetUi32(validData - 6) != 0) // reserved
return E_NOTIMPL;
UInt32 validSize = GetUi16(validData - 2);
if ((validSize & 0xF) != 0 || 16 + rdSize + validSize != _remSize)
return E_NOTIMPL; return E_NOTIMPL;
/*
if (cert)
{
// how to filter rd, if ((rdSize & 0xF) != 0) ?
/*
if ((rdSize & 0x7) != 0)
return E_NOTIMPL;
}
else
*/
{
if ((rdSize & 0xF) != 0)
return E_NOTIMPL;
}
memmove(p, p + 10, rdSize);
const Byte *p2 = p + rdSize + 10;
UInt32 reserved = GetUi32(p2);
p2 += 4;
/*
if (cert)
{
UInt32 numRecipients = reserved;
if (numRecipients == 0)
return E_NOTIMPL;
{
UInt32 hashAlg = GetUi16(p2);
hashAlg = hashAlg;
UInt32 hashSize = GetUi16(p2 + 2);
hashSize = hashSize;
p2 += 4;
reserved = reserved;
// return E_NOTIMPL;
for (unsigned r = 0; r < numRecipients; r++)
{
UInt32 specSize = GetUi16(p2);
p2 += 2;
p2 += specSize;
}
}
}
else
*/
{
if (reserved != 0)
return E_NOTIMPL;
}
UInt32 validSize = GetUi16(p2);
p2 += 2;
const size_t validOffset = p2 - p;
if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize)
return E_NOTIMPL;
{ {
RINOK(SetKey(_key.MasterKey, _key.KeySize)); RINOK(SetKey(_key.MasterKey, _key.KeySize));
@@ -149,12 +211,14 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
RINOK(SetKey(fileKey, _key.KeySize)); RINOK(SetKey(fileKey, _key.KeySize));
RINOK(SetInitVector(_iv, 16)); RINOK(SetInitVector(_iv, 16));
Init(); Init();
Filter(validData, validSize);
memmove(p, p + validOffset, validSize);
Filter(p, validSize);
if (validSize < 4) if (validSize < 4)
return E_NOTIMPL; return E_NOTIMPL;
validSize -= 4; validSize -= 4;
if (GetUi32(validData + validSize) != CrcCalc(validData, validSize)) if (GetUi32(p + validSize) != CrcCalc(p, validSize))
return S_OK; return S_OK;
passwOK = true; passwOK = true;
return S_OK; return S_OK;

View File

@@ -248,7 +248,8 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
unsigned len = 0; unsigned len = 0;
bool isPtrName = false; bool isPtrName = false;
#ifdef MY_CPU_LE #if defined(MY_CPU_LE) && defined(_WIN32)
// it works only if (sizeof(wchar_t) == 2)
if (arc.GetRawProps) if (arc.GetRawProps)
{ {
const void *p; const void *p;

View File

@@ -693,7 +693,7 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDef
return StringToBstr(Password, password); return StringToBstr(Password, password);
} }
//////////////////////////////////////////////////////////////////////////
// Main function // Main function
#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; #define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
@@ -709,12 +709,14 @@ int MY_CDECL main(int numArgs, const char *args[])
PrintStringLn(kHelpString); PrintStringLn(kHelpString);
return 1; return 1;
} }
NDLL::CLibrary lib; NDLL::CLibrary lib;
if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName))) if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName)))
{ {
PrintError("Can not load 7-zip library"); PrintError("Can not load 7-zip library");
return 1; return 1;
} }
Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject"); Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject");
if (!createObjectFunc) if (!createObjectFunc)
{ {
@@ -732,7 +734,9 @@ int MY_CDECL main(int numArgs, const char *args[])
} }
c = (char)MyCharLower_Ascii(command[0]); c = (char)MyCharLower_Ascii(command[0]);
} }
FString archiveName = CmdStringToFString(args[2]); FString archiveName = CmdStringToFString(args[2]);
if (c == 'a') if (c == 'a')
{ {
// create archive command // create archive command
@@ -766,6 +770,7 @@ int MY_CDECL main(int numArgs, const char *args[])
dirItems.Add(di); dirItems.Add(di);
} }
} }
COutFileStream *outFileStreamSpec = new COutFileStream; COutFileStream *outFileStreamSpec = new COutFileStream;
CMyComPtr<IOutStream> outFileStream = outFileStreamSpec; CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
if (!outFileStreamSpec->Create(archiveName, false)) if (!outFileStreamSpec->Create(archiveName, false))
@@ -812,17 +817,21 @@ int MY_CDECL main(int numArgs, const char *args[])
*/ */
HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback); HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);
updateCallbackSpec->Finilize(); updateCallbackSpec->Finilize();
if (result != S_OK) if (result != S_OK)
{ {
PrintError("Update Error"); PrintError("Update Error");
return 1; return 1;
} }
FOR_VECTOR (i, updateCallbackSpec->FailedFiles) FOR_VECTOR (i, updateCallbackSpec->FailedFiles)
{ {
PrintNewLine(); PrintNewLine();
PrintError("Error for file", updateCallbackSpec->FailedFiles[i]); PrintError("Error for file", updateCallbackSpec->FailedFiles[i]);
} }
if (updateCallbackSpec->FailedFiles.Size() != 0) if (updateCallbackSpec->FailedFiles.Size() != 0)
return 1; return 1;
} }
@@ -835,6 +844,7 @@ int MY_CDECL main(int numArgs, const char *args[])
} }
bool listCommand; bool listCommand;
if (c == 'l') if (c == 'l')
listCommand = true; listCommand = true;
else if (c == 'x') else if (c == 'x')
@@ -913,7 +923,27 @@ int MY_CDECL main(int numArgs, const char *args[])
extractCallbackSpec->PasswordIsDefined = false; extractCallbackSpec->PasswordIsDefined = false;
// extractCallbackSpec->PasswordIsDefined = true; // extractCallbackSpec->PasswordIsDefined = true;
// extractCallbackSpec->Password = L"1"; // extractCallbackSpec->Password = L"1";
/*
const wchar_t *names[] =
{
L"mt",
L"mtf"
};
const unsigned kNumProps = sizeof(names) / sizeof(names[0]);
NCOM::CPropVariant values[kNumProps] =
{
(UInt32)1,
false
};
CMyComPtr<ISetProperties> setProperties;
archive->QueryInterface(IID_ISetProperties, (void **)&setProperties);
if (setProperties)
setProperties->SetProperties(names, values, kNumProps);
*/
HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback); HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);
if (result != S_OK) if (result != S_OK)
{ {
PrintError("Extract Error"); PrintError("Extract Error");
@@ -921,5 +951,6 @@ int MY_CDECL main(int numArgs, const char *args[])
} }
} }
} }
return 0; return 0;
} }

View File

@@ -271,7 +271,7 @@ static const unsigned kCommandIndex = 0;
static const char *kCannotFindListFile = "Cannot find listfile"; static const char *kCannotFindListFile = "Cannot find listfile";
static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch."; static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
static const char *kTerminalOutError = "I won't write compressed data to a terminal"; static const char *kTerminalOutError = "I won't write compressed data to a terminal";
static const char *kSameTerminalError = "I won't write data and program's messages to same terminal"; static const char *kSameTerminalError = "I won't write data and program's messages to same stream";
static const char *kEmptyFilePath = "Empty file path"; static const char *kEmptyFilePath = "Empty file path";
static const char *kCannotFindArchive = "Cannot find archive"; static const char *kCannotFindArchive = "Cannot find archive";
@@ -917,7 +917,7 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
if (parser[NKey::kAffinity].ThereIs) if (parser[NKey::kAffinity].ThereIs)
{ {
const UString &s = us2fs(parser[NKey::kAffinity].PostStrings[0]); const UString &s = parser[NKey::kAffinity].PostStrings[0];
if (!s.IsEmpty()) if (!s.IsEmpty())
{ {
UInt32 v = 0; UInt32 v = 0;
@@ -1219,8 +1219,26 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (isExtractGroupCommand) if (isExtractGroupCommand)
{ {
if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal) if (options.StdOutMode)
{
if (
options.Number_for_Percents == k_OutStream_stdout
// || options.Number_for_Out == k_OutStream_stdout
// || options.Number_for_Errors == k_OutStream_stdout
||
(
(options.IsStdOutTerminal && options.IsStdErrTerminal)
&&
(
options.Number_for_Percents != k_OutStream_disabled
// || options.Number_for_Out != k_OutStream_disabled
// || options.Number_for_Errors != k_OutStream_disabled
)
)
)
throw CArcCmdLineException(kSameTerminalError); throw CArcCmdLineException(kSameTerminalError);
}
if (parser[NKey::kOutputDir].ThereIs) if (parser[NKey::kOutputDir].ThereIs)
{ {
eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]); eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
@@ -1293,8 +1311,18 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (updateOptions.StdOutMode && updateOptions.EMailMode) if (updateOptions.StdOutMode && updateOptions.EMailMode)
throw CArcCmdLineException("stdout mode and email mode cannot be combined"); throw CArcCmdLineException("stdout mode and email mode cannot be combined");
if (updateOptions.StdOutMode && options.IsStdOutTerminal)
if (updateOptions.StdOutMode)
{
if (options.IsStdOutTerminal)
throw CArcCmdLineException(kTerminalOutError); throw CArcCmdLineException(kTerminalOutError);
if (options.Number_for_Percents == k_OutStream_stdout
|| options.Number_for_Out == k_OutStream_stdout
|| options.Number_for_Errors == k_OutStream_stdout)
throw CArcCmdLineException(kSameTerminalError);
}
if (updateOptions.StdInMode) if (updateOptions.StdInMode)
updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front(); updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();

View File

@@ -451,32 +451,42 @@ static UString GetDirPrefixOf(const UString &src)
return s; return s;
} }
static bool IsSafePath(const UString &path) #endif
bool IsSafePath(const UString &path)
{ {
if (NName::IsAbsolutePath(path))
return false;
UStringVector parts; UStringVector parts;
SplitPathToParts(path, parts); SplitPathToParts(path, parts);
int level = 0; unsigned level = 0;
FOR_VECTOR (i, parts) FOR_VECTOR (i, parts)
{ {
const UString &s = parts[i]; const UString &s = parts[i];
if (s.IsEmpty()) if (s.IsEmpty())
{
if (i == 0)
return false;
continue; continue;
}
if (s == L".") if (s == L".")
continue; continue;
if (s == L"..") if (s == L"..")
{ {
if (level <= 0) if (level == 0)
return false; return false;
level--; level--;
} }
else else
level++; level++;
} }
return level > 0; return level > 0;
} }
#endif
bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include) bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include)
{ {
@@ -1255,7 +1265,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
CReparseAttr attr; CReparseAttr attr;
if (!attr.Parse(data, data.Size())) if (!attr.Parse(data, data.Size()))
{ {
RINOK(SendMessageError("Internal error for symbolic link file", _item.Path)); RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)));
// return E_FAIL; // return E_FAIL;
} }
else else

View File

@@ -73,18 +73,40 @@ struct CInFileStreamVol: public CInFileStream
} }
}; };
// from ArchiveExtractCallback.cpp
bool IsSafePath(const UString &path);
STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream) STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
*inStream = NULL; *inStream = NULL;
if (_subArchiveMode) if (_subArchiveMode)
return S_FALSE; return S_FALSE;
if (Callback) if (Callback)
{ {
RINOK(Callback->Open_CheckBreak()); RINOK(Callback->Open_CheckBreak());
} }
UString name2 = name;
#ifndef _SFX
#ifdef _WIN32
name2.Replace(L'/', WCHAR_PATH_SEPARATOR);
#endif
// if (!allowAbsVolPaths)
if (!IsSafePath(name2))
return S_FALSE;
#endif
FString fullPath; FString fullPath;
if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name), fullPath)) if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath))
return S_FALSE; return S_FALSE;
if (!_fileInfo.Find(fullPath)) if (!_fileInfo.Find(fullPath))
return S_FALSE; return S_FALSE;
@@ -93,10 +115,15 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
CInFileStreamVol *inFile = new CInFileStreamVol; CInFileStreamVol *inFile = new CInFileStreamVol;
CMyComPtr<IInStream> inStreamTemp = inFile; CMyComPtr<IInStream> inStreamTemp = inFile;
if (!inFile->Open(fullPath)) if (!inFile->Open(fullPath))
return ::GetLastError(); {
DWORD lastError = ::GetLastError();
if (lastError == 0)
return E_FAIL;
return HRESULT_FROM_WIN32(lastError);
}
FileSizes.Add(_fileInfo.Size); FileSizes.Add(_fileInfo.Size);
FileNames.Add(name); FileNames.Add(name2);
inFile->FileNameIndex = FileNames_WasUsed.Add(true); inFile->FileNameIndex = FileNames_WasUsed.Add(true);
inFile->OpenCallbackImp = this; inFile->OpenCallbackImp = this;
inFile->OpenCallbackRef = this; inFile->OpenCallbackRef = this;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -32,9 +32,9 @@ struct IBenchCallback
UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations); UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations);
const int kBenchMinDicLogSize = 18; const unsigned kBenchMinDicLogSize = 18;
UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary); UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench = false);
struct IBenchPrintCallback struct IBenchPrintCallback
{ {

View File

@@ -39,7 +39,7 @@
#endif #endif
// increase it, if you need to support larger SFX stubs // increase it, if you need to support larger SFX stubs
static const UInt64 kMaxCheckStartPosition = 1 << 22; static const UInt64 kMaxCheckStartPosition = 1 << 23;
/* /*
Open: Open:

View File

@@ -142,15 +142,17 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr
case kpidVa: case kpidVa:
{ {
UInt64 v = 0; UInt64 v = 0;
if (ConvertPropVariantToUInt64(prop, v)) if (prop.vt == VT_UI4)
{ v = prop.ulVal;
else if (prop.vt == VT_UI8)
v = (UInt64)prop.uhVal.QuadPart;
else
break;
dest[0] = '0'; dest[0] = '0';
dest[1] = 'x'; dest[1] = 'x';
ConvertUInt64ToHex(prop.ulVal, dest + 2); ConvertUInt64ToHex(v, dest + 2);
return; return;
} }
break;
}
} }
ConvertPropVariantToShortString(prop, dest); ConvertPropVariantToShortString(prop, dest);

View File

@@ -14,8 +14,10 @@ static int CompareStrings(const unsigned *p1, const unsigned *p2, void *param)
void SortFileNames(const UStringVector &strings, CUIntVector &indices) void SortFileNames(const UStringVector &strings, CUIntVector &indices)
{ {
unsigned numItems = strings.Size(); const unsigned numItems = strings.Size();
indices.ClearAndSetSize(numItems); indices.ClearAndSetSize(numItems);
if (numItems == 0)
return;
unsigned *vals = &indices[0]; unsigned *vals = &indices[0];
for (unsigned i = 0; i < numItems; i++) for (unsigned i = 0; i < numItems; i++)
vals[i] = i; vals[i] = i;

View File

@@ -17,5 +17,3 @@ void CTempFiles::Clear()
Paths.DeleteBack(); Paths.DeleteBack();
} }
} }

View File

@@ -14,7 +14,6 @@
#include "../../../Windows/FileDir.h" #include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h" #include "../../../Windows/FileName.h"
#include "../../../Windows/PropVariant.h" #include "../../../Windows/PropVariant.h"
#include "../../../Windows/Synchronization.h"
#include "../../Common/StreamObjects.h" #include "../../Common/StreamObjects.h"
@@ -429,7 +428,9 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
COM_TRY_END COM_TRY_END
} }
#ifndef _7ZIP_ST
static NSynchronization::CCriticalSection CS; static NSynchronization::CCriticalSection CS;
#endif
STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode) STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)
{ {
@@ -536,7 +537,9 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
if (ProcessedItemsStatuses) if (ProcessedItemsStatuses)
{ {
#ifndef _7ZIP_ST
NSynchronization::CCriticalSectionLock lock(CS); NSynchronization::CCriticalSectionLock lock(CS);
#endif
ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1; ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1;
} }
*inStream = inStreamLoc.Detach(); *inStream = inStreamLoc.Detach();
@@ -754,4 +757,3 @@ void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val)
} }
throw 20141125; throw 20141125;
} }

View File

@@ -92,6 +92,7 @@ void GetUpdatePairInfoList(
{ {
arcIndices.ClearAndSetSize(numArcItems); arcIndices.ClearAndSetSize(numArcItems);
if (numArcItems != 0)
{ {
unsigned *vals = &arcIndices[0]; unsigned *vals = &arcIndices[0];
for (unsigned i = 0; i < numArcItems; i++) for (unsigned i = 0; i < numArcItems; i++)

View File

@@ -17,7 +17,7 @@ FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FStr
{ {
NWorkDir::NMode::EEnum mode = workDirInfo.Mode; NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
#ifndef UNDER_CE #if defined(_WIN32) && !defined(UNDER_CE)
if (workDirInfo.ForRemovableOnly) if (workDirInfo.ForRemovableOnly)
{ {
mode = NWorkDir::NMode::kCurrent; mode = NWorkDir::NMode::kCurrent;

View File

@@ -42,6 +42,12 @@ static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
} }
static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
{
b.Val = true;
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
}
namespace NExtract namespace NExtract
{ {
@@ -112,9 +118,8 @@ void CInfo::Load()
OverwriteMode_Force = true; OverwriteMode_Force = true;
} }
Key_Get_BoolPair(key, kSplitDest, SplitDest); Key_Get_BoolPair_true(key, kSplitDest, SplitDest);
if (!SplitDest.Def)
SplitDest.Val = true;
Key_Get_BoolPair(key, kElimDup, ElimDup); Key_Get_BoolPair(key, kElimDup, ElimDup);
// Key_Get_BoolPair(key, kAltStreams, AltStreams); // Key_Get_BoolPair(key, kAltStreams, AltStreams);
Key_Get_BoolPair(key, kNtSecur, NtSecurity); Key_Get_BoolPair(key, kNtSecur, NtSecurity);
@@ -348,27 +353,45 @@ void CInfo::Load()
static const TCHAR *kCascadedMenu = TEXT("CascadedMenu"); static const TCHAR *kCascadedMenu = TEXT("CascadedMenu");
static const TCHAR *kContextMenu = TEXT("ContextMenu"); static const TCHAR *kContextMenu = TEXT("ContextMenu");
static const TCHAR *kMenuIcons = TEXT("MenuIcons"); static const TCHAR *kMenuIcons = TEXT("MenuIcons");
static const TCHAR *kElimDup = TEXT("ElimDupExtract");
void CContextMenuInfo::Save() const void CContextMenuInfo::Save() const
{ {
CS_LOCK CS_LOCK
CKey key; CKey key;
CreateMainKey(key, kOptionsInfoKeyName); CreateMainKey(key, kOptionsInfoKeyName);
key.SetValue(kCascadedMenu, Cascaded);
key.SetValue(kMenuIcons, MenuIcons); Key_Set_BoolPair(key, kCascadedMenu, Cascaded);
Key_Set_BoolPair(key, kMenuIcons, MenuIcons);
Key_Set_BoolPair(key, kElimDup, ElimDup);
if (Flags_Def)
key.SetValue(kContextMenu, Flags); key.SetValue(kContextMenu, Flags);
} }
void CContextMenuInfo::Load() void CContextMenuInfo::Load()
{ {
MenuIcons = false; Cascaded.Val = true;
Cascaded = true; Cascaded.Def = false;
MenuIcons.Val = false;
MenuIcons.Def = false;
ElimDup.Val = true;
ElimDup.Def = false;
Flags = (UInt32)(Int32)-1; Flags = (UInt32)(Int32)-1;
Flags_Def = false;
CS_LOCK CS_LOCK
CKey key; CKey key;
if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS) if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
return; return;
key.GetValue_IfOk(kCascadedMenu, Cascaded);
key.GetValue_IfOk(kMenuIcons, MenuIcons); Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded);
key.GetValue_IfOk(kContextMenu, Flags); Key_Get_BoolPair_true(key, kElimDup, ElimDup);
Key_Get_BoolPair(key, kMenuIcons, MenuIcons);
Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
} }

View File

@@ -111,8 +111,11 @@ namespace NWorkDir
struct CContextMenuInfo struct CContextMenuInfo
{ {
bool Cascaded; CBoolPair Cascaded;
bool MenuIcons; CBoolPair MenuIcons;
CBoolPair ElimDup;
bool Flags_Def;
UInt32 Flags; UInt32 Flags;
void Save() const; void Save() const;

View File

@@ -33,3 +33,4 @@ UI_COMMON_OBJS = \
$O\UpdatePair.obj \ $O\UpdatePair.obj \
$O\UpdateProduce.obj \ $O\UpdateProduce.obj \
#

View File

@@ -4,11 +4,13 @@
#include "../../../Common/MyWindows.h" #include "../../../Common/MyWindows.h"
#ifdef _WIN32
#include <Psapi.h> #include <Psapi.h>
#endif
#include "../../../../C/CpuArch.h" #include "../../../../C/CpuArch.h"
#if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES) #if defined( _7ZIP_LARGE_PAGES)
#include "../../../../C/Alloc.h" #include "../../../../C/Alloc.h"
#endif #endif
@@ -158,7 +160,7 @@ static const char *kHelpString =
" -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n" " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n"
" -v{Size}[b|k|m|g] : Create volumes\n" " -v{Size}[b|k|m|g] : Create volumes\n"
" -w[{path}] : assign Work directory. Empty path means a temporary directory\n" " -w[{path}] : assign Work directory. Empty path means a temporary directory\n"
" -x[r[-|0]]]{@listfile|!wildcard} : eXclude filenames\n" " -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames\n"
" -y : assume Yes on all queries\n"; " -y : assume Yes on all queries\n";
// --------------------------- // ---------------------------
@@ -470,7 +472,7 @@ static void PrintHexId(CStdOutStream &so, UInt64 id)
int Main2( int Main2(
#ifndef _WIN32 #ifndef _WIN32
int numArgs, const char *args[] int numArgs, char *args[]
#endif #endif
) )
{ {

View File

@@ -20,7 +20,7 @@ CStdOutStream *g_ErrStream = NULL;
extern int Main2( extern int Main2(
#ifndef _WIN32 #ifndef _WIN32
int numArgs, const char *args[] int numArgs, char *args[]
#endif #endif
); );
@@ -49,7 +49,7 @@ static void PrintError(const char *message)
int MY_CDECL main int MY_CDECL main
( (
#ifndef _WIN32 #ifndef _WIN32
int numArgs, const char *args[] int numArgs, char *args[]
#endif #endif
) )
{ {

View File

@@ -241,7 +241,7 @@ static const CHashCommand g_HashCommands[] =
static int FindCommand(CZipContextMenu::ECommandInternalID &id) static int FindCommand(CZipContextMenu::ECommandInternalID &id)
{ {
for (int i = 0; i < ARRAY_SIZE(g_Commands); i++) for (unsigned i = 0; i < ARRAY_SIZE(g_Commands); i++)
if (g_Commands[i].CommandInternalID == id) if (g_Commands[i].CommandInternalID == id)
return i; return i;
return -1; return -1;
@@ -287,12 +287,10 @@ static const char * const kArcExts[] =
, "zip" , "zip"
}; };
static bool IsItArcExt(const UString &ext2) static bool IsItArcExt(const UString &ext)
{ {
UString ext = ext2;
ext.MakeLower_Ascii();
for (unsigned i = 0; i < ARRAY_SIZE(kArcExts); i++) for (unsigned i = 0; i < ARRAY_SIZE(kArcExts); i++)
if (ext.IsEqualTo(kArcExts[i])) if (ext.IsEqualTo_Ascii_NoCase(kArcExts[i]))
return true; return true;
return false; return false;
} }
@@ -429,6 +427,7 @@ void CZipContextMenu::AddMapItem_ForSubMenu(const wchar_t *verb)
_commandMap.Add(commandMapItem); _commandMap.Add(commandMapItem);
} }
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT commandIDFirst, UINT commandIDLast, UINT flags) UINT commandIDFirst, UINT commandIDLast, UINT flags)
{ {
@@ -451,12 +450,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
CContextMenuInfo ci; CContextMenuInfo ci;
ci.Load(); ci.Load();
_elimDup = ci.ElimDup;
HBITMAP bitmap = NULL; HBITMAP bitmap = NULL;
if (ci.MenuIcons) if (ci.MenuIcons.Val)
bitmap = _bitmap; bitmap = _bitmap;
UINT subIndex = indexMenu; UINT subIndex = indexMenu;
if (ci.Cascaded)
if (ci.Cascaded.Val)
{ {
if (!popupMenu.CreatePopup()) if (!popupMenu.CreatePopup())
return E_FAIL; return E_FAIL;
@@ -473,15 +475,21 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
else else
{ {
popupMenu.Attach(hMenu); popupMenu.Attach(hMenu);
CMenuItem mi;
mi.fType = MFT_SEPARATOR;
mi.fMask = MIIM_TYPE;
popupMenu.InsertItem(subIndex++, true, mi);
} }
UInt32 contextMenuFlags = ci.Flags; UInt32 contextMenuFlags = ci.Flags;
NFind::CFileInfo fi0; NFind::CFileInfo fi0;
FString folderPrefix; FString folderPrefix;
if (_fileNames.Size() > 0) if (_fileNames.Size() > 0)
{ {
const UString &fileName = _fileNames.Front(); const UString &fileName = _fileNames.Front();
#if defined(_WIN32) && !defined(UNDER_CE) #if defined(_WIN32) && !defined(UNDER_CE)
if (NName::IsDevicePath(us2fs(fileName))) if (NName::IsDevicePath(us2fs(fileName)))
{ {
@@ -505,6 +513,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
} }
UString mainString; UString mainString;
if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast) if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast)
{ {
if (!fi0.IsDir() && DoNeedExtract(fi0.Name)) if (!fi0.IsDir() && DoNeedExtract(fi0.Name))
@@ -565,6 +574,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast) if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
{ {
bool needExtract = (!fi0.IsDir() && DoNeedExtract(fi0.Name)); bool needExtract = (!fi0.IsDir() && DoNeedExtract(fi0.Name));
if (!needExtract) if (!needExtract)
{ {
FOR_VECTOR (i, _fileNames) FOR_VECTOR (i, _fileNames)
@@ -579,7 +589,9 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
} }
} }
} }
const UString &fileName = _fileNames.Front(); const UString &fileName = _fileNames.Front();
if (needExtract) if (needExtract)
{ {
// Extract // Extract
@@ -629,6 +641,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem); _commandMap.Add(commandMapItem);
} }
// Test // Test
if ((contextMenuFlags & NContextMenuFlags::kTest) != 0) if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
{ {
@@ -644,6 +657,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
arcName = CreateArchiveName(fi0, false); arcName = CreateArchiveName(fi0, false);
else else
arcName = CreateArchiveName(fileName, _fileNames.Size() > 1, false); arcName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
UString arcName7z = arcName + L".7z"; UString arcName7z = arcName + L".7z";
UString arcNameZip = arcName + L".zip"; UString arcNameZip = arcName + L".zip";
@@ -745,7 +759,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
// PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension // PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension
// ID: Q214477 // ID: Q214477
if (ci.Cascaded) if (ci.Cascaded.Val)
{ {
CMenuItem mi; CMenuItem mi;
mi.fType = MFT_STRING; mi.fType = MFT_STRING;
@@ -756,12 +770,20 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
mi.hSubMenu = popupMenu.Detach(); mi.hSubMenu = popupMenu.Detach();
mi.StringValue.SetFromAscii("7-Zip"); // LangString(IDS_CONTEXT_POPUP_CAPTION); mi.StringValue.SetFromAscii("7-Zip"); // LangString(IDS_CONTEXT_POPUP_CAPTION);
mi.hbmpUnchecked = bitmap; mi.hbmpUnchecked = bitmap;
CMenu menu; CMenu menu;
menu.Attach(hMenu); menu.Attach(hMenu);
menuDestroyer.Disable(); menuDestroyer.Disable();
menu.InsertItem(indexMenu++, true, mi); menu.InsertItem(indexMenu++, true, mi);
AddMapItem_ForSubMenu(kMainVerb); AddMapItem_ForSubMenu(kMainVerb);
} }
else
{
popupMenu.Detach();
indexMenu = subIndex;
}
if (!_isMenuForFM && if (!_isMenuForFM &&
((contextMenuFlags & NContextMenuFlags::kCRC) != 0 ((contextMenuFlags & NContextMenuFlags::kCRC) != 0
@@ -771,6 +793,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
// CMenuDestroyer menuDestroyer_CRC; // CMenuDestroyer menuDestroyer_CRC;
UINT subIndex_CRC = 0; UINT subIndex_CRC = 0;
if (subMenu.CreatePopup()) if (subMenu.CreatePopup())
{ {
// menuDestroyer_CRC.Attach(subMenu); // menuDestroyer_CRC.Attach(subMenu);
@@ -783,13 +806,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
mi.hSubMenu = subMenu; mi.hSubMenu = subMenu;
mi.StringValue.SetFromAscii("CRC SHA"); mi.StringValue.SetFromAscii("CRC SHA");
mi.hbmpUnchecked = bitmap; mi.hbmpUnchecked = bitmap;
CMenu menu; CMenu menu;
menu.Attach(hMenu); menu.Attach(hMenu);
// menuDestroyer_CRC.Disable(); // menuDestroyer_CRC.Disable();
menu.InsertItem(indexMenu++, true, mi); menu.InsertItem(indexMenu++, true, mi);
AddMapItem_ForSubMenu(kCheckSumCascadedVerb); AddMapItem_ForSubMenu(kCheckSumCascadedVerb);
for (int i = 0; i < ARRAY_SIZE(g_HashCommands); i++) for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{ {
const CHashCommand &hc = g_HashCommands[i]; const CHashCommand &hc = g_HashCommands[i];
CCommandMapItem commandMapItem; CCommandMapItem commandMapItem;
@@ -799,6 +824,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, hc.UserName, bitmap); MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, hc.UserName, bitmap);
_commandMap.Add(commandMapItem); _commandMap.Add(commandMapItem);
} }
subMenu.Detach(); subMenu.Detach();
} }
} }
@@ -872,7 +898,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
{ {
ExtractArchives(_fileNames, commandMapItem.Folder, ExtractArchives(_fileNames, commandMapItem.Folder,
(cmdID == kExtract), // showDialog (cmdID == kExtract), // showDialog
(cmdID == kExtractTo) // elimDup (cmdID == kExtractTo) && _elimDup.Val // elimDup
); );
break; break;
} }
@@ -902,12 +928,14 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
_fileNames, email, showDialog, false); _fileNames, email, showDialog, false);
break; break;
} }
case kHash_CRC32: case kHash_CRC32:
case kHash_CRC64: case kHash_CRC64:
case kHash_SHA1: case kHash_SHA1:
case kHash_SHA256: case kHash_SHA256:
case kHash_All: case kHash_All:
for (int i = 0; i < ARRAY_SIZE(g_HashCommands); i++) {
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{ {
const CHashCommand &hc = g_HashCommands[i]; const CHashCommand &hc = g_HashCommands[i];
if (hc.CommandInternalID == cmdID) if (hc.CommandInternalID == cmdID)
@@ -919,6 +947,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
break; break;
} }
} }
}
catch(...) catch(...)
{ {
::MessageBoxW(0, L"Error", L"7-Zip", MB_ICONERROR); ::MessageBoxW(0, L"Error", L"7-Zip", MB_ICONERROR);

View File

@@ -74,6 +74,8 @@ private:
HBITMAP _bitmap; HBITMAP _bitmap;
CBoolPair _elimDup;
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames); HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
int FindVerb(const UString &verb); int FindVerb(const UString &verb);
bool FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem); bool FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem);

View File

@@ -10,13 +10,11 @@
#include "../../../Common/MyWindows.h" #include "../../../Common/MyWindows.h"
#include <ShlGuid.h>
#include <OleCtl.h> #include <OleCtl.h>
#include "../../../Common/MyInitGuid.h" #include "../../../Common/MyInitGuid.h"
#include "../../../Common/ComTry.h" #include "../../../Common/ComTry.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/DLL.h" #include "../../../Windows/DLL.h"
#include "../../../Windows/ErrorMsg.h" #include "../../../Windows/ErrorMsg.h"
@@ -24,11 +22,15 @@
#include "../../../Windows/Registry.h" #include "../../../Windows/Registry.h"
#include "../FileManager/IFolder.h" #include "../FileManager/IFolder.h"
#include "../FileManager/LangUtils.h"
#include "ContextMenu.h" #include "ContextMenu.h"
static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
// {23170F69-40C1-278A-1000-000100020000} // {23170F69-40C1-278A-1000-000100020000}
static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
DEFINE_GUID(CLSID_CZipContextMenu, DEFINE_GUID(CLSID_CZipContextMenu,
k_7zip_GUID_Data1, k_7zip_GUID_Data1,
k_7zip_GUID_Data2, k_7zip_GUID_Data2,
@@ -42,10 +44,6 @@ HWND g_HWND = 0;
LONG g_DllRefCount = 0; // Reference count of this DLL. LONG g_DllRefCount = 0; // Reference count of this DLL.
static LPCWSTR kShellExtName = L"7-Zip Shell Extension";
static LPCTSTR kClsidMask = TEXT("CLSID\\%s");
static LPCTSTR kClsidInprocMask = TEXT("CLSID\\%s\\InprocServer32");
static LPCTSTR kApprovedKeyPath = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
// #define ODS(sz) OutputDebugString(L#sz) // #define ODS(sz) OutputDebugString(L#sz)
@@ -77,7 +75,7 @@ STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
shellExt = new CZipContextMenu(); shellExt = new CZipContextMenu();
} }
catch(...) { return E_OUTOFMEMORY; } catch(...) { return E_OUTOFMEMORY; }
if (shellExt == NULL) if (!shellExt)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
HRESULT res = shellExt->QueryInterface(riid, ppvObj); HRESULT res = shellExt->QueryInterface(riid, ppvObj);
@@ -117,7 +115,7 @@ BOOL WINAPI DllMain(
return TRUE; return TRUE;
} }
/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE // Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void) STDAPI DllCanUnloadNow(void)
@@ -138,7 +136,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
cf = new CShellExtClassFactory; cf = new CShellExtClassFactory;
} }
catch(...) { return E_OUTOFMEMORY; } catch(...) { return E_OUTOFMEMORY; }
if (cf == 0) if (!cf)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
HRESULT res = cf->QueryInterface(riid, ppv); HRESULT res = cf->QueryInterface(riid, ppv);
if (res != S_OK) if (res != S_OK)
@@ -149,66 +147,28 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
// return _Module.GetClassObject(rclsid, riid, ppv); // return _Module.GetClassObject(rclsid, riid, ppv);
} }
static BOOL GetStringFromIID(CLSID clsid, LPTSTR s, int size)
{
LPWSTR pwsz;
if (StringFromIID(clsid, &pwsz) != S_OK)
return FALSE;
if (!pwsz)
return FALSE;
#ifdef UNICODE
for (int i = 0; i < size; i++)
{
s[i] = pwsz[i];
if (pwsz[i] == 0)
break;
}
s[size - 1] = 0;
#else
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, s, size, NULL, NULL);
#endif
CoTaskMemFree(pwsz);
s[size - 1] = 0;
return TRUE;
}
typedef struct static BOOL RegisterServer()
{ {
HKEY hRootKey;
LPCTSTR SubKey;
LPCWSTR ValueName;
LPCWSTR Data;
} CRegItem;
static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
{
TCHAR clsidString[MAX_PATH];
if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
return FALSE;
FString modulePath; FString modulePath;
if (!NDLL::MyGetModuleFileName(modulePath)) if (!NDLL::MyGetModuleFileName(modulePath))
return FALSE; return FALSE;
UString modulePathU = fs2us(modulePath); const UString modulePathU = fs2us(modulePath);
CRegItem clsidEntries[] = CSysString clsidString = k_Clsid;
{ CSysString s = TEXT("CLSID\\");
HKEY_CLASSES_ROOT, kClsidMask, NULL, title, s += clsidString;
HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePathU,
HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment",
NULL, NULL, NULL, NULL
};
//register the CLSID entries
for (int i = 0; clsidEntries[i].hRootKey; i++)
{ {
TCHAR subKey[MAX_PATH];
const CRegItem &r = clsidEntries[i];
wsprintf(subKey, r.SubKey, clsidString);
NRegistry::CKey key; NRegistry::CKey key;
if (key.Create(r.hRootKey, subKey, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR) if (key.Create(HKEY_CLASSES_ROOT, s, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
return FALSE; return FALSE;
key.SetValue(clsidEntries[i].ValueName, clsidEntries[i].Data); key.SetValue(NULL, k_ShellExtName);
NRegistry::CKey keyInproc;
if (keyInproc.Create(key, TEXT("InprocServer32"), NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
return FALSE;
keyInproc.SetValue(NULL, modulePathU);
keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment"));
} }
#if !defined(_WIN64) && !defined(UNDER_CE) #if !defined(_WIN64) && !defined(UNDER_CE)
@@ -216,46 +176,45 @@ static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
#endif #endif
{ {
NRegistry::CKey key; NRegistry::CKey key;
if (key.Create(HKEY_LOCAL_MACHINE, kApprovedKeyPath, NULL, if (key.Create(HKEY_LOCAL_MACHINE, k_Approved, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR) key.SetValue(clsidString, k_ShellExtName);
key.SetValue(GetUnicodeString(clsidString), title);
} }
return TRUE; return TRUE;
} }
STDAPI DllRegisterServer(void) STDAPI DllRegisterServer(void)
{ {
return RegisterServer(CLSID_CZipContextMenu, kShellExtName) ? S_OK: SELFREG_E_CLASS; return RegisterServer() ? S_OK: SELFREG_E_CLASS;
} }
static BOOL UnregisterServer(CLSID clsid) static BOOL UnregisterServer()
{ {
TCHAR clsidString[MAX_PATH]; const CSysString clsidString = k_Clsid;
if (!GetStringFromIID(clsid, clsidString, MAX_PATH)) CSysString s = TEXT("CLSID\\");
return FALSE; s += clsidString;
CSysString s2 = s;
s2.AddAscii("\\InprocServer32");
TCHAR subKey[MAX_PATH]; RegDeleteKey(HKEY_CLASSES_ROOT, s2);
wsprintf(subKey, kClsidInprocMask, clsidString); RegDeleteKey(HKEY_CLASSES_ROOT, s);
RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
wsprintf (subKey, kClsidMask, clsidString);
RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
#if !defined(_WIN64) && !defined(UNDER_CE) #if !defined(_WIN64) && !defined(UNDER_CE)
if (IsItWindowsNT()) if (IsItWindowsNT())
#endif #endif
{ {
HKEY hKey; HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kApprovedKeyPath, 0, KEY_SET_VALUE, &hKey) == NOERROR) if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, k_Approved, 0, KEY_SET_VALUE, &hKey) == NOERROR)
{ {
RegDeleteValue(hKey, clsidString); RegDeleteValue(hKey, clsidString);
RegCloseKey(hKey); RegCloseKey(hKey);
} }
} }
return TRUE; return TRUE;
} }
STDAPI DllUnregisterServer(void) STDAPI DllUnregisterServer(void)
{ {
return UnregisterServer(CLSID_CZipContextMenu) ? S_OK: SELFREG_E_CLASS; return UnregisterServer() ? S_OK: SELFREG_E_CLASS;
} }

View File

@@ -538,13 +538,5 @@ SOURCE=".\7-zip.dll.manifest"
SOURCE=.\ContextMenuFlags.h SOURCE=.\ContextMenuFlags.h
# End Source File # End Source File
# Begin Source File
SOURCE=.\RegistryContextMenu.cpp
# End Source File
# Begin Source File
SOURCE=.\RegistryContextMenu.h
# End Source File
# End Target # End Target
# End Project # End Project

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