mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-17 14:11:53 -06:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
603abd5528 | ||
|
|
232ce79574 | ||
|
|
1eddf527ca | ||
|
|
bec3b479dc | ||
|
|
66ac98bb02 | ||
|
|
c20d013055 | ||
|
|
9608215ad8 | ||
|
|
5de23c1deb | ||
|
|
e24f7fba53 | ||
|
|
7c8a265a15 | ||
|
|
a663a6deb7 | ||
|
|
6543c28020 | ||
|
|
f6444c3256 | ||
|
|
cba375916f |
82
C/7z.h
82
C/7z.h
@@ -1,5 +1,5 @@
|
|||||||
/* 7z.h -- 7z interface
|
/* 7z.h -- 7z interface
|
||||||
2014-02-08 : Igor Pavlov : Public domain */
|
2015-11-18 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_H
|
#ifndef __7Z_H
|
||||||
#define __7Z_H
|
#define __7Z_H
|
||||||
@@ -48,21 +48,10 @@ typedef struct
|
|||||||
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
|
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
|
||||||
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
|
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
|
||||||
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
|
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
|
||||||
UInt64 CodersUnpackSizes[SZ_NUM_CODERS_IN_FOLDER_MAX];
|
|
||||||
} CSzFolder;
|
} CSzFolder;
|
||||||
|
|
||||||
/*
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
size_t CodersDataOffset;
|
|
||||||
size_t UnpackSizeDataOffset;
|
|
||||||
// UInt32 StartCoderUnpackSizesIndex;
|
|
||||||
UInt32 StartPackStreamIndex;
|
|
||||||
// UInt32 IndexOfMainOutStream;
|
|
||||||
} CSzFolder2;
|
|
||||||
*/
|
|
||||||
|
|
||||||
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes);
|
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -92,47 +81,25 @@ typedef struct
|
|||||||
UInt32 NumPackStreams;
|
UInt32 NumPackStreams;
|
||||||
UInt32 NumFolders;
|
UInt32 NumFolders;
|
||||||
|
|
||||||
UInt64 *PackPositions; // NumPackStreams + 1
|
UInt64 *PackPositions; // NumPackStreams + 1
|
||||||
CSzBitUi32s FolderCRCs;
|
CSzBitUi32s FolderCRCs; // NumFolders
|
||||||
|
|
||||||
size_t *FoCodersOffsets;
|
size_t *FoCodersOffsets; // NumFolders + 1
|
||||||
size_t *FoSizesOffsets;
|
UInt32 *FoStartPackStreamIndex; // NumFolders + 1
|
||||||
// UInt32 StartCoderUnpackSizesIndex;
|
UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
|
||||||
UInt32 *FoStartPackStreamIndex;
|
Byte *FoToMainUnpackSizeIndex; // NumFolders
|
||||||
|
UInt64 *CoderUnpackSizes; // for all coders in all folders
|
||||||
|
|
||||||
// CSzFolder2 *Folders; // +1 item for sum values
|
|
||||||
Byte *CodersData;
|
Byte *CodersData;
|
||||||
Byte *UnpackSizesData;
|
|
||||||
size_t UnpackSizesDataSize;
|
|
||||||
// UInt64 *CoderUnpackSizes;
|
|
||||||
} CSzAr;
|
} CSzAr;
|
||||||
|
|
||||||
|
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
|
||||||
|
|
||||||
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
||||||
ILookInStream *stream, UInt64 startPos,
|
ILookInStream *stream, UInt64 startPos,
|
||||||
Byte *outBuffer, size_t outSize,
|
Byte *outBuffer, size_t outSize,
|
||||||
ISzAlloc *allocMain);
|
ISzAlloc *allocMain);
|
||||||
|
|
||||||
/*
|
|
||||||
SzExtract extracts file from archive
|
|
||||||
|
|
||||||
*outBuffer must be 0 before first call for each new archive.
|
|
||||||
|
|
||||||
Extracting cache:
|
|
||||||
If you need to decompress more than one file, you can send
|
|
||||||
these values from previous call:
|
|
||||||
*blockIndex,
|
|
||||||
*outBuffer,
|
|
||||||
*outBufferSize
|
|
||||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
|
||||||
it will increase decompression speed.
|
|
||||||
|
|
||||||
If you use external function, you can declare these 3 cache variables
|
|
||||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
|
||||||
|
|
||||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CSzAr db;
|
CSzAr db;
|
||||||
@@ -142,7 +109,7 @@ typedef struct
|
|||||||
|
|
||||||
UInt32 NumFiles;
|
UInt32 NumFiles;
|
||||||
|
|
||||||
UInt64 *UnpackPositions;
|
UInt64 *UnpackPositions; // NumFiles + 1
|
||||||
// Byte *IsEmptyFiles;
|
// Byte *IsEmptyFiles;
|
||||||
Byte *IsDirs;
|
Byte *IsDirs;
|
||||||
CSzBitUi32s CRCs;
|
CSzBitUi32s CRCs;
|
||||||
@@ -152,9 +119,8 @@ typedef struct
|
|||||||
CSzBitUi64s MTime;
|
CSzBitUi64s MTime;
|
||||||
CSzBitUi64s CTime;
|
CSzBitUi64s CTime;
|
||||||
|
|
||||||
// UInt32 *FolderStartPackStreamIndex;
|
UInt32 *FolderToFile; // NumFolders + 1
|
||||||
UInt32 *FolderStartFileIndex; // + 1
|
UInt32 *FileToFolder; // NumFiles
|
||||||
UInt32 *FileIndexToFolderIndexMap;
|
|
||||||
|
|
||||||
size_t *FileNameOffsets; /* in 2-byte steps */
|
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||||
Byte *FileNames; /* UTF-16-LE */
|
Byte *FileNames; /* UTF-16-LE */
|
||||||
@@ -182,6 +148,28 @@ size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
|
|||||||
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
SzArEx_Extract extracts file from archive
|
||||||
|
|
||||||
|
*outBuffer must be 0 before first call for each new archive.
|
||||||
|
|
||||||
|
Extracting cache:
|
||||||
|
If you need to decompress more than one file, you can send
|
||||||
|
these values from previous call:
|
||||||
|
*blockIndex,
|
||||||
|
*outBuffer,
|
||||||
|
*outBufferSize
|
||||||
|
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||||
|
it will increase decompression speed.
|
||||||
|
|
||||||
|
If you use external function, you can declare these 3 cache variables
|
||||||
|
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||||
|
|
||||||
|
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||||
|
*/
|
||||||
|
|
||||||
SRes SzArEx_Extract(
|
SRes SzArEx_Extract(
|
||||||
const CSzArEx *db,
|
const CSzArEx *db,
|
||||||
ILookInStream *inStream,
|
ILookInStream *inStream,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
566
C/7zArcIn.c
566
C/7zArcIn.c
File diff suppressed because it is too large
Load Diff
68
C/7zDec.c
68
C/7zDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zDec.c -- Decoding from 7z folder
|
/* 7zDec.c -- Decoding from 7z folder
|
||||||
2015-06-13 : 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"
|
||||||
@@ -144,11 +145,11 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte *inBuf = NULL;
|
const void *inBuf = NULL;
|
||||||
size_t lookahead = (1 << 18);
|
size_t lookahead = (1 << 18);
|
||||||
if (lookahead > inSize)
|
if (lookahead > inSize)
|
||||||
lookahead = (size_t)inSize;
|
lookahead = (size_t)inSize;
|
||||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
res = inStream->Look(inStream, &inBuf, &lookahead);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -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;
|
||||||
@@ -197,11 +207,11 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte *inBuf = NULL;
|
const void *inBuf = NULL;
|
||||||
size_t lookahead = (1 << 18);
|
size_t lookahead = (1 << 18);
|
||||||
if (lookahead > inSize)
|
if (lookahead > inSize)
|
||||||
lookahead = (size_t)inSize;
|
lookahead = (size_t)inSize;
|
||||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
res = inStream->Look(inStream, &inBuf, &lookahead);
|
||||||
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;
|
||||||
@@ -237,11 +254,11 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
|
|||||||
{
|
{
|
||||||
while (inSize > 0)
|
while (inSize > 0)
|
||||||
{
|
{
|
||||||
void *inBuf;
|
const void *inBuf;
|
||||||
size_t curSize = (1 << 18);
|
size_t curSize = (1 << 18);
|
||||||
if (curSize > inSize)
|
if (curSize > inSize)
|
||||||
curSize = (size_t)inSize;
|
curSize = (size_t)inSize;
|
||||||
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
RINOK(inStream->Look(inStream, &inBuf, &curSize));
|
||||||
if (curSize == 0)
|
if (curSize == 0)
|
||||||
return SZ_ERROR_INPUT_EOF;
|
return SZ_ERROR_INPUT_EOF;
|
||||||
memcpy(outBuffer, inBuf, curSize);
|
memcpy(outBuffer, inBuf, curSize);
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
#define MY_VER_MAJOR 15
|
#define MY_VER_MAJOR 16
|
||||||
#define MY_VER_MINOR 05
|
#define MY_VER_MINOR 04
|
||||||
#define MY_VER_BUILD 00
|
#define MY_VER_BUILD 0
|
||||||
#define MY_VERSION "15.05 beta"
|
#define MY_VERSION_NUMBERS "16.04"
|
||||||
#define MY_DATE "2015-06-14"
|
#define MY_VERSION "16.04"
|
||||||
|
#define MY_DATE "2016-10-04"
|
||||||
#undef MY_COPYRIGHT
|
#undef MY_COPYRIGHT
|
||||||
#undef MY_VERSION_COPYRIGHT_DATE
|
#undef MY_VERSION_COPYRIGHT_DATE
|
||||||
|
#define MY_AUTHOR_NAME "Igor Pavlov"
|
||||||
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
|
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
|
||||||
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov"
|
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov"
|
||||||
|
|
||||||
#ifdef USE_COPYRIGHT_CR
|
#ifdef USE_COPYRIGHT_CR
|
||||||
#define MY_COPYRIGHT MY_COPYRIGHT_CR
|
#define MY_COPYRIGHT MY_COPYRIGHT_CR
|
||||||
|
|||||||
10
C/Aes.c
10
C/Aes.c
@@ -1,5 +1,5 @@
|
|||||||
/* Aes.c -- AES encryption / decryption
|
/* Aes.c -- AES encryption / decryption
|
||||||
2015-02-23 : Igor Pavlov : Public domain */
|
2016-05-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -167,10 +167,10 @@ void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
|
|||||||
{
|
{
|
||||||
UInt32 r = w[i];
|
UInt32 r = w[i];
|
||||||
w[i] =
|
w[i] =
|
||||||
D[ Sbox[gb0(r)]] ^
|
D[ (unsigned)Sbox[gb0(r)]] ^
|
||||||
D[0x100 + Sbox[gb1(r)]] ^
|
D[0x100 + (unsigned)Sbox[gb1(r)]] ^
|
||||||
D[0x200 + Sbox[gb2(r)]] ^
|
D[0x200 + (unsigned)Sbox[gb2(r)]] ^
|
||||||
D[0x300 + Sbox[gb3(r)]];
|
D[0x300 + (unsigned)Sbox[gb3(r)]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
C/Bcj2.c
6
C/Bcj2.c
@@ -1,5 +1,5 @@
|
|||||||
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
|
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
|
||||||
2014-11-09 : Igor Pavlov : Public domain */
|
2015-08-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -178,8 +178,8 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p)
|
|||||||
p->state =
|
p->state =
|
||||||
p->bufs[BCJ2_STREAM_MAIN] ==
|
p->bufs[BCJ2_STREAM_MAIN] ==
|
||||||
p->lims[BCJ2_STREAM_MAIN] ?
|
p->lims[BCJ2_STREAM_MAIN] ?
|
||||||
BCJ2_STREAM_MAIN :
|
(unsigned)BCJ2_STREAM_MAIN :
|
||||||
BCJ2_DEC_STATE_ORIG;
|
(unsigned)BCJ2_DEC_STATE_ORIG;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
48
C/Blake2.h
Normal file
48
C/Blake2.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* Blake2.h -- BLAKE2 Hash
|
||||||
|
2015-06-30 : Igor Pavlov : Public domain
|
||||||
|
2015 : Samuel Neves : Public domain */
|
||||||
|
|
||||||
|
#ifndef __BLAKE2_H
|
||||||
|
#define __BLAKE2_H
|
||||||
|
|
||||||
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define BLAKE2S_BLOCK_SIZE 64
|
||||||
|
#define BLAKE2S_DIGEST_SIZE 32
|
||||||
|
#define BLAKE2SP_PARALLEL_DEGREE 8
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 h[8];
|
||||||
|
UInt32 t[2];
|
||||||
|
UInt32 f[2];
|
||||||
|
Byte buf[BLAKE2S_BLOCK_SIZE];
|
||||||
|
UInt32 bufPos;
|
||||||
|
UInt32 lastNode_f1;
|
||||||
|
UInt32 dummy[2]; /* for sizeof(CBlake2s) alignment */
|
||||||
|
} CBlake2s;
|
||||||
|
|
||||||
|
/* You need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */
|
||||||
|
/*
|
||||||
|
void Blake2s_Init0(CBlake2s *p);
|
||||||
|
void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size);
|
||||||
|
void Blake2s_Final(CBlake2s *p, Byte *digest);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CBlake2s S[BLAKE2SP_PARALLEL_DEGREE];
|
||||||
|
unsigned bufPos;
|
||||||
|
} CBlake2sp;
|
||||||
|
|
||||||
|
|
||||||
|
void Blake2sp_Init(CBlake2sp *p);
|
||||||
|
void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size);
|
||||||
|
void Blake2sp_Final(CBlake2sp *p, Byte *digest);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
244
C/Blake2s.c
Normal file
244
C/Blake2s.c
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
/* Blake2s.c -- BLAKE2s and BLAKE2sp Hash
|
||||||
|
2015-06-30 : Igor Pavlov : Public domain
|
||||||
|
2015 : Samuel Neves : Public domain */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Blake2.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
#include "RotateDefs.h"
|
||||||
|
|
||||||
|
#define rotr32 rotrFixed
|
||||||
|
|
||||||
|
#define BLAKE2S_NUM_ROUNDS 10
|
||||||
|
#define BLAKE2S_FINAL_FLAG (~(UInt32)0)
|
||||||
|
|
||||||
|
static const UInt32 k_Blake2s_IV[8] =
|
||||||
|
{
|
||||||
|
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||||
|
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Byte k_Blake2s_Sigma[BLAKE2S_NUM_ROUNDS][16] =
|
||||||
|
{
|
||||||
|
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||||
|
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||||
|
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||||
|
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||||
|
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||||
|
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||||
|
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||||
|
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||||
|
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||||
|
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void Blake2s_Init0(CBlake2s *p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
p->h[i] = k_Blake2s_IV[i];
|
||||||
|
p->t[0] = 0;
|
||||||
|
p->t[1] = 0;
|
||||||
|
p->f[0] = 0;
|
||||||
|
p->f[1] = 0;
|
||||||
|
p->bufPos = 0;
|
||||||
|
p->lastNode_f1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Blake2s_Compress(CBlake2s *p)
|
||||||
|
{
|
||||||
|
UInt32 m[16];
|
||||||
|
UInt32 v[16];
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
m[i] = GetUi32(p->buf + i * sizeof(m[i]));
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
v[i] = p->h[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
v[ 8] = k_Blake2s_IV[0];
|
||||||
|
v[ 9] = k_Blake2s_IV[1];
|
||||||
|
v[10] = k_Blake2s_IV[2];
|
||||||
|
v[11] = k_Blake2s_IV[3];
|
||||||
|
|
||||||
|
v[12] = p->t[0] ^ k_Blake2s_IV[4];
|
||||||
|
v[13] = p->t[1] ^ k_Blake2s_IV[5];
|
||||||
|
v[14] = p->f[0] ^ k_Blake2s_IV[6];
|
||||||
|
v[15] = p->f[1] ^ k_Blake2s_IV[7];
|
||||||
|
|
||||||
|
#define G(r,i,a,b,c,d) \
|
||||||
|
a += b + m[sigma[2*i+0]]; d ^= a; d = rotr32(d, 16); c += d; b ^= c; b = rotr32(b, 12); \
|
||||||
|
a += b + m[sigma[2*i+1]]; d ^= a; d = rotr32(d, 8); c += d; b ^= c; b = rotr32(b, 7); \
|
||||||
|
|
||||||
|
#define R(r) \
|
||||||
|
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||||
|
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||||
|
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||||
|
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||||
|
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||||
|
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||||
|
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||||
|
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned r;
|
||||||
|
for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++)
|
||||||
|
{
|
||||||
|
const Byte *sigma = k_Blake2s_Sigma[r];
|
||||||
|
R(r);
|
||||||
|
}
|
||||||
|
/* R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); */
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef G
|
||||||
|
#undef R
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
p->h[i] ^= v[i] ^ v[i + 8];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define Blake2s_Increment_Counter(S, inc) \
|
||||||
|
{ p->t[0] += (inc); p->t[1] += (p->t[0] < (inc)); }
|
||||||
|
|
||||||
|
#define Blake2s_Set_LastBlock(p) \
|
||||||
|
{ p->f[0] = BLAKE2S_FINAL_FLAG; p->f[1] = p->lastNode_f1; }
|
||||||
|
|
||||||
|
|
||||||
|
static void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size)
|
||||||
|
{
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
unsigned pos = (unsigned)p->bufPos;
|
||||||
|
unsigned rem = BLAKE2S_BLOCK_SIZE - pos;
|
||||||
|
|
||||||
|
if (size <= rem)
|
||||||
|
{
|
||||||
|
memcpy(p->buf + pos, data, size);
|
||||||
|
p->bufPos += (UInt32)size;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(p->buf + pos, data, rem);
|
||||||
|
Blake2s_Increment_Counter(S, BLAKE2S_BLOCK_SIZE);
|
||||||
|
Blake2s_Compress(p);
|
||||||
|
p->bufPos = 0;
|
||||||
|
data += rem;
|
||||||
|
size -= rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Blake2s_Final(CBlake2s *p, Byte *digest)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
Blake2s_Increment_Counter(S, (UInt32)p->bufPos);
|
||||||
|
Blake2s_Set_LastBlock(p);
|
||||||
|
memset(p->buf + p->bufPos, 0, BLAKE2S_BLOCK_SIZE - p->bufPos);
|
||||||
|
Blake2s_Compress(p);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
SetUi32(digest + sizeof(p->h[i]) * i, p->h[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- BLAKE2s ---------- */
|
||||||
|
|
||||||
|
/* we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */
|
||||||
|
/*
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Byte digest_length;
|
||||||
|
Byte key_length;
|
||||||
|
Byte fanout;
|
||||||
|
Byte depth;
|
||||||
|
UInt32 leaf_length;
|
||||||
|
Byte node_offset[6];
|
||||||
|
Byte node_depth;
|
||||||
|
Byte inner_length;
|
||||||
|
Byte salt[BLAKE2S_SALTBYTES];
|
||||||
|
Byte personal[BLAKE2S_PERSONALBYTES];
|
||||||
|
} CBlake2sParam;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static void Blake2sp_Init_Spec(CBlake2s *p, unsigned node_offset, unsigned node_depth)
|
||||||
|
{
|
||||||
|
Blake2s_Init0(p);
|
||||||
|
|
||||||
|
p->h[0] ^= (BLAKE2S_DIGEST_SIZE | ((UInt32)BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24));
|
||||||
|
p->h[2] ^= ((UInt32)node_offset);
|
||||||
|
p->h[3] ^= ((UInt32)node_depth << 16) | ((UInt32)BLAKE2S_DIGEST_SIZE << 24);
|
||||||
|
/*
|
||||||
|
P->digest_length = BLAKE2S_DIGEST_SIZE;
|
||||||
|
P->key_length = 0;
|
||||||
|
P->fanout = BLAKE2SP_PARALLEL_DEGREE;
|
||||||
|
P->depth = 2;
|
||||||
|
P->leaf_length = 0;
|
||||||
|
store48(P->node_offset, node_offset);
|
||||||
|
P->node_depth = node_depth;
|
||||||
|
P->inner_length = BLAKE2S_DIGEST_SIZE;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Blake2sp_Init(CBlake2sp *p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
p->bufPos = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++)
|
||||||
|
Blake2sp_Init_Spec(&p->S[i], i, 0);
|
||||||
|
|
||||||
|
p->S[BLAKE2SP_PARALLEL_DEGREE - 1].lastNode_f1 = BLAKE2S_FINAL_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size)
|
||||||
|
{
|
||||||
|
unsigned pos = p->bufPos;
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
unsigned index = pos / BLAKE2S_BLOCK_SIZE;
|
||||||
|
unsigned rem = BLAKE2S_BLOCK_SIZE - (pos & (BLAKE2S_BLOCK_SIZE - 1));
|
||||||
|
if (rem > size)
|
||||||
|
rem = (unsigned)size;
|
||||||
|
Blake2s_Update(&p->S[index], data, rem);
|
||||||
|
size -= rem;
|
||||||
|
data += rem;
|
||||||
|
pos += rem;
|
||||||
|
pos &= (BLAKE2S_BLOCK_SIZE * BLAKE2SP_PARALLEL_DEGREE - 1);
|
||||||
|
}
|
||||||
|
p->bufPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Blake2sp_Final(CBlake2sp *p, Byte *digest)
|
||||||
|
{
|
||||||
|
CBlake2s R;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
Blake2sp_Init_Spec(&R, 0, 1);
|
||||||
|
R.lastNode_f1 = BLAKE2S_FINAL_FLAG;
|
||||||
|
|
||||||
|
for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++)
|
||||||
|
{
|
||||||
|
Byte hash[BLAKE2S_DIGEST_SIZE];
|
||||||
|
Blake2s_Final(&p->S[i], hash);
|
||||||
|
Blake2s_Update(&R, hash, BLAKE2S_DIGEST_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Blake2s_Final(&R, digest);
|
||||||
|
}
|
||||||
@@ -513,4 +513,3 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
|||||||
#endif
|
#endif
|
||||||
return Groups[0];
|
return Groups[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Compiler.h
|
/* Compiler.h
|
||||||
2015-03-25 : Igor Pavlov : Public domain */
|
2015-08-02 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_COMPILER_H
|
#ifndef __7Z_COMPILER_H
|
||||||
#define __7Z_COMPILER_H
|
#define __7Z_COMPILER_H
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#else
|
#else
|
||||||
#pragma warning(disable : 4511) // copy constructor could not be generated
|
#pragma warning(disable : 4511) // copy constructor could not be generated
|
||||||
#pragma warning(disable : 4512) // assignment operator could not be generated
|
#pragma warning(disable : 4512) // assignment operator could not be generated
|
||||||
|
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
||||||
#pragma warning(disable : 4702) // unreachable code
|
#pragma warning(disable : 4702) // unreachable code
|
||||||
#pragma warning(disable : 4710) // not inlined
|
#pragma warning(disable : 4710) // not inlined
|
||||||
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
|
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
|
||||||
|
|||||||
13
C/CpuArch.c
13
C/CpuArch.c
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.c -- CPU specific code
|
/* CpuArch.c -- CPU specific code
|
||||||
2015-03-25: Igor Pavlov : Public domain */
|
2016-02-25: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
|
|||||||
"push %%EDX\n\t"
|
"push %%EDX\n\t"
|
||||||
"popf\n\t"
|
"popf\n\t"
|
||||||
"andl %%EAX, %0\n\t":
|
"andl %%EAX, %0\n\t":
|
||||||
"=c" (flag) : "c" (flag));
|
"=c" (flag) : "c" (flag) :
|
||||||
|
"%eax", "%edx");
|
||||||
#endif
|
#endif
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
@@ -79,7 +80,13 @@ void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
#if defined(MY_CPU_X86) && defined(__PIC__)
|
#if defined(MY_CPU_AMD64) && defined(__PIC__)
|
||||||
|
"mov %%rbx, %%rdi;"
|
||||||
|
"cpuid;"
|
||||||
|
"xchg %%rbx, %%rdi;"
|
||||||
|
: "=a" (*a) ,
|
||||||
|
"=D" (*b) ,
|
||||||
|
#elif defined(MY_CPU_X86) && defined(__PIC__)
|
||||||
"mov %%ebx, %%edi;"
|
"mov %%ebx, %%edi;"
|
||||||
"cpuid;"
|
"cpuid;"
|
||||||
"xchgl %%ebx, %%edi;"
|
"xchgl %%ebx, %%edi;"
|
||||||
|
|||||||
52
C/CpuArch.h
52
C/CpuArch.h
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.h -- CPU specific code
|
/* CpuArch.h -- CPU specific code
|
||||||
2015-03-25: Igor Pavlov : Public domain */
|
2016-06-09: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CPU_ARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define __CPU_ARCH_H
|
#define __CPU_ARCH_H
|
||||||
@@ -10,14 +10,18 @@ EXTERN_C_BEGIN
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||||||
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
|
MY_CPU_BE means that CPU is BIG ENDIAN.
|
||||||
|
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
|
||||||
|
|
||||||
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||||||
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
#if defined(_M_X64) \
|
||||||
#define MY_CPU_AMD64
|
|| defined(_M_AMD64) \
|
||||||
|
|| defined(__x86_64__) \
|
||||||
|
|| defined(__AMD64__) \
|
||||||
|
|| defined(__amd64__)
|
||||||
|
#define MY_CPU_AMD64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_AMD64) \
|
#if defined(MY_CPU_AMD64) \
|
||||||
@@ -52,10 +56,6 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|
|||||||
#define MY_CPU_IA64_LE
|
#define MY_CPU_IA64_LE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64)
|
|
||||||
#define MY_CPU_LE_UNALIGN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) \
|
#if defined(MY_CPU_X86_OR_AMD64) \
|
||||||
|| defined(MY_CPU_ARM_LE) \
|
|| defined(MY_CPU_ARM_LE) \
|
||||||
|| defined(MY_CPU_IA64_LE) \
|
|| defined(MY_CPU_IA64_LE) \
|
||||||
@@ -65,7 +65,9 @@ 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(__BFIN__) \
|
||||||
|
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||||
#define MY_CPU_LE
|
#define MY_CPU_LE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -76,7 +78,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,14 +91,23 @@ 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))
|
||||||
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
|
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
|
||||||
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
|
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
|
||||||
#define SetUi16(p, v) *(UInt16 *)(p) = (v);
|
|
||||||
#define SetUi32(p, v) *(UInt32 *)(p) = (v);
|
#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
|
||||||
#define SetUi64(p, v) *(UInt64 *)(p) = (v);
|
#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
|
||||||
|
#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -127,6 +142,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)
|
||||||
@@ -136,6 +153,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) ( \
|
||||||
|
|||||||
87
C/DllSecur.c
Normal file
87
C/DllSecur.c
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/* DllSecur.c -- DLL loading security
|
||||||
|
2016-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "DllSecur.h"
|
||||||
|
|
||||||
|
#ifndef UNDER_CE
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *Func_SetDefaultDllDirectories)(DWORD DirectoryFlags);
|
||||||
|
|
||||||
|
#define MY_LOAD_LIBRARY_SEARCH_USER_DIRS 0x400
|
||||||
|
#define MY_LOAD_LIBRARY_SEARCH_SYSTEM32 0x800
|
||||||
|
|
||||||
|
static const char * const g_Dlls =
|
||||||
|
#ifndef _CONSOLE
|
||||||
|
"UXTHEME\0"
|
||||||
|
#endif
|
||||||
|
"USERENV\0"
|
||||||
|
"SETUPAPI\0"
|
||||||
|
"APPHELP\0"
|
||||||
|
"PROPSYS\0"
|
||||||
|
"DWMAPI\0"
|
||||||
|
"CRYPTBASE\0"
|
||||||
|
"OLEACC\0"
|
||||||
|
"CLBCATQ\0"
|
||||||
|
;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void LoadSecurityDlls()
|
||||||
|
{
|
||||||
|
#ifndef UNDER_CE
|
||||||
|
|
||||||
|
wchar_t buf[MAX_PATH + 100];
|
||||||
|
|
||||||
|
{
|
||||||
|
// at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ???
|
||||||
|
OSVERSIONINFO vi;
|
||||||
|
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||||
|
if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0)
|
||||||
|
{
|
||||||
|
Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories)
|
||||||
|
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories");
|
||||||
|
if (setDllDirs)
|
||||||
|
if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2);
|
||||||
|
if (len == 0 || len > MAX_PATH)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const char *dll;
|
||||||
|
unsigned pos = (unsigned)lstrlenW(buf);
|
||||||
|
|
||||||
|
if (buf[pos - 1] != '\\')
|
||||||
|
buf[pos++] = '\\';
|
||||||
|
|
||||||
|
for (dll = g_Dlls; dll[0] != 0;)
|
||||||
|
{
|
||||||
|
unsigned k = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char c = *dll++;
|
||||||
|
buf[pos + k] = c;
|
||||||
|
k++;
|
||||||
|
if (c == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lstrcatW(buf, L".dll");
|
||||||
|
LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
19
C/DllSecur.h
Normal file
19
C/DllSecur.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* DllSecur.h -- DLL loading for security
|
||||||
|
2016-06-08 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __DLL_SECUR_H
|
||||||
|
#define __DLL_SECUR_H
|
||||||
|
|
||||||
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
void LoadSecurityDlls();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
12
C/HuffEnc.c
12
C/HuffEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* HuffEnc.c -- functions for Huffman encoding
|
/* HuffEnc.c -- functions for Huffman encoding
|
||||||
2009-09-02 : Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -121,8 +121,8 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
i = 0;
|
i = 0;
|
||||||
for (len = maxLen; len != 0; len--)
|
for (len = maxLen; len != 0; len--)
|
||||||
{
|
{
|
||||||
UInt32 num;
|
UInt32 k;
|
||||||
for (num = lenCounters[len]; num != 0; num--)
|
for (k = lenCounters[len]; k != 0; k--)
|
||||||
lens[p[i++] & MASK] = (Byte)len;
|
lens[p[i++] & MASK] = (Byte)len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,9 +138,9 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
|
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 k;
|
||||||
for (i = 0; i < numSymbols; i++)
|
for (k = 0; k < numSymbols; k++)
|
||||||
p[i] = nextCodes[lens[i]]++;
|
p[k] = nextCodes[lens[k]]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
C/LzFind.c
22
C/LzFind.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzFind.c -- Match finder for LZ algorithms
|
/* LzFind.c -- Match finder for LZ algorithms
|
||||||
2015-05-15 : Igor Pavlov : Public domain */
|
2015-10-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#define kEmptyHashValue 0
|
#define kEmptyHashValue 0
|
||||||
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||||
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||||
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
|
||||||
#define kMaxHistorySize ((UInt32)7 << 29)
|
#define kMaxHistorySize ((UInt32)7 << 29)
|
||||||
|
|
||||||
#define kStartMaxLen 3
|
#define kStartMaxLen 3
|
||||||
@@ -60,9 +60,11 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
|
|||||||
if (p->streamEndWasReached || p->result != SZ_OK)
|
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */
|
||||||
|
|
||||||
if (p->directInput)
|
if (p->directInput)
|
||||||
{
|
{
|
||||||
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
|
UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos);
|
||||||
if (curSize > p->directInputRem)
|
if (curSize > p->directInputRem)
|
||||||
curSize = (UInt32)p->directInputRem;
|
curSize = (UInt32)p->directInputRem;
|
||||||
p->directInputRem -= curSize;
|
p->directInputRem -= curSize;
|
||||||
@@ -97,7 +99,7 @@ void MatchFinder_MoveBlock(CMatchFinder *p)
|
|||||||
{
|
{
|
||||||
memmove(p->bufferBase,
|
memmove(p->bufferBase,
|
||||||
p->buffer - p->keepSizeBefore,
|
p->buffer - p->keepSizeBefore,
|
||||||
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
(size_t)(p->streamPos - p->pos) + p->keepSizeBefore);
|
||||||
p->buffer = p->bufferBase + p->keepSizeBefore;
|
p->buffer = p->bufferBase + p->keepSizeBefore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +292,7 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
|||||||
p->posLimit = p->pos + limit;
|
p->posLimit = p->pos + limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinder_Init(CMatchFinder *p)
|
void MatchFinder_Init_2(CMatchFinder *p, int readData)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
UInt32 *hash = p->hash;
|
UInt32 *hash = p->hash;
|
||||||
@@ -303,10 +305,18 @@ void MatchFinder_Init(CMatchFinder *p)
|
|||||||
p->pos = p->streamPos = p->cyclicBufferSize;
|
p->pos = p->streamPos = p->cyclicBufferSize;
|
||||||
p->result = SZ_OK;
|
p->result = SZ_OK;
|
||||||
p->streamEndWasReached = 0;
|
p->streamEndWasReached = 0;
|
||||||
MatchFinder_ReadBlock(p);
|
|
||||||
|
if (readData)
|
||||||
|
MatchFinder_ReadBlock(p);
|
||||||
|
|
||||||
MatchFinder_SetLimits(p);
|
MatchFinder_SetLimits(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MatchFinder_Init(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
MatchFinder_Init_2(p, True);
|
||||||
|
}
|
||||||
|
|
||||||
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
||||||
|
|||||||
10
C/LzFind.h
10
C/LzFind.h
@@ -1,5 +1,5 @@
|
|||||||
/* LzFind.h -- Match finder for LZ algorithms
|
/* LzFind.h -- Match finder for LZ algorithms
|
||||||
2015-05-01 : Igor Pavlov : Public domain */
|
2015-10-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZ_FIND_H
|
#ifndef __LZ_FIND_H
|
||||||
#define __LZ_FIND_H
|
#define __LZ_FIND_H
|
||||||
@@ -53,6 +53,11 @@ typedef struct _CMatchFinder
|
|||||||
|
|
||||||
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||||
|
|
||||||
|
#define Inline_MatchFinder_IsFinishedOK(p) \
|
||||||
|
((p)->streamEndWasReached \
|
||||||
|
&& (p)->streamPos == (p)->pos \
|
||||||
|
&& (!(p)->directInput || (p)->directInputRem == 0))
|
||||||
|
|
||||||
int MatchFinder_NeedMove(CMatchFinder *p);
|
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||||
void MatchFinder_MoveBlock(CMatchFinder *p);
|
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||||
@@ -98,9 +103,12 @@ typedef struct _IMatchFinder
|
|||||||
|
|
||||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||||
|
|
||||||
|
void MatchFinder_Init_2(CMatchFinder *p, int readData);
|
||||||
void MatchFinder_Init(CMatchFinder *p);
|
void MatchFinder_Init(CMatchFinder *p);
|
||||||
|
|
||||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
|
|
||||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||||
|
|
||||||
|
|||||||
19
C/LzFindMt.c
19
C/LzFindMt.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||||
2015-05-03 : Igor Pavlov : Public domain */
|
2015-10-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -173,12 +173,12 @@ static void HashThreadFunc(CMatchFinderMt *mt)
|
|||||||
CriticalSection_Enter(&mt->btSync.cs);
|
CriticalSection_Enter(&mt->btSync.cs);
|
||||||
CriticalSection_Enter(&mt->hashSync.cs);
|
CriticalSection_Enter(&mt->hashSync.cs);
|
||||||
{
|
{
|
||||||
const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
|
const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
const Byte *afterPtr;
|
ptrdiff_t offset;
|
||||||
MatchFinder_MoveBlock(mf);
|
MatchFinder_MoveBlock(mf);
|
||||||
afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
|
offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
mt->pointerToCurPos -= beforePtr - afterPtr;
|
mt->pointerToCurPos -= offset;
|
||||||
mt->buffer -= beforePtr - afterPtr;
|
mt->buffer -= offset;
|
||||||
}
|
}
|
||||||
CriticalSection_Leave(&mt->btSync.cs);
|
CriticalSection_Leave(&mt->btSync.cs);
|
||||||
CriticalSection_Leave(&mt->hashSync.cs);
|
CriticalSection_Leave(&mt->hashSync.cs);
|
||||||
@@ -501,8 +501,11 @@ void MatchFinderMt_Init(CMatchFinderMt *p)
|
|||||||
CMatchFinder *mf = p->MatchFinder;
|
CMatchFinder *mf = p->MatchFinder;
|
||||||
p->btBufPos = p->btBufPosLimit = 0;
|
p->btBufPos = p->btBufPosLimit = 0;
|
||||||
p->hashBufPos = p->hashBufPosLimit = 0;
|
p->hashBufPos = p->hashBufPosLimit = 0;
|
||||||
MatchFinder_Init(mf);
|
|
||||||
p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
|
/* Init without data reading. We don't want to read data in this thread */
|
||||||
|
MatchFinder_Init_2(mf, False);
|
||||||
|
|
||||||
|
p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
p->btNumAvailBytes = 0;
|
p->btNumAvailBytes = 0;
|
||||||
p->lzPos = p->historySize + 1;
|
p->lzPos = p->historySize + 1;
|
||||||
|
|
||||||
|
|||||||
10
C/Lzma2Dec.c
10
C/Lzma2Dec.c
@@ -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);
|
||||||
|
|
||||||
|
|||||||
55
C/Lzma2Enc.c
55
C/Lzma2Enc.c
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Enc.c -- LZMA2 Encoder
|
/* Lzma2Enc.c -- LZMA2 Encoder
|
||||||
2012-06-19 : Igor Pavlov : Public domain */
|
2015-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -109,6 +109,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
{
|
{
|
||||||
size_t destPos = 0;
|
size_t destPos = 0;
|
||||||
PRF(printf("################# COPY "));
|
PRF(printf("################# COPY "));
|
||||||
|
|
||||||
while (unpackSize > 0)
|
while (unpackSize > 0)
|
||||||
{
|
{
|
||||||
UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
|
UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
|
||||||
@@ -121,6 +122,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
unpackSize -= u;
|
unpackSize -= u;
|
||||||
destPos += u;
|
destPos += u;
|
||||||
p->srcPos += u;
|
p->srcPos += u;
|
||||||
|
|
||||||
if (outStream)
|
if (outStream)
|
||||||
{
|
{
|
||||||
*packSizeRes += destPos;
|
*packSizeRes += destPos;
|
||||||
@@ -132,9 +134,11 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
*packSizeRes = destPos;
|
*packSizeRes = destPos;
|
||||||
/* needInitState = True; */
|
/* needInitState = True; */
|
||||||
}
|
}
|
||||||
|
|
||||||
LzmaEnc_RestoreState(p->enc);
|
LzmaEnc_RestoreState(p->enc);
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t destPos = 0;
|
size_t destPos = 0;
|
||||||
UInt32 u = unpackSize - 1;
|
UInt32 u = unpackSize - 1;
|
||||||
@@ -160,11 +164,13 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
if (outStream)
|
if (outStream)
|
||||||
if (outStream->Write(outStream, outBuf, destPos) != destPos)
|
if (outStream->Write(outStream, outBuf, destPos) != destPos)
|
||||||
return SZ_ERROR_WRITE;
|
return SZ_ERROR_WRITE;
|
||||||
|
|
||||||
*packSizeRes = destPos;
|
*packSizeRes = destPos;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Lzma2 Props ---------- */
|
/* ---------- Lzma2 Props ---------- */
|
||||||
|
|
||||||
void Lzma2EncProps_Init(CLzma2EncProps *p)
|
void Lzma2EncProps_Init(CLzma2EncProps *p)
|
||||||
@@ -221,6 +227,8 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
|||||||
|
|
||||||
LzmaEncProps_Normalize(&p->lzmaProps);
|
LzmaEncProps_Normalize(&p->lzmaProps);
|
||||||
|
|
||||||
|
t1 = p->lzmaProps.numThreads;
|
||||||
|
|
||||||
if (p->blockSize == 0)
|
if (p->blockSize == 0)
|
||||||
{
|
{
|
||||||
UInt32 dictSize = p->lzmaProps.dictSize;
|
UInt32 dictSize = p->lzmaProps.dictSize;
|
||||||
@@ -232,7 +240,8 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
|||||||
if (blockSize < dictSize) blockSize = dictSize;
|
if (blockSize < dictSize) blockSize = dictSize;
|
||||||
p->blockSize = (size_t)blockSize;
|
p->blockSize = (size_t)blockSize;
|
||||||
}
|
}
|
||||||
if (t2 > 1)
|
|
||||||
|
if (t2 > 1 && p->lzmaProps.reduceSize != (UInt64)(Int64)-1)
|
||||||
{
|
{
|
||||||
UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1;
|
UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1;
|
||||||
if (temp > p->lzmaProps.reduceSize)
|
if (temp > p->lzmaProps.reduceSize)
|
||||||
@@ -241,19 +250,24 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
|||||||
if (numBlocks < (unsigned)t2)
|
if (numBlocks < (unsigned)t2)
|
||||||
{
|
{
|
||||||
t2 = (unsigned)numBlocks;
|
t2 = (unsigned)numBlocks;
|
||||||
|
if (t2 == 0)
|
||||||
|
t2 = 1;
|
||||||
t3 = t1 * t2;
|
t3 = t1 * t2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->numBlockThreads = t2;
|
p->numBlockThreads = t2;
|
||||||
p->numTotalThreads = t3;
|
p->numTotalThreads = t3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
||||||
{
|
{
|
||||||
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
|
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Lzma2 ---------- */
|
/* ---------- Lzma2 ---------- */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -283,15 +297,17 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
|
|||||||
UInt64 packTotal = 0;
|
UInt64 packTotal = 0;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
if (mainEncoder->outBuf == 0)
|
if (!mainEncoder->outBuf)
|
||||||
{
|
{
|
||||||
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
|
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
|
||||||
if (mainEncoder->outBuf == 0)
|
if (!mainEncoder->outBuf)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
|
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
|
||||||
RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
|
RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
|
||||||
mainEncoder->alloc, mainEncoder->allocBig));
|
mainEncoder->alloc, mainEncoder->allocBig));
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
|
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
|
||||||
@@ -305,16 +321,20 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
|
|||||||
if (packSize == 0)
|
if (packSize == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LzmaEnc_Finish(p->enc);
|
LzmaEnc_Finish(p->enc);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
Byte b = 0;
|
Byte b = 0;
|
||||||
if (outStream->Write(outStream, &b, 1) != 1)
|
if (outStream->Write(outStream, &b, 1) != 1)
|
||||||
return SZ_ERROR_WRITE;
|
return SZ_ERROR_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -362,10 +382,12 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LzmaEnc_Finish(p->enc);
|
LzmaEnc_Finish(p->enc);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finished)
|
if (finished)
|
||||||
{
|
{
|
||||||
if (*destSize == destLim)
|
if (*destSize == destLim)
|
||||||
@@ -378,12 +400,13 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Lzma2Enc ---------- */
|
/* ---------- Lzma2Enc ---------- */
|
||||||
|
|
||||||
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
|
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||||
{
|
{
|
||||||
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
|
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
|
||||||
if (p == 0)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
Lzma2EncProps_Init(&p->props);
|
Lzma2EncProps_Init(&p->props);
|
||||||
Lzma2EncProps_Normalize(&p->props);
|
Lzma2EncProps_Normalize(&p->props);
|
||||||
@@ -395,6 +418,7 @@ CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
|
|||||||
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
||||||
p->coders[i].enc = 0;
|
p->coders[i].enc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
MtCoder_Construct(&p->mtCoder);
|
MtCoder_Construct(&p->mtCoder);
|
||||||
#endif
|
#endif
|
||||||
@@ -455,22 +479,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
|
|||||||
|
|
||||||
for (i = 0; i < p->props.numBlockThreads; i++)
|
for (i = 0; i < p->props.numBlockThreads; i++)
|
||||||
{
|
{
|
||||||
CLzma2EncInt *t = &p->coders[i];
|
CLzma2EncInt *t = &p->coders[(unsigned)i];
|
||||||
if (t->enc == NULL)
|
if (!t->enc)
|
||||||
{
|
{
|
||||||
t->enc = LzmaEnc_Create(p->alloc);
|
t->enc = LzmaEnc_Create(p->alloc);
|
||||||
if (t->enc == NULL)
|
if (!t->enc)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
if (p->props.numBlockThreads <= 1)
|
if (p->props.numBlockThreads > 1)
|
||||||
#endif
|
|
||||||
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
|
|
||||||
{
|
{
|
||||||
CMtCallbackImp mtCallback;
|
CMtCallbackImp mtCallback;
|
||||||
|
|
||||||
@@ -485,9 +504,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
|
|||||||
|
|
||||||
p->mtCoder.blockSize = p->props.blockSize;
|
p->mtCoder.blockSize = p->props.blockSize;
|
||||||
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
|
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
|
||||||
|
if (p->mtCoder.destBlockSize < p->props.blockSize)
|
||||||
|
{
|
||||||
|
p->mtCoder.destBlockSize = (size_t)0 - 1;
|
||||||
|
if (p->mtCoder.destBlockSize < p->props.blockSize)
|
||||||
|
return SZ_ERROR_FAIL;
|
||||||
|
}
|
||||||
p->mtCoder.numThreads = p->props.numBlockThreads;
|
p->mtCoder.numThreads = p->props.numBlockThreads;
|
||||||
|
|
||||||
return MtCoder_Code(&p->mtCoder);
|
return MtCoder_Code(&p->mtCoder);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "Lzma86.h"
|
#include "Lzma86.h"
|
||||||
|
|
||||||
@@ -7,9 +9,6 @@
|
|||||||
#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 SzFree(void *p, void *address) { p = p; MyFree(address); }
|
|
||||||
|
|
||||||
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -23,7 +22,6 @@ SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
|||||||
|
|
||||||
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
|
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
|
||||||
{
|
{
|
||||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|
||||||
SRes res;
|
SRes res;
|
||||||
int useFilter;
|
int useFilter;
|
||||||
SizeT inSizePure;
|
SizeT inSizePure;
|
||||||
|
|||||||
@@ -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 */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -11,13 +13,9 @@
|
|||||||
|
|
||||||
#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 SzFree(void *p, void *address) { p = 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)
|
||||||
{
|
{
|
||||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|
||||||
size_t outSize2 = *destLen;
|
size_t outSize2 = *destLen;
|
||||||
Byte *filteredStream;
|
Byte *filteredStream;
|
||||||
Bool useFilter;
|
Bool useFilter;
|
||||||
|
|||||||
21
C/LzmaDec.c
21
C/LzmaDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaDec.c -- LZMA Decoder
|
/* LzmaDec.c -- LZMA Decoder
|
||||||
2015-05-14 : Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -294,14 +294,14 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
|
|
||||||
#ifdef _LZMA_SIZE_OPT
|
#ifdef _LZMA_SIZE_OPT
|
||||||
{
|
{
|
||||||
unsigned limit, offset;
|
unsigned lim, offset;
|
||||||
CLzmaProb *probLen = prob + LenChoice;
|
CLzmaProb *probLen = prob + LenChoice;
|
||||||
IF_BIT_0(probLen)
|
IF_BIT_0(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0(probLen);
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
limit = (1 << kLenNumLowBits);
|
lim = (1 << kLenNumLowBits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -312,17 +312,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
UPDATE_0(probLen);
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||||
offset = kLenNumLowSymbols;
|
offset = kLenNumLowSymbols;
|
||||||
limit = (1 << kLenNumMidBits);
|
lim = (1 << kLenNumMidBits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(probLen);
|
UPDATE_1(probLen);
|
||||||
probLen = prob + LenHigh;
|
probLen = prob + LenHigh;
|
||||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||||
limit = (1 << kLenNumHighBits);
|
lim = (1 << kLenNumHighBits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TREE_DECODE(probLen, limit, len);
|
TREE_DECODE(probLen, lim, len);
|
||||||
len += offset;
|
len += offset;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -438,10 +438,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
if (checkDicSize == 0)
|
if (checkDicSize == 0)
|
||||||
{
|
{
|
||||||
if (distance >= processedPos)
|
if (distance >= processedPos)
|
||||||
|
{
|
||||||
|
p->dicPos = dicPos;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (distance >= checkDicSize)
|
else if (distance >= checkDicSize)
|
||||||
|
{
|
||||||
|
p->dicPos = dicPos;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +459,10 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
SizeT pos;
|
SizeT pos;
|
||||||
|
|
||||||
if ((rem = limit - dicPos) == 0)
|
if ((rem = limit - dicPos) == 0)
|
||||||
|
{
|
||||||
|
p->dicPos = dicPos;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
curLen = ((rem < len) ? (unsigned)rem : len);
|
curLen = ((rem < len) ? (unsigned)rem : len);
|
||||||
pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
|
pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
|
||||||
|
|||||||
108
C/LzmaEnc.c
108
C/LzmaEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaEnc.c -- LZMA Encoder
|
/* LzmaEnc.c -- LZMA Encoder
|
||||||
2015-05-15 Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
|
|||||||
|
|
||||||
#define kDicLogSizeMaxCompress 32
|
#define kDicLogSizeMaxCompress 32
|
||||||
|
|
||||||
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
|
#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }
|
||||||
|
|
||||||
static UInt32 GetPosSlot1(UInt32 pos)
|
static UInt32 GetPosSlot1(UInt32 pos)
|
||||||
{
|
{
|
||||||
@@ -145,19 +145,19 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos)
|
|||||||
|
|
||||||
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
|
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
|
||||||
/*
|
/*
|
||||||
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
|
#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
|
||||||
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
|
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
|
||||||
res = p->g_FastPos[pos >> i] + (i * 2); }
|
res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
|
#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
|
||||||
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
|
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
|
||||||
res = p->g_FastPos[pos >> i] + (i * 2); }
|
res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
|
#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
|
||||||
res = p->g_FastPos[pos >> i] + (i * 2); }
|
res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
|
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
|
||||||
@@ -505,8 +505,8 @@ static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11,
|
|||||||
|
|
||||||
static void RangeEnc_Construct(CRangeEnc *p)
|
static void RangeEnc_Construct(CRangeEnc *p)
|
||||||
{
|
{
|
||||||
p->outStream = 0;
|
p->outStream = NULL;
|
||||||
p->bufBase = 0;
|
p->bufBase = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
|
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
|
||||||
@@ -514,10 +514,10 @@ static void RangeEnc_Construct(CRangeEnc *p)
|
|||||||
#define RC_BUF_SIZE (1 << 16)
|
#define RC_BUF_SIZE (1 << 16)
|
||||||
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
|
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
if (p->bufBase == 0)
|
if (!p->bufBase)
|
||||||
{
|
{
|
||||||
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
|
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
|
||||||
if (p->bufBase == 0)
|
if (!p->bufBase)
|
||||||
return 0;
|
return 0;
|
||||||
p->bufLim = p->bufBase + RC_BUF_SIZE;
|
p->bufLim = p->bufBase + RC_BUF_SIZE;
|
||||||
}
|
}
|
||||||
@@ -854,7 +854,7 @@ static void MovePos(CLzmaEnc *p, UInt32 num)
|
|||||||
{
|
{
|
||||||
#ifdef SHOW_STAT
|
#ifdef SHOW_STAT
|
||||||
g_STAT_OFFSET += num;
|
g_STAT_OFFSET += num;
|
||||||
printf("\n MovePos %d", num);
|
printf("\n MovePos %u", num);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (num != 0)
|
if (num != 0)
|
||||||
@@ -871,12 +871,12 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
|
|||||||
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
|
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
|
||||||
|
|
||||||
#ifdef SHOW_STAT
|
#ifdef SHOW_STAT
|
||||||
printf("\n i = %d numPairs = %d ", g_STAT_OFFSET, numPairs / 2);
|
printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
|
||||||
g_STAT_OFFSET++;
|
g_STAT_OFFSET++;
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < numPairs; i += 2)
|
for (i = 0; i < numPairs; i += 2)
|
||||||
printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
|
printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -983,12 +983,17 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
|
|||||||
|
|
||||||
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
||||||
{
|
{
|
||||||
UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
|
UInt32 lenEnd, cur;
|
||||||
UInt32 matchPrice, repMatchPrice, normalMatchPrice;
|
|
||||||
UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
|
UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
|
||||||
UInt32 *matches;
|
UInt32 *matches;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len;
|
||||||
|
UInt32 matchPrice, repMatchPrice, normalMatchPrice;
|
||||||
const Byte *data;
|
const Byte *data;
|
||||||
Byte curByte, matchByte;
|
Byte curByte, matchByte;
|
||||||
|
|
||||||
if (p->optimumEndIndex != p->optimumCurrentIndex)
|
if (p->optimumEndIndex != p->optimumCurrentIndex)
|
||||||
{
|
{
|
||||||
const COptimal *opt = &p->opt[p->optimumCurrentIndex];
|
const COptimal *opt = &p->opt[p->optimumCurrentIndex];
|
||||||
@@ -1167,17 +1172,20 @@ 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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
UInt32 numAvail;
|
||||||
UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
|
UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
|
||||||
UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
|
UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
|
||||||
Bool nextIsChar;
|
Bool nextIsChar;
|
||||||
@@ -1397,13 +1405,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 =
|
||||||
@@ -1465,6 +1473,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
for (lenTest = /*2*/ startLen; ; lenTest++)
|
for (lenTest = /*2*/ startLen; ; lenTest++)
|
||||||
{
|
{
|
||||||
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
|
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
|
||||||
|
{
|
||||||
UInt32 lenToPosState = GetLenToPosState(lenTest);
|
UInt32 lenToPosState = GetLenToPosState(lenTest);
|
||||||
COptimal *opt;
|
COptimal *opt;
|
||||||
if (curBack < kNumFullDistances)
|
if (curBack < kNumFullDistances)
|
||||||
@@ -1480,6 +1489,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
opt->backPrev = curBack + LZMA_NUM_REPS;
|
opt->backPrev = curBack + LZMA_NUM_REPS;
|
||||||
opt->prev1IsChar = False;
|
opt->prev1IsChar = False;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (/*_maxMode && */lenTest == matches[offs])
|
if (/*_maxMode && */lenTest == matches[offs])
|
||||||
{
|
{
|
||||||
@@ -1487,13 +1497,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 +
|
||||||
@@ -1509,15 +1519,15 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
/* for (; lenTest2 >= 2; lenTest2--) */
|
/* for (; lenTest2 >= 2; lenTest2--) */
|
||||||
{
|
{
|
||||||
UInt32 offset = cur + lenTest + 1 + lenTest2;
|
UInt32 offset = cur + lenTest + 1 + lenTest2;
|
||||||
UInt32 curAndLenPrice;
|
UInt32 curAndLenPrice2;
|
||||||
COptimal *opt;
|
COptimal *opt;
|
||||||
while (lenEnd < offset)
|
while (lenEnd < offset)
|
||||||
p->opt[++lenEnd].price = kInfinityPrice;
|
p->opt[++lenEnd].price = kInfinityPrice;
|
||||||
curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
|
curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
|
||||||
opt = &p->opt[offset];
|
opt = &p->opt[offset];
|
||||||
if (curAndLenPrice < opt->price)
|
if (curAndLenPrice2 < opt->price)
|
||||||
{
|
{
|
||||||
opt->price = curAndLenPrice;
|
opt->price = curAndLenPrice2;
|
||||||
opt->posPrev = cur + lenTest + 1;
|
opt->posPrev = cur + lenTest + 1;
|
||||||
opt->backPrev = 0;
|
opt->backPrev = 0;
|
||||||
opt->prev1IsChar = True;
|
opt->prev1IsChar = True;
|
||||||
@@ -1718,7 +1728,6 @@ static void FillDistancesPrices(CLzmaEnc *p)
|
|||||||
|
|
||||||
{
|
{
|
||||||
UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
|
UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < kStartPosModelIndex; i++)
|
for (i = 0; i < kStartPosModelIndex; i++)
|
||||||
distancesPrices[i] = posSlotPrices[i];
|
distancesPrices[i] = posSlotPrices[i];
|
||||||
for (; i < kNumFullDistances; i++)
|
for (; i < kNumFullDistances; i++)
|
||||||
@@ -1749,15 +1758,15 @@ void LzmaEnc_Construct(CLzmaEnc *p)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
LzmaEnc_InitPriceTables(p->ProbPrices);
|
LzmaEnc_InitPriceTables(p->ProbPrices);
|
||||||
p->litProbs = 0;
|
p->litProbs = NULL;
|
||||||
p->saveState.litProbs = 0;
|
p->saveState.litProbs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
|
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
|
p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
|
||||||
if (p != 0)
|
if (p)
|
||||||
LzmaEnc_Construct((CLzmaEnc *)p);
|
LzmaEnc_Construct((CLzmaEnc *)p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -1766,8 +1775,8 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
|
|||||||
{
|
{
|
||||||
alloc->Free(alloc, p->litProbs);
|
alloc->Free(alloc, p->litProbs);
|
||||||
alloc->Free(alloc, p->saveState.litProbs);
|
alloc->Free(alloc, p->saveState.litProbs);
|
||||||
p->litProbs = 0;
|
p->litProbs = NULL;
|
||||||
p->saveState.litProbs = 0;
|
p->saveState.litProbs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||||
@@ -1829,7 +1838,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
|
|||||||
len = GetOptimum(p, nowPos32, &pos);
|
len = GetOptimum(p, nowPos32, &pos);
|
||||||
|
|
||||||
#ifdef SHOW_STAT2
|
#ifdef SHOW_STAT2
|
||||||
printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
|
printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
posState = nowPos32 & p->pbMask;
|
posState = nowPos32 & p->pbMask;
|
||||||
@@ -1963,12 +1972,12 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||||||
|
|
||||||
{
|
{
|
||||||
unsigned lclp = p->lc + p->lp;
|
unsigned lclp = p->lc + p->lp;
|
||||||
if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
|
if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
|
||||||
{
|
{
|
||||||
LzmaEnc_FreeLits(p, alloc);
|
LzmaEnc_FreeLits(p, alloc);
|
||||||
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
||||||
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
||||||
if (p->litProbs == 0 || p->saveState.litProbs == 0)
|
if (!p->litProbs || !p->saveState.litProbs)
|
||||||
{
|
{
|
||||||
LzmaEnc_FreeLits(p, alloc);
|
LzmaEnc_FreeLits(p, alloc);
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
@@ -2140,6 +2149,7 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqOutStream funcTable;
|
ISeqOutStream funcTable;
|
||||||
@@ -2169,12 +2179,14 @@ UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
|
|||||||
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
|
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
|
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
|
||||||
{
|
{
|
||||||
const CLzmaEnc *p = (CLzmaEnc *)pp;
|
const CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
|
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
||||||
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
|
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
|
||||||
{
|
{
|
||||||
@@ -2209,6 +2221,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
||||||
{
|
{
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
@@ -2222,9 +2235,9 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
|
res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
|
||||||
if (res != SZ_OK || p->finished != 0)
|
if (res != SZ_OK || p->finished)
|
||||||
break;
|
break;
|
||||||
if (progress != 0)
|
if (progress)
|
||||||
{
|
{
|
||||||
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
|
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
@@ -2234,10 +2247,19 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LzmaEnc_Finish(p);
|
LzmaEnc_Finish(p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
|
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
|
||||||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||||
{
|
{
|
||||||
@@ -2245,6 +2267,7 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
|
|||||||
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
|
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
|
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
|
||||||
{
|
{
|
||||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
@@ -2272,6 +2295,7 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||||
{
|
{
|
||||||
@@ -2280,19 +2304,22 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
|
|||||||
|
|
||||||
CSeqOutStreamBuf outStream;
|
CSeqOutStreamBuf outStream;
|
||||||
|
|
||||||
LzmaEnc_SetInputBuf(p, src, srcLen);
|
|
||||||
|
|
||||||
outStream.funcTable.Write = MyWrite;
|
outStream.funcTable.Write = MyWrite;
|
||||||
outStream.data = dest;
|
outStream.data = dest;
|
||||||
outStream.rem = *destLen;
|
outStream.rem = *destLen;
|
||||||
outStream.overflow = False;
|
outStream.overflow = False;
|
||||||
|
|
||||||
p->writeEndMark = writeEndMark;
|
p->writeEndMark = writeEndMark;
|
||||||
|
|
||||||
p->rc.outStream = &outStream.funcTable;
|
p->rc.outStream = &outStream.funcTable;
|
||||||
|
|
||||||
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
|
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
res = LzmaEnc_Encode2(p, progress);
|
res = LzmaEnc_Encode2(p, progress);
|
||||||
|
if (res == SZ_OK && p->nowPos64 != srcLen)
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
*destLen -= outStream.rem;
|
*destLen -= outStream.rem;
|
||||||
if (outStream.overflow)
|
if (outStream.overflow)
|
||||||
@@ -2300,13 +2327,14 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||||
{
|
{
|
||||||
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
|
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
|
||||||
SRes res;
|
SRes res;
|
||||||
if (p == 0)
|
if (!p)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
|
|
||||||
res = LzmaEnc_SetProps(p, props);
|
res = LzmaEnc_SetProps(p, props);
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
/* MtCoder.c -- Multi-thread Coder
|
/* MtCoder.c -- Multi-thread Coder
|
||||||
2010-09-24 : Igor Pavlov : Public domain */
|
2015-10-13 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "MtCoder.h"
|
#include "MtCoder.h"
|
||||||
|
|
||||||
void LoopThread_Construct(CLoopThread *p)
|
void LoopThread_Construct(CLoopThread *p)
|
||||||
@@ -120,7 +118,7 @@ void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
|
|||||||
LoopThread_Construct(&p->thread);
|
LoopThread_Construct(&p->thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; }
|
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
|
||||||
|
|
||||||
static void CMtThread_CloseEvents(CMtThread *p)
|
static void CMtThread_CloseEvents(CMtThread *p)
|
||||||
{
|
{
|
||||||
|
|||||||
6
C/Ppmd.h
6
C/Ppmd.h
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd.h -- PPMD codec common code
|
/* Ppmd.h -- PPMD codec common code
|
||||||
2013-01-18 : Igor Pavlov : Public domain
|
2016-05-16 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#ifndef __PPMD_H
|
#ifndef __PPMD_H
|
||||||
@@ -77,8 +77,8 @@ typedef
|
|||||||
CPpmd_Byte_Ref;
|
CPpmd_Byte_Ref;
|
||||||
|
|
||||||
#define PPMD_SetAllBitsIn256Bytes(p) \
|
#define PPMD_SetAllBitsIn256Bytes(p) \
|
||||||
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
|
{ unsigned z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
|
||||||
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
|
p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
14
C/Ppmd7.c
14
C/Ppmd7.c
@@ -1,10 +1,10 @@
|
|||||||
/* Ppmd7.c -- PPMdH codec
|
/* Ppmd7.c -- PPMdH codec
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2016-05-21 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include <memory.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "Ppmd7.h"
|
#include "Ppmd7.h"
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ void Ppmd7_Construct(CPpmd7 *p)
|
|||||||
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
||||||
{
|
{
|
||||||
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
||||||
do { p->Units2Indx[k++] = (Byte)i; } while(--step);
|
do { p->Units2Indx[k++] = (Byte)i; } while (--step);
|
||||||
p->Indx2Units[i] = (Byte)k;
|
p->Indx2Units[i] = (Byte)k;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
|
|||||||
|
|
||||||
#define MyMem12Cpy(dest, src, num) \
|
#define MyMem12Cpy(dest, src, num) \
|
||||||
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
|
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
|
||||||
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
|
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
|
||||||
|
|
||||||
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
||||||
{
|
{
|
||||||
@@ -639,10 +639,10 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
|
|||||||
unsigned nonMasked = p->MinContext->NumStats - numMasked;
|
unsigned nonMasked = p->MinContext->NumStats - numMasked;
|
||||||
if (p->MinContext->NumStats != 256)
|
if (p->MinContext->NumStats != 256)
|
||||||
{
|
{
|
||||||
see = p->See[p->NS2Indx[nonMasked - 1]] +
|
see = p->See[(unsigned)p->NS2Indx[nonMasked - 1]] +
|
||||||
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
|
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
|
||||||
2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
|
2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
|
||||||
4 * (numMasked > nonMasked) +
|
4 * (unsigned)(numMasked > nonMasked) +
|
||||||
p->HiBitsFlag;
|
p->HiBitsFlag;
|
||||||
{
|
{
|
||||||
unsigned r = (see->Summ >> see->Shift);
|
unsigned r = (see->Summ >> see->Shift);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd7.h -- PPMdH compression codec
|
/* Ppmd7.h -- PPMdH compression codec
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2016-05-21 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
/* This code supports virtual RangeDecoder and includes the implementation
|
/* This code supports virtual RangeDecoder and includes the implementation
|
||||||
@@ -86,10 +86,10 @@ void Ppmd7_Update2(CPpmd7 *p);
|
|||||||
void Ppmd7_UpdateBin(CPpmd7 *p);
|
void Ppmd7_UpdateBin(CPpmd7 *p);
|
||||||
|
|
||||||
#define Ppmd7_GetBinSumm(p) \
|
#define Ppmd7_GetBinSumm(p) \
|
||||||
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
|
&p->BinSumm[(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
|
||||||
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
|
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
|
||||||
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
|
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
|
||||||
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
|
2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
|
||||||
((p->RunLength >> 26) & 0x20)]
|
((p->RunLength >> 26) & 0x20)]
|
||||||
|
|
||||||
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd7Enc.c -- PPMdH Encoder
|
/* Ppmd7Enc.c -- PPMdH Encoder
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2015-09-28 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
@@ -26,7 +26,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
|
|||||||
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
|
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
|
||||||
temp = 0xFF;
|
temp = 0xFF;
|
||||||
}
|
}
|
||||||
while(--p->CacheSize != 0);
|
while (--p->CacheSize != 0);
|
||||||
p->Cache = (Byte)((UInt32)p->Low >> 24);
|
p->Cache = (Byte)((UInt32)p->Low >> 24);
|
||||||
}
|
}
|
||||||
p->CacheSize++;
|
p->CacheSize++;
|
||||||
|
|||||||
42
C/Ppmd8.c
42
C/Ppmd8.c
@@ -1,10 +1,10 @@
|
|||||||
/* Ppmd8.c -- PPMdI codec
|
/* Ppmd8.c -- PPMdI codec
|
||||||
2013-11-12 : Igor Pavlov : Public domain
|
2016-05-21 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include <memory.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "Ppmd8.h"
|
#include "Ppmd8.h"
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ void Ppmd8_Construct(CPpmd8 *p)
|
|||||||
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
||||||
{
|
{
|
||||||
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
||||||
do { p->Units2Indx[k++] = (Byte)i; } while(--step);
|
do { p->Units2Indx[k++] = (Byte)i; } while (--step);
|
||||||
p->Indx2Units[i] = (Byte)k;
|
p->Indx2Units[i] = (Byte)k;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,8 +240,8 @@ static void *AllocUnits(CPpmd8 *p, unsigned indx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define MyMem12Cpy(dest, src, num) \
|
#define MyMem12Cpy(dest, src, num) \
|
||||||
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
|
{ UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \
|
||||||
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
|
do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); }
|
||||||
|
|
||||||
static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
||||||
{
|
{
|
||||||
@@ -772,7 +772,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
|
|||||||
if (SUCCESSOR(s) <= upBranch)
|
if (SUCCESSOR(s) <= upBranch)
|
||||||
{
|
{
|
||||||
CTX_PTR successor;
|
CTX_PTR successor;
|
||||||
CPpmd_State *s1 = p->FoundState;
|
CPpmd_State *s2 = p->FoundState;
|
||||||
p->FoundState = s;
|
p->FoundState = s;
|
||||||
|
|
||||||
successor = CreateSuccessors(p, False, NULL, c);
|
successor = CreateSuccessors(p, False, NULL, c);
|
||||||
@@ -780,7 +780,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
|
|||||||
SetSuccessor(s, 0);
|
SetSuccessor(s, 0);
|
||||||
else
|
else
|
||||||
SetSuccessor(s, REF(successor));
|
SetSuccessor(s, REF(successor));
|
||||||
p->FoundState = s1;
|
p->FoundState = s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->OrderFall == 1 && c1 == p->MaxContext)
|
if (p->OrderFall == 1 && c1 == p->MaxContext)
|
||||||
@@ -924,19 +924,19 @@ static void UpdateModel(CPpmd8 *p)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
|
CPpmd_State *s2 = (CPpmd_State*)AllocUnits(p, 0);
|
||||||
if (!s)
|
if (!s2)
|
||||||
{
|
{
|
||||||
RESTORE_MODEL(c, CTX(fSuccessor));
|
RESTORE_MODEL(c, CTX(fSuccessor));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*s = *ONE_STATE(c);
|
*s2 = *ONE_STATE(c);
|
||||||
c->Stats = REF(s);
|
c->Stats = REF(s2);
|
||||||
if (s->Freq < MAX_FREQ / 4 - 1)
|
if (s2->Freq < MAX_FREQ / 4 - 1)
|
||||||
s->Freq <<= 1;
|
s2->Freq <<= 1;
|
||||||
else
|
else
|
||||||
s->Freq = MAX_FREQ - 4;
|
s2->Freq = MAX_FREQ - 4;
|
||||||
c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 2));
|
c->SummFreq = (UInt16)(s2->Freq + p->InitEsc + (ns > 2));
|
||||||
}
|
}
|
||||||
cf = 2 * fFreq * (c->SummFreq + 6);
|
cf = 2 * fFreq * (c->SummFreq + 6);
|
||||||
sf = (UInt32)s0 + c->SummFreq;
|
sf = (UInt32)s0 + c->SummFreq;
|
||||||
@@ -951,10 +951,10 @@ static void UpdateModel(CPpmd8 *p)
|
|||||||
c->SummFreq = (UInt16)(c->SummFreq + cf);
|
c->SummFreq = (UInt16)(c->SummFreq + cf);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CPpmd_State *s = STATS(c) + ns1 + 1;
|
CPpmd_State *s2 = STATS(c) + ns1 + 1;
|
||||||
SetSuccessor(s, successor);
|
SetSuccessor(s2, successor);
|
||||||
s->Symbol = fSymbol;
|
s2->Symbol = fSymbol;
|
||||||
s->Freq = (Byte)cf;
|
s2->Freq = (Byte)cf;
|
||||||
c->Flags |= flag;
|
c->Flags |= flag;
|
||||||
c->NumStats = (Byte)(ns1 + 1);
|
c->NumStats = (Byte)(ns1 + 1);
|
||||||
}
|
}
|
||||||
@@ -1038,9 +1038,9 @@ CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
|
|||||||
CPpmd_See *see;
|
CPpmd_See *see;
|
||||||
if (p->MinContext->NumStats != 0xFF)
|
if (p->MinContext->NumStats != 0xFF)
|
||||||
{
|
{
|
||||||
see = p->See[p->NS2Indx[p->MinContext->NumStats + 2] - 3] +
|
see = p->See[(unsigned)p->NS2Indx[(unsigned)p->MinContext->NumStats + 2] - 3] +
|
||||||
(p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
|
(p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
|
||||||
2 * (2 * (unsigned)p->MinContext->NumStats <
|
2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats <
|
||||||
((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
|
((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
|
||||||
p->MinContext->Flags;
|
p->MinContext->Flags;
|
||||||
{
|
{
|
||||||
|
|||||||
28
C/Sha1.c
28
C/Sha1.c
@@ -1,5 +1,5 @@
|
|||||||
/* Sha1.c -- SHA-1 Hash
|
/* Sha1.c -- SHA-1 Hash
|
||||||
2015-05-10 : Igor Pavlov : Public domain
|
2016-05-20 : Igor Pavlov : Public domain
|
||||||
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
|
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
@@ -151,18 +151,23 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
|
|||||||
|
|
||||||
if (pos2 != 0)
|
if (pos2 != 0)
|
||||||
{
|
{
|
||||||
UInt32 w = ((UInt32)data[0]) << 24;
|
UInt32 w;
|
||||||
if (--size && pos2 < 3)
|
pos2 = (3 - pos2) * 8;
|
||||||
|
w = ((UInt32)*data++) << pos2;
|
||||||
|
if (--size && pos2)
|
||||||
{
|
{
|
||||||
w |= ((UInt32)data[1]) << 16;
|
pos2 -= 8;
|
||||||
if (--size && pos2 < 2)
|
w |= ((UInt32)*data++) << pos2;
|
||||||
|
if (--size && pos2)
|
||||||
{
|
{
|
||||||
w |= ((UInt32)data[2]) << 8;
|
pos2 -= 8;
|
||||||
--size;
|
w |= ((UInt32)*data++) << pos2;
|
||||||
|
size--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data += 4 - pos2;
|
p->buffer[pos] |= w;
|
||||||
p->buffer[pos++] |= (w >> (8 * pos2));
|
if (pos2 == 0)
|
||||||
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -207,7 +212,7 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode)
|
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */)
|
||||||
{
|
{
|
||||||
int returnRes = False;
|
int returnRes = False;
|
||||||
|
|
||||||
@@ -241,7 +246,8 @@ void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode)
|
|||||||
SetUi32(prev, d);
|
SetUi32(prev, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
returnRes = rar350Mode;
|
// returnRes = rar350Mode;
|
||||||
|
returnRes = True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
C/Sha1.h
4
C/Sha1.h
@@ -1,5 +1,5 @@
|
|||||||
/* Sha1.h -- SHA-1 Hash
|
/* Sha1.h -- SHA-1 Hash
|
||||||
2015-03-04 : Igor Pavlov : Public domain */
|
2016-05-20 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_SHA1_H
|
#ifndef __7Z_SHA1_H
|
||||||
#define __7Z_SHA1_H
|
#define __7Z_SHA1_H
|
||||||
@@ -27,7 +27,7 @@ void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest);
|
|||||||
void Sha1_Update(CSha1 *p, const Byte *data, size_t size);
|
void Sha1_Update(CSha1 *p, const Byte *data, size_t size);
|
||||||
void Sha1_Final(CSha1 *p, Byte *digest);
|
void Sha1_Final(CSha1 *p, Byte *digest);
|
||||||
|
|
||||||
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode);
|
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */);
|
||||||
|
|
||||||
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size);
|
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size);
|
||||||
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size);
|
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size);
|
||||||
|
|||||||
37
C/Sha256.c
37
C/Sha256.c
@@ -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);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zMain.c - Test application for 7z Decoder
|
/* 7zMain.c - Test application for 7z Decoder
|
||||||
2015-05-11 : Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -310,10 +310,10 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
|
|||||||
ms[1] = 29;
|
ms[1] = 29;
|
||||||
for (mon = 0;; mon++)
|
for (mon = 0;; mon++)
|
||||||
{
|
{
|
||||||
unsigned s = ms[mon];
|
unsigned d = ms[mon];
|
||||||
if (v < s)
|
if (v < d)
|
||||||
break;
|
break;
|
||||||
v -= s;
|
v -= d;
|
||||||
}
|
}
|
||||||
s = UIntToStr(s, year, 4); *s++ = '-';
|
s = UIntToStr(s, year, 4); *s++ = '-';
|
||||||
UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
|
UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
|
||||||
@@ -328,22 +328,20 @@ void PrintError(char *sz)
|
|||||||
printf("\nERROR: %s\n", sz);
|
printf("\nERROR: %s\n", sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_FILE
|
|
||||||
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
|
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.');
|
s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.');
|
||||||
s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.');
|
s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.');
|
||||||
s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.');
|
s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.');
|
||||||
s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.');
|
s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.');
|
||||||
s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.');
|
s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.');
|
||||||
s[5] = '\0';
|
s[5] = 0;
|
||||||
|
#else
|
||||||
|
s[0] = (char)(((wa & (1 << 4)) != 0 || isDir) ? 'D' : '.');
|
||||||
|
s[1] = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void GetAttribString(UInt32, Bool, char *s)
|
|
||||||
{
|
|
||||||
s[0] = '\0';
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// #define NUM_PARENTS_MAX 128
|
// #define NUM_PARENTS_MAX 128
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
PROG = 7zDec
|
PROG = 7zDec
|
||||||
CXX = g++
|
CXX = gcc
|
||||||
LIB =
|
LIB =
|
||||||
RM = rm -f
|
RM = rm -f
|
||||||
CFLAGS = -c -O2 -Wall
|
CFLAGS = -c -O2 -Wall
|
||||||
|
|
||||||
OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
|
OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o Delta.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o BraIA64.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
|
|
||||||
@@ -38,6 +38,9 @@ $(PROG): $(OBJS)
|
|||||||
CpuArch.o: ../../CpuArch.c
|
CpuArch.o: ../../CpuArch.c
|
||||||
$(CXX) $(CFLAGS) ../../CpuArch.c
|
$(CXX) $(CFLAGS) ../../CpuArch.c
|
||||||
|
|
||||||
|
Delta.o: ../../Delta.c
|
||||||
|
$(CXX) $(CFLAGS) ../../Delta.c
|
||||||
|
|
||||||
LzmaDec.o: ../../LzmaDec.c
|
LzmaDec.o: ../../LzmaDec.c
|
||||||
$(CXX) $(CFLAGS) ../../LzmaDec.c
|
$(CXX) $(CFLAGS) ../../LzmaDec.c
|
||||||
|
|
||||||
@@ -50,6 +53,9 @@ Bra.o: ../../Bra.c
|
|||||||
Bra86.o: ../../Bra86.c
|
Bra86.o: ../../Bra86.c
|
||||||
$(CXX) $(CFLAGS) ../../Bra86.c
|
$(CXX) $(CFLAGS) ../../Bra86.c
|
||||||
|
|
||||||
|
BraIA64.o: ../../BraIA64.c
|
||||||
|
$(CXX) $(CFLAGS) ../../BraIA64.c
|
||||||
|
|
||||||
Bcj2.o: ../../Bcj2.c
|
Bcj2.o: ../../Bcj2.c
|
||||||
$(CXX) $(CFLAGS) ../../Bcj2.c
|
$(CXX) $(CFLAGS) ../../Bcj2.c
|
||||||
|
|
||||||
@@ -67,4 +73,3 @@ Ppmd7Dec.o: ../../Ppmd7Dec.c
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
-$(RM) $(PROG) $(OBJS)
|
-$(RM) $(PROG) $(OBJS)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zipInnstall.c - 7-Zip Installer
|
/* 7zipInstall.c - 7-Zip Installer
|
||||||
2015-06-13 : Igor Pavlov : Public domain */
|
2016-06-08 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "../../7zFile.h"
|
#include "../../7zFile.h"
|
||||||
#include "../../7zVersion.h"
|
#include "../../7zVersion.h"
|
||||||
#include "../../CpuArch.h"
|
#include "../../CpuArch.h"
|
||||||
|
#include "../../DllSecur.h"
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ static const WCHAR *k_Reg_Software_7zip = L"Software\\7-Zip";
|
|||||||
#define k_7zip_with_Ver_base L"7-Zip " LLL(MY_VERSION)
|
#define k_7zip_with_Ver_base L"7-Zip " LLL(MY_VERSION)
|
||||||
|
|
||||||
#ifdef _64BIT_INSTALLER
|
#ifdef _64BIT_INSTALLER
|
||||||
#define k_7zip_with_Ver k_7zip_with_Ver_base L" x64"
|
#define k_7zip_with_Ver k_7zip_with_Ver_base L" (x64)"
|
||||||
#else
|
#else
|
||||||
#define k_7zip_with_Ver k_7zip_with_Ver_base
|
#define k_7zip_with_Ver k_7zip_with_Ver_base
|
||||||
#endif
|
#endif
|
||||||
@@ -84,6 +85,8 @@ static HWND g_Path_HWND;
|
|||||||
static HWND g_InfoLine_HWND;
|
static HWND g_InfoLine_HWND;
|
||||||
static HWND g_Progress_HWND;
|
static HWND g_Progress_HWND;
|
||||||
|
|
||||||
|
static DWORD g_TotalSize;
|
||||||
|
|
||||||
static WCHAR path[MAX_PATH * 2 + 40];
|
static WCHAR path[MAX_PATH * 2 + 40];
|
||||||
|
|
||||||
|
|
||||||
@@ -143,7 +146,7 @@ static WRes CreateComplexDir()
|
|||||||
|
|
||||||
if (IS_DRIVE_PATH(s))
|
if (IS_DRIVE_PATH(s))
|
||||||
prefixSize = 3;
|
prefixSize = 3;
|
||||||
else if (IS_SEPAR(s[1]) && IS_SEPAR(s[1]))
|
else if (IS_SEPAR(s[0]) && IS_SEPAR(s[1]))
|
||||||
prefixSize = 2;
|
prefixSize = 2;
|
||||||
else
|
else
|
||||||
return ERROR_INVALID_NAME;
|
return ERROR_INVALID_NAME;
|
||||||
@@ -259,7 +262,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;
|
||||||
}
|
}
|
||||||
@@ -282,7 +285,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;
|
||||||
}
|
}
|
||||||
@@ -320,7 +323,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)
|
||||||
@@ -569,6 +572,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default: return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -596,8 +601,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;
|
||||||
}
|
}
|
||||||
@@ -716,10 +721,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
|
||||||
@@ -735,10 +740,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -796,16 +801,30 @@ static void WriteShellEx()
|
|||||||
// wcscpy(destPath, path);
|
// wcscpy(destPath, path);
|
||||||
// wcscat(destPath, L"7zFM.exe");
|
// wcscat(destPath, L"7zFM.exe");
|
||||||
MyRegistry_SetString(destKey, L"DisplayName", k_7zip_with_Ver_str);
|
MyRegistry_SetString(destKey, L"DisplayName", k_7zip_with_Ver_str);
|
||||||
|
MyRegistry_SetString(destKey, L"DisplayVersion", LLL(MY_VERSION_NUMBERS));
|
||||||
|
|
||||||
MyRegistry_SetString(destKey, L"DisplayIcon", destPath);
|
MyRegistry_SetString(destKey, L"DisplayIcon", destPath);
|
||||||
|
|
||||||
wcscpy(destPath, path);
|
wcscpy(destPath, path);
|
||||||
// MyRegistry_SetString(destKey, L"InstallLocation", destPath);
|
MyRegistry_SetString(destKey, L"InstallLocation", destPath);
|
||||||
wcscat(destPath, L"Uninstall.exe");
|
wcscat(destPath, L"Uninstall.exe");
|
||||||
// wcscat(destPath, L"\"");
|
// wcscat(destPath, L"\"");
|
||||||
MyRegistry_SetString(destKey, L"UninstallString", destPath);
|
MyRegistry_SetString(destKey, L"UninstallString", destPath);
|
||||||
|
|
||||||
MyRegistry_SetDWORD(destKey, L"NoModify", 1);
|
MyRegistry_SetDWORD(destKey, L"NoModify", 1);
|
||||||
MyRegistry_SetDWORD(destKey, L"NoRepair", 1);
|
MyRegistry_SetDWORD(destKey, L"NoRepair", 1);
|
||||||
|
|
||||||
|
MyRegistry_SetDWORD(destKey, L"EstimatedSize", g_TotalSize >> 10);
|
||||||
|
|
||||||
|
MyRegistry_SetDWORD(destKey, L"VersionMajor", MY_VER_MAJOR);
|
||||||
|
MyRegistry_SetDWORD(destKey, L"VersionMinor", MY_VER_MINOR);
|
||||||
|
|
||||||
|
MyRegistry_SetString(destKey, L"Publisher", LLL(MY_AUTHOR_NAME));
|
||||||
|
|
||||||
|
// MyRegistry_SetString(destKey, L"HelpLink", L"http://www.7-zip.org/support.html");
|
||||||
|
// MyRegistry_SetString(destKey, L"URLInfoAbout", L"http://www.7-zip.org/");
|
||||||
|
// MyRegistry_SetString(destKey, L"URLUpdateInfo", L"http://www.7-zip.org/");
|
||||||
|
|
||||||
RegCloseKey(destKey);
|
RegCloseKey(destKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -858,6 +877,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
UNUSED_VAR(nCmdShow)
|
UNUSED_VAR(nCmdShow)
|
||||||
|
|
||||||
#ifndef UNDER_CE
|
#ifndef UNDER_CE
|
||||||
|
LoadSecurityDlls();
|
||||||
CoInitialize(NULL);
|
CoInitialize(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -995,7 +1015,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;
|
||||||
@@ -1067,7 +1088,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;
|
||||||
@@ -1100,6 +1120,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);
|
||||||
@@ -1108,6 +1129,23 @@ if (res == SZ_OK)
|
|||||||
FileInStream_CreateVTable(&archiveStream);
|
FileInStream_CreateVTable(&archiveStream);
|
||||||
LookToRead_CreateVTable(&lookStream, False);
|
LookToRead_CreateVTable(&lookStream, False);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Remove post spaces
|
||||||
|
unsigned endPos = 0;
|
||||||
|
unsigned i = 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
wchar_t c = path[i++];
|
||||||
|
if (c == 0)
|
||||||
|
break;
|
||||||
|
if (c != ' ')
|
||||||
|
endPos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
path[endPos] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
NormalizePrefix(path);
|
NormalizePrefix(path);
|
||||||
winRes = CreateComplexDir();
|
winRes = CreateComplexDir();
|
||||||
|
|
||||||
@@ -1128,9 +1166,11 @@ if (res == SZ_OK)
|
|||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call, if(!outBuf) */
|
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call, if (!outBuf) */
|
||||||
Byte *outBuf = NULL; /* it must be NULL before first call for each new archive. */
|
Byte *outBuf = NULL; /* it must be NULL before first call for each new archive. */
|
||||||
size_t outBufSize = 0; /* it can have any value before first call, if(!outBuf) */
|
size_t outBufSize = 0; /* it can have any value before first call, if (!outBuf) */
|
||||||
|
|
||||||
|
g_TotalSize = 0;
|
||||||
|
|
||||||
if (!g_SilentMode)
|
if (!g_SilentMode)
|
||||||
{
|
{
|
||||||
@@ -1309,6 +1349,8 @@ if (res == SZ_OK)
|
|||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_TotalSize += (DWORD)outSizeProcessed;
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_FILE
|
#ifdef USE_WINDOWS_FILE
|
||||||
if (SzBitWithVals_Check(&db.MTime, i))
|
if (SzBitWithVals_Check(&db.MTime, i))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,6 +191,14 @@ SOURCE=..\..\Delta.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\DllSecur.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\DllSecur.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Lzma2Dec.c
|
SOURCE=..\..\Lzma2Dec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ C_OBJS = \
|
|||||||
$O\7zStream.obj \
|
$O\7zStream.obj \
|
||||||
$O\Bcj2.obj \
|
$O\Bcj2.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
|
$O\DllSecur.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
OBJS = \
|
OBJS = \
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#define IDD_INSTALL 100
|
#define IDD_INSTALL 100
|
||||||
|
|
||||||
#define IDT_EXTRACT_EXTRACT_TO 110
|
#define IDT_EXTRACT_EXTRACT_TO 110
|
||||||
#define IDE_EXTRACT_PATH 111
|
#define IDE_EXTRACT_PATH 111
|
||||||
#define IDB_EXTRACT_SET_PATH 112
|
#define IDB_EXTRACT_SET_PATH 112
|
||||||
#define IDT_CUR_FILE 113
|
#define IDT_CUR_FILE 113
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zipUninstall.c - 7-Zip Uninstaller
|
/* 7zipUninstall.c - 7-Zip Uninstaller
|
||||||
2015-06-13 : Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
#define k_7zip_with_Ver_base L"7-Zip " LLL(MY_VERSION)
|
#define k_7zip_with_Ver_base L"7-Zip " LLL(MY_VERSION)
|
||||||
|
|
||||||
#ifdef _64BIT_INSTALLER
|
#ifdef _64BIT_INSTALLER
|
||||||
#define k_7zip_with_Ver k_7zip_with_Ver_base L" x64"
|
#define k_7zip_with_Ver k_7zip_with_Ver_base L" (x64)"
|
||||||
#else
|
#else
|
||||||
#define k_7zip_with_Ver k_7zip_with_Ver_base
|
#define k_7zip_with_Ver k_7zip_with_Ver_base
|
||||||
#endif
|
#endif
|
||||||
@@ -362,9 +362,11 @@ static void WriteCLSID()
|
|||||||
{
|
{
|
||||||
if (AreEqual_Path_PrefixName(s, path, L"7-zip.dll"))
|
if (AreEqual_Path_PrefixName(s, path, L"7-zip.dll"))
|
||||||
{
|
{
|
||||||
LONG res = MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc);
|
{
|
||||||
if (res == ERROR_SUCCESS)
|
LONG res = MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc);
|
||||||
MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip);
|
if (res == ERROR_SUCCESS)
|
||||||
|
MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -384,7 +386,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,9 +399,11 @@ static void WriteCLSID()
|
|||||||
{
|
{
|
||||||
if (AreEqual_Path_PrefixName(s, path, L"7-zip32.dll"))
|
if (AreEqual_Path_PrefixName(s, path, L"7-zip32.dll"))
|
||||||
{
|
{
|
||||||
LONG res = MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc);
|
{
|
||||||
if (res == ERROR_SUCCESS)
|
LONG res = MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc);
|
||||||
MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip);
|
if (res == ERROR_SUCCESS)
|
||||||
|
MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -419,7 +423,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 +546,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 +560,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 +775,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||||||
OnClose();
|
OnClose();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default: return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1033,7 +1039,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;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#define IDD_INSTALL 100
|
#define IDD_INSTALL 100
|
||||||
|
|
||||||
#define IDT_EXTRACT_EXTRACT_TO 110
|
#define IDT_EXTRACT_EXTRACT_TO 110
|
||||||
#define IDE_EXTRACT_PATH 111
|
#define IDE_EXTRACT_PATH 111
|
||||||
|
|
||||||
#define IDT_CUR_FILE 113
|
#define IDT_CUR_FILE 113
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* SfxSetup.c - 7z SFX Setup
|
/* SfxSetup.c - 7z SFX Setup
|
||||||
2015-03-25 : Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "../../7zCrc.h"
|
#include "../../7zCrc.h"
|
||||||
#include "../../7zFile.h"
|
#include "../../7zFile.h"
|
||||||
#include "../../CpuArch.h"
|
#include "../../CpuArch.h"
|
||||||
|
#include "../../DllSecur.h"
|
||||||
|
|
||||||
#define k_EXE_ExtIndex 2
|
#define k_EXE_ExtIndex 2
|
||||||
|
|
||||||
@@ -88,7 +89,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 +145,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)
|
||||||
@@ -254,13 +255,15 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
Bool useShellExecute = True;
|
Bool useShellExecute = True;
|
||||||
DWORD exitCode = 0;
|
DWORD exitCode = 0;
|
||||||
|
|
||||||
|
LoadSecurityDlls();
|
||||||
|
|
||||||
#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();
|
||||||
@@ -396,11 +399,9 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t outSizeProcessed = 0;
|
size_t outSizeProcessed = 0;
|
||||||
size_t len;
|
|
||||||
WCHAR *temp;
|
WCHAR *temp;
|
||||||
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
|
||||||
|
|
||||||
if (len >= MAX_PATH)
|
if (SzArEx_GetFileNameUtf16(&db, i, NULL) >= MAX_PATH)
|
||||||
{
|
{
|
||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -187,6 +187,14 @@ SOURCE=..\..\Delta.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\DllSecur.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\DllSecur.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Lzma2Dec.c
|
SOURCE=..\..\Lzma2Dec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ C_OBJS = \
|
|||||||
$O\BraIA64.obj \
|
$O\BraIA64.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
$O\Delta.obj \
|
$O\Delta.obj \
|
||||||
|
$O\DllSecur.obj \
|
||||||
$O\Lzma2Dec.obj \
|
$O\Lzma2Dec.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ C_OBJS = \
|
|||||||
$O\BraIA64.obj \
|
$O\BraIA64.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
$O\Delta.obj \
|
$O\Delta.obj \
|
||||||
|
$O\DllSecur.obj \
|
||||||
$O\Lzma2Dec.obj \
|
$O\Lzma2Dec.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
|
|||||||
16
C/XzDec.c
16
C/XzDec.c
@@ -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++)
|
||||||
|
|||||||
65
C/XzEnc.c
65
C/XzEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzEnc.c -- Xz Encode
|
/* XzEnc.c -- Xz Encode
|
||||||
2015-05-01 : Igor Pavlov : Public domain */
|
2015-09-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "Alloc.h"
|
#include "Alloc.h"
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
#include "Bcj3Enc.c"
|
#include "Bcj3Enc.c"
|
||||||
#include "SbFind.c"
|
#include "SbFind.c"
|
||||||
@@ -34,7 +35,7 @@ static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UIn
|
|||||||
return WriteBytes(s, buf, size);
|
return WriteBytes(s, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
|
static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
|
||||||
{
|
{
|
||||||
UInt32 crc;
|
UInt32 crc;
|
||||||
Byte header[XZ_STREAM_HEADER_SIZE];
|
Byte header[XZ_STREAM_HEADER_SIZE];
|
||||||
@@ -46,7 +47,8 @@ SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
|
|||||||
return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE);
|
return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
|
|
||||||
|
static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
|
||||||
{
|
{
|
||||||
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
|
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
|
||||||
@@ -75,7 +77,8 @@ SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
|
|||||||
return WriteBytes(s, header, pos + 4);
|
return WriteBytes(s, header, pos + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
|
||||||
|
static SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
||||||
{
|
{
|
||||||
Byte buf[32];
|
Byte buf[32];
|
||||||
UInt64 globalPos;
|
UInt64 globalPos;
|
||||||
@@ -87,6 +90,7 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
|||||||
globalPos = pos;
|
globalPos = pos;
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
|
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
|
||||||
|
|
||||||
for (i = 0; i < p->numBlocks; i++)
|
for (i = 0; i < p->numBlocks; i++)
|
||||||
{
|
{
|
||||||
const CXzBlockSizes *block = &p->blocks[i];
|
const CXzBlockSizes *block = &p->blocks[i];
|
||||||
@@ -95,7 +99,9 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
|||||||
globalPos += pos;
|
globalPos += pos;
|
||||||
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
|
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = ((unsigned)globalPos & 3);
|
pos = ((unsigned)globalPos & 3);
|
||||||
|
|
||||||
if (pos != 0)
|
if (pos != 0)
|
||||||
{
|
{
|
||||||
buf[0] = buf[1] = buf[2] = 0;
|
buf[0] = buf[1] = buf[2] = 0;
|
||||||
@@ -120,34 +126,36 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
|
|
||||||
|
static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
if (p->blocks == 0 || p->numBlocksAllocated == p->numBlocks)
|
if (!p->blocks || p->numBlocksAllocated == p->numBlocks)
|
||||||
{
|
{
|
||||||
size_t num = (p->numBlocks + 1) * 2;
|
size_t num = p->numBlocks * 2 + 1;
|
||||||
size_t newSize = sizeof(CXzBlockSizes) * num;
|
size_t newSize = sizeof(CXzBlockSizes) * num;
|
||||||
CXzBlockSizes *blocks;
|
CXzBlockSizes *blocks;
|
||||||
if (newSize / sizeof(CXzBlockSizes) != num)
|
if (newSize / sizeof(CXzBlockSizes) != num)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize);
|
blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize);
|
||||||
if (blocks == 0)
|
if (!blocks)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
if (p->numBlocks != 0)
|
if (p->numBlocks != 0)
|
||||||
{
|
{
|
||||||
memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes));
|
memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes));
|
||||||
Xz_Free(p, alloc);
|
alloc->Free(alloc, p->blocks);
|
||||||
}
|
}
|
||||||
p->blocks = blocks;
|
p->blocks = blocks;
|
||||||
p->numBlocksAllocated = num;
|
p->numBlocksAllocated = num;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CXzBlockSizes *block = &p->blocks[p->numBlocks++];
|
CXzBlockSizes *block = &p->blocks[p->numBlocks++];
|
||||||
block->totalSize = totalSize;
|
|
||||||
block->unpackSize = unpackSize;
|
block->unpackSize = unpackSize;
|
||||||
|
block->totalSize = totalSize;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- CSeqCheckInStream ---------- */
|
/* ---------- CSeqCheckInStream ---------- */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -178,6 +186,7 @@ static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- CSeqSizeOutStream ---------- */
|
/* ---------- CSeqSizeOutStream ---------- */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -195,6 +204,7 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- CSeqInFilter ---------- */
|
/* ---------- CSeqInFilter ---------- */
|
||||||
|
|
||||||
#define FILTER_BUF_SIZE (1 << 20)
|
#define FILTER_BUF_SIZE (1 << 20)
|
||||||
@@ -217,6 +227,7 @@ static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
|
|||||||
if (sizeOriginal == 0)
|
if (sizeOriginal == 0)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!p->srcWasFinished && p->curPos == p->endPos)
|
if (!p->srcWasFinished && p->curPos == p->endPos)
|
||||||
@@ -274,6 +285,7 @@ static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- CSbEncInStream ---------- */
|
/* ---------- CSbEncInStream ---------- */
|
||||||
|
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
@@ -291,6 +303,7 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
|
|||||||
size_t sizeOriginal = *size;
|
size_t sizeOriginal = *size;
|
||||||
if (sizeOriginal == 0)
|
if (sizeOriginal == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (p->enc.needRead && !p->enc.readWasFinished)
|
if (p->enc.needRead && !p->enc.readWasFinished)
|
||||||
@@ -305,6 +318,7 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
|
|||||||
}
|
}
|
||||||
p->enc.needRead = False;
|
p->enc.needRead = False;
|
||||||
}
|
}
|
||||||
|
|
||||||
*size = sizeOriginal;
|
*size = sizeOriginal;
|
||||||
RINOK(SbEnc_Read(&p->enc, data, size));
|
RINOK(SbEnc_Read(&p->enc, data, size));
|
||||||
if (*size != 0 || !p->enc.needRead)
|
if (*size != 0 || !p->enc.needRead)
|
||||||
@@ -357,7 +371,7 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS
|
|||||||
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
|
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
|
||||||
{
|
{
|
||||||
p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc);
|
p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc);
|
||||||
if (p->lzma2 == 0)
|
if (!p->lzma2)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
@@ -375,10 +389,11 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XzProps_Init(CXzProps *p)
|
void XzProps_Init(CXzProps *p)
|
||||||
{
|
{
|
||||||
p->lzma2Props = 0;
|
p->lzma2Props = NULL;
|
||||||
p->filterProps = 0;
|
p->filterProps = NULL;
|
||||||
p->checkId = XZ_CHECK_CRC32;
|
p->checkId = XZ_CHECK_CRC32;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,10 +401,11 @@ void XzFilterProps_Init(CXzFilterProps *p)
|
|||||||
{
|
{
|
||||||
p->id = 0;
|
p->id = 0;
|
||||||
p->delta = 0;
|
p->delta = 0;
|
||||||
p->ip= 0;
|
p->ip = 0;
|
||||||
p->ipDefined = False;
|
p->ipDefined = False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
||||||
ISeqOutStream *outStream, ISeqInStream *inStream,
|
ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
const CXzProps *props, ICompressProgress *progress)
|
const CXzProps *props, ICompressProgress *progress)
|
||||||
@@ -415,6 +431,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
|||||||
filter = &block.filters[filterIndex++];
|
filter = &block.filters[filterIndex++];
|
||||||
filter->id = fp->id;
|
filter->id = fp->id;
|
||||||
filter->propsSize = 0;
|
filter->propsSize = 0;
|
||||||
|
|
||||||
if (fp->id == XZ_ID_Delta)
|
if (fp->id == XZ_ID_Delta)
|
||||||
{
|
{
|
||||||
filter->props[0] = (Byte)(fp->delta - 1);
|
filter->props[0] = (Byte)(fp->delta - 1);
|
||||||
@@ -462,14 +479,16 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
|||||||
|
|
||||||
{
|
{
|
||||||
UInt64 packPos = seqSizeOutStream.processed;
|
UInt64 packPos = seqSizeOutStream.processed;
|
||||||
|
|
||||||
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
||||||
fp ?
|
fp ?
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
(fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
|
(fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
|
||||||
#endif
|
#endif
|
||||||
&lzmaf->filter.p:
|
&lzmaf->filter.p:
|
||||||
&checkInStream.p,
|
&checkInStream.p,
|
||||||
progress);
|
progress);
|
||||||
|
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
block.unpackSize = checkInStream.processed;
|
block.unpackSize = checkInStream.processed;
|
||||||
block.packSize = seqSizeOutStream.processed - packPos;
|
block.packSize = seqSizeOutStream.processed - packPos;
|
||||||
@@ -478,7 +497,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
|||||||
{
|
{
|
||||||
unsigned padSize = 0;
|
unsigned padSize = 0;
|
||||||
Byte buf[128];
|
Byte buf[128];
|
||||||
while((((unsigned)block.packSize + padSize) & 3) != 0)
|
while ((((unsigned)block.packSize + padSize) & 3) != 0)
|
||||||
buf[padSize++] = 0;
|
buf[padSize++] = 0;
|
||||||
SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
|
SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
|
||||||
RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
|
RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
|
||||||
@@ -488,6 +507,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
|||||||
return Xz_WriteFooter(xz, outStream);
|
return Xz_WriteFooter(xz, outStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
const CXzProps *props, ICompressProgress *progress)
|
const CXzProps *props, ICompressProgress *progress)
|
||||||
{
|
{
|
||||||
@@ -504,6 +524,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes Xz_EncodeEmpty(ISeqOutStream *outStream)
|
SRes Xz_EncodeEmpty(ISeqOutStream *outStream)
|
||||||
{
|
{
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|||||||
5
C/XzIn.c
5
C/XzIn.c
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -301,6 +301,12 @@ HRESULT CDecoder::Decode(
|
|||||||
{
|
{
|
||||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||||
|
|
||||||
|
#ifndef _SFX
|
||||||
|
// we don't support RAR codecs here
|
||||||
|
if ((coderInfo.MethodID >> 8) == 0x403)
|
||||||
|
return E_NOTIMPL;
|
||||||
|
#endif
|
||||||
|
|
||||||
CCreatedCoder cod;
|
CCreatedCoder cod;
|
||||||
RINOK(CreateCoder(
|
RINOK(CreateCoder(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
@@ -398,11 +404,11 @@ HRESULT CDecoder::Decode(
|
|||||||
len = password.Len();
|
len = password.Len();
|
||||||
}
|
}
|
||||||
CByteBuffer buffer(len * 2);
|
CByteBuffer buffer(len * 2);
|
||||||
for (size_t i = 0; i < len; i++)
|
for (size_t k = 0; k < len; k++)
|
||||||
{
|
{
|
||||||
wchar_t c = passwordBSTR[i];
|
wchar_t c = passwordBSTR[k];
|
||||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
((Byte *)buffer)[k * 2] = (Byte)c;
|
||||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8);
|
||||||
}
|
}
|
||||||
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size()));
|
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,9 +148,9 @@ HRESULT CEncoder::CreateMixerCoder(
|
|||||||
|
|
||||||
RINOK(_mixer->SetBindInfo(_bindInfo));
|
RINOK(_mixer->SetBindInfo(_bindInfo));
|
||||||
|
|
||||||
FOR_VECTOR (i, _options.Methods)
|
FOR_VECTOR (m, _options.Methods)
|
||||||
{
|
{
|
||||||
const CMethodFull &methodFull = _options.Methods[i];
|
const CMethodFull &methodFull = _options.Methods[m];
|
||||||
|
|
||||||
CCreatedCoder cod;
|
CCreatedCoder cod;
|
||||||
|
|
||||||
@@ -410,9 +410,9 @@ HRESULT CEncoder::Encode(
|
|||||||
mtOutStreamNotifySpec->_stream = outStream;
|
mtOutStreamNotifySpec->_stream = outStream;
|
||||||
mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec;
|
mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec;
|
||||||
|
|
||||||
FOR_VECTOR(i, tempBufferSpecs)
|
FOR_VECTOR(t, tempBufferSpecs)
|
||||||
{
|
{
|
||||||
tempBufferSpecs[i]->_mtProgresSpec = mtProgressSpec;
|
tempBufferSpecs[t]->_mtProgresSpec = mtProgressSpec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,9 +591,9 @@ HRESULT CEncoder::EncoderConstr()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = _bindInfo.FindStream_in_PackStreams(outIndex);
|
int si = _bindInfo.FindStream_in_PackStreams(outIndex);
|
||||||
if (i >= 0)
|
if (si >= 0)
|
||||||
_bindInfo.PackStreams.MoveToFront(i);
|
_bindInfo.PackStreams.MoveToFront(si);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -311,13 +319,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
curUnpacked += _db.Files[k].Size;
|
curUnpacked += _db.Files[k].Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT result = folderOutStream->Init(fileIndex,
|
{
|
||||||
allFilesMode ? NULL : indices + i,
|
HRESULT result = folderOutStream->Init(fileIndex,
|
||||||
numSolidFiles);
|
allFilesMode ? NULL : indices + i,
|
||||||
|
numSolidFiles);
|
||||||
|
|
||||||
i += numSolidFiles;
|
i += numSolidFiles;
|
||||||
|
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
|
}
|
||||||
|
|
||||||
// to test solid block with zero unpacked size we disable that code
|
// to test solid block with zero unpacked size we disable that code
|
||||||
if (folderOutStream->WasWritingFinished())
|
if (folderOutStream->WasWritingFinished())
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
// 7zFolderOutStream.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
// 7zFolderOutStream.h
|
|
||||||
|
|
||||||
#ifndef __7Z_FOLDER_OUT_STREAM_H
|
|
||||||
#define __7Z_FOLDER_OUT_STREAM_H
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,11 +429,11 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
|||||||
name = "LZMA2";
|
name = "LZMA2";
|
||||||
if (propsSize == 1)
|
if (propsSize == 1)
|
||||||
{
|
{
|
||||||
Byte p = props[0];
|
Byte d = props[0];
|
||||||
if ((p & 1) == 0)
|
if ((d & 1) == 0)
|
||||||
ConvertUInt32ToString((UInt32)((p >> 1) + 12), s);
|
ConvertUInt32ToString((UInt32)((d >> 1) + 12), s);
|
||||||
else
|
else
|
||||||
GetStringForSizeValue(s, 3 << ((p >> 1) + 11));
|
GetStringForSizeValue(s, 3 << ((d >> 1) + 11));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (id == k_PPMD)
|
else if (id == k_PPMD)
|
||||||
@@ -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));
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ namespace N7z {
|
|||||||
#ifndef __7Z_SET_PROPERTIES
|
#ifndef __7Z_SET_PROPERTIES
|
||||||
|
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||||
#define __7Z_SET_PROPERTIES
|
#define __7Z_SET_PROPERTIES
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define __7Z_SET_PROPERTIES
|
#define __7Z_SET_PROPERTIES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -44,6 +44,7 @@ public:
|
|||||||
UInt64 _numSolidBytes;
|
UInt64 _numSolidBytes;
|
||||||
bool _numSolidBytesDefined;
|
bool _numSolidBytesDefined;
|
||||||
bool _solidExtension;
|
bool _solidExtension;
|
||||||
|
bool _useTypeSorting;
|
||||||
|
|
||||||
bool _compressHeaders;
|
bool _compressHeaders;
|
||||||
bool _encryptHeadersSpecified;
|
bool _encryptHeadersSpecified;
|
||||||
|
|||||||
@@ -282,7 +282,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
|
bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
|
||||||
bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
|
bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
|
||||||
bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
|
bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
|
||||||
if (db)
|
|
||||||
|
if (db && !db->Files.IsEmpty())
|
||||||
{
|
{
|
||||||
if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
|
if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
|
||||||
if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
|
if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
|
||||||
@@ -508,14 +509,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
if (ui.NewData)
|
if (ui.NewData)
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant prop;
|
ui.Size = 0;
|
||||||
RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
|
if (!ui.IsDir)
|
||||||
if (prop.vt != VT_UI8)
|
{
|
||||||
return E_INVALIDARG;
|
NCOM::CPropVariant prop;
|
||||||
ui.Size = (UInt64)prop.uhVal.QuadPart;
|
RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
|
||||||
if (ui.Size != 0 && ui.IsAnti)
|
if (prop.vt != VT_UI8)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
ui.Size = (UInt64)prop.uhVal.QuadPart;
|
||||||
|
if (ui.Size != 0 && ui.IsAnti)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateItems.Add(ui);
|
updateItems.Add(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,6 +619,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
options.NumSolidFiles = _numSolidFiles;
|
options.NumSolidFiles = _numSolidFiles;
|
||||||
options.NumSolidBytes = _numSolidBytes;
|
options.NumSolidBytes = _numSolidBytes;
|
||||||
options.SolidExtension = _solidExtension;
|
options.SolidExtension = _solidExtension;
|
||||||
|
options.UseTypeSorting = _useTypeSorting;
|
||||||
|
|
||||||
options.RemoveSfxBlock = _removeSfxBlock;
|
options.RemoveSfxBlock = _removeSfxBlock;
|
||||||
// options.VolumeMode = _volumeMode;
|
// options.VolumeMode = _volumeMode;
|
||||||
|
|
||||||
@@ -667,14 +675,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
|
static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
|
||||||
{
|
{
|
||||||
stream = 0;
|
stream = 0;
|
||||||
int index = ParseStringToUInt32(srcString, coder);
|
{
|
||||||
if (index == 0)
|
unsigned index = ParseStringToUInt32(srcString, coder);
|
||||||
return E_INVALIDARG;
|
if (index == 0)
|
||||||
srcString.DeleteFrontal(index);
|
return E_INVALIDARG;
|
||||||
|
srcString.DeleteFrontal(index);
|
||||||
|
}
|
||||||
if (srcString[0] == 's')
|
if (srcString[0] == 's')
|
||||||
{
|
{
|
||||||
srcString.Delete(0);
|
srcString.Delete(0);
|
||||||
int index = ParseStringToUInt32(srcString, stream);
|
unsigned index = ParseStringToUInt32(srcString, stream);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
srcString.DeleteFrontal(index);
|
srcString.DeleteFrontal(index);
|
||||||
@@ -701,6 +711,7 @@ void COutHandler::InitProps()
|
|||||||
// _volumeMode = false;
|
// _volumeMode = false;
|
||||||
|
|
||||||
InitSolid();
|
InitSolid();
|
||||||
|
_useTypeSorting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT COutHandler::SetSolidFromString(const UString &s)
|
HRESULT COutHandler::SetSolidFromString(const UString &s)
|
||||||
@@ -821,6 +832,8 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
|||||||
|
|
||||||
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
|
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
|
||||||
|
|
||||||
|
if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
|
||||||
|
|
||||||
// if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
|
// if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
|
||||||
}
|
}
|
||||||
return CMultiMethodProps::SetProperty(name, value);
|
return CMultiMethodProps::SetProperty(name, value);
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
|
|||||||
Byte external = archive->ReadByte();
|
Byte external = archive->ReadByte();
|
||||||
if (external != 0)
|
if (external != 0)
|
||||||
{
|
{
|
||||||
|
if (!dataVector)
|
||||||
|
ThrowIncorrect();
|
||||||
CNum dataIndex = archive->ReadNum();
|
CNum dataIndex = archive->ReadNum();
|
||||||
if (dataIndex >= dataVector->Size())
|
if (dataIndex >= dataVector->Size())
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
@@ -761,6 +763,8 @@ void CInArchive::ReadUnpackInfo(
|
|||||||
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
|
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
|
||||||
numCodersOutStreams += numCoders;
|
numCodersOutStreams += numCoders;
|
||||||
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
||||||
|
if (numPackStreams > folders.NumPackStreams - packStreamIndex)
|
||||||
|
ThrowIncorrect();
|
||||||
packStreamIndex += numPackStreams;
|
packStreamIndex += numPackStreams;
|
||||||
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
|
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
|
||||||
}
|
}
|
||||||
@@ -770,6 +774,8 @@ void CInArchive::ReadUnpackInfo(
|
|||||||
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
||||||
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
|
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
|
||||||
folders.CodersData.CopyFrom(startBufPtr, dataSize);
|
folders.CodersData.CopyFrom(startBufPtr, dataSize);
|
||||||
|
|
||||||
|
// if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitId(NID::kCodersUnpackSize);
|
WaitId(NID::kCodersUnpackSize);
|
||||||
@@ -1091,7 +1097,10 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
|
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
}
|
}
|
||||||
HeadersSize += folders.PackPositions[folders.NumPackStreams];
|
|
||||||
|
if (folders.PackPositions)
|
||||||
|
HeadersSize += folders.PackPositions[folders.NumPackStreams];
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1144,9 +1153,8 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
if (type == NID::kFilesInfo)
|
if (type == NID::kFilesInfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
CNum numFiles = ReadNum();
|
const CNum numFiles = ReadNum();
|
||||||
db.Files.ClearAndSetSize(numFiles);
|
db.Files.ClearAndSetSize(numFiles);
|
||||||
CNum i;
|
|
||||||
/*
|
/*
|
||||||
db.Files.Reserve(numFiles);
|
db.Files.Reserve(numFiles);
|
||||||
CNum i;
|
CNum i;
|
||||||
@@ -1168,8 +1176,8 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt64 type = ReadID();
|
const UInt64 type2 = ReadID();
|
||||||
if (type == NID::kEnd)
|
if (type2 == NID::kEnd)
|
||||||
break;
|
break;
|
||||||
UInt64 size = ReadNumber();
|
UInt64 size = ReadNumber();
|
||||||
if (size > _inByteBack->GetRem())
|
if (size > _inByteBack->GetRem())
|
||||||
@@ -1178,9 +1186,9 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true);
|
switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true);
|
||||||
bool addPropIdToList = true;
|
bool addPropIdToList = true;
|
||||||
bool isKnownType = true;
|
bool isKnownType = true;
|
||||||
if (type > ((UInt32)1 << 30))
|
if (type2 > ((UInt32)1 << 30))
|
||||||
isKnownType = false;
|
isKnownType = false;
|
||||||
else switch((UInt32)type)
|
else switch ((UInt32)type2)
|
||||||
{
|
{
|
||||||
case NID::kName:
|
case NID::kName:
|
||||||
{
|
{
|
||||||
@@ -1214,7 +1222,7 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
ReadBoolVector2(db.Files.Size(), boolVector);
|
ReadBoolVector2(db.Files.Size(), boolVector);
|
||||||
CStreamSwitch streamSwitch;
|
CStreamSwitch streamSwitch;
|
||||||
streamSwitch.Set(this, &dataVector);
|
streamSwitch.Set(this, &dataVector);
|
||||||
for (i = 0; i < numFiles; i++)
|
for (CNum i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
CFileItem &file = db.Files[i];
|
CFileItem &file = db.Files[i];
|
||||||
file.AttribDefined = boolVector[i];
|
file.AttribDefined = boolVector[i];
|
||||||
@@ -1257,7 +1265,7 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
{
|
{
|
||||||
ReadBoolVector(numFiles, emptyStreamVector);
|
ReadBoolVector(numFiles, emptyStreamVector);
|
||||||
numEmptyStreams = 0;
|
numEmptyStreams = 0;
|
||||||
for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
|
for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++)
|
||||||
if (emptyStreamVector[i])
|
if (emptyStreamVector[i])
|
||||||
numEmptyStreams++;
|
numEmptyStreams++;
|
||||||
|
|
||||||
@@ -1331,14 +1339,14 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
if (isKnownType)
|
if (isKnownType)
|
||||||
{
|
{
|
||||||
if (addPropIdToList)
|
if (addPropIdToList)
|
||||||
db.ArcInfo.FileInfoPopIDs.Add(type);
|
db.ArcInfo.FileInfoPopIDs.Add(type2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
db.UnsupportedFeatureWarning = true;
|
db.UnsupportedFeatureWarning = true;
|
||||||
_inByteBack->SkipRem();
|
_inByteBack->SkipRem();
|
||||||
}
|
}
|
||||||
// SkipData worked incorrectly in some versions before v4.59 (7zVer <= 00.02)
|
// SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02)
|
||||||
if (_inByteBack->GetRem() != 0)
|
if (_inByteBack->GetRem() != 0)
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
}
|
}
|
||||||
@@ -1352,6 +1360,9 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
CNum sizeIndex = 0;
|
CNum sizeIndex = 0;
|
||||||
|
|
||||||
CNum numAntiItems = 0;
|
CNum numAntiItems = 0;
|
||||||
|
|
||||||
|
CNum i;
|
||||||
|
|
||||||
for (i = 0; i < numEmptyStreams; i++)
|
for (i = 0; i < numEmptyStreams; i++)
|
||||||
if (antiFileVector[i])
|
if (antiFileVector[i])
|
||||||
numAntiItems++;
|
numAntiItems++;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -540,13 +540,13 @@ void COutArchive::WriteHeader(
|
|||||||
*/
|
*/
|
||||||
_useAlign = true;
|
_useAlign = true;
|
||||||
|
|
||||||
unsigned i;
|
{
|
||||||
|
UInt64 packSize = 0;
|
||||||
|
FOR_VECTOR (i, db.PackSizes)
|
||||||
|
packSize += db.PackSizes[i];
|
||||||
|
headerOffset = packSize;
|
||||||
|
}
|
||||||
|
|
||||||
UInt64 packedSize = 0;
|
|
||||||
for (i = 0; i < db.PackSizes.Size(); i++)
|
|
||||||
packedSize += db.PackSizes[i];
|
|
||||||
|
|
||||||
headerOffset = packedSize;
|
|
||||||
|
|
||||||
WriteByte(NID::kHeader);
|
WriteByte(NID::kHeader);
|
||||||
|
|
||||||
@@ -560,7 +560,7 @@ void COutArchive::WriteHeader(
|
|||||||
|
|
||||||
CRecordVector<UInt64> unpackSizes;
|
CRecordVector<UInt64> unpackSizes;
|
||||||
CUInt32DefVector digests;
|
CUInt32DefVector digests;
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
FOR_VECTOR (i, db.Files)
|
||||||
{
|
{
|
||||||
const CFileItem &file = db.Files[i];
|
const CFileItem &file = db.Files[i];
|
||||||
if (!file.HasStream)
|
if (!file.HasStream)
|
||||||
@@ -588,14 +588,17 @@ void COutArchive::WriteHeader(
|
|||||||
CBoolVector emptyStreamVector;
|
CBoolVector emptyStreamVector;
|
||||||
emptyStreamVector.ClearAndSetSize(db.Files.Size());
|
emptyStreamVector.ClearAndSetSize(db.Files.Size());
|
||||||
unsigned numEmptyStreams = 0;
|
unsigned numEmptyStreams = 0;
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
{
|
||||||
if (db.Files[i].HasStream)
|
FOR_VECTOR (i, db.Files)
|
||||||
emptyStreamVector[i] = false;
|
if (db.Files[i].HasStream)
|
||||||
else
|
emptyStreamVector[i] = false;
|
||||||
{
|
else
|
||||||
emptyStreamVector[i] = true;
|
{
|
||||||
numEmptyStreams++;
|
emptyStreamVector[i] = true;
|
||||||
}
|
numEmptyStreams++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (numEmptyStreams != 0)
|
if (numEmptyStreams != 0)
|
||||||
{
|
{
|
||||||
WritePropBoolVector(NID::kEmptyStream, emptyStreamVector);
|
WritePropBoolVector(NID::kEmptyStream, emptyStreamVector);
|
||||||
@@ -605,7 +608,8 @@ void COutArchive::WriteHeader(
|
|||||||
antiVector.ClearAndSetSize(numEmptyStreams);
|
antiVector.ClearAndSetSize(numEmptyStreams);
|
||||||
bool thereAreEmptyFiles = false, thereAreAntiItems = false;
|
bool thereAreEmptyFiles = false, thereAreAntiItems = false;
|
||||||
unsigned cur = 0;
|
unsigned cur = 0;
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
|
||||||
|
FOR_VECTOR (i, db.Files)
|
||||||
{
|
{
|
||||||
const CFileItem &file = db.Files[i];
|
const CFileItem &file = db.Files[i];
|
||||||
if (file.HasStream)
|
if (file.HasStream)
|
||||||
@@ -672,17 +676,21 @@ void COutArchive::WriteHeader(
|
|||||||
CBoolVector boolVector;
|
CBoolVector boolVector;
|
||||||
boolVector.ClearAndSetSize(db.Files.Size());
|
boolVector.ClearAndSetSize(db.Files.Size());
|
||||||
unsigned numDefined = 0;
|
unsigned numDefined = 0;
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
|
||||||
{
|
{
|
||||||
bool defined = db.Files[i].AttribDefined;
|
FOR_VECTOR (i, db.Files)
|
||||||
boolVector[i] = defined;
|
{
|
||||||
if (defined)
|
bool defined = db.Files[i].AttribDefined;
|
||||||
numDefined++;
|
boolVector[i] = defined;
|
||||||
|
if (defined)
|
||||||
|
numDefined++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numDefined != 0)
|
if (numDefined != 0)
|
||||||
{
|
{
|
||||||
WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
|
WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
FOR_VECTOR (i, db.Files)
|
||||||
{
|
{
|
||||||
const CFileItem &file = db.Files[i];
|
const CFileItem &file = db.Files[i];
|
||||||
if (file.AttribDefined)
|
if (file.AttribDefined)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace N7z {
|
|||||||
struct CPropMap
|
struct CPropMap
|
||||||
{
|
{
|
||||||
UInt32 FilePropID;
|
UInt32 FilePropID;
|
||||||
STATPROPSTG StatPROPSTG;
|
CStatProp StatProp;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const CPropMap kPropMap[] =
|
static const CPropMap kPropMap[] =
|
||||||
@@ -24,11 +24,11 @@ static const CPropMap kPropMap[] =
|
|||||||
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
|
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
|
||||||
|
|
||||||
#ifdef _MULTI_PACK
|
#ifdef _MULTI_PACK
|
||||||
{ 100, { L"Pack0", kpidPackedSize0, VT_UI8 } },
|
{ 100, { "Pack0", kpidPackedSize0, VT_UI8 } },
|
||||||
{ 101, { L"Pack1", kpidPackedSize1, VT_UI8 } },
|
{ 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
|
||||||
{ 102, { L"Pack2", kpidPackedSize2, VT_UI8 } },
|
{ 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
|
||||||
{ 103, { L"Pack3", kpidPackedSize3, VT_UI8 } },
|
{ 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
|
||||||
{ 104, { L"Pack4", kpidPackedSize4, VT_UI8 } },
|
{ 104, { "Pack4", kpidPackedSize4, VT_UI8 } },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
|
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
|
||||||
@@ -90,7 +90,7 @@ void CHandler::FillPopIDs()
|
|||||||
_fileInfoPopIDs.Clear();
|
_fileInfoPopIDs.Clear();
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
if(_volumes.Size() < 1)
|
if (_volumes.Size() < 1)
|
||||||
return;
|
return;
|
||||||
const CVolume &volume = _volumes.Front();
|
const CVolume &volume = _volumes.Front();
|
||||||
const CArchiveDatabaseEx &_db = volume.Database;
|
const CArchiveDatabaseEx &_db = volume.Database;
|
||||||
@@ -156,8 +156,8 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID,
|
|||||||
const CPropMap &pr = kPropMap[i];
|
const CPropMap &pr = kPropMap[i];
|
||||||
if (pr.FilePropID == id)
|
if (pr.FilePropID == id)
|
||||||
{
|
{
|
||||||
const STATPROPSTG &st = pr.StatPROPSTG;
|
const CStatProp &st = pr.StatProp;
|
||||||
*propID = st.propid;
|
*propID = st.PropID;
|
||||||
*varType = st.vt;
|
*varType = st.vt;
|
||||||
/*
|
/*
|
||||||
if (st.lpwstrName)
|
if (st.lpwstrName)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ struct CFilterMode
|
|||||||
{
|
{
|
||||||
if (Id == k_IA64)
|
if (Id == k_IA64)
|
||||||
Delta = 16;
|
Delta = 16;
|
||||||
else if (Id == k_ARM || Id == k_PPC || Id == k_PPC)
|
else if (Id == k_ARM || Id == k_PPC || Id == k_SPARC)
|
||||||
Delta = 4;
|
Delta = 4;
|
||||||
else if (Id == k_ARMT)
|
else if (Id == k_ARMT)
|
||||||
Delta = 2;
|
Delta = 2;
|
||||||
@@ -118,11 +118,11 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
|
|||||||
|
|
||||||
#define ELF_SIG 0x464C457F
|
#define ELF_SIG 0x464C457F
|
||||||
|
|
||||||
#define ELF_CLASS_32 1
|
#define ELF_CLASS_32 1
|
||||||
#define ELF_CLASS_64 2
|
#define ELF_CLASS_64 2
|
||||||
|
|
||||||
#define ELF_DATA_2LSB 1
|
#define ELF_DATA_2LSB 1
|
||||||
#define ELF_DATA_2MSB 2
|
#define ELF_DATA_2MSB 2
|
||||||
|
|
||||||
static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
|
static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
|
||||||
static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); }
|
static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); }
|
||||||
@@ -380,29 +380,33 @@ static inline bool IsExeFilter(CMethodId m)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned Get_FilterGroup_for_Folder(CRecordVector<CFilterMode2> &filters, const CFolderEx &f)
|
static unsigned Get_FilterGroup_for_Folder(
|
||||||
|
CRecordVector<CFilterMode2> &filters, const CFolderEx &f, bool extractFilter)
|
||||||
{
|
{
|
||||||
CFilterMode2 m;
|
CFilterMode2 m;
|
||||||
m.Id = 0;
|
m.Id = 0;
|
||||||
m.Delta = 0;
|
m.Delta = 0;
|
||||||
m.Encrypted = f.IsEncrypted();
|
m.Encrypted = f.IsEncrypted();
|
||||||
|
|
||||||
const CCoderInfo &coder = f.Coders[f.UnpackCoder];
|
if (extractFilter)
|
||||||
|
{
|
||||||
|
const CCoderInfo &coder = f.Coders[f.UnpackCoder];
|
||||||
|
|
||||||
if (coder.MethodID == k_Delta)
|
if (coder.MethodID == k_Delta)
|
||||||
{
|
|
||||||
if (coder.Props.Size() == 1)
|
|
||||||
{
|
{
|
||||||
m.Delta = (unsigned)coder.Props[0] + 1;
|
if (coder.Props.Size() == 1)
|
||||||
m.Id = k_Delta;
|
{
|
||||||
|
m.Delta = (unsigned)coder.Props[0] + 1;
|
||||||
|
m.Id = k_Delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsExeFilter(coder.MethodID))
|
||||||
|
{
|
||||||
|
m.Id = (UInt32)coder.MethodID;
|
||||||
|
if (m.Id == k_BCJ2)
|
||||||
|
m.Id = k_BCJ;
|
||||||
|
m.SetDelta();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (IsExeFilter(coder.MethodID))
|
|
||||||
{
|
|
||||||
m.Id = (UInt32)coder.MethodID;
|
|
||||||
if (m.Id == k_BCJ2)
|
|
||||||
m.Id = k_BCJ;
|
|
||||||
m.SetDelta();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetGroup(filters, m);
|
return GetGroup(filters, m);
|
||||||
@@ -554,11 +558,11 @@ static int CompareEmptyItems(const unsigned *p1, const unsigned *p2, void *param
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *g_Exts =
|
static const char *g_Exts =
|
||||||
" lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
|
" 7z xz lzma ace arc arj bz tbz bz2 tbz2 cab deb gz tgz ha lha lzh lzo lzx pak rar rpm sit zoo"
|
||||||
" zip jar ear war msi"
|
" zip jar ear war msi"
|
||||||
" 3gp avi mov mpeg mpg mpe wmv"
|
" 3gp avi mov mpeg mpg mpe wmv"
|
||||||
" aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
|
" aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
|
||||||
" swf "
|
" swf"
|
||||||
" chm hxi hxs"
|
" chm hxi hxs"
|
||||||
" gif jpeg jpg jp2 png tiff bmp ico psd psp"
|
" gif jpeg jpg jp2 png tiff bmp ico psd psp"
|
||||||
" awg ps eps cgm dxf svg vrml wmf emf ai md"
|
" awg ps eps cgm dxf svg vrml wmf emf ai md"
|
||||||
@@ -567,20 +571,23 @@ 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"
|
||||||
" mak clw csproj vcproj sln dsp dsw "
|
" sql manifest dep"
|
||||||
" class "
|
" mak clw csproj vcproj sln dsp dsw"
|
||||||
" bat cmd"
|
" class"
|
||||||
|
" 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"
|
||||||
" abf afm bdf fon mgf otf pcf pfa snf ttf"
|
" abf afm bdf fon mgf otf pcf pfa snf ttf"
|
||||||
" dbf mdb nsf ntf wdb db fdb gdb"
|
" dbf mdb nsf ntf wdb db fdb gdb"
|
||||||
" exe dll ocx vbx sfx sys tlb awx com obj lib out o so "
|
" exe dll ocx vbx sfx sys tlb awx com obj lib out o so"
|
||||||
" pdb pch idb ncb opt";
|
" pdb pch idb ncb opt";
|
||||||
|
|
||||||
static unsigned GetExtIndex(const char *ext)
|
static unsigned GetExtIndex(const char *ext)
|
||||||
@@ -772,7 +779,7 @@ struct CSolidGroup
|
|||||||
CRecordVector<CFolderRepack> folderRefs;
|
CRecordVector<CFolderRepack> folderRefs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *g_ExeExts[] =
|
static const char * const g_ExeExts[] =
|
||||||
{
|
{
|
||||||
"dll"
|
"dll"
|
||||||
, "exe"
|
, "exe"
|
||||||
@@ -1574,7 +1581,7 @@ HRESULT Update(
|
|||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UInt64 startBlockSize = db != 0 ? db->ArcInfo.StartPosition: 0;
|
UInt64 startBlockSize = db ? db->ArcInfo.StartPosition: 0;
|
||||||
if (startBlockSize > 0 && !options.RemoveSfxBlock)
|
if (startBlockSize > 0 && !options.RemoveSfxBlock)
|
||||||
{
|
{
|
||||||
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
|
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
|
||||||
@@ -1589,7 +1596,20 @@ HRESULT Update(
|
|||||||
CObjectVector<CSolidGroup> groups;
|
CObjectVector<CSolidGroup> groups;
|
||||||
bool thereAreRepacks = false;
|
bool thereAreRepacks = false;
|
||||||
|
|
||||||
if (db != 0)
|
bool useFilters = options.UseFilters;
|
||||||
|
if (useFilters)
|
||||||
|
{
|
||||||
|
const CCompressionMethodMode &method = *options.Method;
|
||||||
|
|
||||||
|
FOR_VECTOR (i, method.Methods)
|
||||||
|
if (IsFilterMethod(method.Methods[i].Id))
|
||||||
|
{
|
||||||
|
useFilters = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db)
|
||||||
{
|
{
|
||||||
fileIndexToUpdateIndexMap.Alloc(db->Files.Size());
|
fileIndexToUpdateIndexMap.Alloc(db->Files.Size());
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -1635,16 +1655,18 @@ HRESULT Update(
|
|||||||
CFolderEx f;
|
CFolderEx f;
|
||||||
db->ParseFolderEx(i, f);
|
db->ParseFolderEx(i, f);
|
||||||
|
|
||||||
bool isEncrypted = f.IsEncrypted();
|
const bool isEncrypted = f.IsEncrypted();
|
||||||
|
const bool needCopy = (numCopyItems == numUnpackStreams);
|
||||||
|
const bool extractFilter = (useFilters || needCopy);
|
||||||
|
|
||||||
unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f);
|
unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter);
|
||||||
|
|
||||||
while (groupIndex >= groups.Size())
|
while (groupIndex >= groups.Size())
|
||||||
groups.AddNew();
|
groups.AddNew();
|
||||||
|
|
||||||
groups[groupIndex].folderRefs.Add(rep);
|
groups[groupIndex].folderRefs.Add(rep);
|
||||||
|
|
||||||
if (numCopyItems == numUnpackStreams)
|
if (needCopy)
|
||||||
complexity += db->GetFolderFullPackSize(i);
|
complexity += db->GetFolderFullPackSize(i);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1659,17 +1681,18 @@ HRESULT Update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt64 inSizeForReduce = 0;
|
UInt64 inSizeForReduce = 0;
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < updateItems.Size(); i++)
|
|
||||||
{
|
{
|
||||||
const CUpdateItem &ui = updateItems[i];
|
FOR_VECTOR (i, updateItems)
|
||||||
if (ui.NewData)
|
|
||||||
{
|
{
|
||||||
complexity += ui.Size;
|
const CUpdateItem &ui = updateItems[i];
|
||||||
if (numSolidFiles != 1)
|
if (ui.NewData)
|
||||||
inSizeForReduce += ui.Size;
|
{
|
||||||
else if (inSizeForReduce < ui.Size)
|
complexity += ui.Size;
|
||||||
inSizeForReduce = ui.Size;
|
if (numSolidFiles != 1)
|
||||||
|
inSizeForReduce += ui.Size;
|
||||||
|
else if (inSizeForReduce < ui.Size)
|
||||||
|
inSizeForReduce = ui.Size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1729,23 +1752,9 @@ HRESULT Update(
|
|||||||
|
|
||||||
// ---------- Split files to groups ----------
|
// ---------- Split files to groups ----------
|
||||||
|
|
||||||
bool useFilters = options.UseFilters;
|
|
||||||
const CCompressionMethodMode &method = *options.Method;
|
const CCompressionMethodMode &method = *options.Method;
|
||||||
|
|
||||||
if (useFilters)
|
FOR_VECTOR (i, updateItems)
|
||||||
for (i = 0; i < method.Methods.Size(); i++)
|
|
||||||
if (IsFilterMethod(method.Methods[i].Id))
|
|
||||||
{
|
|
||||||
useFilters = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (!method.Bonds.IsEmpty())
|
|
||||||
useFilters = false;
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = 0; i < updateItems.Size(); i++)
|
|
||||||
{
|
{
|
||||||
const CUpdateItem &ui = updateItems[i];
|
const CUpdateItem &ui = updateItems[i];
|
||||||
if (!ui.NewData || !ui.HasStream())
|
if (!ui.NewData || !ui.HasStream())
|
||||||
@@ -1849,6 +1858,8 @@ HRESULT Update(
|
|||||||
/* ---------- Write non-AUX dirs and Empty files ---------- */
|
/* ---------- Write non-AUX dirs and Empty files ---------- */
|
||||||
CUIntVector emptyRefs;
|
CUIntVector emptyRefs;
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < updateItems.Size(); i++)
|
for (i = 0; i < updateItems.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &ui = updateItems[i];
|
const CUpdateItem &ui = updateItems[i];
|
||||||
@@ -1911,7 +1922,8 @@ HRESULT Update(
|
|||||||
const CFilterMode2 &filterMode = filters[groupIndex];
|
const CFilterMode2 &filterMode = filters[groupIndex];
|
||||||
|
|
||||||
CCompressionMethodMode method = *options.Method;
|
CCompressionMethodMode method = *options.Method;
|
||||||
HRESULT res = MakeExeMethod(method, filterMode,
|
{
|
||||||
|
HRESULT res = MakeExeMethod(method, filterMode,
|
||||||
#ifdef _7ZIP_ST
|
#ifdef _7ZIP_ST
|
||||||
false
|
false
|
||||||
#else
|
#else
|
||||||
@@ -1919,7 +1931,8 @@ HRESULT Update(
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
|
}
|
||||||
|
|
||||||
if (filterMode.Encrypted)
|
if (filterMode.Encrypted)
|
||||||
{
|
{
|
||||||
@@ -2153,7 +2166,13 @@ HRESULT Update(
|
|||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
if (options.MultiThreadMixer)
|
if (options.MultiThreadMixer)
|
||||||
{
|
{
|
||||||
|
// 16.00: hang was fixed : for case if decoding was not finished.
|
||||||
|
// We close CBinderInStream and it calls CStreamBinder::CloseRead()
|
||||||
|
inStreamSizeCount.Release();
|
||||||
|
sbInStream.Release();
|
||||||
|
|
||||||
threadDecoder.WaitExecuteFinish();
|
threadDecoder.WaitExecuteFinish();
|
||||||
|
|
||||||
HRESULT decodeRes = threadDecoder.Result;
|
HRESULT decodeRes = threadDecoder.Result;
|
||||||
// if (res == k_My_HRESULT_CRC_ERROR)
|
// if (res == k_My_HRESULT_CRC_ERROR)
|
||||||
if (decodeRes == S_FALSE)
|
if (decodeRes == S_FALSE)
|
||||||
@@ -2251,9 +2270,13 @@ HRESULT Update(
|
|||||||
continue;
|
continue;
|
||||||
CRecordVector<CRefItem> refItems;
|
CRecordVector<CRefItem> refItems;
|
||||||
refItems.ClearAndSetSize(numFiles);
|
refItems.ClearAndSetSize(numFiles);
|
||||||
bool sortByType = (numSolidFiles > 1);
|
bool sortByType = (options.UseTypeSorting && numSolidFiles > 1);
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < numFiles; i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType);
|
refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType);
|
||||||
|
|
||||||
CSortParam sortParam;
|
CSortParam sortParam;
|
||||||
// sortParam.TreeFolders = &treeFolders;
|
// sortParam.TreeFolders = &treeFolders;
|
||||||
sortParam.SortByType = sortByType;
|
sortParam.SortByType = sortByType;
|
||||||
|
|||||||
@@ -97,6 +97,9 @@ struct CUpdateOptions
|
|||||||
UInt64 NumSolidFiles;
|
UInt64 NumSolidFiles;
|
||||||
UInt64 NumSolidBytes;
|
UInt64 NumSolidBytes;
|
||||||
bool SolidExtension;
|
bool SolidExtension;
|
||||||
|
|
||||||
|
bool UseTypeSorting;
|
||||||
|
|
||||||
bool RemoveSfxBlock;
|
bool RemoveSfxBlock;
|
||||||
bool MultiThreadMixer;
|
bool MultiThreadMixer;
|
||||||
|
|
||||||
@@ -109,6 +112,7 @@ struct CUpdateOptions
|
|||||||
NumSolidFiles((UInt64)(Int64)(-1)),
|
NumSolidFiles((UInt64)(Int64)(-1)),
|
||||||
NumSolidBytes((UInt64)(Int64)(-1)),
|
NumSolidBytes((UInt64)(Int64)(-1)),
|
||||||
SolidExtension(false),
|
SolidExtension(false),
|
||||||
|
UseTypeSorting(true),
|
||||||
RemoveSfxBlock(false),
|
RemoveSfxBlock(false),
|
||||||
MultiThreadMixer(true)
|
MultiThreadMixer(true)
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
PROG = 7z.dll
|
PROG = 7z.dll
|
||||||
DEF_FILE = ../../Archive/Archive2.def
|
DEF_FILE = ../Archive.def
|
||||||
CFLAGS = $(CFLAGS) \
|
CFLAGS = $(CFLAGS) \
|
||||||
-DEXTERNAL_CODECS \
|
-DEXTERNAL_CODECS \
|
||||||
|
|
||||||
@@ -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 \
|
||||||
@@ -60,10 +59,11 @@ WIN_OBJS = \
|
|||||||
$O\StreamUtils.obj \
|
$O\StreamUtils.obj \
|
||||||
$O\VirtThread.obj \
|
$O\VirtThread.obj \
|
||||||
|
|
||||||
|
COMPRESS_OBJS = \
|
||||||
|
$O\CopyCoder.obj \
|
||||||
|
|
||||||
AR_COMMON_OBJS = \
|
AR_COMMON_OBJS = \
|
||||||
$O\CoderMixer2.obj \
|
$O\CoderMixer2.obj \
|
||||||
$O\CoderMixer2MT.obj \
|
|
||||||
$O\CrossThreadProgress.obj \
|
|
||||||
$O\HandlerOut.obj \
|
$O\HandlerOut.obj \
|
||||||
$O\InStreamWithCRC.obj \
|
$O\InStreamWithCRC.obj \
|
||||||
$O\ItemNameUtils.obj \
|
$O\ItemNameUtils.obj \
|
||||||
@@ -76,4 +76,6 @@ C_OBJS = \
|
|||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
$O\Threads.obj \
|
$O\Threads.obj \
|
||||||
|
|
||||||
|
!include "../../Crc.mak"
|
||||||
|
|
||||||
!include "../../7zip.mak"
|
!include "../../7zip.mak"
|
||||||
|
|||||||
@@ -7,16 +7,13 @@
|
|||||||
#include "../../Common/ComTry.h"
|
#include "../../Common/ComTry.h"
|
||||||
#include "../../Common/Defs.h"
|
#include "../../Common/Defs.h"
|
||||||
#include "../../Common/IntToString.h"
|
#include "../../Common/IntToString.h"
|
||||||
#include "../../Common/MyString.h"
|
|
||||||
|
|
||||||
#include "../../Windows/PropVariant.h"
|
#include "../../Windows/PropVariant.h"
|
||||||
|
|
||||||
#include "../Common/LimitedStreams.h"
|
|
||||||
#include "../Common/ProgressUtils.h"
|
|
||||||
#include "../Common/RegisterArc.h"
|
#include "../Common/RegisterArc.h"
|
||||||
#include "../Common/StreamUtils.h"
|
#include "../Common/StreamUtils.h"
|
||||||
|
|
||||||
#include "../Compress/CopyCoder.h"
|
#include "HandlerCont.h"
|
||||||
|
|
||||||
#define Get16(p) GetBe16(p)
|
#define Get16(p) GetBe16(p)
|
||||||
#define Get32(p) GetBe32(p)
|
#define Get32(p) GetBe32(p)
|
||||||
@@ -75,13 +72,9 @@ struct CItem
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CHandler:
|
class CHandler: public CHandlerCont
|
||||||
public IInArchive,
|
|
||||||
public IInArchiveGetStream,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
{
|
||||||
CRecordVector<CItem> _items;
|
CRecordVector<CItem> _items;
|
||||||
CMyComPtr<IInStream> _stream;
|
|
||||||
unsigned _blockSizeLog;
|
unsigned _blockSizeLog;
|
||||||
UInt32 _numBlocks;
|
UInt32 _numBlocks;
|
||||||
UInt64 _phySize;
|
UInt64 _phySize;
|
||||||
@@ -89,11 +82,17 @@ class CHandler:
|
|||||||
|
|
||||||
HRESULT ReadTables(IInStream *stream);
|
HRESULT ReadTables(IInStream *stream);
|
||||||
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
|
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
|
||||||
UInt64 GetItemSize(const CItem &item) const { return BlocksToBytes(item.NumBlocks); }
|
|
||||||
|
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
|
||||||
|
{
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
pos = BlocksToBytes(item.StartBlock);
|
||||||
|
size = BlocksToBytes(item.NumBlocks);
|
||||||
|
return NExtract::NOperationResult::kOK;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
|
INTERFACE_IInArchive_Cont(;)
|
||||||
INTERFACE_IInArchive(;)
|
|
||||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const UInt32 kSectorSize = 512;
|
static const UInt32 kSectorSize = 512;
|
||||||
@@ -300,7 +299,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
}
|
}
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
case kpidPackSize:
|
case kpidPackSize:
|
||||||
prop = GetItemSize(item);
|
prop = BlocksToBytes(item.NumBlocks);
|
||||||
break;
|
break;
|
||||||
case kpidOffset: prop = BlocksToBytes(item.StartBlock); break;
|
case kpidOffset: prop = BlocksToBytes(item.StartBlock); break;
|
||||||
}
|
}
|
||||||
@@ -309,73 +308,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|
||||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
|
||||||
if (allFilesMode)
|
|
||||||
numItems = _items.Size();
|
|
||||||
if (numItems == 0)
|
|
||||||
return S_OK;
|
|
||||||
UInt64 totalSize = 0;
|
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < numItems; i++)
|
|
||||||
totalSize += GetItemSize(_items[allFilesMode ? i : indices[i]]);
|
|
||||||
extractCallback->SetTotal(totalSize);
|
|
||||||
|
|
||||||
totalSize = 0;
|
|
||||||
|
|
||||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
|
||||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
|
||||||
|
|
||||||
CLocalProgress *lps = new CLocalProgress;
|
|
||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
|
||||||
lps->Init(extractCallback, false);
|
|
||||||
|
|
||||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
|
||||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
|
||||||
streamSpec->SetStream(_stream);
|
|
||||||
|
|
||||||
for (i = 0; i < numItems; i++)
|
|
||||||
{
|
|
||||||
lps->InSize = totalSize;
|
|
||||||
lps->OutSize = totalSize;
|
|
||||||
RINOK(lps->SetCur());
|
|
||||||
CMyComPtr<ISequentialOutStream> outStream;
|
|
||||||
Int32 askMode = testMode ?
|
|
||||||
NExtract::NAskMode::kTest :
|
|
||||||
NExtract::NAskMode::kExtract;
|
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
|
||||||
const CItem &item = _items[index];
|
|
||||||
|
|
||||||
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
|
||||||
UInt64 size = GetItemSize(item);
|
|
||||||
totalSize += size;
|
|
||||||
if (!testMode && !outStream)
|
|
||||||
continue;
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
|
||||||
|
|
||||||
RINOK(_stream->Seek(BlocksToBytes(item.StartBlock), STREAM_SEEK_SET, NULL));
|
|
||||||
streamSpec->Init(size);
|
|
||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
|
|
||||||
outStream.Release();
|
|
||||||
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == size ?
|
|
||||||
NExtract::NOperationResult::kOK:
|
|
||||||
NExtract::NOperationResult::kDataError));
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
const CItem &item = _items[index];
|
|
||||||
return CreateLimitedInStream(_stream, BlocksToBytes(item.StartBlock), GetItemSize(item), stream);
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
static const Byte k_Signature[] = { kSig0, kSig1 };
|
static const Byte k_Signature[] = { kSig0, kSig1 };
|
||||||
|
|
||||||
REGISTER_ARC_I(
|
REGISTER_ARC_I(
|
||||||
|
|||||||
@@ -343,16 +343,17 @@ HRESULT CHandler::ParseLongNames(IInStream *stream)
|
|||||||
if (item.Size > ((UInt32)1 << 30))
|
if (item.Size > ((UInt32)1 << 30))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
RINOK(stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL));
|
RINOK(stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL));
|
||||||
size_t size = (size_t)item.Size;
|
const size_t size = (size_t)item.Size;
|
||||||
|
|
||||||
CByteArr p(size);
|
CByteArr p(size);
|
||||||
RINOK(ReadStream_FALSE(stream, p, size));
|
RINOK(ReadStream_FALSE(stream, p, size));
|
||||||
|
|
||||||
for (i = 0; i < _items.Size(); i++)
|
for (i = 0; i < _items.Size(); i++)
|
||||||
{
|
{
|
||||||
CItem &item = _items[i];
|
CItem &item2 = _items[i];
|
||||||
if (item.Name[0] != '/')
|
if (item2.Name[0] != '/')
|
||||||
continue;
|
continue;
|
||||||
const char *ptr = item.Name.Ptr(1);
|
const char *ptr = item2.Name.Ptr(1);
|
||||||
const char *end;
|
const char *end;
|
||||||
UInt32 pos = ConvertStringToUInt32(ptr, &end);
|
UInt32 pos = ConvertStringToUInt32(ptr, &end);
|
||||||
if (*end != 0 || end == ptr)
|
if (*end != 0 || end == ptr)
|
||||||
@@ -369,8 +370,9 @@ HRESULT CHandler::ParseLongNames(IInStream *stream)
|
|||||||
break;
|
break;
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
item.Name.SetFrom((const char *)(p + start), pos - start);
|
item2.Name.SetFrom((const char *)(p + start), pos - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
_longNames_FileIndex = fileIndex;
|
_longNames_FileIndex = fileIndex;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,15 +29,24 @@ CCabBlockInStream::~CCabBlockInStream()
|
|||||||
static UInt32 CheckSum(const Byte *p, UInt32 size)
|
static UInt32 CheckSum(const Byte *p, UInt32 size)
|
||||||
{
|
{
|
||||||
UInt32 sum = 0;
|
UInt32 sum = 0;
|
||||||
for (UInt32 i = size >> 2; i != 0; i--)
|
|
||||||
|
for (; size >= 8; size -= 8)
|
||||||
|
{
|
||||||
|
sum ^= GetUi32(p) ^ GetUi32(p + 4);
|
||||||
|
p += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size >= 4)
|
||||||
{
|
{
|
||||||
sum ^= GetUi32(p);
|
sum ^= GetUi32(p);
|
||||||
p += 4;
|
p += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
size &= 3;
|
size &= 3;
|
||||||
if (size > 2) sum ^= (UInt32)(*p++) << 16;
|
if (size > 2) sum ^= (UInt32)(*p++) << 16;
|
||||||
if (size > 1) sum ^= (UInt32)(*p++) << 8;
|
if (size > 1) sum ^= (UInt32)(*p++) << 8;
|
||||||
if (size > 0) sum ^= (UInt32)(*p++);
|
if (size > 0) sum ^= (UInt32)(*p++);
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,16 @@ public:
|
|||||||
|
|
||||||
CCabBlockInStream(): _buf(0), ReservedSize(0), MsZip(false) {}
|
CCabBlockInStream(): _buf(0), ReservedSize(0), MsZip(false) {}
|
||||||
~CCabBlockInStream();
|
~CCabBlockInStream();
|
||||||
|
|
||||||
bool Create();
|
bool Create();
|
||||||
|
|
||||||
void InitForNewBlock() { _size = 0; _pos = 0; }
|
void InitForNewBlock() { _size = 0; _pos = 0; }
|
||||||
|
|
||||||
HRESULT PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize);
|
HRESULT PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize);
|
||||||
|
|
||||||
|
UInt32 GetPackSizeAvail() const { return _size - _pos; }
|
||||||
|
const Byte *GetData() const { return _buf + _pos; }
|
||||||
|
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
|
|
||||||
case kpidVolumeIndex:
|
case kpidVolumeIndex:
|
||||||
{
|
{
|
||||||
if (m_Database.Volumes.Size() == 1)
|
if (!m_Database.Volumes.IsEmpty())
|
||||||
{
|
{
|
||||||
const CDatabaseEx &db = m_Database.Volumes[0];
|
const CDatabaseEx &db = m_Database.Volumes[0];
|
||||||
const CInArcInfo &ai = db.ArcInfo;
|
const CInArcInfo &ai = db.ArcInfo;
|
||||||
@@ -348,15 +348,19 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
|
|
||||||
CMyComPtr<IInStream> nextStream = inStream;
|
CMyComPtr<IInStream> nextStream = inStream;
|
||||||
bool prevChecked = false;
|
bool prevChecked = false;
|
||||||
|
UString startVolName;
|
||||||
|
bool startVolName_was_Requested = false;
|
||||||
UInt64 numItems = 0;
|
UInt64 numItems = 0;
|
||||||
unsigned numTempVolumes = 0;
|
unsigned numTempVolumes = 0;
|
||||||
// try
|
// try
|
||||||
{
|
{
|
||||||
while (nextStream != NULL)
|
while (nextStream)
|
||||||
{
|
{
|
||||||
CDatabaseEx db;
|
CDatabaseEx db;
|
||||||
db.Stream = nextStream;
|
db.Stream = nextStream;
|
||||||
|
|
||||||
HRESULT res = archive.Open(db, maxCheckStartPosition);
|
HRESULT res = archive.Open(db, maxCheckStartPosition);
|
||||||
|
|
||||||
_errorInHeaders |= archive.HeaderError;
|
_errorInHeaders |= archive.HeaderError;
|
||||||
_errorInHeaders |= archive.ErrorInNames;
|
_errorInHeaders |= archive.ErrorInNames;
|
||||||
_unexpectedEnd |= archive.UnexpectedEnd;
|
_unexpectedEnd |= archive.UnexpectedEnd;
|
||||||
@@ -426,6 +430,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
const COtherArc *otherArc = NULL;
|
const COtherArc *otherArc = NULL;
|
||||||
|
|
||||||
if (!prevChecked)
|
if (!prevChecked)
|
||||||
{
|
{
|
||||||
if (numTempVolumes == 0)
|
if (numTempVolumes == 0)
|
||||||
@@ -449,18 +454,35 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!otherArc)
|
if (!otherArc)
|
||||||
{
|
{
|
||||||
const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo;
|
const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo;
|
||||||
if (ai.IsThereNext())
|
if (ai.IsThereNext())
|
||||||
otherArc = &ai.NextArc;
|
otherArc = &ai.NextArc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!otherArc)
|
if (!otherArc)
|
||||||
break;
|
break;
|
||||||
if (!openVolumeCallback)
|
if (!openVolumeCallback)
|
||||||
break;
|
break;
|
||||||
// printf("\n%s", otherArc->FileName);
|
// printf("\n%s", otherArc->FileName);
|
||||||
const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP);
|
const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP);
|
||||||
|
|
||||||
|
if (!startVolName_was_Requested)
|
||||||
|
{
|
||||||
|
// some "bad" cab example can contain the link to itself.
|
||||||
|
startVolName_was_Requested = true;
|
||||||
|
{
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
||||||
|
if (prop.vt == VT_BSTR)
|
||||||
|
startVolName = prop.bstrVal;
|
||||||
|
}
|
||||||
|
if (fullName == startVolName)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
|
HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
|
||||||
if (result == S_OK)
|
if (result == S_OK)
|
||||||
break;
|
break;
|
||||||
@@ -569,13 +591,15 @@ public:
|
|||||||
UInt64 folderSize,
|
UInt64 folderSize,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
bool testMode);
|
bool testMode);
|
||||||
HRESULT FlushCorrupted();
|
HRESULT FlushCorrupted(unsigned folderIndex);
|
||||||
HRESULT Unsupported();
|
HRESULT Unsupported();
|
||||||
|
|
||||||
|
bool NeedMoreWrite() const { return (m_FolderSize > m_PosInFolder); }
|
||||||
UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; }
|
UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; }
|
||||||
UInt64 GetPosInFolder() const { return m_PosInFolder; }
|
UInt64 GetPosInFolder() const { return m_PosInFolder; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void CFolderOutStream::Init(
|
void CFolderOutStream::Init(
|
||||||
const CMvDatabaseEx *database,
|
const CMvDatabaseEx *database,
|
||||||
const CRecordVector<bool> *extractStatuses,
|
const CRecordVector<bool> *extractStatuses,
|
||||||
@@ -600,6 +624,7 @@ void CFolderOutStream::Init(
|
|||||||
NumIdenticalFiles = 0;
|
NumIdenticalFiles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::CloseFileWithResOp(Int32 resOp)
|
HRESULT CFolderOutStream::CloseFileWithResOp(Int32 resOp)
|
||||||
{
|
{
|
||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
@@ -608,6 +633,7 @@ HRESULT CFolderOutStream::CloseFileWithResOp(Int32 resOp)
|
|||||||
return m_ExtractCallback->SetOperationResult(resOp);
|
return m_ExtractCallback->SetOperationResult(resOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::CloseFile()
|
HRESULT CFolderOutStream::CloseFile()
|
||||||
{
|
{
|
||||||
return CloseFileWithResOp(m_IsOk ?
|
return CloseFileWithResOp(m_IsOk ?
|
||||||
@@ -615,6 +641,7 @@ HRESULT CFolderOutStream::CloseFile()
|
|||||||
NExtract::NOperationResult::kDataError);
|
NExtract::NOperationResult::kDataError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::OpenFile()
|
HRESULT CFolderOutStream::OpenFile()
|
||||||
{
|
{
|
||||||
if (NumIdenticalFiles == 0)
|
if (NumIdenticalFiles == 0)
|
||||||
@@ -680,6 +707,7 @@ HRESULT CFolderOutStream::OpenFile()
|
|||||||
return m_ExtractCallback->PrepareOperation(askMode);
|
return m_ExtractCallback->PrepareOperation(askMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::WriteEmptyFiles()
|
HRESULT CFolderOutStream::WriteEmptyFiles()
|
||||||
{
|
{
|
||||||
if (m_FileIsOpen)
|
if (m_FileIsOpen)
|
||||||
@@ -699,13 +727,15 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is Write function
|
|
||||||
HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
|
HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
|
|
||||||
UInt32 realProcessed = 0;
|
UInt32 realProcessed = 0;
|
||||||
if (processedSize)
|
if (processedSize)
|
||||||
*processedSize = 0;
|
*processedSize = 0;
|
||||||
|
|
||||||
while (size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
if (m_FileIsOpen)
|
if (m_FileIsOpen)
|
||||||
@@ -732,8 +762,10 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
|||||||
size -= numBytesToWrite;
|
size -= numBytesToWrite;
|
||||||
m_RemainFileSize -= numBytesToWrite;
|
m_RemainFileSize -= numBytesToWrite;
|
||||||
m_PosInFolder += numBytesToWrite;
|
m_PosInFolder += numBytesToWrite;
|
||||||
|
|
||||||
if (res != S_OK)
|
if (res != S_OK)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (m_RemainFileSize == 0)
|
if (m_RemainFileSize == 0)
|
||||||
{
|
{
|
||||||
RINOK(CloseFile());
|
RINOK(CloseFile());
|
||||||
@@ -754,17 +786,28 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
|||||||
{
|
{
|
||||||
RINOK(CloseFile());
|
RINOK(CloseFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TempBufMode = false;
|
TempBufMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (realProcessed > 0)
|
if (realProcessed > 0)
|
||||||
break; // with this break this function works as Write-Part
|
break; // with this break this function works as Write-Part
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_CurrentIndex >= m_ExtractStatuses->Size())
|
if (m_CurrentIndex >= m_ExtractStatuses->Size())
|
||||||
return E_FAIL;
|
{
|
||||||
|
// we ignore extra data;
|
||||||
|
realProcessed += size;
|
||||||
|
if (processedSize)
|
||||||
|
*processedSize = realProcessed;
|
||||||
|
m_PosInFolder += size;
|
||||||
|
return S_OK;
|
||||||
|
// return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
|
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
|
||||||
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||||
@@ -772,8 +815,10 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
|||||||
m_RemainFileSize = item.Size;
|
m_RemainFileSize = item.Size;
|
||||||
|
|
||||||
UInt32 fileOffset = item.Offset;
|
UInt32 fileOffset = item.Offset;
|
||||||
|
|
||||||
if (fileOffset < m_PosInFolder)
|
if (fileOffset < m_PosInFolder)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
if (fileOffset > m_PosInFolder)
|
if (fileOffset > m_PosInFolder)
|
||||||
{
|
{
|
||||||
UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size);
|
UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size);
|
||||||
@@ -784,6 +829,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
|||||||
size -= numBytesToWrite;
|
size -= numBytesToWrite;
|
||||||
m_PosInFolder += numBytesToWrite;
|
m_PosInFolder += numBytesToWrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileOffset == m_PosInFolder)
|
if (fileOffset == m_PosInFolder)
|
||||||
{
|
{
|
||||||
RINOK(OpenFile());
|
RINOK(OpenFile());
|
||||||
@@ -793,32 +839,49 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteEmptyFiles();
|
return WriteEmptyFiles();
|
||||||
|
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
return Write2(data, size, processedSize, true);
|
return Write2(data, size, processedSize, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CFolderOutStream::FlushCorrupted()
|
|
||||||
|
HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
|
||||||
{
|
{
|
||||||
const unsigned kBufSize = (1 << 10);
|
if (!NeedMoreWrite())
|
||||||
|
{
|
||||||
|
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
|
||||||
|
m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
|
||||||
|
if (callbackMessage)
|
||||||
|
{
|
||||||
|
RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, NExtract::NOperationResult::kDataError));
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned kBufSize = (1 << 12);
|
||||||
Byte buf[kBufSize];
|
Byte buf[kBufSize];
|
||||||
for (unsigned i = 0; i < kBufSize; i++)
|
for (unsigned i = 0; i < kBufSize; i++)
|
||||||
buf[i] = 0;
|
buf[i] = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt64 remain = GetRemain();
|
if (!NeedMoreWrite())
|
||||||
if (remain == 0)
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
UInt64 remain = GetRemain();
|
||||||
UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize);
|
UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize);
|
||||||
UInt32 processedSizeLocal = 0;
|
UInt32 processedSizeLocal = 0;
|
||||||
RINOK(Write2(buf, size, &processedSizeLocal, false));
|
RINOK(Write2(buf, size, &processedSizeLocal, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT CFolderOutStream::Unsupported()
|
HRESULT CFolderOutStream::Unsupported()
|
||||||
{
|
{
|
||||||
while (m_CurrentIndex < m_ExtractStatuses->Size())
|
while (m_CurrentIndex < m_ExtractStatuses->Size())
|
||||||
@@ -838,6 +901,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
|
|
||||||
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = m_Database.Items.Size();
|
numItems = m_Database.Items.Size();
|
||||||
@@ -883,10 +947,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
CMyComPtr<ICompressCoder> deflateDecoder;
|
CMyComPtr<ICompressCoder> deflateDecoder;
|
||||||
|
|
||||||
NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL;
|
NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL;
|
||||||
CMyComPtr<ICompressCoder> lzxDecoder;
|
CMyComPtr<IUnknown> lzxDecoder;
|
||||||
|
|
||||||
NCompress::NQuantum::CDecoder *quantumDecoderSpec = NULL;
|
NCompress::NQuantum::CDecoder *quantumDecoderSpec = NULL;
|
||||||
CMyComPtr<ICompressCoder> quantumDecoder;
|
CMyComPtr<IUnknown> quantumDecoder;
|
||||||
|
|
||||||
CCabBlockInStream *cabBlockInStreamSpec = new CCabBlockInStream();
|
CCabBlockInStream *cabBlockInStreamSpec = new CCabBlockInStream();
|
||||||
CMyComPtr<ISequentialInStream> cabBlockInStream = cabBlockInStreamSpec;
|
CMyComPtr<ISequentialInStream> cabBlockInStream = cabBlockInStreamSpec;
|
||||||
@@ -895,8 +959,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];
|
||||||
@@ -946,11 +1017,11 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
for (; i < numItems; i++)
|
for (; i < numItems; i++)
|
||||||
{
|
{
|
||||||
unsigned indexNext = allFilesMode ? i : indices[i];
|
unsigned indexNext = allFilesMode ? i : indices[i];
|
||||||
const CMvItem &mvItem = m_Database.Items[indexNext];
|
const CMvItem &mvItem2 = m_Database.Items[indexNext];
|
||||||
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
const CItem &item2 = m_Database.Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex];
|
||||||
if (item.IsDir())
|
if (item2.IsDir())
|
||||||
continue;
|
continue;
|
||||||
int newFolderIndex = m_Database.GetFolderIndex(&mvItem);
|
int newFolderIndex = m_Database.GetFolderIndex(&mvItem2);
|
||||||
|
|
||||||
if (newFolderIndex != folderIndex)
|
if (newFolderIndex != folderIndex)
|
||||||
break;
|
break;
|
||||||
@@ -958,17 +1029,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
extractStatuses.Add(false);
|
extractStatuses.Add(false);
|
||||||
extractStatuses.Add(true);
|
extractStatuses.Add(true);
|
||||||
startIndex++;
|
startIndex++;
|
||||||
curUnpack = item.GetEndOffset();
|
curUnpack = item2.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);
|
||||||
|
|
||||||
const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
|
unsigned folderIndex2 = item.GetFolderIndex(db.Folders.Size());
|
||||||
|
const CFolder &folder = db.Folders[folderIndex2];
|
||||||
|
|
||||||
cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
|
cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
|
||||||
curUnpack, extractCallback, testMode);
|
curUnpack, extractCallback, testMode);
|
||||||
@@ -980,6 +1048,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
case NHeader::NMethod::kNone:
|
case NHeader::NMethod::kNone:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NHeader::NMethod::kMSZip:
|
case NHeader::NMethod::kMSZip:
|
||||||
if (!deflateDecoder)
|
if (!deflateDecoder)
|
||||||
{
|
{
|
||||||
@@ -988,14 +1057,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
cabBlockInStreamSpec->MsZip = true;
|
cabBlockInStreamSpec->MsZip = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NHeader::NMethod::kLZX:
|
case NHeader::NMethod::kLZX:
|
||||||
if (!lzxDecoder)
|
if (!lzxDecoder)
|
||||||
{
|
{
|
||||||
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
||||||
lzxDecoder = lzxDecoderSpec;
|
lzxDecoder = lzxDecoderSpec;
|
||||||
}
|
}
|
||||||
res = lzxDecoderSpec->SetParams(folder.MethodMinor);
|
res = lzxDecoderSpec->SetParams_and_Alloc(folder.MethodMinor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NHeader::NMethod::kQuantum:
|
case NHeader::NMethod::kQuantum:
|
||||||
if (!quantumDecoder)
|
if (!quantumDecoder)
|
||||||
{
|
{
|
||||||
@@ -1004,6 +1075,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
res = quantumDecoderSpec->SetParams(folder.MethodMinor);
|
res = quantumDecoderSpec->SetParams(folder.MethodMinor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
res = E_INVALIDARG;
|
res = E_INVALIDARG;
|
||||||
break;
|
break;
|
||||||
@@ -1022,8 +1094,9 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
int locFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
int locFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
||||||
bool keepHistory = false;
|
bool keepHistory = false;
|
||||||
bool keepInputBuffer = false;
|
bool keepInputBuffer = false;
|
||||||
|
bool thereWasNotAlignedChunk = false;
|
||||||
|
|
||||||
for (UInt32 bl = 0; cabFolderOutStream->GetRemain() != 0;)
|
for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();)
|
||||||
{
|
{
|
||||||
if (volIndex >= m_Database.Volumes.Size())
|
if (volIndex >= m_Database.Volumes.Size())
|
||||||
{
|
{
|
||||||
@@ -1031,16 +1104,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CDatabaseEx &db = m_Database.Volumes[volIndex];
|
const CDatabaseEx &db2 = m_Database.Volumes[volIndex];
|
||||||
const CFolder &folder = db.Folders[locFolderIndex];
|
const CFolder &folder2 = db2.Folders[locFolderIndex];
|
||||||
|
|
||||||
if (bl == 0)
|
if (bl == 0)
|
||||||
{
|
{
|
||||||
cabBlockInStreamSpec->ReservedSize = db.ArcInfo.GetDataBlockReserveSize();
|
cabBlockInStreamSpec->ReservedSize = db2.ArcInfo.GetDataBlockReserveSize();
|
||||||
RINOK(db.Stream->Seek(db.StartPosition + folder.DataStart, STREAM_SEEK_SET, NULL));
|
RINOK(db2.Stream->Seek(db2.StartPosition + folder2.DataStart, STREAM_SEEK_SET, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bl == folder.NumDataBlocks)
|
if (bl == folder2.NumDataBlocks)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 16-bit.
|
CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 16-bit.
|
||||||
@@ -1058,13 +1131,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bl++;
|
bl++;
|
||||||
|
|
||||||
if (!keepInputBuffer)
|
if (!keepInputBuffer)
|
||||||
cabBlockInStreamSpec->InitForNewBlock();
|
cabBlockInStreamSpec->InitForNewBlock();
|
||||||
|
|
||||||
UInt32 packSize, unpackSize;
|
UInt32 packSize, unpackSize;
|
||||||
res = cabBlockInStreamSpec->PreRead(db.Stream, packSize, unpackSize);
|
res = cabBlockInStreamSpec->PreRead(db2.Stream, packSize, unpackSize);
|
||||||
if (res == S_FALSE)
|
if (res == S_FALSE)
|
||||||
break;
|
break;
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
@@ -1079,19 +1153,39 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
lps->InSize = totalPacked;
|
lps->InSize = totalPacked;
|
||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
UInt64 unpackRemain = cabFolderOutStream->GetRemain();
|
|
||||||
|
|
||||||
const UInt32 kBlockSizeMax = (1 << 15);
|
const UInt32 kBlockSizeMax = (1 << 15);
|
||||||
if (unpackRemain > kBlockSizeMax)
|
|
||||||
unpackRemain = kBlockSizeMax;
|
|
||||||
if (unpackRemain > unpackSize)
|
|
||||||
unpackRemain = unpackSize;
|
|
||||||
|
|
||||||
switch (folder.GetMethod())
|
/* We don't try to reduce last block.
|
||||||
|
Note that LZX converts data with x86 filter.
|
||||||
|
and filter needs larger input data than reduced size.
|
||||||
|
It's simpler to decompress full chunk here.
|
||||||
|
also we need full block for quantum for more integrity checks */
|
||||||
|
|
||||||
|
if (unpackSize > kBlockSizeMax)
|
||||||
|
{
|
||||||
|
res = S_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unpackSize != kBlockSizeMax)
|
||||||
|
{
|
||||||
|
if (thereWasNotAlignedChunk)
|
||||||
|
{
|
||||||
|
res = S_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
thereWasNotAlignedChunk = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 unpackSize64 = unpackSize;
|
||||||
|
UInt32 packSizeChunk = cabBlockInStreamSpec->GetPackSizeAvail();
|
||||||
|
|
||||||
|
switch (folder2.GetMethod())
|
||||||
{
|
{
|
||||||
case NHeader::NMethod::kNone:
|
case NHeader::NMethod::kNone:
|
||||||
res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
|
res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackSize64, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NHeader::NMethod::kMSZip:
|
case NHeader::NMethod::kMSZip:
|
||||||
deflateDecoderSpec->Set_KeepHistory(keepHistory);
|
deflateDecoderSpec->Set_KeepHistory(keepHistory);
|
||||||
/* v9.31: now we follow MSZIP specification that requires to finish deflate stream at the end of each block.
|
/* v9.31: now we follow MSZIP specification that requires to finish deflate stream at the end of each block.
|
||||||
@@ -1100,7 +1194,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
Maybe we also should ignore that error?
|
Maybe we also should ignore that error?
|
||||||
Or we should extract full file and show the warning? */
|
Or we should extract full file and show the warning? */
|
||||||
deflateDecoderSpec->Set_NeedFinishInput(true);
|
deflateDecoderSpec->Set_NeedFinishInput(true);
|
||||||
res = deflateDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
|
res = deflateDecoder->Code(cabBlockInStream, outStream, NULL, &unpackSize64, NULL);
|
||||||
if (res == S_OK)
|
if (res == S_OK)
|
||||||
{
|
{
|
||||||
if (!deflateDecoderSpec->IsFinished())
|
if (!deflateDecoderSpec->IsFinished())
|
||||||
@@ -1108,16 +1202,24 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
if (!deflateDecoderSpec->IsFinalBlock())
|
if (!deflateDecoderSpec->IsFinalBlock())
|
||||||
res = S_FALSE;
|
res = S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NHeader::NMethod::kLZX:
|
case NHeader::NMethod::kLZX:
|
||||||
lzxDecoderSpec->SetKeepHistory(keepHistory);
|
lzxDecoderSpec->SetKeepHistory(keepHistory);
|
||||||
res = lzxDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
|
lzxDecoderSpec->KeepHistoryForNext = true;
|
||||||
|
|
||||||
|
res = lzxDecoderSpec->Code(cabBlockInStreamSpec->GetData(), packSizeChunk, unpackSize);
|
||||||
|
|
||||||
|
if (res == S_OK)
|
||||||
|
res = WriteStream(outStream,
|
||||||
|
lzxDecoderSpec->GetUnpackData(),
|
||||||
|
lzxDecoderSpec->GetUnpackSize());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NHeader::NMethod::kQuantum:
|
case NHeader::NMethod::kQuantum:
|
||||||
quantumDecoderSpec->SetKeepHistory(keepHistory);
|
res = quantumDecoderSpec->Code(cabBlockInStreamSpec->GetData(),
|
||||||
res = quantumDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
|
packSizeChunk, outStream, unpackSize, keepHistory);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res != S_OK)
|
if (res != S_OK)
|
||||||
@@ -1135,17 +1237,21 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
RINOK(cabFolderOutStream->WriteEmptyFiles());
|
RINOK(cabFolderOutStream->WriteEmptyFiles());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res != S_OK || cabFolderOutStream->GetRemain() != 0)
|
|
||||||
|
if (res != S_OK || cabFolderOutStream->NeedMoreWrite())
|
||||||
{
|
{
|
||||||
RINOK(cabFolderOutStream->FlushCorrupted());
|
RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2));
|
||||||
}
|
}
|
||||||
|
|
||||||
totalUnPacked += curUnpack;
|
totalUnPacked += curUnpack;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
{
|
{
|
||||||
*numItems = m_Database.Items.Size();
|
*numItems = m_Database.Items.Size();
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -101,9 +101,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
|
|
||||||
if (m_Database.NewFormat)
|
if (m_Database.NewFormat)
|
||||||
{
|
{
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
prop = (UInt64)m_Database.NewFormatString.Len();
|
prop = (UInt64)m_Database.NewFormatString.Len();
|
||||||
@@ -112,12 +113,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
int entryIndex;
|
|
||||||
|
unsigned entryIndex;
|
||||||
if (m_Database.LowLevel)
|
if (m_Database.LowLevel)
|
||||||
entryIndex = index;
|
entryIndex = index;
|
||||||
else
|
else
|
||||||
entryIndex = m_Database.Indices[index];
|
entryIndex = m_Database.Indices[index];
|
||||||
|
|
||||||
const CItem &item = m_Database.Items[entryIndex];
|
const CItem &item = m_Database.Items[entryIndex];
|
||||||
|
|
||||||
switch (propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidPath:
|
case kpidPath:
|
||||||
@@ -144,13 +148,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
if (item.Section == 0)
|
if (item.Section == 0)
|
||||||
prop = "Copy";
|
prop = "Copy";
|
||||||
else if (item.Section < m_Database.Sections.Size())
|
else if (item.Section < m_Database.Sections.Size())
|
||||||
prop = m_Database.Sections[(int)item.Section].GetMethodName();
|
prop = m_Database.Sections[(unsigned)item.Section].GetMethodName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidBlock:
|
case kpidBlock:
|
||||||
if (m_Database.LowLevel)
|
if (m_Database.LowLevel)
|
||||||
prop = item.Section;
|
prop = item.Section;
|
||||||
else if (item.Section != 0)
|
else if (item.Section != 0 && item.Section < m_Database.Sections.Size())
|
||||||
prop = m_Database.GetFolder(index);
|
prop = m_Database.GetFolder(index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -161,6 +165,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
@@ -244,9 +249,9 @@ public:
|
|||||||
UInt64 m_PosInFolder;
|
UInt64 m_PosInFolder;
|
||||||
UInt64 m_PosInSection;
|
UInt64 m_PosInSection;
|
||||||
const CRecordVector<bool> *m_ExtractStatuses;
|
const CRecordVector<bool> *m_ExtractStatuses;
|
||||||
int m_StartIndex;
|
unsigned m_StartIndex;
|
||||||
int m_CurrentIndex;
|
unsigned m_CurrentIndex;
|
||||||
int m_NumFiles;
|
unsigned m_NumFiles;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const CFilesDatabase *m_Database;
|
const CFilesDatabase *m_Database;
|
||||||
@@ -298,7 +303,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
|
|||||||
{
|
{
|
||||||
if (m_FileIsOpen)
|
if (m_FileIsOpen)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
for (;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
|
for (; m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
|
||||||
{
|
{
|
||||||
UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex);
|
UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex);
|
||||||
if (fileSize != 0)
|
if (fileSize != 0)
|
||||||
@@ -315,9 +320,10 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
|
|||||||
HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
|
HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
|
||||||
{
|
{
|
||||||
UInt32 realProcessed = 0;
|
UInt32 realProcessed = 0;
|
||||||
if (processedSize != NULL)
|
if (processedSize)
|
||||||
*processedSize = 0;
|
*processedSize = 0;
|
||||||
while(size != 0)
|
|
||||||
|
while (size != 0)
|
||||||
{
|
{
|
||||||
if (m_FileIsOpen)
|
if (m_FileIsOpen)
|
||||||
{
|
{
|
||||||
@@ -335,7 +341,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
realProcessed += numBytesToWrite;
|
realProcessed += numBytesToWrite;
|
||||||
if (processedSize != NULL)
|
if (processedSize)
|
||||||
*processedSize = realProcessed;
|
*processedSize = realProcessed;
|
||||||
data = (const void *)((const Byte *)data + numBytesToWrite);
|
data = (const void *)((const Byte *)data + numBytesToWrite);
|
||||||
size -= numBytesToWrite;
|
size -= numBytesToWrite;
|
||||||
@@ -359,23 +365,32 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_CurrentIndex >= m_NumFiles)
|
if (m_CurrentIndex >= m_NumFiles)
|
||||||
return E_FAIL;
|
{
|
||||||
int fullIndex = m_StartIndex + m_CurrentIndex;
|
realProcessed += size;
|
||||||
|
if (processedSize)
|
||||||
|
*processedSize = realProcessed;
|
||||||
|
return S_OK;
|
||||||
|
// return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned fullIndex = m_StartIndex + m_CurrentIndex;
|
||||||
m_RemainFileSize = m_Database->GetFileSize(fullIndex);
|
m_RemainFileSize = m_Database->GetFileSize(fullIndex);
|
||||||
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
|
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
|
||||||
if (fileOffset < m_PosInSection)
|
if (fileOffset < m_PosInSection)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
if (fileOffset > m_PosInSection)
|
if (fileOffset > m_PosInSection)
|
||||||
{
|
{
|
||||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileOffset - m_PosInSection, UInt64(size));
|
UInt32 numBytesToWrite = (UInt32)MyMin(fileOffset - m_PosInSection, UInt64(size));
|
||||||
realProcessed += numBytesToWrite;
|
realProcessed += numBytesToWrite;
|
||||||
if (processedSize != NULL)
|
if (processedSize)
|
||||||
*processedSize = realProcessed;
|
*processedSize = realProcessed;
|
||||||
data = (const void *)((const Byte *)data + numBytesToWrite);
|
data = (const void *)((const Byte *)data + numBytesToWrite);
|
||||||
size -= numBytesToWrite;
|
size -= numBytesToWrite;
|
||||||
m_PosInSection += numBytesToWrite;
|
m_PosInSection += numBytesToWrite;
|
||||||
m_PosInFolder += numBytesToWrite;
|
m_PosInFolder += numBytesToWrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileOffset == m_PosInSection)
|
if (fileOffset == m_PosInSection)
|
||||||
{
|
{
|
||||||
RINOK(OpenFile());
|
RINOK(OpenFile());
|
||||||
@@ -385,6 +400,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteEmptyFiles();
|
return WriteEmptyFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +413,7 @@ HRESULT CChmFolderOutStream::FlushCorrupted(UInt64 maxSize)
|
|||||||
{
|
{
|
||||||
const UInt32 kBufferSize = (1 << 10);
|
const UInt32 kBufferSize = (1 << 10);
|
||||||
Byte buffer[kBufferSize];
|
Byte buffer[kBufferSize];
|
||||||
for (int i = 0; i < kBufferSize; i++)
|
for (unsigned i = 0; i < kBufferSize; i++)
|
||||||
buffer[i] = 0;
|
buffer[i] = 0;
|
||||||
if (maxSize > m_FolderSize)
|
if (maxSize > m_FolderSize)
|
||||||
maxSize = m_FolderSize;
|
maxSize = m_FolderSize;
|
||||||
@@ -430,7 +446,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
|
|
||||||
UInt64 currentTotalSize = 0;
|
UInt64 currentTotalSize = 0;
|
||||||
|
|
||||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
|
|
||||||
@@ -446,11 +462,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
UInt64 currentItemSize = 0;
|
UInt64 currentItemSize = 0;
|
||||||
UInt64 totalSize = 0;
|
UInt64 totalSize = 0;
|
||||||
|
|
||||||
if (m_Database.NewFormat)
|
if (m_Database.NewFormat)
|
||||||
totalSize = m_Database.NewFormatString.Len();
|
totalSize = m_Database.NewFormatString.Len();
|
||||||
else
|
else
|
||||||
for (i = 0; i < numItems; i++)
|
for (i = 0; i < numItems; i++)
|
||||||
totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size;
|
totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size;
|
||||||
|
|
||||||
extractCallback->SetTotal(totalSize);
|
extractCallback->SetTotal(totalSize);
|
||||||
|
|
||||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||||
@@ -481,6 +499,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CItem &item = m_Database.Items[index];
|
const CItem &item = m_Database.Items[index];
|
||||||
|
|
||||||
currentItemSize = item.Size;
|
currentItemSize = item.Size;
|
||||||
@@ -513,12 +532,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt64 lastFolderIndex = ((UInt64)0 - 1);
|
UInt64 lastFolderIndex = ((UInt64)0 - 1);
|
||||||
|
|
||||||
for (i = 0; i < numItems; i++)
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
UInt32 index = allFilesMode ? i : indices[i];
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
int entryIndex = m_Database.Indices[index];
|
const CItem &item = m_Database.Items[m_Database.Indices[index]];
|
||||||
const CItem &item = m_Database.Items[entryIndex];
|
const UInt64 sectionIndex = item.Section;
|
||||||
UInt64 sectionIndex = item.Section;
|
|
||||||
if (item.IsDir() || item.Size == 0)
|
if (item.IsDir() || item.Size == 0)
|
||||||
continue;
|
continue;
|
||||||
if (sectionIndex == 0)
|
if (sectionIndex == 0)
|
||||||
@@ -526,7 +545,11 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
currentTotalSize += item.Size;
|
currentTotalSize += item.Size;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const CSectionInfo §ion = m_Database.Sections[(int)item.Section];
|
|
||||||
|
if (sectionIndex >= m_Database.Sections.Size())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const CSectionInfo §ion = m_Database.Sections[(unsigned)sectionIndex];
|
||||||
if (section.IsLzx())
|
if (section.IsLzx())
|
||||||
{
|
{
|
||||||
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
|
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
|
||||||
@@ -541,25 +564,32 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
|
|
||||||
RINOK(extractCallback->SetTotal(currentTotalSize));
|
RINOK(extractCallback->SetTotal(currentTotalSize));
|
||||||
|
|
||||||
NCompress::NLzx::CDecoder *lzxDecoderSpec = 0;
|
NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL;
|
||||||
CMyComPtr<ICompressCoder> lzxDecoder;
|
CMyComPtr<IUnknown> lzxDecoder;
|
||||||
CChmFolderOutStream *chmFolderOutStream = 0;
|
CChmFolderOutStream *chmFolderOutStream = 0;
|
||||||
CMyComPtr<ISequentialOutStream> outStream;
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
|
|
||||||
currentTotalSize = 0;
|
currentTotalSize = 0;
|
||||||
|
|
||||||
CRecordVector<bool> extractStatuses;
|
CRecordVector<bool> extractStatuses;
|
||||||
for (i = 0; i < numItems;)
|
|
||||||
|
CByteBuffer packBuf;
|
||||||
|
|
||||||
|
for (i = 0;;)
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||||
|
|
||||||
|
if (i >= numItems)
|
||||||
|
break;
|
||||||
|
|
||||||
UInt32 index = allFilesMode ? i : indices[i];
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
i++;
|
i++;
|
||||||
int entryIndex = m_Database.Indices[index];
|
const CItem &item = m_Database.Items[m_Database.Indices[index]];
|
||||||
const CItem &item = m_Database.Items[entryIndex];
|
const UInt64 sectionIndex = item.Section;
|
||||||
UInt64 sectionIndex = item.Section;
|
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode= testMode ?
|
||||||
NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
|
|
||||||
if (item.IsDir())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
@@ -595,7 +625,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CSectionInfo §ion = m_Database.Sections[(int)sectionIndex];
|
if (sectionIndex >= m_Database.Sections.Size())
|
||||||
|
{
|
||||||
|
// we must report error here;
|
||||||
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
if (!testMode && !realOutStream)
|
||||||
|
continue;
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kHeadersError));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CSectionInfo §ion = m_Database.Sections[(unsigned)sectionIndex];
|
||||||
|
|
||||||
if (!section.IsLzx())
|
if (!section.IsLzx())
|
||||||
{
|
{
|
||||||
@@ -610,7 +652,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
|
|
||||||
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
|
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
|
||||||
|
|
||||||
if (chmFolderOutStream == 0)
|
if (!chmFolderOutStream)
|
||||||
{
|
{
|
||||||
chmFolderOutStream = new CChmFolderOutStream;
|
chmFolderOutStream = new CChmFolderOutStream;
|
||||||
outStream = chmFolderOutStream;
|
outStream = chmFolderOutStream;
|
||||||
@@ -618,7 +660,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
|
|
||||||
chmFolderOutStream->Init(&m_Database, extractCallback, testMode);
|
chmFolderOutStream->Init(&m_Database, extractCallback, testMode);
|
||||||
|
|
||||||
if (lzxDecoderSpec == NULL)
|
if (!lzxDecoderSpec)
|
||||||
{
|
{
|
||||||
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
||||||
lzxDecoder = lzxDecoderSpec;
|
lzxDecoder = lzxDecoderSpec;
|
||||||
@@ -626,9 +668,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
|
|
||||||
UInt64 folderIndex = m_Database.GetFolder(index);
|
UInt64 folderIndex = m_Database.GetFolder(index);
|
||||||
|
|
||||||
UInt64 compressedPos = m_Database.ContentOffset + section.Offset;
|
const UInt64 compressedPos = m_Database.ContentOffset + section.Offset;
|
||||||
UInt32 numDictBits = lzxInfo.GetNumDictBits();
|
RINOK(lzxDecoderSpec->SetParams_and_Alloc(lzxInfo.GetNumDictBits()));
|
||||||
RINOK(lzxDecoderSpec->SetParams(numDictBits));
|
|
||||||
|
|
||||||
const CItem *lastItem = &item;
|
const CItem *lastItem = &item;
|
||||||
extractStatuses.Clear();
|
extractStatuses.Clear();
|
||||||
@@ -645,17 +686,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
lastFolderIndex = m_Database.GetLastFolder(index);
|
lastFolderIndex = m_Database.GetLastFolder(index);
|
||||||
UInt64 folderSize = lzxInfo.GetFolderSize();
|
UInt64 folderSize = lzxInfo.GetFolderSize();
|
||||||
UInt64 unPackSize = folderSize;
|
UInt64 unPackSize = folderSize;
|
||||||
|
|
||||||
if (extractStatuses.IsEmpty())
|
if (extractStatuses.IsEmpty())
|
||||||
chmFolderOutStream->m_StartIndex = index + 1;
|
chmFolderOutStream->m_StartIndex = index + 1;
|
||||||
else
|
else
|
||||||
chmFolderOutStream->m_StartIndex = index;
|
chmFolderOutStream->m_StartIndex = index;
|
||||||
|
|
||||||
if (limitFolderIndex == folderIndex)
|
if (limitFolderIndex == folderIndex)
|
||||||
{
|
{
|
||||||
for (; i < numItems; i++)
|
for (; i < numItems; i++)
|
||||||
{
|
{
|
||||||
UInt32 nextIndex = allFilesMode ? i : indices[i];
|
const UInt32 nextIndex = allFilesMode ? i : indices[i];
|
||||||
int entryIndex = m_Database.Indices[nextIndex];
|
const CItem &nextItem = m_Database.Items[m_Database.Indices[nextIndex]];
|
||||||
const CItem &nextItem = m_Database.Items[entryIndex];
|
|
||||||
if (nextItem.Section != sectionIndex)
|
if (nextItem.Section != sectionIndex)
|
||||||
break;
|
break;
|
||||||
UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex);
|
UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex);
|
||||||
@@ -671,6 +713,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
lastFolderIndex = m_Database.GetLastFolder(index);
|
lastFolderIndex = m_Database.GetLastFolder(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unPackSize = MyMin(finishPos - startPos, unPackSize);
|
unPackSize = MyMin(finishPos - startPos, unPackSize);
|
||||||
|
|
||||||
chmFolderOutStream->m_FolderSize = folderSize;
|
chmFolderOutStream->m_FolderSize = folderSize;
|
||||||
@@ -679,11 +722,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
chmFolderOutStream->m_ExtractStatuses = &extractStatuses;
|
chmFolderOutStream->m_ExtractStatuses = &extractStatuses;
|
||||||
chmFolderOutStream->m_NumFiles = extractStatuses.Size();
|
chmFolderOutStream->m_NumFiles = extractStatuses.Size();
|
||||||
chmFolderOutStream->m_CurrentIndex = 0;
|
chmFolderOutStream->m_CurrentIndex = 0;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex);
|
UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex);
|
||||||
const CResetTable &rt = lzxInfo.ResetTable;
|
const CResetTable &rt = lzxInfo.ResetTable;
|
||||||
UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize);
|
UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize);
|
||||||
|
|
||||||
for (UInt32 b = 0; b < numBlocks; b++)
|
for (UInt32 b = 0; b < numBlocks; b++)
|
||||||
{
|
{
|
||||||
UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos;
|
UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos;
|
||||||
@@ -691,17 +736,35 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
UInt64 bCur = startBlock + b;
|
UInt64 bCur = startBlock + b;
|
||||||
if (bCur >= rt.ResetOffsets.Size())
|
if (bCur >= rt.ResetOffsets.Size())
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
UInt64 offset = rt.ResetOffsets[(int)bCur];
|
UInt64 offset = rt.ResetOffsets[(unsigned)bCur];
|
||||||
UInt64 compressedSize;
|
UInt64 compressedSize;
|
||||||
rt.GetCompressedSizeOfBlock(bCur, compressedSize);
|
rt.GetCompressedSizeOfBlock(bCur, compressedSize);
|
||||||
UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection;
|
|
||||||
if (rem > rt.BlockSize)
|
// chm writes full blocks. So we don't need to use reduced size for last block
|
||||||
rem = rt.BlockSize;
|
|
||||||
RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL));
|
RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL));
|
||||||
streamSpec->SetStream(m_Stream);
|
streamSpec->SetStream(m_Stream);
|
||||||
streamSpec->Init(compressedSize);
|
streamSpec->Init(compressedSize);
|
||||||
|
|
||||||
lzxDecoderSpec->SetKeepHistory(b > 0);
|
lzxDecoderSpec->SetKeepHistory(b > 0);
|
||||||
HRESULT res = lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL);
|
|
||||||
|
size_t compressedSizeT = (size_t)compressedSize;
|
||||||
|
if (compressedSizeT != compressedSize)
|
||||||
|
throw 2;
|
||||||
|
packBuf.AllocAtLeast(compressedSizeT);
|
||||||
|
|
||||||
|
HRESULT res = ReadStream_FALSE(inStream, packBuf, compressedSizeT);
|
||||||
|
|
||||||
|
if (res == S_OK)
|
||||||
|
{
|
||||||
|
lzxDecoderSpec->KeepHistoryForNext = true;
|
||||||
|
res = lzxDecoderSpec->Code(packBuf, compressedSizeT, kBlockSize); // rt.BlockSize;
|
||||||
|
if (res == S_OK)
|
||||||
|
res = WriteStream(chmFolderOutStream,
|
||||||
|
lzxDecoderSpec->GetUnpackData(),
|
||||||
|
lzxDecoderSpec->GetUnpackSize());
|
||||||
|
}
|
||||||
|
|
||||||
if (res != S_OK)
|
if (res != S_OK)
|
||||||
{
|
{
|
||||||
if (res != S_FALSE)
|
if (res != S_FALSE)
|
||||||
@@ -714,6 +777,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
RINOK(chmFolderOutStream->FlushCorrupted(unPackSize));
|
RINOK(chmFolderOutStream->FlushCorrupted(unPackSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTotalSize += folderSize;
|
currentTotalSize += folderSize;
|
||||||
if (folderIndex == lastFolderIndex)
|
if (folderIndex == lastFolderIndex)
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
// #include <stdio.h>
|
// #include <stdio.h>
|
||||||
|
|
||||||
|
#include "../../../../C/CpuArch.h"
|
||||||
|
|
||||||
#include "../../../Common/IntToString.h"
|
#include "../../../Common/IntToString.h"
|
||||||
#include "../../../Common/UTFConvert.h"
|
#include "../../../Common/UTFConvert.h"
|
||||||
|
|
||||||
@@ -11,6 +13,10 @@
|
|||||||
|
|
||||||
#include "ChmIn.h"
|
#include "ChmIn.h"
|
||||||
|
|
||||||
|
#define Get16(p) GetUi16(p)
|
||||||
|
#define Get32(p) GetUi32(p)
|
||||||
|
#define Get64(p) GetUi64(p)
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NChm {
|
namespace NChm {
|
||||||
|
|
||||||
@@ -168,38 +174,36 @@ Byte CInArchive::ReadByte()
|
|||||||
|
|
||||||
void CInArchive::Skip(size_t size)
|
void CInArchive::Skip(size_t size)
|
||||||
{
|
{
|
||||||
while (size-- != 0)
|
if (_inBuffer.Skip(size) != size)
|
||||||
ReadByte();
|
throw CEnexpectedEndException();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInArchive::ReadBytes(Byte *data, UInt32 size)
|
void CInArchive::ReadBytes(Byte *data, UInt32 size)
|
||||||
{
|
{
|
||||||
for (UInt32 i = 0; i < size; i++)
|
if (_inBuffer.ReadBytes(data, size) != size)
|
||||||
data[i] = ReadByte();
|
throw CEnexpectedEndException();
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt16 CInArchive::ReadUInt16()
|
UInt16 CInArchive::ReadUInt16()
|
||||||
{
|
{
|
||||||
UInt16 val = 0;
|
Byte b0, b1;
|
||||||
for (int i = 0; i < 2; i++)
|
if (!_inBuffer.ReadByte(b0)) throw CEnexpectedEndException();
|
||||||
val |= ((UInt16)(ReadByte()) << (8 * i));
|
if (!_inBuffer.ReadByte(b1)) throw CEnexpectedEndException();
|
||||||
return val;
|
return (UInt16)(((UInt16)b1 << 8) | b0);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 CInArchive::ReadUInt32()
|
UInt32 CInArchive::ReadUInt32()
|
||||||
{
|
{
|
||||||
UInt32 val = 0;
|
Byte p[4];
|
||||||
for (int i = 0; i < 4; i++)
|
ReadBytes(p, 4);
|
||||||
val |= ((UInt32)(ReadByte()) << (8 * i));
|
return Get32(p);
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 CInArchive::ReadUInt64()
|
UInt64 CInArchive::ReadUInt64()
|
||||||
{
|
{
|
||||||
UInt64 val = 0;
|
Byte p[8];
|
||||||
for (int i = 0; i < 8; i++)
|
ReadBytes(p, 8);
|
||||||
val |= ((UInt64)(ReadByte()) << (8 * i));
|
return Get64(p);
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 CInArchive::ReadEncInt()
|
UInt64 CInArchive::ReadEncInt()
|
||||||
@@ -227,15 +231,10 @@ void CInArchive::ReadGUID(GUID &g)
|
|||||||
void CInArchive::ReadString(unsigned size, AString &s)
|
void CInArchive::ReadString(unsigned size, AString &s)
|
||||||
{
|
{
|
||||||
s.Empty();
|
s.Empty();
|
||||||
while (size-- != 0)
|
if (size != 0)
|
||||||
{
|
{
|
||||||
char c = (char)ReadByte();
|
ReadBytes((Byte *)s.GetBuf(size), size);
|
||||||
if (c == 0)
|
s.ReleaseBuf_CalcLen(size);
|
||||||
{
|
|
||||||
Skip(size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
s += c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,6 +379,7 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
|
|||||||
ReadUInt32(); // Chunk number of next listing chunk when reading
|
ReadUInt32(); // Chunk number of next listing chunk when reading
|
||||||
// directory in sequence (-1 if this is the last listing chunk)
|
// directory in sequence (-1 if this is the last listing chunk)
|
||||||
unsigned numItems = 0;
|
unsigned numItems = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
|
UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
|
||||||
@@ -391,9 +391,16 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
|
|||||||
RINOK(ReadDirEntry(database));
|
RINOK(ReadDirEntry(database));
|
||||||
numItems++;
|
numItems++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Skip(quickrefLength - 2);
|
Skip(quickrefLength - 2);
|
||||||
if (ReadUInt16() != numItems)
|
|
||||||
return S_FALSE;
|
unsigned rrr = ReadUInt16();
|
||||||
|
if (rrr != numItems)
|
||||||
|
{
|
||||||
|
// Lazarus 9-26-2 chm contains 0 here.
|
||||||
|
if (rrr != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Skip(dirChunkSize - 4);
|
Skip(dirChunkSize - 4);
|
||||||
@@ -649,7 +656,7 @@ static AString GetSectionPrefix(const AString &name)
|
|||||||
|
|
||||||
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
||||||
|
|
||||||
static int CompareFiles(const int *p1, const int *p2, void *param)
|
static int CompareFiles(const unsigned *p1, const unsigned *p2, void *param)
|
||||||
{
|
{
|
||||||
const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param;
|
const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param;
|
||||||
const CItem &item1 = items[*p1];
|
const CItem &item1 = items[*p1];
|
||||||
@@ -660,13 +667,15 @@ static int CompareFiles(const int *p1, const int *p2, void *param)
|
|||||||
return -1;
|
return -1;
|
||||||
if (isDir2)
|
if (isDir2)
|
||||||
{
|
{
|
||||||
if (isDir1)
|
if (!isDir1)
|
||||||
return MyCompare(*p1, *p2);
|
return 1;
|
||||||
return 1;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RINOZ(MyCompare(item1.Section, item2.Section));
|
||||||
|
RINOZ(MyCompare(item1.Offset, item2.Offset));
|
||||||
|
RINOZ(MyCompare(item1.Size, item2.Size));
|
||||||
}
|
}
|
||||||
RINOZ(MyCompare(item1.Section, item2.Section));
|
|
||||||
RINOZ(MyCompare(item1.Offset, item2.Offset));
|
|
||||||
RINOZ(MyCompare(item1.Size, item2.Size));
|
|
||||||
return MyCompare(*p1, *p2);
|
return MyCompare(*p1, *p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,6 +718,27 @@ bool CFilesDatabase::Check()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CFilesDatabase::CheckSectionRefs()
|
||||||
|
{
|
||||||
|
FOR_VECTOR (i, Indices)
|
||||||
|
{
|
||||||
|
const CItem &item = Items[Indices[i]];
|
||||||
|
if (item.Section == 0 || item.IsDir())
|
||||||
|
continue;
|
||||||
|
if (item.Section >= Sections.Size())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int inline GetLog(UInt32 num)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
if (((UInt32)1 << i) == num)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -716,7 +746,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
|||||||
RINOK(DecompressStream(inStream, database, kNameList));
|
RINOK(DecompressStream(inStream, database, kNameList));
|
||||||
/* UInt16 length = */ ReadUInt16();
|
/* UInt16 length = */ ReadUInt16();
|
||||||
UInt16 numSections = ReadUInt16();
|
UInt16 numSections = ReadUInt16();
|
||||||
for (int i = 0; i < numSections; i++)
|
for (unsigned i = 0; i < numSections; i++)
|
||||||
{
|
{
|
||||||
CSectionInfo section;
|
CSectionInfo section;
|
||||||
UInt16 nameLen = ReadUInt16();
|
UInt16 nameLen = ReadUInt16();
|
||||||
@@ -730,10 +760,10 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned i;
|
unsigned si;
|
||||||
for (i = 1; i < database.Sections.Size(); i++)
|
for (si = 1; si < database.Sections.Size(); si++)
|
||||||
{
|
{
|
||||||
CSectionInfo §ion = database.Sections[i];
|
CSectionInfo §ion = database.Sections[si];
|
||||||
AString sectionPrefix = GetSectionPrefix(section.Name);
|
AString sectionPrefix = GetSectionPrefix(section.Name);
|
||||||
{
|
{
|
||||||
// Content
|
// Content
|
||||||
@@ -751,10 +781,10 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
|||||||
RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList));
|
RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList));
|
||||||
if ((_chunkSize & 0xF) != 0)
|
if ((_chunkSize & 0xF) != 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
int numGuids = (int)(_chunkSize / 0x10);
|
unsigned numGuids = (unsigned)(_chunkSize / 0x10);
|
||||||
if (numGuids < 1)
|
if (numGuids < 1)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
for (int i = 0; i < numGuids; i++)
|
for (unsigned i = 0; i < numGuids; i++)
|
||||||
{
|
{
|
||||||
CMethodInfo method;
|
CMethodInfo method;
|
||||||
ReadGUID(method.Guid);
|
ReadGUID(method.Guid);
|
||||||
@@ -771,6 +801,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
|||||||
{
|
{
|
||||||
// Control Data
|
// Control Data
|
||||||
RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData));
|
RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData));
|
||||||
|
|
||||||
FOR_VECTOR (mi, section.Methods)
|
FOR_VECTOR (mi, section.Methods)
|
||||||
{
|
{
|
||||||
CMethodInfo &method = section.Methods[mi];
|
CMethodInfo &method = section.Methods[mi];
|
||||||
@@ -785,27 +816,25 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
|||||||
li.Version = ReadUInt32();
|
li.Version = ReadUInt32();
|
||||||
if (li.Version != 2 && li.Version != 3)
|
if (li.Version != 2 && li.Version != 3)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
li.ResetInterval = ReadUInt32();
|
|
||||||
li.WindowSize = ReadUInt32();
|
{
|
||||||
|
// There is bug in VC6, if we use function call as parameter for inline function
|
||||||
|
UInt32 val32 = ReadUInt32();
|
||||||
|
int n = GetLog(val32);
|
||||||
|
if (n < 0 || n > 16)
|
||||||
|
return S_FALSE;
|
||||||
|
li.ResetIntervalBits = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt32 val32 = ReadUInt32();
|
||||||
|
int n = GetLog(val32);
|
||||||
|
if (n < 0 || n > 16)
|
||||||
|
return S_FALSE;
|
||||||
|
li.WindowSizeBits = n;
|
||||||
|
}
|
||||||
|
|
||||||
li.CacheSize = ReadUInt32();
|
li.CacheSize = ReadUInt32();
|
||||||
if (
|
|
||||||
li.ResetInterval != 1 &&
|
|
||||||
li.ResetInterval != 2 &&
|
|
||||||
li.ResetInterval != 4 &&
|
|
||||||
li.ResetInterval != 8 &&
|
|
||||||
li.ResetInterval != 16 &&
|
|
||||||
li.ResetInterval != 32 &&
|
|
||||||
li.ResetInterval != 64)
|
|
||||||
return S_FALSE;
|
|
||||||
if (
|
|
||||||
li.WindowSize != 1 &&
|
|
||||||
li.WindowSize != 2 &&
|
|
||||||
li.WindowSize != 4 &&
|
|
||||||
li.WindowSize != 8 &&
|
|
||||||
li.WindowSize != 16 &&
|
|
||||||
li.WindowSize != 32 &&
|
|
||||||
li.WindowSize != 64)
|
|
||||||
return S_FALSE;
|
|
||||||
numDWORDS -= 5;
|
numDWORDS -= 5;
|
||||||
while (numDWORDS-- != 0)
|
while (numDWORDS-- != 0)
|
||||||
ReadUInt32();
|
ReadUInt32();
|
||||||
@@ -835,6 +864,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
|||||||
RINOK(DecompressStream(inStream, database, transformPrefix +
|
RINOK(DecompressStream(inStream, database, transformPrefix +
|
||||||
method.GetGuidString() + kResetTable));
|
method.GetGuidString() + kResetTable));
|
||||||
CResetTable &rt = method.LzxInfo.ResetTable;
|
CResetTable &rt = method.LzxInfo.ResetTable;
|
||||||
|
|
||||||
if (_chunkSize < 4)
|
if (_chunkSize < 4)
|
||||||
{
|
{
|
||||||
if (_chunkSize != 0)
|
if (_chunkSize != 0)
|
||||||
@@ -844,7 +874,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
rt.UncompressedSize = 0;
|
rt.UncompressedSize = 0;
|
||||||
rt.CompressedSize = 0;
|
rt.CompressedSize = 0;
|
||||||
rt.BlockSize = 0;
|
// rt.BlockSize = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -852,18 +882,45 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
|||||||
if (ver != 2 && ver != 3)
|
if (ver != 2 && ver != 3)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
UInt32 numEntries = ReadUInt32();
|
UInt32 numEntries = ReadUInt32();
|
||||||
if (ReadUInt32() != 8) // Size of table entry (bytes)
|
const unsigned kEntrySize = 8;
|
||||||
|
if (ReadUInt32() != kEntrySize)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if (ReadUInt32() != 0x28) // Len of table header
|
const unsigned kRtHeaderSize = 4 * 4 + 8 * 3;
|
||||||
|
if (ReadUInt32() != kRtHeaderSize)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
if (kRtHeaderSize + kEntrySize * (UInt64)numEntries != _chunkSize)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
rt.UncompressedSize = ReadUInt64();
|
rt.UncompressedSize = ReadUInt64();
|
||||||
rt.CompressedSize = ReadUInt64();
|
rt.CompressedSize = ReadUInt64();
|
||||||
rt.BlockSize = ReadUInt64(); // 0x8000 block size for locations below
|
UInt64 blockSize = ReadUInt64();
|
||||||
if (rt.BlockSize != 0x8000)
|
if (blockSize != kBlockSize)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
UInt64 numBlocks = (rt.UncompressedSize + kBlockSize + 1) / kBlockSize;
|
||||||
|
if (numEntries != numBlocks &&
|
||||||
|
numEntries != numBlocks + 1)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
rt.ResetOffsets.ClearAndReserve(numEntries);
|
rt.ResetOffsets.ClearAndReserve(numEntries);
|
||||||
|
|
||||||
for (UInt32 i = 0; i < numEntries; i++)
|
for (UInt32 i = 0; i < numEntries; i++)
|
||||||
rt.ResetOffsets.AddInReserved(ReadUInt64());
|
{
|
||||||
|
UInt64 v = ReadUInt64();
|
||||||
|
if (i != 0 && v < rt.ResetOffsets[i - 1])
|
||||||
|
return S_FALSE;
|
||||||
|
rt.ResetOffsets.AddInReserved(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numEntries != 0)
|
||||||
|
if (rt.ResetOffsets[0] != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
if (numEntries == numBlocks + 1)
|
||||||
|
{
|
||||||
|
// Lazarus 9-26-2 chm contains additional entty
|
||||||
|
if (rt.ResetOffsets.Back() != rt.CompressedSize)
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -896,14 +953,16 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
|||||||
|
|
||||||
if (_help2)
|
if (_help2)
|
||||||
{
|
{
|
||||||
const int kSignatureSize = 8;
|
const unsigned kSignatureSize = 8;
|
||||||
UInt64 signature = ((UInt64)kSignature_ITLS << 32)| kSignature_ITOL;
|
const UInt64 signature = ((UInt64)kSignature_ITLS << 32) | kSignature_ITOL;
|
||||||
UInt64 limit = 1 << 18;
|
UInt64 limit = 1 << 18;
|
||||||
|
|
||||||
if (searchHeaderSizeLimit)
|
if (searchHeaderSizeLimit)
|
||||||
if (limit > *searchHeaderSizeLimit)
|
if (limit > *searchHeaderSizeLimit)
|
||||||
limit = *searchHeaderSizeLimit;
|
limit = *searchHeaderSizeLimit;
|
||||||
|
|
||||||
UInt64 val = 0;
|
UInt64 val = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte b;
|
Byte b;
|
||||||
@@ -919,6 +978,7 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
database.StartPosition += _inBuffer.GetProcessedSize() - kSignatureSize;
|
database.StartPosition += _inBuffer.GetProcessedSize() - kSignatureSize;
|
||||||
RINOK(OpenHelp2(inStream, database));
|
RINOK(OpenHelp2(inStream, database));
|
||||||
if (database.NewFormat)
|
if (database.NewFormat)
|
||||||
@@ -948,6 +1008,8 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
|
if (!database.CheckSectionRefs())
|
||||||
|
HeadersError = true;
|
||||||
database.LowLevel = false;
|
database.LowLevel = false;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
|||||||
@@ -36,12 +36,13 @@ struct CItem
|
|||||||
|
|
||||||
bool IsDir() const
|
bool IsDir() const
|
||||||
{
|
{
|
||||||
if (Name.Len() == 0)
|
if (Name.IsEmpty())
|
||||||
return false;
|
return false;
|
||||||
return (Name.Back() == '/');
|
return (Name.Back() == '/');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CDatabase
|
struct CDatabase
|
||||||
{
|
{
|
||||||
UInt64 StartPosition;
|
UInt64 StartPosition;
|
||||||
@@ -73,11 +74,14 @@ struct CDatabase
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const UInt32 kBlockSize = 1 << 15;
|
||||||
|
|
||||||
struct CResetTable
|
struct CResetTable
|
||||||
{
|
{
|
||||||
UInt64 UncompressedSize;
|
UInt64 UncompressedSize;
|
||||||
UInt64 CompressedSize;
|
UInt64 CompressedSize;
|
||||||
UInt64 BlockSize;
|
// unsigned BlockSizeBits;
|
||||||
CRecordVector<UInt64> ResetOffsets;
|
CRecordVector<UInt64> ResetOffsets;
|
||||||
|
|
||||||
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
|
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
|
||||||
@@ -91,39 +95,41 @@ struct CResetTable
|
|||||||
size = ResetOffsets[(unsigned)(blockIndex + numBlocks)] - startPos;
|
size = ResetOffsets[(unsigned)(blockIndex + numBlocks)] - startPos;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
|
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
|
||||||
{
|
{
|
||||||
return GetCompressedSizeOfBlocks(blockIndex, 1, size);
|
return GetCompressedSizeOfBlocks(blockIndex, 1, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 GetNumBlocks(UInt64 size) const
|
UInt64 GetNumBlocks(UInt64 size) const
|
||||||
{
|
{
|
||||||
return (size + BlockSize - 1) / BlockSize;
|
return (size + kBlockSize - 1) / kBlockSize;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CLzxInfo
|
struct CLzxInfo
|
||||||
{
|
{
|
||||||
UInt32 Version;
|
UInt32 Version;
|
||||||
UInt32 ResetInterval;
|
|
||||||
UInt32 WindowSize;
|
unsigned ResetIntervalBits;
|
||||||
|
unsigned WindowSizeBits;
|
||||||
UInt32 CacheSize;
|
UInt32 CacheSize;
|
||||||
|
|
||||||
CResetTable ResetTable;
|
CResetTable ResetTable;
|
||||||
|
|
||||||
UInt32 GetNumDictBits() const
|
unsigned GetNumDictBits() const
|
||||||
{
|
{
|
||||||
if (Version == 2 || Version == 3)
|
if (Version == 2 || Version == 3)
|
||||||
{
|
return 15 + WindowSizeBits;
|
||||||
for (unsigned i = 0; i <= 31; i++)
|
|
||||||
if (((UInt32)1 << i) >= WindowSize)
|
|
||||||
return 15 + i;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 GetFolderSize() const { return ResetTable.BlockSize * ResetInterval; }
|
UInt64 GetFolderSize() const { return kBlockSize << ResetIntervalBits; }
|
||||||
UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); }
|
UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); }
|
||||||
UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); }
|
UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); }
|
||||||
UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; }
|
UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex << ResetIntervalBits; }
|
||||||
|
|
||||||
bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
|
bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
|
||||||
{
|
{
|
||||||
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
||||||
@@ -132,24 +138,28 @@ struct CLzxInfo
|
|||||||
offset = ResetTable.ResetOffsets[(unsigned)blockIndex];
|
offset = ResetTable.ResetOffsets[(unsigned)blockIndex];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
|
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
|
||||||
{
|
{
|
||||||
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
||||||
return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, size);
|
return ResetTable.GetCompressedSizeOfBlocks(blockIndex, (UInt32)1 << ResetIntervalBits, size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CMethodInfo
|
struct CMethodInfo
|
||||||
{
|
{
|
||||||
GUID Guid;
|
GUID Guid;
|
||||||
CByteBuffer ControlData;
|
CByteBuffer ControlData;
|
||||||
CLzxInfo LzxInfo;
|
CLzxInfo LzxInfo;
|
||||||
|
|
||||||
bool IsLzx() const;
|
bool IsLzx() const;
|
||||||
bool IsDes() const;
|
bool IsDes() const;
|
||||||
AString GetGuidString() const;
|
AString GetGuidString() const;
|
||||||
UString GetName() const;
|
UString GetName() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CSectionInfo
|
struct CSectionInfo
|
||||||
{
|
{
|
||||||
UInt64 Offset;
|
UInt64 Offset;
|
||||||
@@ -167,27 +177,33 @@ class CFilesDatabase: public CDatabase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool LowLevel;
|
bool LowLevel;
|
||||||
CRecordVector<int> Indices;
|
CUIntVector Indices;
|
||||||
CObjectVector<CSectionInfo> Sections;
|
CObjectVector<CSectionInfo> Sections;
|
||||||
|
|
||||||
UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; }
|
UInt64 GetFileSize(unsigned fileIndex) const { return Items[Indices[fileIndex]].Size; }
|
||||||
UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; }
|
UInt64 GetFileOffset(unsigned fileIndex) const { return Items[Indices[fileIndex]].Offset; }
|
||||||
|
|
||||||
UInt64 GetFolder(int fileIndex) const
|
UInt64 GetFolder(unsigned fileIndex) const
|
||||||
{
|
{
|
||||||
const CItem &item = Items[Indices[fileIndex]];
|
const CItem &item = Items[Indices[fileIndex]];
|
||||||
const CSectionInfo §ion = Sections[(int)item.Section];
|
if (item.Section < Sections.Size())
|
||||||
if (section.IsLzx())
|
{
|
||||||
return section.Methods[0].LzxInfo.GetFolder(item.Offset);
|
const CSectionInfo §ion = Sections[(unsigned)item.Section];
|
||||||
|
if (section.IsLzx())
|
||||||
|
return section.Methods[0].LzxInfo.GetFolder(item.Offset);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 GetLastFolder(int fileIndex) const
|
UInt64 GetLastFolder(unsigned fileIndex) const
|
||||||
{
|
{
|
||||||
const CItem &item = Items[Indices[fileIndex]];
|
const CItem &item = Items[Indices[fileIndex]];
|
||||||
const CSectionInfo §ion = Sections[(int)item.Section];
|
if (item.Section < Sections.Size())
|
||||||
if (section.IsLzx())
|
{
|
||||||
return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);
|
const CSectionInfo §ion = Sections[(unsigned)item.Section];
|
||||||
|
if (section.IsLzx())
|
||||||
|
return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,19 +219,13 @@ public:
|
|||||||
CDatabase::Clear();
|
CDatabase::Clear();
|
||||||
HighLevelClear();
|
HighLevelClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIndices();
|
void SetIndices();
|
||||||
void Sort();
|
void Sort();
|
||||||
bool Check();
|
bool Check();
|
||||||
|
bool CheckSectionRefs();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
class CProgressVirt
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE;
|
|
||||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
class CInArchive
|
class CInArchive
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ HRESULT CDatabase::ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSiz
|
|||||||
{
|
{
|
||||||
UpdatePhySize(((UInt64)sid + 2) << sectorSizeBits);
|
UpdatePhySize(((UInt64)sid + 2) << sectorSizeBits);
|
||||||
RINOK(inStream->Seek((((UInt64)sid + 1) << sectorSizeBits), STREAM_SEEK_SET, NULL));
|
RINOK(inStream->Seek((((UInt64)sid + 1) << sectorSizeBits), STREAM_SEEK_SET, NULL));
|
||||||
return ReadStream_FALSE(inStream, buf, (UInt32)1 << sectorSizeBits);
|
return ReadStream_FALSE(inStream, buf, (size_t)1 << sectorSizeBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CDatabase::ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest)
|
HRESULT CDatabase::ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest)
|
||||||
@@ -433,9 +433,9 @@ HRESULT CDatabase::Open(IInStream *inStream)
|
|||||||
SectorSizeBits = sectorSizeBits;
|
SectorSizeBits = sectorSizeBits;
|
||||||
MiniSectorSizeBits = miniSectorSizeBits;
|
MiniSectorSizeBits = miniSectorSizeBits;
|
||||||
|
|
||||||
if (sectorSizeBits > 28 ||
|
if (sectorSizeBits > 24 ||
|
||||||
sectorSizeBits < 7 ||
|
sectorSizeBits < 7 ||
|
||||||
miniSectorSizeBits > 28 ||
|
miniSectorSizeBits > 24 ||
|
||||||
miniSectorSizeBits < 2 ||
|
miniSectorSizeBits < 2 ||
|
||||||
miniSectorSizeBits > sectorSizeBits)
|
miniSectorSizeBits > sectorSizeBits)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
@@ -571,34 +571,41 @@ 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];
|
||||||
if (item.IsDir() || numCabs > 1)
|
if (item.IsDir() || numCabs > 1)
|
||||||
continue;
|
continue;
|
||||||
bool isMsiName;
|
bool isMsiName;
|
||||||
UString msiName = ConvertName(item.Name, isMsiName);
|
const UString msiName = ConvertName(item.Name, isMsiName);
|
||||||
if (isMsiName)
|
if (isMsiName && !msiName.IsEmpty())
|
||||||
{
|
{
|
||||||
|
// bool isThereExt = (msiName.Find(L'.') >= 0);
|
||||||
|
bool isMsiSpec = (msiName[0] == k_Msi_SpecChar);
|
||||||
if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
|
if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
|
||||||
|| msiName.Len() >= 3 && msiName[0] != k_Msi_SpecChar && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe"))
|
|| !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")
|
||||||
|
// || !isMsiSpec && !isThereExt
|
||||||
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
numCabs++;
|
numCabs++;
|
||||||
MainSubfile = i;
|
MainSubfile = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numCabs > 1)
|
if (numCabs > 1)
|
||||||
MainSubfile = -1;
|
MainSubfile = -1;
|
||||||
|
|
||||||
{
|
{
|
||||||
FOR_VECTOR(t, Items)
|
FOR_VECTOR (t, Items)
|
||||||
{
|
{
|
||||||
Update_PhySize_WithItem(t);
|
Update_PhySize_WithItem(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
FOR_VECTOR(t, Items)
|
FOR_VECTOR (t, Items)
|
||||||
{
|
{
|
||||||
const CItem &item = Items[t];
|
const CItem &item = Items[t];
|
||||||
|
|
||||||
@@ -739,7 +746,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
UInt64 totalSize = 0;
|
UInt64 totalSize = 0;
|
||||||
for(i = 0; i < numItems; i++)
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
const CItem &item = _db.Items[_db.Refs[allFilesMode ? i : indices[i]].Did];
|
const CItem &item = _db.Items[_db.Refs[allFilesMode ? i : indices[i]].Did];
|
||||||
if (!item.IsDir())
|
if (!item.IsDir())
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
// CoderMixer.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "CoderMixer.h"
|
|
||||||
|
|
||||||
namespace NCoderMixer {
|
|
||||||
|
|
||||||
void CCoderInfo::SetCoderInfo(const UInt64 *inSize, const UInt64 *outSize)
|
|
||||||
{
|
|
||||||
InSizeAssigned = (inSize != 0);
|
|
||||||
if (InSizeAssigned)
|
|
||||||
InSizeValue = *inSize;
|
|
||||||
OutSizeAssigned = (outSize != 0);
|
|
||||||
if (OutSizeAssigned)
|
|
||||||
OutSizeValue = *outSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
// CoderMixer.h
|
|
||||||
|
|
||||||
#ifndef __CODER_MIXER_H
|
|
||||||
#define __CODER_MIXER_H
|
|
||||||
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
namespace NCoderMixer {
|
|
||||||
|
|
||||||
struct CCoderInfo
|
|
||||||
{
|
|
||||||
CMyComPtr<ICompressCoder> Coder;
|
|
||||||
CMyComPtr<ISequentialInStream> InStream;
|
|
||||||
CMyComPtr<ISequentialOutStream> OutStream;
|
|
||||||
CMyComPtr<ICompressProgressInfo> Progress;
|
|
||||||
|
|
||||||
UInt64 InSizeValue;
|
|
||||||
UInt64 OutSizeValue;
|
|
||||||
bool InSizeAssigned;
|
|
||||||
bool OutSizeAssigned;
|
|
||||||
|
|
||||||
void ReInit()
|
|
||||||
{
|
|
||||||
InSizeAssigned = OutSizeAssigned = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetCoderInfo(const UInt64 *inSize, const UInt64 *outSize);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,254 +0,0 @@
|
|||||||
// CoderMixer2MT.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "CoderMixer2MT.h"
|
|
||||||
|
|
||||||
namespace NCoderMixer2 {
|
|
||||||
|
|
||||||
void CCoderMT::Execute() { Code(NULL); }
|
|
||||||
|
|
||||||
void CCoderMT::Code(ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
unsigned numInStreams = EncodeMode ? 1 : NumStreams;
|
|
||||||
unsigned numOutStreams = EncodeMode ? NumStreams : 1;
|
|
||||||
|
|
||||||
InStreamPointers.ClearAndReserve(numInStreams);
|
|
||||||
OutStreamPointers.ClearAndReserve(numOutStreams);
|
|
||||||
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < numInStreams; i++)
|
|
||||||
InStreamPointers.AddInReserved((ISequentialInStream *)InStreams[i]);
|
|
||||||
|
|
||||||
for (i = 0; i < numOutStreams; i++)
|
|
||||||
OutStreamPointers.AddInReserved((ISequentialOutStream *)OutStreams[i]);
|
|
||||||
|
|
||||||
// we suppose that UnpackSizePointer and PackSizePointers contain correct pointers.
|
|
||||||
/*
|
|
||||||
if (UnpackSizePointer)
|
|
||||||
UnpackSizePointer = &UnpackSize;
|
|
||||||
for (i = 0; i < NumStreams; i++)
|
|
||||||
if (PackSizePointers[i])
|
|
||||||
PackSizePointers[i] = &PackSizes[i];
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (Coder)
|
|
||||||
Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
|
|
||||||
EncodeMode ? UnpackSizePointer : PackSizePointers[0],
|
|
||||||
EncodeMode ? PackSizePointers[0] : UnpackSizePointer,
|
|
||||||
progress);
|
|
||||||
else
|
|
||||||
Result = Coder2->Code(
|
|
||||||
&InStreamPointers.Front(), EncodeMode ? &UnpackSizePointer : &PackSizePointers.Front(), numInStreams,
|
|
||||||
&OutStreamPointers.Front(), EncodeMode ? &PackSizePointers.Front(): &UnpackSizePointer, numOutStreams,
|
|
||||||
progress);
|
|
||||||
|
|
||||||
InStreamPointers.Clear();
|
|
||||||
OutStreamPointers.Clear();
|
|
||||||
|
|
||||||
for (i = 0; i < InStreams.Size(); i++)
|
|
||||||
InStreams[i].Release();
|
|
||||||
for (i = 0; i < OutStreams.Size(); i++)
|
|
||||||
OutStreams[i].Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CMixerMT::SetBindInfo(const CBindInfo &bindInfo)
|
|
||||||
{
|
|
||||||
CMixer::SetBindInfo(bindInfo);
|
|
||||||
|
|
||||||
_streamBinders.Clear();
|
|
||||||
FOR_VECTOR (i, _bi.Bonds)
|
|
||||||
{
|
|
||||||
RINOK(_streamBinders.AddNew().CreateEvents());
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMixerMT::AddCoder(ICompressCoder *coder, ICompressCoder2 *coder2, bool isFilter)
|
|
||||||
{
|
|
||||||
const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()];
|
|
||||||
CCoderMT &c2 = _coders.AddNew();
|
|
||||||
c2.NumStreams = c.NumStreams;
|
|
||||||
c2.EncodeMode = EncodeMode;
|
|
||||||
c2.Coder = coder;
|
|
||||||
c2.Coder2 = coder2;
|
|
||||||
IsFilter_Vector.Add(isFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
CCoder &CMixerMT::GetCoder(unsigned index)
|
|
||||||
{
|
|
||||||
return _coders[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMixerMT::ReInit()
|
|
||||||
{
|
|
||||||
FOR_VECTOR (i, _streamBinders)
|
|
||||||
_streamBinders[i].ReInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMixerMT::SelectMainCoder(bool useFirst)
|
|
||||||
{
|
|
||||||
unsigned ci = _bi.UnpackCoder;
|
|
||||||
|
|
||||||
if (!useFirst)
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (_coders[ci].NumStreams != 1)
|
|
||||||
break;
|
|
||||||
if (!IsFilter_Vector[ci])
|
|
||||||
break;
|
|
||||||
|
|
||||||
UInt32 st = _bi.Coder_to_Stream[ci];
|
|
||||||
if (_bi.IsStream_in_PackStreams(st))
|
|
||||||
break;
|
|
||||||
int bond = _bi.FindBond_for_PackStream(st);
|
|
||||||
if (bond < 0)
|
|
||||||
throw 20150213;
|
|
||||||
ci = _bi.Bonds[bond].UnpackIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainCoderIndex = ci;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
{
|
|
||||||
CCoderMT &coderInfo = _coders[i];
|
|
||||||
const CCoderStreamsInfo &csi = _bi.Coders[i];
|
|
||||||
|
|
||||||
UInt32 j;
|
|
||||||
|
|
||||||
unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams;
|
|
||||||
unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1;
|
|
||||||
|
|
||||||
coderInfo.InStreams.Clear();
|
|
||||||
for (j = 0; j < numInStreams; j++)
|
|
||||||
coderInfo.InStreams.AddNew();
|
|
||||||
|
|
||||||
coderInfo.OutStreams.Clear();
|
|
||||||
for (j = 0; j < numOutStreams; j++)
|
|
||||||
coderInfo.OutStreams.AddNew();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < _bi.Bonds.Size(); i++)
|
|
||||||
{
|
|
||||||
const CBond &bond = _bi.Bonds[i];
|
|
||||||
|
|
||||||
UInt32 inCoderIndex, inCoderStreamIndex;
|
|
||||||
UInt32 outCoderIndex, outCoderStreamIndex;
|
|
||||||
|
|
||||||
{
|
|
||||||
UInt32 coderIndex, coderStreamIndex;
|
|
||||||
_bi.GetCoder_for_Stream(bond.PackIndex, coderIndex, coderStreamIndex);
|
|
||||||
|
|
||||||
inCoderIndex = EncodeMode ? bond.UnpackIndex : coderIndex;
|
|
||||||
outCoderIndex = EncodeMode ? coderIndex : bond.UnpackIndex;
|
|
||||||
|
|
||||||
inCoderStreamIndex = EncodeMode ? 0 : coderStreamIndex;
|
|
||||||
outCoderStreamIndex = EncodeMode ? coderStreamIndex : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_streamBinders[i].CreateStreams(
|
|
||||||
&_coders[inCoderIndex].InStreams[inCoderStreamIndex],
|
|
||||||
&_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
|
|
||||||
|
|
||||||
CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize;
|
|
||||||
_coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize);
|
|
||||||
_coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize);
|
|
||||||
if (inSetSize && outSetSize)
|
|
||||||
{
|
|
||||||
const UInt32 kBufSize = 1 << 19;
|
|
||||||
inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize);
|
|
||||||
outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
CCoderMT &cod = _coders[_bi.UnpackCoder];
|
|
||||||
if (EncodeMode)
|
|
||||||
cod.InStreams[0] = inStreams[0];
|
|
||||||
else
|
|
||||||
cod.OutStreams[0] = outStreams[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < _bi.PackStreams.Size(); i++)
|
|
||||||
{
|
|
||||||
UInt32 coderIndex, coderStreamIndex;
|
|
||||||
_bi.GetCoder_for_Stream(_bi.PackStreams[i], coderIndex, coderStreamIndex);
|
|
||||||
CCoderMT &cod = _coders[coderIndex];
|
|
||||||
if (EncodeMode)
|
|
||||||
cod.OutStreams[coderStreamIndex] = outStreams[i];
|
|
||||||
else
|
|
||||||
cod.InStreams[coderStreamIndex] = inStreams[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CMixerMT::ReturnIfError(HRESULT code)
|
|
||||||
{
|
|
||||||
FOR_VECTOR (i, _coders)
|
|
||||||
if (_coders[i].Result == code)
|
|
||||||
return code;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CMixerMT::Code(
|
|
||||||
ISequentialInStream * const *inStreams,
|
|
||||||
ISequentialOutStream * const *outStreams,
|
|
||||||
ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
Init(inStreams, outStreams);
|
|
||||||
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
if (i != MainCoderIndex)
|
|
||||||
{
|
|
||||||
RINOK(_coders[i].Create());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
if (i != MainCoderIndex)
|
|
||||||
_coders[i].Start();
|
|
||||||
|
|
||||||
_coders[MainCoderIndex].Code(progress);
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
if (i != MainCoderIndex)
|
|
||||||
_coders[i].WaitExecuteFinish();
|
|
||||||
|
|
||||||
RINOK(ReturnIfError(E_ABORT));
|
|
||||||
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
{
|
|
||||||
HRESULT result = _coders[i].Result;
|
|
||||||
if (result != S_OK
|
|
||||||
&& result != k_My_HRESULT_WritingWasCut
|
|
||||||
&& result != S_FALSE
|
|
||||||
&& result != E_FAIL)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
RINOK(ReturnIfError(S_FALSE));
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
{
|
|
||||||
HRESULT result = _coders[i].Result;
|
|
||||||
if (result != S_OK && result != k_My_HRESULT_WritingWasCut)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt64 CMixerMT::GetBondStreamSize(unsigned bondIndex) const
|
|
||||||
{
|
|
||||||
return _streamBinders[bondIndex].ProcessedSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
// CoderMixer2MT.h
|
|
||||||
|
|
||||||
#ifndef __CODER_MIXER2_MT_H
|
|
||||||
#define __CODER_MIXER2_MT_H
|
|
||||||
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
|
|
||||||
#include "../../Common/StreamBinder.h"
|
|
||||||
#include "../../Common/VirtThread.h"
|
|
||||||
|
|
||||||
#include "CoderMixer2.h"
|
|
||||||
|
|
||||||
namespace NCoderMixer2 {
|
|
||||||
|
|
||||||
class CCoderMT: public CCoder, public CVirtThread
|
|
||||||
{
|
|
||||||
CLASS_NO_COPY(CCoderMT)
|
|
||||||
CRecordVector<ISequentialInStream*> InStreamPointers;
|
|
||||||
CRecordVector<ISequentialOutStream*> OutStreamPointers;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Execute();
|
|
||||||
public:
|
|
||||||
bool EncodeMode;
|
|
||||||
HRESULT Result;
|
|
||||||
CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
|
|
||||||
CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
|
|
||||||
|
|
||||||
CCoderMT(): EncodeMode(false) {}
|
|
||||||
~CCoderMT() { CVirtThread::WaitThreadFinish(); }
|
|
||||||
|
|
||||||
void Code(ICompressProgressInfo *progress);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CMixerMT:
|
|
||||||
public IUnknown,
|
|
||||||
public CMixer,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
CObjectVector<CStreamBinder> _streamBinders;
|
|
||||||
|
|
||||||
HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);
|
|
||||||
HRESULT ReturnIfError(HRESULT code);
|
|
||||||
|
|
||||||
public:
|
|
||||||
CObjectVector<CCoderMT> _coders;
|
|
||||||
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
virtual HRESULT SetBindInfo(const CBindInfo &bindInfo);
|
|
||||||
|
|
||||||
virtual void AddCoder(ICompressCoder *coder, ICompressCoder2 *coder2, bool isFilter);
|
|
||||||
|
|
||||||
virtual CCoder &GetCoder(unsigned index);
|
|
||||||
|
|
||||||
virtual void SelectMainCoder(bool useFirst);
|
|
||||||
|
|
||||||
virtual void ReInit();
|
|
||||||
|
|
||||||
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
|
|
||||||
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
|
|
||||||
|
|
||||||
virtual HRESULT Code(
|
|
||||||
ISequentialInStream * const *inStreams,
|
|
||||||
ISequentialOutStream * const *outStreams,
|
|
||||||
ICompressProgressInfo *progress);
|
|
||||||
|
|
||||||
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
|
|
||||||
|
|
||||||
CMixerMT(bool encodeMode): CMixer(encodeMode) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,562 +0,0 @@
|
|||||||
// CoderMixer2ST.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "CoderMixer2ST.h"
|
|
||||||
|
|
||||||
STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
UInt32 realProcessed = 0;
|
|
||||||
HRESULT result = S_OK;
|
|
||||||
if (_stream)
|
|
||||||
result = _stream->Read(data, size, &realProcessed);
|
|
||||||
_size += realProcessed;
|
|
||||||
if (size != 0 && realProcessed == 0)
|
|
||||||
_wasFinished = true;
|
|
||||||
if (processedSize)
|
|
||||||
*processedSize = realProcessed;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
HRESULT result = S_OK;
|
|
||||||
if (_stream)
|
|
||||||
result = _stream->Write(data, size, &size);
|
|
||||||
_size += size;
|
|
||||||
if (processedSize)
|
|
||||||
*processedSize = size;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP COutStreamCalcSize::Flush()
|
|
||||||
{
|
|
||||||
HRESULT result = S_OK;
|
|
||||||
if (_stream)
|
|
||||||
{
|
|
||||||
CMyComPtr<IOutStreamFlush> outStreamFlush;
|
|
||||||
_stream.QueryInterface(IID_IOutStreamFlush, &outStreamFlush);
|
|
||||||
if (outStreamFlush)
|
|
||||||
result = outStreamFlush->Flush();;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace NCoderMixer2 {
|
|
||||||
|
|
||||||
CMixerST::CMixerST(bool encodeMode):
|
|
||||||
CMixer(encodeMode)
|
|
||||||
{}
|
|
||||||
|
|
||||||
CMixerST::~CMixerST() {}
|
|
||||||
|
|
||||||
void CMixerST::AddCoder(ICompressCoder *coder, ICompressCoder2 *coder2, bool isFilter)
|
|
||||||
{
|
|
||||||
IsFilter_Vector.Add(isFilter);
|
|
||||||
const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()];
|
|
||||||
CCoderST &c2 = _coders.AddNew();
|
|
||||||
c2.NumStreams = c.NumStreams;
|
|
||||||
c2.Coder = coder;
|
|
||||||
c2.Coder2 = coder2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (isFilter)
|
|
||||||
{
|
|
||||||
c2.CanRead = true;
|
|
||||||
c2.CanWrite = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
IUnknown *unk = (coder ? (IUnknown *)coder : (IUnknown *)coder2);
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialInStream> s;
|
|
||||||
unk->QueryInterface(IID_ISequentialInStream, (void**)&s);
|
|
||||||
c2.CanRead = (s != NULL);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialOutStream> s;
|
|
||||||
unk->QueryInterface(IID_ISequentialOutStream, (void**)&s);
|
|
||||||
c2.CanWrite = (s != NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CCoder &CMixerST::GetCoder(unsigned index)
|
|
||||||
{
|
|
||||||
return _coders[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMixerST::ReInit() {}
|
|
||||||
|
|
||||||
HRESULT CMixerST::GetInStream2(
|
|
||||||
ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
|
|
||||||
UInt32 outStreamIndex, ISequentialInStream **inStreamRes)
|
|
||||||
{
|
|
||||||
UInt32 coderIndex = outStreamIndex, coderStreamIndex = 0;
|
|
||||||
|
|
||||||
if (EncodeMode)
|
|
||||||
{
|
|
||||||
_bi.GetCoder_for_Stream(outStreamIndex, coderIndex, coderStreamIndex);
|
|
||||||
if (coderStreamIndex != 0)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CCoder &coder = _coders[coderIndex];
|
|
||||||
|
|
||||||
CMyComPtr<ISequentialInStream> seqInStream;
|
|
||||||
coder.QueryInterface(IID_ISequentialInStream, (void **)&seqInStream);
|
|
||||||
if (!seqInStream)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams;
|
|
||||||
UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex];
|
|
||||||
|
|
||||||
bool isSet = false;
|
|
||||||
|
|
||||||
if (numInStreams == 1)
|
|
||||||
{
|
|
||||||
CMyComPtr<ICompressSetInStream> setStream;
|
|
||||||
coder.QueryInterface(IID_ICompressSetInStream, (void **)&setStream);
|
|
||||||
if (setStream)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialInStream> seqInStream2;
|
|
||||||
RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2));
|
|
||||||
RINOK(setStream->SetInStream(seqInStream2));
|
|
||||||
isSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isSet && numInStreams != 0)
|
|
||||||
{
|
|
||||||
CMyComPtr<ICompressSetInStream2> setStream2;
|
|
||||||
coder.QueryInterface(IID_ICompressSetInStream2, (void **)&setStream2);
|
|
||||||
if (!setStream2)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
for (UInt32 i = 0; i < numInStreams; i++)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialInStream> seqInStream2;
|
|
||||||
RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2));
|
|
||||||
RINOK(setStream2->SetInStream2(i, seqInStream2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*inStreamRes = seqInStream.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CMixerST::GetInStream(
|
|
||||||
ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
|
|
||||||
UInt32 inStreamIndex, ISequentialInStream **inStreamRes)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialInStream> seqInStream;
|
|
||||||
|
|
||||||
{
|
|
||||||
int index = -1;
|
|
||||||
if (EncodeMode)
|
|
||||||
{
|
|
||||||
if (_bi.UnpackCoder == inStreamIndex)
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
index = _bi.FindStream_in_PackStreams(inStreamIndex);
|
|
||||||
|
|
||||||
if (index >= 0)
|
|
||||||
{
|
|
||||||
seqInStream = inStreams[index];
|
|
||||||
*inStreamRes = seqInStream.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int bond = FindBond_for_Stream(
|
|
||||||
true, // forInputStream
|
|
||||||
inStreamIndex);
|
|
||||||
if (bond < 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
RINOK(GetInStream2(inStreams, /* inSizes, */
|
|
||||||
_bi.Bonds[bond].Get_OutIndex(EncodeMode), &seqInStream));
|
|
||||||
|
|
||||||
while (_binderStreams.Size() <= (unsigned)bond)
|
|
||||||
_binderStreams.AddNew();
|
|
||||||
CStBinderStream &bs = _binderStreams[bond];
|
|
||||||
|
|
||||||
if (bs.StreamRef || bs.InStreamSpec)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
CSequentialInStreamCalcSize *spec = new CSequentialInStreamCalcSize;
|
|
||||||
bs.StreamRef = spec;
|
|
||||||
bs.InStreamSpec = spec;
|
|
||||||
|
|
||||||
spec->SetStream(seqInStream);
|
|
||||||
spec->Init();
|
|
||||||
|
|
||||||
seqInStream = bs.InStreamSpec;
|
|
||||||
|
|
||||||
*inStreamRes = seqInStream.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CMixerST::GetOutStream(
|
|
||||||
ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */
|
|
||||||
UInt32 outStreamIndex, ISequentialOutStream **outStreamRes)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialOutStream> seqOutStream;
|
|
||||||
|
|
||||||
{
|
|
||||||
int index = -1;
|
|
||||||
if (!EncodeMode)
|
|
||||||
{
|
|
||||||
if (_bi.UnpackCoder == outStreamIndex)
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
index = _bi.FindStream_in_PackStreams(outStreamIndex);
|
|
||||||
|
|
||||||
if (index >= 0)
|
|
||||||
{
|
|
||||||
seqOutStream = outStreams[index];
|
|
||||||
*outStreamRes = seqOutStream.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int bond = FindBond_for_Stream(
|
|
||||||
false, // forInputStream
|
|
||||||
outStreamIndex);
|
|
||||||
if (bond < 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode);
|
|
||||||
|
|
||||||
UInt32 coderIndex = inStreamIndex;
|
|
||||||
UInt32 coderStreamIndex = 0;
|
|
||||||
|
|
||||||
if (!EncodeMode)
|
|
||||||
_bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex);
|
|
||||||
|
|
||||||
CCoder &coder = _coders[coderIndex];
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (!coder.Coder)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
*/
|
|
||||||
|
|
||||||
coder.QueryInterface(IID_ISequentialOutStream, (void **)&seqOutStream);
|
|
||||||
if (!seqOutStream)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1;
|
|
||||||
UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex;
|
|
||||||
|
|
||||||
bool isSet = false;
|
|
||||||
|
|
||||||
if (numOutStreams == 1)
|
|
||||||
{
|
|
||||||
CMyComPtr<ICompressSetOutStream> setOutStream;
|
|
||||||
coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
|
|
||||||
if (setOutStream)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialOutStream> seqOutStream2;
|
|
||||||
RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2));
|
|
||||||
RINOK(setOutStream->SetOutStream(seqOutStream2));
|
|
||||||
isSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isSet && numOutStreams != 0)
|
|
||||||
{
|
|
||||||
// return E_NOTIMPL;
|
|
||||||
// /*
|
|
||||||
CMyComPtr<ICompressSetOutStream2> setStream2;
|
|
||||||
coder.QueryInterface(IID_ICompressSetOutStream2, (void **)&setStream2);
|
|
||||||
if (!setStream2)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
for (UInt32 i = 0; i < numOutStreams; i++)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialOutStream> seqOutStream2;
|
|
||||||
RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2));
|
|
||||||
RINOK(setStream2->SetOutStream2(i, seqOutStream2));
|
|
||||||
}
|
|
||||||
// */
|
|
||||||
}
|
|
||||||
|
|
||||||
while (_binderStreams.Size() <= (unsigned)bond)
|
|
||||||
_binderStreams.AddNew();
|
|
||||||
CStBinderStream &bs = _binderStreams[bond];
|
|
||||||
|
|
||||||
if (bs.StreamRef || bs.OutStreamSpec)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
COutStreamCalcSize *spec = new COutStreamCalcSize;
|
|
||||||
bs.StreamRef = (ISequentialOutStream *)spec;
|
|
||||||
bs.OutStreamSpec = spec;
|
|
||||||
|
|
||||||
spec->SetStream(seqOutStream);
|
|
||||||
spec->Init();
|
|
||||||
|
|
||||||
seqOutStream = bs.OutStreamSpec;
|
|
||||||
|
|
||||||
*outStreamRes = seqOutStream.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static HRESULT GetError(HRESULT res, HRESULT res2)
|
|
||||||
{
|
|
||||||
if (res == res2)
|
|
||||||
return res;
|
|
||||||
if (res == S_OK)
|
|
||||||
return res2;
|
|
||||||
if (res == k_My_HRESULT_WritingWasCut)
|
|
||||||
{
|
|
||||||
if (res2 != S_OK)
|
|
||||||
return res2;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CMixerST::FlushStream(UInt32 streamIndex)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
int index = -1;
|
|
||||||
if (!EncodeMode)
|
|
||||||
{
|
|
||||||
if (_bi.UnpackCoder == streamIndex)
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
index = _bi.FindStream_in_PackStreams(streamIndex);
|
|
||||||
|
|
||||||
if (index >= 0)
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bond = FindBond_for_Stream(
|
|
||||||
false, // forInputStream
|
|
||||||
streamIndex);
|
|
||||||
if (bond < 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode);
|
|
||||||
|
|
||||||
UInt32 coderIndex = inStreamIndex;
|
|
||||||
UInt32 coderStreamIndex = 0;
|
|
||||||
if (!EncodeMode)
|
|
||||||
_bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex);
|
|
||||||
|
|
||||||
CCoder &coder = _coders[coderIndex];
|
|
||||||
CMyComPtr<IOutStreamFlush> flush;
|
|
||||||
coder.QueryInterface(IID_IOutStreamFlush, (void **)&flush);
|
|
||||||
HRESULT res = S_OK;
|
|
||||||
if (flush)
|
|
||||||
{
|
|
||||||
res = flush->Flush();
|
|
||||||
}
|
|
||||||
return GetError(res, FlushCoder(coderIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CMixerST::FlushCoder(UInt32 coderIndex)
|
|
||||||
{
|
|
||||||
CCoder &coder = _coders[coderIndex];
|
|
||||||
|
|
||||||
UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1;
|
|
||||||
UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex;
|
|
||||||
|
|
||||||
HRESULT res = S_OK;
|
|
||||||
for (unsigned i = 0; i < numOutStreams; i++)
|
|
||||||
res = GetError(res, FlushStream(startIndex + i));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CMixerST::SelectMainCoder(bool useFirst)
|
|
||||||
{
|
|
||||||
unsigned ci = _bi.UnpackCoder;
|
|
||||||
|
|
||||||
int firstNonFilter = -1;
|
|
||||||
int firstAllowed = ci;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
const CCoderST &coder = _coders[ci];
|
|
||||||
// break;
|
|
||||||
|
|
||||||
if (ci != _bi.UnpackCoder)
|
|
||||||
if (EncodeMode ? !coder.CanWrite : !coder.CanRead)
|
|
||||||
{
|
|
||||||
firstAllowed = ci;
|
|
||||||
firstNonFilter = -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (coder.NumStreams != 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
UInt32 st = _bi.Coder_to_Stream[ci];
|
|
||||||
if (_bi.IsStream_in_PackStreams(st))
|
|
||||||
break;
|
|
||||||
int bond = _bi.FindBond_for_PackStream(st);
|
|
||||||
if (bond < 0)
|
|
||||||
throw 20150213;
|
|
||||||
|
|
||||||
if (EncodeMode ? !coder.CanRead : !coder.CanWrite)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (firstNonFilter == -1 && !IsFilter_Vector[ci])
|
|
||||||
firstNonFilter = ci;
|
|
||||||
|
|
||||||
ci = _bi.Bonds[bond].UnpackIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
ci = firstNonFilter;
|
|
||||||
if (firstNonFilter < 0 || useFirst)
|
|
||||||
ci = firstAllowed;
|
|
||||||
MainCoderIndex = ci;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CMixerST::Code(
|
|
||||||
ISequentialInStream * const *inStreams,
|
|
||||||
ISequentialOutStream * const *outStreams,
|
|
||||||
ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
_binderStreams.Clear();
|
|
||||||
unsigned ci = MainCoderIndex;
|
|
||||||
|
|
||||||
const CCoder &mainCoder = _coders[MainCoderIndex];
|
|
||||||
|
|
||||||
CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
|
|
||||||
CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
|
|
||||||
|
|
||||||
UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams;
|
|
||||||
UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams;
|
|
||||||
|
|
||||||
UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci];
|
|
||||||
UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci];
|
|
||||||
|
|
||||||
UInt32 i;
|
|
||||||
|
|
||||||
for (i = 0; i < numInStreams; i++)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialInStream> seqInStream;
|
|
||||||
RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream));
|
|
||||||
seqInStreams.Add(seqInStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < numOutStreams; i++)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialOutStream> seqOutStream;
|
|
||||||
RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream));
|
|
||||||
seqOutStreams.Add(seqOutStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
CRecordVector< ISequentialInStream * > seqInStreamsSpec;
|
|
||||||
CRecordVector< ISequentialOutStream * > seqOutStreamsSpec;
|
|
||||||
|
|
||||||
for (i = 0; i < numInStreams; i++)
|
|
||||||
seqInStreamsSpec.Add(seqInStreams[i]);
|
|
||||||
for (i = 0; i < numOutStreams; i++)
|
|
||||||
seqOutStreamsSpec.Add(seqOutStreams[i]);
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
{
|
|
||||||
if (i == ci)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CCoder &coder = _coders[i];
|
|
||||||
|
|
||||||
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
|
|
||||||
coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize);
|
|
||||||
if (setOutStreamSize)
|
|
||||||
{
|
|
||||||
RINOK(setOutStreamSize->SetOutStreamSize(
|
|
||||||
EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const UInt64 * const *isSizes2 = EncodeMode ? &mainCoder.UnpackSizePointer : &mainCoder.PackSizePointers.Front();
|
|
||||||
const UInt64 * const *outSizes2 = EncodeMode ? &mainCoder.PackSizePointers.Front() : &mainCoder.UnpackSizePointer;
|
|
||||||
|
|
||||||
HRESULT res;
|
|
||||||
if (mainCoder.Coder)
|
|
||||||
{
|
|
||||||
res = mainCoder.Coder->Code(
|
|
||||||
seqInStreamsSpec[0], seqOutStreamsSpec[0],
|
|
||||||
isSizes2[0], outSizes2[0],
|
|
||||||
progress);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res = mainCoder.Coder2->Code(
|
|
||||||
&seqInStreamsSpec.Front(), isSizes2, numInStreams,
|
|
||||||
&seqOutStreamsSpec.Front(), outSizes2, numOutStreams,
|
|
||||||
progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == k_My_HRESULT_WritingWasCut)
|
|
||||||
res = S_OK;
|
|
||||||
|
|
||||||
if (res == S_OK || res == S_FALSE)
|
|
||||||
{
|
|
||||||
res = GetError(res, FlushCoder(ci));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < _binderStreams.Size(); i++)
|
|
||||||
{
|
|
||||||
const CStBinderStream &bs = _binderStreams[i];
|
|
||||||
if (bs.InStreamSpec)
|
|
||||||
bs.InStreamSpec->ReleaseStream();
|
|
||||||
else
|
|
||||||
bs.OutStreamSpec->ReleaseStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == k_My_HRESULT_WritingWasCut)
|
|
||||||
res = S_OK;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CMixerST::GetMainUnpackStream(
|
|
||||||
ISequentialInStream * const *inStreams,
|
|
||||||
ISequentialInStream **inStreamRes)
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialInStream> seqInStream;
|
|
||||||
|
|
||||||
RINOK(GetInStream2(inStreams, /* inSizes, */
|
|
||||||
_bi.UnpackCoder, &seqInStream))
|
|
||||||
|
|
||||||
FOR_VECTOR (i, _coders)
|
|
||||||
{
|
|
||||||
CCoder &coder = _coders[i];
|
|
||||||
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
|
|
||||||
coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize);
|
|
||||||
if (setOutStreamSize)
|
|
||||||
{
|
|
||||||
RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*inStreamRes = seqInStream.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
UInt64 CMixerST::GetBondStreamSize(unsigned bondIndex) const
|
|
||||||
{
|
|
||||||
const CStBinderStream &bs = _binderStreams[bondIndex];
|
|
||||||
if (bs.InStreamSpec)
|
|
||||||
return bs.InStreamSpec->GetSize();
|
|
||||||
return bs.OutStreamSpec->GetSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
// CoderMixer2ST.h
|
|
||||||
|
|
||||||
#ifndef __CODER_MIXER2_ST_H
|
|
||||||
#define __CODER_MIXER2_ST_H
|
|
||||||
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
#include "CoderMixer2.h"
|
|
||||||
|
|
||||||
class CSequentialInStreamCalcSize:
|
|
||||||
public ISequentialInStream,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP1(ISequentialInStream)
|
|
||||||
|
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
private:
|
|
||||||
CMyComPtr<ISequentialInStream> _stream;
|
|
||||||
UInt64 _size;
|
|
||||||
bool _wasFinished;
|
|
||||||
public:
|
|
||||||
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
_size = 0;
|
|
||||||
_wasFinished = false;
|
|
||||||
}
|
|
||||||
void ReleaseStream() { _stream.Release(); }
|
|
||||||
UInt64 GetSize() const { return _size; }
|
|
||||||
bool WasFinished() const { return _wasFinished; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class COutStreamCalcSize:
|
|
||||||
public ISequentialOutStream,
|
|
||||||
public IOutStreamFlush,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
CMyComPtr<ISequentialOutStream> _stream;
|
|
||||||
UInt64 _size;
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFlush)
|
|
||||||
|
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
STDMETHOD(Flush)();
|
|
||||||
|
|
||||||
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
|
|
||||||
void ReleaseStream() { _stream.Release(); }
|
|
||||||
void Init() { _size = 0; }
|
|
||||||
UInt64 GetSize() const { return _size; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace NCoderMixer2 {
|
|
||||||
|
|
||||||
struct CCoderST: public CCoder
|
|
||||||
{
|
|
||||||
bool CanRead;
|
|
||||||
bool CanWrite;
|
|
||||||
|
|
||||||
CCoderST(): CanRead(false), CanWrite(false) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct CStBinderStream
|
|
||||||
{
|
|
||||||
CSequentialInStreamCalcSize *InStreamSpec;
|
|
||||||
COutStreamCalcSize *OutStreamSpec;
|
|
||||||
CMyComPtr<IUnknown> StreamRef;
|
|
||||||
|
|
||||||
CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class CMixerST:
|
|
||||||
public IUnknown,
|
|
||||||
public CMixer,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
|
|
||||||
UInt32 outStreamIndex, ISequentialInStream **inStreamRes);
|
|
||||||
HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
|
|
||||||
UInt32 inStreamIndex, ISequentialInStream **inStreamRes);
|
|
||||||
HRESULT GetOutStream(ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */
|
|
||||||
UInt32 outStreamIndex, ISequentialOutStream **outStreamRes);
|
|
||||||
|
|
||||||
HRESULT FlushStream(UInt32 streamIndex);
|
|
||||||
HRESULT FlushCoder(UInt32 coderIndex);
|
|
||||||
|
|
||||||
public:
|
|
||||||
CObjectVector<CCoderST> _coders;
|
|
||||||
|
|
||||||
CObjectVector<CStBinderStream> _binderStreams;
|
|
||||||
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
CMixerST(bool encodeMode);
|
|
||||||
~CMixerST();
|
|
||||||
|
|
||||||
virtual void AddCoder(ICompressCoder *coder, ICompressCoder2 *coder2, bool isFilter);
|
|
||||||
|
|
||||||
virtual CCoder &GetCoder(unsigned index);
|
|
||||||
|
|
||||||
virtual void SelectMainCoder(bool useFirst);
|
|
||||||
|
|
||||||
virtual void ReInit();
|
|
||||||
|
|
||||||
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
|
|
||||||
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
|
|
||||||
|
|
||||||
virtual HRESULT Code(
|
|
||||||
ISequentialInStream * const *inStreams,
|
|
||||||
ISequentialOutStream * const *outStreams,
|
|
||||||
ICompressProgressInfo *progress);
|
|
||||||
|
|
||||||
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
|
|
||||||
|
|
||||||
HRESULT GetMainUnpackStream(
|
|
||||||
ISequentialInStream * const *inStreams,
|
|
||||||
ISequentialInStream **inStreamRes);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
// CoderMixerMT.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "CoderMixerMT.h"
|
|
||||||
|
|
||||||
namespace NCoderMixer {
|
|
||||||
|
|
||||||
void CCoder::Execute() { Code(NULL); }
|
|
||||||
|
|
||||||
void CCoder::Code(ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
Result = Coder->Code(InStream, OutStream,
|
|
||||||
InSizeAssigned ? &InSizeValue : NULL,
|
|
||||||
OutSizeAssigned ? &OutSizeValue : NULL,
|
|
||||||
progress);
|
|
||||||
InStream.Release();
|
|
||||||
OutStream.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCoderMixerMT::AddCoder(ICompressCoder *coder)
|
|
||||||
{
|
|
||||||
_coders.Add(CCoder());
|
|
||||||
_coders.Back().Coder = coder;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCoderMixerMT::ReInit()
|
|
||||||
{
|
|
||||||
for(int i = 0; i < _coders.Size(); i++)
|
|
||||||
_coders[i].ReInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CCoderMixerMT::ReturnIfError(HRESULT code)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _coders.Size(); i++)
|
|
||||||
if (_coders[i].Result == code)
|
|
||||||
return code;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
const UInt64 * /* inSize */, const UInt64 * /* outSize */,
|
|
||||||
ICompressProgressInfo *progress)
|
|
||||||
{
|
|
||||||
_coders.Front().InStream = inStream;
|
|
||||||
int i;
|
|
||||||
_coders.Back().OutStream = outStream;
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
if (i != _progressCoderIndex)
|
|
||||||
{
|
|
||||||
RINOK(_coders[i].Create());
|
|
||||||
}
|
|
||||||
|
|
||||||
_streamBinders.Clear();
|
|
||||||
for (i = 0; i + 1 < _coders.Size(); i++)
|
|
||||||
{
|
|
||||||
_streamBinders.Add(CStreamBinder());
|
|
||||||
CStreamBinder &sb = _streamBinders[i];
|
|
||||||
RINOK(sb.CreateEvents());
|
|
||||||
sb.CreateStreams(&_coders[i + 1].InStream, &_coders[i].OutStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < _streamBinders.Size(); i++)
|
|
||||||
_streamBinders[i].ReInit();
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
if (i != _progressCoderIndex)
|
|
||||||
_coders[i].Start();
|
|
||||||
|
|
||||||
_coders[_progressCoderIndex].Code(progress);
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
if (i != _progressCoderIndex)
|
|
||||||
_coders[i].WaitExecuteFinish();
|
|
||||||
|
|
||||||
RINOK(ReturnIfError(E_ABORT));
|
|
||||||
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
{
|
|
||||||
HRESULT result = _coders[i].Result;
|
|
||||||
if (result != S_OK && result != E_FAIL && result != S_FALSE)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
RINOK(ReturnIfError(S_FALSE));
|
|
||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
|
||||||
{
|
|
||||||
HRESULT result = _coders[i].Result;
|
|
||||||
if (result != S_OK)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
// CoderMixerMT.h
|
|
||||||
|
|
||||||
#ifndef __CODER_MIXER_MT_H
|
|
||||||
#define __CODER_MIXER_MT_H
|
|
||||||
|
|
||||||
#include "../../../Common/MyVector.h"
|
|
||||||
#include "../../../Common/MyCom.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
#include "../../Common/StreamBinder.h"
|
|
||||||
#include "../../Common/VirtThread.h"
|
|
||||||
#include "CoderMixer.h"
|
|
||||||
|
|
||||||
namespace NCoderMixer {
|
|
||||||
|
|
||||||
struct CCoder: public CCoderInfo, public CVirtThread
|
|
||||||
{
|
|
||||||
HRESULT Result;
|
|
||||||
|
|
||||||
virtual void Execute();
|
|
||||||
void Code(ICompressProgressInfo *progress);
|
|
||||||
virtual ~CCoder() { CVirtThread::WaitThreadFinish(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
for each coder
|
|
||||||
AddCoder()
|
|
||||||
SetProgressIndex(UInt32 coderIndex);
|
|
||||||
|
|
||||||
for each file
|
|
||||||
{
|
|
||||||
ReInit()
|
|
||||||
for each coder
|
|
||||||
SetCoderInfo
|
|
||||||
Code
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
class CCoderMixerMT:
|
|
||||||
public ICompressCoder,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
CObjectVector<CStreamBinder> _streamBinders;
|
|
||||||
int _progressCoderIndex;
|
|
||||||
|
|
||||||
HRESULT ReturnIfError(HRESULT code);
|
|
||||||
public:
|
|
||||||
CObjectVector<CCoder> _coders;
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
|
||||||
ISequentialOutStream *outStream,
|
|
||||||
const UInt64 *inSize, const UInt64 *outSize,
|
|
||||||
ICompressProgressInfo *progress);
|
|
||||||
|
|
||||||
void AddCoder(ICompressCoder *coder);
|
|
||||||
void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; }
|
|
||||||
|
|
||||||
void ReInit();
|
|
||||||
void SetCoderInfo(UInt32 coderIndex, const UInt64 *inSize, const UInt64 *outSize)
|
|
||||||
{ _coders[coderIndex].SetCoderInfo(inSize, outSize); }
|
|
||||||
|
|
||||||
/*
|
|
||||||
UInt64 GetWriteProcessedSize(UInt32 binderIndex) const
|
|
||||||
{ return _streamBinders[binderIndex].ProcessedSize; }
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "../../../Common/MyBuffer.h"
|
#include "../../../Common/MyBuffer.h"
|
||||||
|
|
||||||
#include "../../Common/StreamUtils.h"
|
#include "../../Common/StreamUtils.h"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// FindSignature.h
|
// FindSignature.h
|
||||||
|
|
||||||
#ifndef __FINDSIGNATURE_H
|
#ifndef __FIND_SIGNATURE_H
|
||||||
#define __FINDSIGNATURE_H
|
#define __FIND_SIGNATURE_H
|
||||||
|
|
||||||
#include "../../IStream.h"
|
#include "../../IStream.h"
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt32 number;
|
UInt32 number;
|
||||||
int index = ParseStringToUInt32(name, number);
|
unsigned index = ParseStringToUInt32(name, number);
|
||||||
UString realName = name.Ptr(index);
|
UString realName = name.Ptr(index);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
{
|
{
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,9 +119,9 @@ HRESULT COutVolumeStream::Flush()
|
|||||||
/*
|
/*
|
||||||
STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
if(processedSize != NULL)
|
if (processedSize)
|
||||||
*processedSize = 0;
|
*processedSize = 0;
|
||||||
while(size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
if (_streamIndex >= Streams.Size())
|
if (_streamIndex >= Streams.Size())
|
||||||
{
|
{
|
||||||
@@ -157,7 +157,7 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
|
|||||||
_absPos += realProcessed;
|
_absPos += realProcessed;
|
||||||
if (_absPos > _length)
|
if (_absPos > _length)
|
||||||
_length = _absPos;
|
_length = _absPos;
|
||||||
if(processedSize != NULL)
|
if (processedSize)
|
||||||
*processedSize += realProcessed;
|
*processedSize += realProcessed;
|
||||||
if (subStream.Pos == subStream.Size)
|
if (subStream.Pos == subStream.Size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "../../../C/CpuArch.h"
|
#include "../../../C/CpuArch.h"
|
||||||
|
|
||||||
#include "../../Common/ComTry.h"
|
#include "../../Common/ComTry.h"
|
||||||
|
#include "../../Common/MyLinux.h"
|
||||||
#include "../../Common/StringConvert.h"
|
#include "../../Common/StringConvert.h"
|
||||||
#include "../../Common/StringToInt.h"
|
#include "../../Common/StringToInt.h"
|
||||||
#include "../../Common/UTFConvert.h"
|
#include "../../Common/UTFConvert.h"
|
||||||
@@ -121,7 +122,7 @@ struct CItem
|
|||||||
|
|
||||||
bool IsBin() const { return Type == k_Type_BinLe || Type == k_Type_BinBe; }
|
bool IsBin() const { return Type == k_Type_BinLe || Type == k_Type_BinBe; }
|
||||||
bool IsCrcFormat() const { return Type == k_Type_HexCrc; }
|
bool IsCrcFormat() const { return Type == k_Type_HexCrc; }
|
||||||
bool IsDir() const { return (Mode & 0170000) == 0040000; }
|
bool IsDir() const { return MY_LIN_S_ISDIR(Mode); }
|
||||||
bool IsTrailer() const { return strcmp(Name, kName_TRAILER) == 0; }
|
bool IsTrailer() const { return strcmp(Name, kName_TRAILER) == 0; }
|
||||||
UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; }
|
UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "../../../C/LzmaDec.h"
|
#include "../../../C/LzmaDec.h"
|
||||||
|
|
||||||
#include "../../Common/ComTry.h"
|
#include "../../Common/ComTry.h"
|
||||||
|
#include "../../Common/MyLinux.h"
|
||||||
#include "../../Common/StringConvert.h"
|
#include "../../Common/StringConvert.h"
|
||||||
|
|
||||||
#include "../../Windows/PropVariantUtils.h"
|
#include "../../Windows/PropVariantUtils.h"
|
||||||
@@ -98,7 +99,7 @@ struct CNode
|
|||||||
#define Get32(p) (be ? GetBe32(p) : GetUi32(p))
|
#define Get32(p) (be ? GetBe32(p) : GetUi32(p))
|
||||||
|
|
||||||
static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); }
|
static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); }
|
||||||
static bool IsDir(const Byte *p, bool be) { return (GetMode(p, be) & 0xF000) == 0x4000; }
|
static bool IsDir(const Byte *p, bool be) { return MY_LIN_S_ISDIR(GetMode(p, be)); }
|
||||||
|
|
||||||
static UInt32 GetSize(const Byte *p, bool be)
|
static UInt32 GetSize(const Byte *p, bool be)
|
||||||
{
|
{
|
||||||
@@ -146,7 +147,7 @@ struct CHeader
|
|||||||
{
|
{
|
||||||
if (memcmp(p + 16, kSignature, ARRAY_SIZE(kSignature)) != 0)
|
if (memcmp(p + 16, kSignature, ARRAY_SIZE(kSignature)) != 0)
|
||||||
return false;
|
return false;
|
||||||
switch(GetUi32(p))
|
switch (GetUi32(p))
|
||||||
{
|
{
|
||||||
case 0x28CD3D45: be = false; break;
|
case 0x28CD3D45: be = false; break;
|
||||||
case 0x453DCD28: be = true; break;
|
case 0x453DCD28: be = true; break;
|
||||||
@@ -354,7 +355,7 @@ HRESULT CHandler::Open2(IInStream *inStream)
|
|||||||
|
|
||||||
if (!_h.IsVer2())
|
if (!_h.IsVer2())
|
||||||
{
|
{
|
||||||
FOR_VECTOR(i, _items)
|
FOR_VECTOR (i, _items)
|
||||||
{
|
{
|
||||||
const CItem &item = _items[i];
|
const CItem &item = _items[i];
|
||||||
const Byte *p = _data + item.Offset;
|
const Byte *p = _data + item.Offset;
|
||||||
@@ -530,7 +531,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
const Byte *p = _data + item.Offset;
|
const Byte *p = _data + item.Offset;
|
||||||
bool be = _h.be;
|
bool be = _h.be;
|
||||||
bool isDir = IsDir(p, be);
|
bool isDir = IsDir(p, be);
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
|
case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
|
||||||
case kpidIsDir: prop = isDir; break;
|
case kpidIsDir: prop = isDir; break;
|
||||||
@@ -582,13 +583,13 @@ HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool be = _h.be;
|
const bool be = _h.be;
|
||||||
const Byte *p = _data + (_curBlocksOffset + (UInt32)blockIndex * 4);
|
const Byte *p2 = _data + (_curBlocksOffset + (UInt32)blockIndex * 4);
|
||||||
UInt32 start = (blockIndex == 0 ? _curBlocksOffset + _curNumBlocks * 4: Get32(p - 4));
|
const UInt32 start = (blockIndex == 0 ? _curBlocksOffset + _curNumBlocks * 4: Get32(p2 - 4));
|
||||||
UInt32 end = Get32(p);
|
const UInt32 end = Get32(p2);
|
||||||
if (end < start || end > _size)
|
if (end < start || end > _size)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
UInt32 inSize = end - start;
|
const UInt32 inSize = end - start;
|
||||||
|
|
||||||
if (_method == k_Flags_Method_LZMA)
|
if (_method == k_Flags_Method_LZMA)
|
||||||
{
|
{
|
||||||
@@ -660,10 +661,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
lps->Init(extractCallback, false);
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
|
||||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
|
||||||
streamSpec->SetStream(_stream);
|
|
||||||
|
|
||||||
for (i = 0; i < numItems; i++)
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
lps->InSize = totalPackSize;
|
lps->InSize = totalPackSize;
|
||||||
@@ -701,20 +698,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
int res = NExtract::NOperationResult::kDataError;
|
int res = NExtract::NOperationResult::kDataError;
|
||||||
{
|
{
|
||||||
CMyComPtr<ISequentialInStream> inSeqStream;
|
CMyComPtr<ISequentialInStream> inSeqStream;
|
||||||
CMyComPtr<IInStream> inStream;
|
|
||||||
HRESULT hres = GetStream(index, &inSeqStream);
|
HRESULT hres = GetStream(index, &inSeqStream);
|
||||||
if (inSeqStream)
|
|
||||||
inSeqStream.QueryInterface(IID_IInStream, &inStream);
|
|
||||||
if (hres == E_OUTOFMEMORY)
|
if (hres == E_OUTOFMEMORY)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
if (hres == S_FALSE || !inStream)
|
if (hres == S_FALSE || !inSeqStream)
|
||||||
res = NExtract::NOperationResult::kUnsupportedMethod;
|
res = NExtract::NOperationResult::kUnsupportedMethod;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RINOK(hres);
|
RINOK(hres);
|
||||||
if (inStream)
|
|
||||||
{
|
{
|
||||||
HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress);
|
||||||
if (hres == S_OK)
|
if (hres == S_OK)
|
||||||
{
|
{
|
||||||
if (copyCoderSpec->TotalSize == curSize)
|
if (copyCoderSpec->TotalSize == curSize)
|
||||||
@@ -729,6 +722,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
RINOK(extractCallback->SetOperationResult(res));
|
RINOK(extractCallback->SetOperationResult(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../Common/MyWindows.h"
|
||||||
|
|
||||||
#include "../../Common/MyInitGuid.h"
|
#include "../../Common/MyInitGuid.h"
|
||||||
|
|
||||||
#if defined(_7ZIP_LARGE_PAGES)
|
#if defined(_7ZIP_LARGE_PAGES)
|
||||||
@@ -24,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
|
||||||
@@ -47,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,
|
||||||
|
|||||||
@@ -34,48 +34,35 @@
|
|||||||
|
|
||||||
static const Byte k_Base64Table[256] =
|
static const Byte k_Base64Table[256] =
|
||||||
{
|
{
|
||||||
64,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
66,77,77,77,77,77,77,77,77,65,65,77,77,65,77,77,
|
||||||
77,77,77,77,77,77,77,77,77,77,77,62,77,64,77,63,52,53,54,55,56,57,58,59,60,61,77,77,77,77,77,77,
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
||||||
77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,77,77,77,77,77,
|
65,77,77,77,77,77,77,77,77,77,77,62,77,77,77,63,
|
||||||
77,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,77,77,77,77,77,
|
52,53,54,55,56,57,58,59,60,61,77,77,77,64,77,77,
|
||||||
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
|
||||||
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
15,16,17,18,19,20,21,22,23,24,25,77,77,77,77,77,
|
||||||
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
77,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
|
||||||
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77
|
41,42,43,44,45,46,47,48,49,50,51,77,77,77,77,77,
|
||||||
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
||||||
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
||||||
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
||||||
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
||||||
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
||||||
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
||||||
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
|
||||||
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77
|
||||||
};
|
};
|
||||||
|
|
||||||
static Byte *Base64ToBin(Byte *dest, const char *src)
|
static Byte *Base64ToBin(Byte *dest, const char *src)
|
||||||
{
|
{
|
||||||
UInt32 val = 1;
|
UInt32 val = 1;
|
||||||
UInt32 c = k_Base64Table[(Byte)(*src++)];
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/*
|
UInt32 c = k_Base64Table[(Byte)(*src++)];
|
||||||
UInt32 c = (Byte)(*src++);
|
|
||||||
if (c >= 'A')
|
|
||||||
{
|
|
||||||
if (c <= 'Z') c -= 'A';
|
|
||||||
else if (c >= 'a' && c <= 'z') c -= 'a' - 26;
|
|
||||||
else continue;
|
|
||||||
}
|
|
||||||
else if (c >= '0')
|
|
||||||
{
|
|
||||||
if (c <= '9') c += 52 - '0';
|
|
||||||
else if (c == '=') break;
|
|
||||||
else continue;
|
|
||||||
}
|
|
||||||
else if (c == '+') c = 62;
|
|
||||||
else if (c == '/') c = 63;
|
|
||||||
else if (c == 0) break;
|
|
||||||
else continue;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// UInt32 c = k_Base64Table[(Byte)(*src++)];
|
|
||||||
if (c < 64)
|
if (c < 64)
|
||||||
{
|
{
|
||||||
val = (val << 6) | c;
|
val = (val << 6) | c;
|
||||||
c = k_Base64Table[(Byte)(*src++)];
|
|
||||||
if ((val & ((UInt32)1 << 24)) == 0)
|
if ((val & ((UInt32)1 << 24)) == 0)
|
||||||
continue;
|
continue;
|
||||||
dest[0] = (Byte)(val >> 16);
|
dest[0] = (Byte)(val >> 16);
|
||||||
@@ -85,19 +72,41 @@ static Byte *Base64ToBin(Byte *dest, const char *src)
|
|||||||
val = 1;
|
val = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c == 64)
|
|
||||||
|
if (c == 65) // space
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (c == 64) // '='
|
||||||
break;
|
break;
|
||||||
c = k_Base64Table[(Byte)(*src++)];
|
|
||||||
|
if (c == 66 && val == 1) // end of string
|
||||||
|
return dest;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val >= ((UInt32)1 << 12))
|
if (val < (1 << 12))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (val & (1 << 18))
|
||||||
{
|
{
|
||||||
if (val >= ((UInt32)1 << 18))
|
*dest++ = (Byte)(val >> 10);
|
||||||
*dest++ = (Byte)(val >> 16);
|
*dest++ = (Byte)(val >> 2);
|
||||||
*dest++ = (Byte)(val);
|
|
||||||
}
|
}
|
||||||
|
else if (k_Base64Table[(Byte)(*src++)] != 64) // '='
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
*dest++ = (Byte)(val >> 4);
|
||||||
|
|
||||||
return dest;
|
for (;;)
|
||||||
|
{
|
||||||
|
Byte c = k_Base64Table[(Byte)(*src++)];
|
||||||
|
if (c == 65) // space
|
||||||
|
continue;
|
||||||
|
if (c == 66) // end of string
|
||||||
|
return dest;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -545,8 +554,8 @@ HRESULT CHandler::Open2(IInStream *stream)
|
|||||||
CChecksum masterChecksum;
|
CChecksum masterChecksum;
|
||||||
masterChecksum.Parse(buf + 0x160);
|
masterChecksum.Parse(buf + 0x160);
|
||||||
|
|
||||||
// UInt32 imageVariant = Get32(buf + 0x1E8);
|
// UInt32 imageVariant = Get32(buf + 0x1E8);
|
||||||
// UInt64 numSectors = Get64(buf + 0x1EC);
|
// UInt64 numSectors = Get64(buf + 0x1EC);
|
||||||
// Byte reserved[0x12]
|
// Byte reserved[0x12]
|
||||||
|
|
||||||
const UInt32 RSRC_HEAD_SIZE = 0x100;
|
const UInt32 RSRC_HEAD_SIZE = 0x100;
|
||||||
@@ -720,7 +729,13 @@ HRESULT CHandler::Open2(IInStream *stream)
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
destLen = dataString->Len() / 4 * 3 + 4;
|
destLen = dataString->Len() / 4 * 3 + 4;
|
||||||
rawBuf.Alloc(destLen);
|
rawBuf.Alloc(destLen);
|
||||||
destLen = (unsigned)(Base64ToBin(rawBuf, *dataString) - rawBuf);
|
{
|
||||||
|
const Byte *endPtr = Base64ToBin(rawBuf, *dataString);
|
||||||
|
if (!endPtr)
|
||||||
|
return S_FALSE;
|
||||||
|
destLen = (unsigned)(endPtr - rawBuf);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DMG_SHOW_RAW
|
#ifdef DMG_SHOW_RAW
|
||||||
CExtraFile &extra = _extras.AddNew();
|
CExtraFile &extra = _extras.AddNew();
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ bool CHeader::Parse(const Byte *p)
|
|||||||
|
|
||||||
#define PT_PHDR 6
|
#define PT_PHDR 6
|
||||||
|
|
||||||
static const char *g_SegnmentTypes[] =
|
static const char * const g_SegnmentTypes[] =
|
||||||
{
|
{
|
||||||
"Unused",
|
"Unused",
|
||||||
"Loadable segment",
|
"Loadable segment",
|
||||||
@@ -226,25 +226,25 @@ void CSegment::Parse(const Byte *p, bool mode64, bool be)
|
|||||||
|
|
||||||
// Section types
|
// Section types
|
||||||
|
|
||||||
#define SHT_NULL 0
|
#define SHT_NULL 0
|
||||||
#define SHT_PROGBITS 1
|
#define SHT_PROGBITS 1
|
||||||
#define SHT_SYMTAB 2
|
#define SHT_SYMTAB 2
|
||||||
#define SHT_STRTAB 3
|
#define SHT_STRTAB 3
|
||||||
#define SHT_RELA 4
|
#define SHT_RELA 4
|
||||||
#define SHT_HASH 5
|
#define SHT_HASH 5
|
||||||
#define SHT_DYNAMIC 6
|
#define SHT_DYNAMIC 6
|
||||||
#define SHT_NOTE 7
|
#define SHT_NOTE 7
|
||||||
#define SHT_NOBITS 8
|
#define SHT_NOBITS 8
|
||||||
#define SHT_REL 9
|
#define SHT_REL 9
|
||||||
#define SHT_SHLIB 10
|
#define SHT_SHLIB 10
|
||||||
#define SHT_DYNSYM 11
|
#define SHT_DYNSYM 11
|
||||||
#define SHT_UNKNOWN12 12
|
#define SHT_UNKNOWN12 12
|
||||||
#define SHT_UNKNOWN13 13
|
#define SHT_UNKNOWN13 13
|
||||||
#define SHT_INIT_ARRAY 14
|
#define SHT_INIT_ARRAY 14
|
||||||
#define SHT_FINI_ARRAY 15
|
#define SHT_FINI_ARRAY 15
|
||||||
#define SHT_PREINIT_ARRAY 16
|
#define SHT_PREINIT_ARRAY 16
|
||||||
#define SHT_GROUP 17
|
#define SHT_GROUP 17
|
||||||
#define SHT_SYMTAB_SHNDX 18
|
#define SHT_SYMTAB_SHNDX 18
|
||||||
|
|
||||||
|
|
||||||
static const CUInt32PCharPair g_SectTypes[] =
|
static const CUInt32PCharPair g_SectTypes[] =
|
||||||
@@ -554,13 +554,31 @@ static const CUInt32PCharPair g_OS[] =
|
|||||||
{ 255, "Standalone" }
|
{ 255, "Standalone" }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ET_NONE 0
|
#define k_Machine_ARM 40
|
||||||
#define ET_REL 1
|
|
||||||
#define ET_EXEC 2
|
|
||||||
#define ET_DYN 3
|
|
||||||
#define ET_CORE 4
|
|
||||||
|
|
||||||
static const char *g_Types[] =
|
/*
|
||||||
|
#define EF_ARM_ABIMASK 0xFF000000
|
||||||
|
#define EF_ARM_BE8 0x00800000
|
||||||
|
#define EF_ARM_GCCMASK 0x00400FFF
|
||||||
|
#define EF_ARM_ABI_FLOAT_SOFT 0x00000200
|
||||||
|
#define EF_ARM_ABI_FLOAT_HARD 0x00000400
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const CUInt32PCharPair g_ARM_Flags[] =
|
||||||
|
{
|
||||||
|
{ 9, "SF" },
|
||||||
|
{ 10, "HF" },
|
||||||
|
{ 23, "BE8" }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define ET_NONE 0
|
||||||
|
#define ET_REL 1
|
||||||
|
#define ET_EXEC 2
|
||||||
|
#define ET_DYN 3
|
||||||
|
#define ET_CORE 4
|
||||||
|
|
||||||
|
static const char * const g_Types[] =
|
||||||
{
|
{
|
||||||
"None",
|
"None",
|
||||||
"Relocatable file",
|
"Relocatable file",
|
||||||
@@ -569,6 +587,9 @@ static const char *g_Types[] =
|
|||||||
"Core file"
|
"Core file"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
public IArchiveAllowTail,
|
public IArchiveAllowTail,
|
||||||
@@ -632,7 +653,7 @@ enum
|
|||||||
kpidInfoSection
|
kpidInfoSection
|
||||||
};
|
};
|
||||||
|
|
||||||
static const STATPROPSTG kProps[] =
|
static const CStatProp kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR },
|
{ NULL, kpidPath, VT_BSTR },
|
||||||
{ NULL, kpidSize, VT_UI8 },
|
{ NULL, kpidSize, VT_UI8 },
|
||||||
@@ -641,8 +662,8 @@ static const STATPROPSTG kProps[] =
|
|||||||
{ NULL, kpidVa, VT_UI8 },
|
{ NULL, kpidVa, VT_UI8 },
|
||||||
{ NULL, kpidType, VT_BSTR },
|
{ NULL, kpidType, VT_BSTR },
|
||||||
{ NULL, kpidCharacts, VT_BSTR }
|
{ NULL, kpidCharacts, VT_BSTR }
|
||||||
, { (LPOLESTR)L"Link Section", kpidLinkSection, VT_BSTR}
|
, { "Link Section", kpidLinkSection, VT_BSTR}
|
||||||
, { (LPOLESTR)L"Info Section", kpidInfoSection, VT_BSTR}
|
, { "Info Section", kpidInfoSection, VT_BSTR}
|
||||||
};
|
};
|
||||||
|
|
||||||
IMP_IInArchive_Props_WITH_NAME
|
IMP_IInArchive_Props_WITH_NAME
|
||||||
@@ -659,7 +680,29 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
case kpidBit64: if (_header.Mode64) prop = _header.Mode64; break;
|
case kpidBit64: if (_header.Mode64) prop = _header.Mode64; break;
|
||||||
case kpidBigEndian: if (_header.Be) prop = _header.Be; break;
|
case kpidBigEndian: if (_header.Be) prop = _header.Be; break;
|
||||||
case kpidShortComment:
|
case kpidShortComment:
|
||||||
case kpidCpu: PAIR_TO_PROP(g_Machines, _header.Machine, prop); break;
|
|
||||||
|
case kpidCpu:
|
||||||
|
{
|
||||||
|
AString s = TypePairToString(g_Machines, ARRAY_SIZE(g_Machines), _header.Machine);
|
||||||
|
UInt32 flags = _header.Flags;
|
||||||
|
if (flags != 0)
|
||||||
|
{
|
||||||
|
char sz[16];
|
||||||
|
s.Add_Space();
|
||||||
|
if (_header.Machine == k_Machine_ARM)
|
||||||
|
{
|
||||||
|
s += FlagsToString(g_ARM_Flags, ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1));
|
||||||
|
s += " ABI:";
|
||||||
|
ConvertUInt32ToString(flags >> 24, sz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ConvertUInt32ToHex(flags, sz);
|
||||||
|
s += sz;
|
||||||
|
}
|
||||||
|
prop = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break;
|
case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break;
|
||||||
case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break;
|
case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break;
|
||||||
case kpidExtension:
|
case kpidExtension:
|
||||||
|
|||||||
2867
CPP/7zip/Archive/ExtHandler.cpp
Normal file
2867
CPP/7zip/Archive/ExtHandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -133,15 +133,23 @@ bool CHeader::Parse(const Byte *p)
|
|||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int s = GetLog(Get16(p + 11));
|
{
|
||||||
if (s < 9 || s > 12)
|
UInt32 val32 = Get16(p + 11);
|
||||||
return false;
|
int s = GetLog(val32);
|
||||||
SectorSizeLog = (Byte)s;
|
if (s < 9 || s > 12)
|
||||||
s = GetLog(p[13]);
|
return false;
|
||||||
if (s < 0)
|
SectorSizeLog = (Byte)s;
|
||||||
return false;
|
}
|
||||||
SectorsPerClusterLog = (Byte)s;
|
{
|
||||||
|
UInt32 val32 = p[13];
|
||||||
|
int s = GetLog(val32);
|
||||||
|
if (s < 0)
|
||||||
|
return false;
|
||||||
|
SectorsPerClusterLog = (Byte)s;
|
||||||
|
}
|
||||||
ClusterSizeLog = (Byte)(SectorSizeLog + SectorsPerClusterLog);
|
ClusterSizeLog = (Byte)(SectorSizeLog + SectorsPerClusterLog);
|
||||||
|
if (ClusterSizeLog > 24)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NumReservedSectors = Get16(p + 14);
|
NumReservedSectors = Get16(p + 14);
|
||||||
@@ -152,10 +160,13 @@ bool CHeader::Parse(const Byte *p)
|
|||||||
if (NumFats < 1 || NumFats > 4)
|
if (NumFats < 1 || NumFats > 4)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// we also support images that contain 0 in offset field.
|
||||||
|
bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0));
|
||||||
|
|
||||||
UInt16 numRootDirEntries = Get16(p + 17);
|
UInt16 numRootDirEntries = Get16(p + 17);
|
||||||
if (numRootDirEntries == 0)
|
if (numRootDirEntries == 0)
|
||||||
{
|
{
|
||||||
if (codeOffset < 90)
|
if (codeOffset < 90 && !isOkOffset)
|
||||||
return false;
|
return false;
|
||||||
NumFatBits = 32;
|
NumFatBits = 32;
|
||||||
NumRootDirSectors = 0;
|
NumRootDirSectors = 0;
|
||||||
@@ -163,7 +174,7 @@ bool CHeader::Parse(const Byte *p)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Some FAT12s don't contain VolFields
|
// Some FAT12s don't contain VolFields
|
||||||
if (codeOffset < 62 - 24)
|
if (codeOffset < 62 - 24 && !isOkOffset)
|
||||||
return false;
|
return false;
|
||||||
NumFatBits = 0;
|
NumFatBits = 0;
|
||||||
UInt32 mask = (1 << (SectorSizeLog - 5)) - 1;
|
UInt32 mask = (1 << (SectorSizeLog - 5)) - 1;
|
||||||
@@ -805,7 +816,7 @@ enum
|
|||||||
// kpidFileSysType
|
// kpidFileSysType
|
||||||
};
|
};
|
||||||
|
|
||||||
static const STATPROPSTG kArcProps[] =
|
static const CStatProp kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidFileSystem, VT_BSTR},
|
{ NULL, kpidFileSystem, VT_BSTR},
|
||||||
{ NULL, kpidClusterSize, VT_UI4},
|
{ NULL, kpidClusterSize, VT_UI4},
|
||||||
@@ -814,12 +825,12 @@ static const STATPROPSTG kArcProps[] =
|
|||||||
{ NULL, kpidMTime, VT_FILETIME},
|
{ NULL, kpidMTime, VT_FILETIME},
|
||||||
{ NULL, kpidVolumeName, VT_BSTR},
|
{ NULL, kpidVolumeName, VT_BSTR},
|
||||||
|
|
||||||
{ (LPOLESTR)L"FATs", kpidNumFats, VT_UI4},
|
{ "FATs", kpidNumFats, VT_UI4},
|
||||||
{ NULL, kpidSectorSize, VT_UI4},
|
{ NULL, kpidSectorSize, VT_UI4},
|
||||||
{ NULL, kpidId, VT_UI4},
|
{ NULL, kpidId, VT_UI4},
|
||||||
// { (LPOLESTR)L"OEM Name", kpidOemName, VT_BSTR},
|
// { "OEM Name", kpidOemName, VT_BSTR},
|
||||||
// { (LPOLESTR)L"Volume Name", kpidVolName, VT_BSTR},
|
// { "Volume Name", kpidVolName, VT_BSTR},
|
||||||
// { (LPOLESTR)L"File System Type", kpidFileSysType, VT_BSTR}
|
// { "File System Type", kpidFileSysType, VT_BSTR}
|
||||||
// { NULL, kpidSectorsPerTrack, VT_UI4},
|
// { NULL, kpidSectorsPerTrack, VT_UI4},
|
||||||
// { NULL, kpidNumHeads, VT_UI4},
|
// { NULL, kpidNumHeads, VT_UI4},
|
||||||
// { NULL, kpidHiddenSectors, VT_UI4}
|
// { NULL, kpidHiddenSectors, VT_UI4}
|
||||||
@@ -858,7 +869,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidFileSystem:
|
case kpidFileSystem:
|
||||||
{
|
{
|
||||||
@@ -897,7 +908,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
const CItem &item = Items[index];
|
const CItem &item = Items[index];
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidPath: prop = GetItemPath(index); break;
|
case kpidPath: prop = GetItemPath(index); break;
|
||||||
case kpidShortName: prop = item.GetShortName(); break;
|
case kpidShortName: prop = item.GetShortName(); break;
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ static const Byte kProps[] =
|
|||||||
IMP_IInArchive_Props
|
IMP_IInArchive_Props
|
||||||
IMP_IInArchive_ArcProps_NO_Table
|
IMP_IInArchive_ArcProps_NO_Table
|
||||||
|
|
||||||
static const char *g_AudioTypes[16] =
|
static const char * const g_AudioTypes[16] =
|
||||||
{
|
{
|
||||||
"pcm"
|
"pcm"
|
||||||
, "adpcm"
|
, "adpcm"
|
||||||
@@ -113,7 +113,7 @@ static const char *g_AudioTypes[16] =
|
|||||||
, "audio15"
|
, "audio15"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *g_VideoTypes[16] =
|
static const char * const g_VideoTypes[16] =
|
||||||
{
|
{
|
||||||
"video0"
|
"video0"
|
||||||
, "jpeg"
|
, "jpeg"
|
||||||
@@ -133,7 +133,7 @@ static const char *g_VideoTypes[16] =
|
|||||||
, "video15"
|
, "video15"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *g_Rates[4] =
|
static const char * const g_Rates[4] =
|
||||||
{
|
{
|
||||||
"5.5 kHz"
|
"5.5 kHz"
|
||||||
, "11 kHz"
|
, "11 kHz"
|
||||||
@@ -145,7 +145,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
{
|
{
|
||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
const CItem2 &item = _items2[index];
|
const CItem2 &item = _items2[index];
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidExtension:
|
case kpidExtension:
|
||||||
prop = _isRaw ?
|
prop = _isRaw ?
|
||||||
@@ -209,7 +209,7 @@ AString CHandler::GetComment()
|
|||||||
Byte type = *p++;
|
Byte type = *p++;
|
||||||
size--;
|
size--;
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
switch(type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
@@ -256,7 +256,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
{
|
{
|
||||||
// COM_TRY_BEGIN
|
// COM_TRY_BEGIN
|
||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
// case kpidComment: prop = GetComment(); break;
|
// case kpidComment: prop = GetComment(); break;
|
||||||
case kpidPhySize: prop = (UInt64)_phySize; break;
|
case kpidPhySize: prop = (UInt64)_phySize; break;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user