mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-17 02:11:49 -06:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e279500d76 | ||
|
|
708873490e | ||
|
|
3dacb5eb8a |
@@ -1,7 +1,7 @@
|
|||||||
#define MY_VER_MAJOR 9
|
#define MY_VER_MAJOR 9
|
||||||
#define MY_VER_MINOR 12
|
#define MY_VER_MINOR 15
|
||||||
#define MY_VER_BUILD 0
|
#define MY_VER_BUILD 0
|
||||||
#define MY_VERSION "9.12 beta"
|
#define MY_VERSION "9.15 beta"
|
||||||
#define MY_DATE "2010-03-24"
|
#define MY_DATE "2010-06-20"
|
||||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
||||||
|
|||||||
6
C/Bra.c
6
C/Bra.c
@@ -1,5 +1,5 @@
|
|||||||
/* Bra.c -- Converters for RISC code
|
/* Bra.c -- Converters for RISC code
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
|
|
||||||
@@ -104,8 +104,8 @@ SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
|||||||
size -= 4;
|
size -= 4;
|
||||||
for (i = 0; i <= size; i += 4)
|
for (i = 0; i <= size; i += 4)
|
||||||
{
|
{
|
||||||
if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
|
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
||||||
data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
|
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
||||||
{
|
{
|
||||||
UInt32 src =
|
UInt32 src =
|
||||||
((UInt32)data[i + 0] << 24) |
|
((UInt32)data[i + 0] << 24) |
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.h -- CPU specific code
|
/* CpuArch.h -- CPU specific code
|
||||||
2010-03-11: Igor Pavlov : Public domain */
|
2010-05-20: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CPU_ARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define __CPU_ARCH_H
|
#define __CPU_ARCH_H
|
||||||
@@ -55,6 +55,7 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|
|||||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||||
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
||||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||||
|
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -78,6 +79,10 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|
|||||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||||
|
|
||||||
|
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
||||||
|
SetUi32(p, (UInt32)_x64_); \
|
||||||
|
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Enc.c -- LZMA2 Encoder
|
/* Lzma2Enc.c -- LZMA2 Encoder
|
||||||
2010-03-24 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #include <stdio.h> */
|
/* #include <stdio.h> */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -141,7 +141,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
|
|
||||||
PRF(printf(" "));
|
PRF(printf(" "));
|
||||||
|
|
||||||
outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | (u >> 16) & 0x1F);
|
outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F));
|
||||||
outBuf[destPos++] = (Byte)(u >> 8);
|
outBuf[destPos++] = (Byte)(u >> 8);
|
||||||
outBuf[destPos++] = (Byte)u;
|
outBuf[destPos++] = (Byte)u;
|
||||||
outBuf[destPos++] = (Byte)(pm >> 8);
|
outBuf[destPos++] = (Byte)(pm >> 8);
|
||||||
@@ -240,9 +240,7 @@ static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
|||||||
|
|
||||||
/* ---------- Lzma2 ---------- */
|
/* ---------- Lzma2 ---------- */
|
||||||
|
|
||||||
extern struct _CLzma2Enc;
|
typedef struct
|
||||||
|
|
||||||
typedef struct _CLzma2Enc
|
|
||||||
{
|
{
|
||||||
Byte propEncoded;
|
Byte propEncoded;
|
||||||
CLzma2EncProps props;
|
CLzma2EncProps props;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaEnc.c -- LZMA Encoder
|
/* LzmaEnc.c -- LZMA Encoder
|
||||||
2009-11-24 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -395,7 +395,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
|||||||
LzmaEncProps_Normalize(&props);
|
LzmaEncProps_Normalize(&props);
|
||||||
|
|
||||||
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
|
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
|
||||||
props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
|
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
|
||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
p->dictSize = props.dictSize;
|
p->dictSize = props.dictSize;
|
||||||
p->matchFinderCycles = props.mc;
|
p->matchFinderCycles = props.mc;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8Dec.c -- PPMdI Decoder
|
/* Ppmd8Dec.c -- PPMdI Decoder
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2010-04-16 : Igor Pavlov : Public domain
|
||||||
This code is based on:
|
This code is based on:
|
||||||
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||||
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||||
@@ -33,7 +33,7 @@ static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
|
|||||||
p->Range *= size;
|
p->Range *= size;
|
||||||
|
|
||||||
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
||||||
p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))
|
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
|
||||||
{
|
{
|
||||||
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
|
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
|
||||||
p->Range <<= 8;
|
p->Range <<= 8;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8Enc.c -- PPMdI Encoder
|
/* Ppmd8Enc.c -- PPMdI Encoder
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2010-04-16 : Igor Pavlov : Public domain
|
||||||
This code is based on:
|
This code is based on:
|
||||||
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||||
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||||
@@ -19,7 +19,7 @@ void Ppmd8_RangeEnc_FlushData(CPpmd8 *p)
|
|||||||
static void RangeEnc_Normalize(CPpmd8 *p)
|
static void RangeEnc_Normalize(CPpmd8 *p)
|
||||||
{
|
{
|
||||||
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
||||||
p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))
|
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
|
||||||
{
|
{
|
||||||
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
||||||
p->Range <<= 8;
|
p->Range <<= 8;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* Crypto/Sha256.c -- SHA-256 Hash function
|
/* Crypto/Sha256.c -- SHA-256 Hash
|
||||||
2008-11-06 : Igor Pavlov : Public domain
|
2010-06-11 : 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 "Sha256.h"
|
|
||||||
#include "RotateDefs.h"
|
#include "RotateDefs.h"
|
||||||
|
#include "Sha256.h"
|
||||||
|
|
||||||
/* define it for speed optimization */
|
/* define it for speed optimization */
|
||||||
/* #define _SHA256_UNROLL */
|
/* #define _SHA256_UNROLL */
|
||||||
@@ -71,7 +71,7 @@ void Sha256_Init(CSha256 *p)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const UInt32 K[64] = {
|
static const UInt32 K[64] = {
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||||
|
|||||||
10
C/Sha256.h
10
C/Sha256.h
@@ -1,14 +1,12 @@
|
|||||||
/* Sha256.h -- SHA-256 Hash
|
/* Sha256.h -- SHA-256 Hash
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2010-06-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CRYPTO_SHA256_H
|
#ifndef __CRYPTO_SHA256_H
|
||||||
#define __CRYPTO_SHA256_H
|
#define __CRYPTO_SHA256_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SHA256_DIGEST_SIZE 32
|
#define SHA256_DIGEST_SIZE 32
|
||||||
|
|
||||||
@@ -23,8 +21,6 @@ void Sha256_Init(CSha256 *p);
|
|||||||
void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
|
void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
|
||||||
void Sha256_Final(CSha256 *p, Byte *digest);
|
void Sha256_Final(CSha256 *p, Byte *digest);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Types.h -- Basic types
|
/* Types.h -- Basic types
|
||||||
2010-03-11 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_TYPES_H
|
#ifndef __7Z_TYPES_H
|
||||||
#define __7Z_TYPES_H
|
#define __7Z_TYPES_H
|
||||||
@@ -77,9 +77,11 @@ typedef unsigned long UInt64;
|
|||||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
typedef __int64 Int64;
|
typedef __int64 Int64;
|
||||||
typedef unsigned __int64 UInt64;
|
typedef unsigned __int64 UInt64;
|
||||||
|
#define UINT64_CONST(n) n
|
||||||
#else
|
#else
|
||||||
typedef long long int Int64;
|
typedef long long int Int64;
|
||||||
typedef unsigned long long int UInt64;
|
typedef unsigned long long int UInt64;
|
||||||
|
#define UINT64_CONST(n) n ## ULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* XzCrc64.c -- CRC64 calculation
|
/* XzCrc64.c -- CRC64 calculation
|
||||||
2009-04-15 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "XzCrc64.h"
|
#include "XzCrc64.h"
|
||||||
|
|
||||||
#define kCrc64Poly 0xC96C5795D7870F42
|
#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
|
||||||
UInt64 g_Crc64Table[256];
|
UInt64 g_Crc64Table[256];
|
||||||
|
|
||||||
void MY_FAST_CALL Crc64GenerateTable(void)
|
void MY_FAST_CALL Crc64GenerateTable(void)
|
||||||
|
|||||||
16
C/XzCrc64.h
16
C/XzCrc64.h
@@ -1,5 +1,5 @@
|
|||||||
/* XzCrc64.c -- CRC64 calculation
|
/* XzCrc64.h -- CRC64 calculation
|
||||||
2009-04-15 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __XZ_CRC64_H
|
#ifndef __XZ_CRC64_H
|
||||||
#define __XZ_CRC64_H
|
#define __XZ_CRC64_H
|
||||||
@@ -8,23 +8,19 @@
|
|||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern UInt64 g_Crc64Table[];
|
extern UInt64 g_Crc64Table[];
|
||||||
|
|
||||||
void MY_FAST_CALL Crc64GenerateTable(void);
|
void MY_FAST_CALL Crc64GenerateTable(void);
|
||||||
|
|
||||||
#define CRC64_INIT_VAL 0xFFFFFFFFFFFFFFFF
|
#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF)
|
||||||
#define CRC64_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFFFFFFFFFF)
|
#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL)
|
||||||
#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size);
|
UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size);
|
||||||
UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size);
|
UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* XzDec.c -- Xz Decode
|
/* XzDec.c -- Xz Decode
|
||||||
2009-06-08 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #define XZ_DUMP */
|
/* #define XZ_DUMP */
|
||||||
|
|
||||||
@@ -858,6 +858,8 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case XZ_STATE_BLOCK: break; /* to disable GCC warning */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ HRESULT CDecoder::Decode(
|
|||||||
size_t size = props.GetCapacity();
|
size_t size = props.GetCapacity();
|
||||||
if (size > 0xFFFFFFFF)
|
if (size > 0xFFFFFFFF)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
if (size > 0)
|
// if (size > 0)
|
||||||
{
|
{
|
||||||
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));
|
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,14 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "7zHandler.h"
|
#include "../../../Common/ComTry.h"
|
||||||
#include "7zFolderOutStream.h"
|
|
||||||
|
#include "../../Common/ProgressUtils.h"
|
||||||
|
|
||||||
#include "7zDecode.h"
|
#include "7zDecode.h"
|
||||||
// #include "7z1Decode.h"
|
// #include "7z1Decode.h"
|
||||||
|
#include "7zFolderOutStream.h"
|
||||||
#include "../../../Common/ComTry.h"
|
#include "7zHandler.h"
|
||||||
#include "../../Common/StreamObjects.h"
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
|
||||||
#include "../../Common/LimitedStreams.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
@@ -138,7 +137,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extractCallback->SetTotal(importantTotalUnpacked);
|
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
|
||||||
|
|
||||||
CDecoder decoder(
|
CDecoder decoder(
|
||||||
#ifdef _ST_MODE
|
#ifdef _ST_MODE
|
||||||
@@ -149,27 +148,26 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
);
|
);
|
||||||
// CDecoder1 decoder;
|
// CDecoder1 decoder;
|
||||||
|
|
||||||
UInt64 currentTotalPacked = 0;
|
UInt64 totalPacked = 0;
|
||||||
UInt64 currentTotalUnpacked = 0;
|
UInt64 totalUnpacked = 0;
|
||||||
UInt64 totalFolderUnpacked;
|
UInt64 curPacked, curUnpacked;
|
||||||
UInt64 totalFolderPacked;
|
|
||||||
|
|
||||||
CLocalProgress *lps = new CLocalProgress;
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
lps->Init(extractCallback, false);
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
|
for (int i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
|
||||||
currentTotalUnpacked += totalFolderUnpacked,
|
|
||||||
currentTotalPacked += totalFolderPacked)
|
|
||||||
{
|
{
|
||||||
lps->OutSize = currentTotalUnpacked;
|
lps->OutSize = totalUnpacked;
|
||||||
lps->InSize = currentTotalPacked;
|
lps->InSize = totalPacked;
|
||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
if (i >= extractFolderInfoVector.Size())
|
||||||
totalFolderUnpacked = efi.UnpackSize;
|
break;
|
||||||
|
|
||||||
totalFolderPacked = 0;
|
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
||||||
|
curUnpacked = efi.UnpackSize;
|
||||||
|
curPacked = 0;
|
||||||
|
|
||||||
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||||
@@ -187,7 +185,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
else
|
else
|
||||||
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
|
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
|
||||||
|
|
||||||
|
|
||||||
HRESULT result = folderOutStream->Init(&db,
|
HRESULT result = folderOutStream->Init(&db,
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
volume.StartRef2Index,
|
volume.StartRef2Index,
|
||||||
@@ -205,7 +202,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
CNum folderIndex = efi.FolderIndex;
|
CNum folderIndex = efi.FolderIndex;
|
||||||
const CFolder &folderInfo = db.Folders[folderIndex];
|
const CFolder &folderInfo = db.Folders[folderIndex];
|
||||||
|
|
||||||
totalFolderPacked = _db.GetFolderFullPackSize(folderIndex);
|
curPacked = _db.GetFolderFullPackSize(folderIndex);
|
||||||
|
|
||||||
CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
|
CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
|
||||||
UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
|
UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ HRESULT CFolderInStream::OpenStream()
|
|||||||
_filePos = 0;
|
_filePos = 0;
|
||||||
while (_fileIndex < _numFiles)
|
while (_fileIndex < _numFiles)
|
||||||
{
|
{
|
||||||
_currentSizeIsDefined = false;
|
|
||||||
CMyComPtr<ISequentialInStream> stream;
|
CMyComPtr<ISequentialInStream> stream;
|
||||||
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
|
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
|
||||||
if (result != S_OK && result != S_FALSE)
|
if (result != S_OK && result != S_FALSE)
|
||||||
@@ -40,26 +39,22 @@ HRESULT CFolderInStream::OpenStream()
|
|||||||
_fileIndex++;
|
_fileIndex++;
|
||||||
_inStreamWithHashSpec->SetStream(stream);
|
_inStreamWithHashSpec->SetStream(stream);
|
||||||
_inStreamWithHashSpec->Init();
|
_inStreamWithHashSpec->Init();
|
||||||
if (!stream)
|
if (stream)
|
||||||
{
|
{
|
||||||
|
_fileIsOpen = true;
|
||||||
|
CMyComPtr<IStreamGetSize> streamGetSize;
|
||||||
|
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
|
||||||
|
if (streamGetSize)
|
||||||
|
{
|
||||||
|
RINOK(streamGetSize->GetSize(&_currentSize));
|
||||||
|
_currentSizeIsDefined = true;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||||
Sizes.Add(0);
|
Sizes.Add(0);
|
||||||
Processed.Add(result == S_OK);
|
Processed.Add(result == S_OK);
|
||||||
AddDigest();
|
AddDigest();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CMyComPtr<IStreamGetSize> streamGetSize;
|
|
||||||
if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK)
|
|
||||||
{
|
|
||||||
if(streamGetSize)
|
|
||||||
{
|
|
||||||
_currentSizeIsDefined = true;
|
|
||||||
RINOK(streamGetSize->GetSize(&_currentSize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_fileIsOpen = true;
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -74,6 +69,7 @@ HRESULT CFolderInStream::CloseStream()
|
|||||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||||
_inStreamWithHashSpec->ReleaseStream();
|
_inStreamWithHashSpec->ReleaseStream();
|
||||||
_fileIsOpen = false;
|
_fileIsOpen = false;
|
||||||
|
_currentSizeIsDefined = false;
|
||||||
Processed.Add(true);
|
Processed.Add(true);
|
||||||
Sizes.Add(_filePos);
|
Sizes.Add(_filePos);
|
||||||
AddDigest();
|
AddDigest();
|
||||||
@@ -82,43 +78,40 @@ HRESULT CFolderInStream::CloseStream()
|
|||||||
|
|
||||||
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
UInt32 realProcessedSize = 0;
|
if (processedSize != 0)
|
||||||
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
|
*processedSize = 0;
|
||||||
|
while (size > 0)
|
||||||
{
|
{
|
||||||
if (_fileIsOpen)
|
if (_fileIsOpen)
|
||||||
{
|
{
|
||||||
UInt32 localProcessedSize;
|
UInt32 processed2;
|
||||||
RINOK(_inStreamWithHash->Read(
|
RINOK(_inStreamWithHash->Read(data, size, &processed2));
|
||||||
((Byte *)data) + realProcessedSize, size, &localProcessedSize));
|
if (processed2 == 0)
|
||||||
if (localProcessedSize == 0)
|
|
||||||
{
|
{
|
||||||
RINOK(CloseStream());
|
RINOK(CloseStream());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
realProcessedSize += localProcessedSize;
|
if (processedSize != 0)
|
||||||
_filePos += localProcessedSize;
|
*processedSize = processed2;
|
||||||
size -= localProcessedSize;
|
_filePos += processed2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
if (_fileIndex >= _numFiles)
|
||||||
{
|
break;
|
||||||
RINOK(OpenStream());
|
RINOK(OpenStream());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (processedSize != 0)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
||||||
{
|
{
|
||||||
*value = 0;
|
*value = 0;
|
||||||
int subStreamIndex = (int)subStream;
|
int index2 = (int)subStream;
|
||||||
if (subStreamIndex < 0 || subStream > Sizes.Size())
|
if (index2 < 0 || subStream > Sizes.Size())
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
if (subStreamIndex < Sizes.Size())
|
if (index2 < Sizes.Size())
|
||||||
{
|
{
|
||||||
*value= Sizes[subStreamIndex];
|
*value = Sizes[index2];
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
if (!_currentSizeIsDefined)
|
if (!_currentSizeIsDefined)
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
// 7z/FolderInStream.h
|
// 7zFolderInStream.h
|
||||||
|
|
||||||
#ifndef __7Z_FOLDERINSTREAM_H
|
#ifndef __7Z_FOLDER_IN_STREAM_H
|
||||||
#define __7Z_FOLDERINSTREAM_H
|
#define __7Z_FOLDER_IN_STREAM_H
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zHeader.h"
|
|
||||||
|
|
||||||
|
#include "../../ICoder.h"
|
||||||
#include "../IArchive.h"
|
#include "../IArchive.h"
|
||||||
#include "../Common/InStreamWithCRC.h"
|
#include "../Common/InStreamWithCRC.h"
|
||||||
#include "../../IStream.h"
|
|
||||||
#include "../../ICoder.h"
|
#include "7zItem.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
@@ -19,26 +17,14 @@ class CFolderInStream:
|
|||||||
public ICompressGetSubStreamSize,
|
public ICompressGetSubStreamSize,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
|
||||||
|
|
||||||
CFolderInStream();
|
|
||||||
|
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
|
|
||||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
|
||||||
private:
|
|
||||||
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
|
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
|
||||||
CMyComPtr<ISequentialInStream> _inStreamWithHash;
|
CMyComPtr<ISequentialInStream> _inStreamWithHash;
|
||||||
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
||||||
|
|
||||||
bool _currentSizeIsDefined;
|
bool _currentSizeIsDefined;
|
||||||
UInt64 _currentSize;
|
|
||||||
|
|
||||||
bool _fileIsOpen;
|
bool _fileIsOpen;
|
||||||
|
UInt64 _currentSize;
|
||||||
UInt64 _filePos;
|
UInt64 _filePos;
|
||||||
|
|
||||||
const UInt32 *_fileIndices;
|
const UInt32 *_fileIndices;
|
||||||
UInt32 _numFiles;
|
UInt32 _numFiles;
|
||||||
UInt32 _fileIndex;
|
UInt32 _fileIndex;
|
||||||
@@ -46,12 +32,18 @@ private:
|
|||||||
HRESULT OpenStream();
|
HRESULT OpenStream();
|
||||||
HRESULT CloseStream();
|
HRESULT CloseStream();
|
||||||
void AddDigest();
|
void AddDigest();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init(IArchiveUpdateCallback *updateCallback,
|
|
||||||
const UInt32 *fileIndices, UInt32 numFiles);
|
|
||||||
CRecordVector<bool> Processed;
|
CRecordVector<bool> Processed;
|
||||||
CRecordVector<UInt32> CRCs;
|
CRecordVector<UInt32> CRCs;
|
||||||
CRecordVector<UInt64> Sizes;
|
CRecordVector<UInt64> Sizes;
|
||||||
|
|
||||||
|
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||||
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||||
|
|
||||||
|
CFolderInStream();
|
||||||
|
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles);
|
||||||
UInt64 GetFullSize() const
|
UInt64 GetFullSize() const
|
||||||
{
|
{
|
||||||
UInt64 size = 0;
|
UInt64 size = 0;
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ CFolderOutStream::CFolderOutStream()
|
|||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CFolderOutStream::Init(
|
HRESULT CFolderOutStream::Init(
|
||||||
const CArchiveDatabaseEx *archiveDatabase,
|
const CArchiveDatabaseEx *db,
|
||||||
UInt32 ref2Offset, UInt32 startIndex,
|
UInt32 ref2Offset, UInt32 startIndex,
|
||||||
const CBoolVector *extractStatuses,
|
const CBoolVector *extractStatuses,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
bool testMode, bool checkCrc)
|
bool testMode, bool checkCrc)
|
||||||
{
|
{
|
||||||
_db = archiveDatabase;
|
_db = db;
|
||||||
_ref2Offset = ref2Offset;
|
_ref2Offset = ref2Offset;
|
||||||
_startIndex = startIndex;
|
_startIndex = startIndex;
|
||||||
|
|
||||||
@@ -121,6 +121,15 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
||||||
|
{
|
||||||
|
*value = 0;
|
||||||
|
if ((int)subStream >= _extractStatuses->Size())
|
||||||
|
return S_FALSE;
|
||||||
|
*value = _db->Files[_startIndex + (int)subStream].Size;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
||||||
{
|
{
|
||||||
while (_currentIndex < _extractStatuses->Size())
|
while (_currentIndex < _extractStatuses->Size())
|
||||||
|
|||||||
@@ -3,17 +3,18 @@
|
|||||||
#ifndef __7Z_FOLDER_OUT_STREAM_H
|
#ifndef __7Z_FOLDER_OUT_STREAM_H
|
||||||
#define __7Z_FOLDER_OUT_STREAM_H
|
#define __7Z_FOLDER_OUT_STREAM_H
|
||||||
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
#include "../../IStream.h"
|
#include "../../IStream.h"
|
||||||
#include "../IArchive.h"
|
#include "../IArchive.h"
|
||||||
#include "../Common/OutStreamWithCRC.h"
|
#include "../Common/OutStreamWithCRC.h"
|
||||||
|
|
||||||
|
#include "7zIn.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
class CFolderOutStream:
|
class CFolderOutStream:
|
||||||
public ISequentialOutStream,
|
public ISequentialOutStream,
|
||||||
|
public ICompressGetSubStreamSize,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
COutStreamWithCRC *_crcStreamSpec;
|
COutStreamWithCRC *_crcStreamSpec;
|
||||||
@@ -34,14 +35,15 @@ class CFolderOutStream:
|
|||||||
HRESULT CloseFileAndSetResult();
|
HRESULT CloseFileAndSetResult();
|
||||||
HRESULT ProcessEmptyFiles();
|
HRESULT ProcessEmptyFiles();
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||||
|
|
||||||
CFolderOutStream();
|
CFolderOutStream();
|
||||||
|
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||||
|
|
||||||
HRESULT Init(
|
HRESULT Init(
|
||||||
const CArchiveDatabaseEx *archiveDatabase,
|
const CArchiveDatabaseEx *db,
|
||||||
UInt32 ref2Offset, UInt32 startIndex,
|
UInt32 ref2Offset, UInt32 startIndex,
|
||||||
const CBoolVector *extractStatuses,
|
const CBoolVector *extractStatuses,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
|
|||||||
@@ -382,6 +382,12 @@ static void MakeExeMethod(const CCompressionMethodMode &method,
|
|||||||
prop.Value = kNumFastBytesForBCJ2_LZMA;
|
prop.Value = kNumFastBytesForBCJ2_LZMA;
|
||||||
methodFull.Props.Add(prop);
|
methodFull.Props.Add(prop);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
CProp prop;
|
||||||
|
prop.Id = NCoderPropID::kNumThreads;
|
||||||
|
prop.Value = (UInt32)1;
|
||||||
|
methodFull.Props.Add(prop);
|
||||||
|
}
|
||||||
|
|
||||||
exeMethod.Methods.Add(methodFull);
|
exeMethod.Methods.Add(methodFull);
|
||||||
exeMethod.Methods.Add(methodFull);
|
exeMethod.Methods.Add(methodFull);
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
|
|||||||
|
|
||||||
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
|
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
if (formatIndex >= g_NumArcs)
|
if (formatIndex >= g_NumArcs)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
const CArcInfo &arc = *g_Arcs[formatIndex];
|
const CArcInfo &arc = *g_Arcs[formatIndex];
|
||||||
@@ -119,6 +120,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
|
|||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../../C/Alloc.h"
|
||||||
|
|
||||||
#include "Common/Buffer.h"
|
#include "Common/Buffer.h"
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/Defs.h"
|
#include "Common/Defs.h"
|
||||||
@@ -32,8 +34,6 @@ namespace NCab {
|
|||||||
|
|
||||||
// #define _CAB_DETAILS
|
// #define _CAB_DETAILS
|
||||||
|
|
||||||
static const UInt32 kMaxTempBufSize = 1 << 20;
|
|
||||||
|
|
||||||
#ifdef _CAB_DETAILS
|
#ifdef _CAB_DETAILS
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -41,7 +41,7 @@ enum
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
@@ -57,18 +57,18 @@ STATPROPSTG kProps[] =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const wchar_t *kMethods[] =
|
static const char *kMethods[] =
|
||||||
{
|
{
|
||||||
L"None",
|
"None",
|
||||||
L"MSZip",
|
"MSZip",
|
||||||
L"Quantum",
|
"Quantum",
|
||||||
L"LZX"
|
"LZX"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
||||||
static const wchar_t *kUnknownMethod = L"Unknown";
|
static const char *kUnknownMethod = "Unknown";
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
static STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
// { NULL, kpidSolid, VT_BOOL},
|
// { NULL, kpidSolid, VT_BOOL},
|
||||||
@@ -87,7 +87,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
{
|
{
|
||||||
case kpidMethod:
|
case kpidMethod:
|
||||||
{
|
{
|
||||||
UString resString;
|
AString resString;
|
||||||
CRecordVector<Byte> ids;
|
CRecordVector<Byte> ids;
|
||||||
int i;
|
int i;
|
||||||
for (int v = 0; v < m_Database.Volumes.Size(); v++)
|
for (int v = 0; v < m_Database.Volumes.Size(); v++)
|
||||||
@@ -99,9 +99,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
for (i = 0; i < ids.Size(); i++)
|
for (i = 0; i < ids.Size(); i++)
|
||||||
{
|
{
|
||||||
Byte id = ids[i];
|
Byte id = ids[i];
|
||||||
UString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
|
AString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
|
||||||
if (!resString.IsEmpty())
|
if (!resString.IsEmpty())
|
||||||
resString += L' ';
|
resString += ' ';
|
||||||
resString += method;
|
resString += method;
|
||||||
}
|
}
|
||||||
prop = resString;
|
prop = resString;
|
||||||
@@ -171,12 +171,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
||||||
const CFolder &folder = db.Folders[realFolderIndex];
|
const CFolder &folder = db.Folders[realFolderIndex];
|
||||||
int methodIndex = folder.GetCompressionMethod();
|
int methodIndex = folder.GetCompressionMethod();
|
||||||
UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
AString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
||||||
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
|
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
|
||||||
methodIndex == NHeader::NCompressionMethodMajor::kQuantum)
|
methodIndex == NHeader::NCompressionMethodMajor::kQuantum)
|
||||||
{
|
{
|
||||||
method += L":";
|
method += ':';
|
||||||
wchar_t temp[32];
|
char temp[32];
|
||||||
ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
|
ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
|
||||||
method += temp;
|
method += temp;
|
||||||
}
|
}
|
||||||
@@ -344,9 +344,10 @@ private:
|
|||||||
const CMvDatabaseEx *m_Database;
|
const CMvDatabaseEx *m_Database;
|
||||||
const CRecordVector<bool> *m_ExtractStatuses;
|
const CRecordVector<bool> *m_ExtractStatuses;
|
||||||
|
|
||||||
CByteBuffer TempBuf;
|
Byte *TempBuf;
|
||||||
|
UInt32 TempBufSize;
|
||||||
|
int NumIdenticalFiles;
|
||||||
bool TempBufMode;
|
bool TempBufMode;
|
||||||
bool IsSupported;
|
|
||||||
UInt32 m_BufStartFolderOffset;
|
UInt32 m_BufStartFolderOffset;
|
||||||
|
|
||||||
int m_StartIndex;
|
int m_StartIndex;
|
||||||
@@ -362,12 +363,21 @@ private:
|
|||||||
UInt64 m_FolderSize;
|
UInt64 m_FolderSize;
|
||||||
UInt64 m_PosInFolder;
|
UInt64 m_PosInFolder;
|
||||||
|
|
||||||
|
void FreeTempBuf()
|
||||||
|
{
|
||||||
|
::MyFree(TempBuf);
|
||||||
|
TempBuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT OpenFile();
|
HRESULT OpenFile();
|
||||||
|
HRESULT CloseFileWithResOp(Int32 resOp);
|
||||||
HRESULT CloseFile();
|
HRESULT CloseFile();
|
||||||
HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
|
HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
|
||||||
public:
|
public:
|
||||||
HRESULT WriteEmptyFiles();
|
HRESULT WriteEmptyFiles();
|
||||||
|
|
||||||
|
CFolderOutStream(): TempBuf(NULL) {}
|
||||||
|
~CFolderOutStream() { FreeTempBuf(); }
|
||||||
void Init(
|
void Init(
|
||||||
const CMvDatabaseEx *database,
|
const CMvDatabaseEx *database,
|
||||||
const CRecordVector<bool> *extractStatuses,
|
const CRecordVector<bool> *extractStatuses,
|
||||||
@@ -403,32 +413,33 @@ void CFolderOutStream::Init(
|
|||||||
m_FileIsOpen = false;
|
m_FileIsOpen = false;
|
||||||
m_IsOk = true;
|
m_IsOk = true;
|
||||||
TempBufMode = false;
|
TempBufMode = false;
|
||||||
|
NumIdenticalFiles = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CFolderOutStream::CloseFileWithResOp(Int32 resOp)
|
||||||
|
{
|
||||||
|
m_RealOutStream.Release();
|
||||||
|
m_FileIsOpen = false;
|
||||||
|
NumIdenticalFiles--;
|
||||||
|
return m_ExtractCallback->SetOperationResult(resOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CFolderOutStream::CloseFile()
|
HRESULT CFolderOutStream::CloseFile()
|
||||||
{
|
{
|
||||||
m_RealOutStream.Release();
|
return CloseFileWithResOp(m_IsOk ?
|
||||||
HRESULT res = m_ExtractCallback->SetOperationResult(m_IsOk ?
|
|
||||||
NExtract::NOperationResult::kOK:
|
NExtract::NOperationResult::kOK:
|
||||||
NExtract::NOperationResult::kDataError);
|
NExtract::NOperationResult::kDataError);
|
||||||
m_FileIsOpen = false;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CFolderOutStream::OpenFile()
|
HRESULT CFolderOutStream::OpenFile()
|
||||||
{
|
{
|
||||||
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
if (NumIdenticalFiles == 0)
|
||||||
NExtract::NAskMode::kTest :
|
|
||||||
NExtract::NAskMode::kExtract) :
|
|
||||||
NExtract::NAskMode::kSkip;
|
|
||||||
|
|
||||||
if (!TempBufMode)
|
|
||||||
{
|
{
|
||||||
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];
|
||||||
int curIndex = m_CurrentIndex + 1;
|
int numExtractItems = 0;
|
||||||
for (; curIndex < m_ExtractStatuses->Size(); curIndex++)
|
int curIndex;
|
||||||
if ((*m_ExtractStatuses)[curIndex])
|
for (curIndex = m_CurrentIndex; curIndex < m_ExtractStatuses->Size(); curIndex++)
|
||||||
{
|
{
|
||||||
const CMvItem &mvItem2 = m_Database->Items[m_StartIndex + curIndex];
|
const CMvItem &mvItem2 = m_Database->Items[m_StartIndex + curIndex];
|
||||||
const CItem &item2 = m_Database->Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex];
|
const CItem &item2 = m_Database->Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex];
|
||||||
@@ -436,21 +447,46 @@ HRESULT CFolderOutStream::OpenFile()
|
|||||||
item.Size != item2.Size ||
|
item.Size != item2.Size ||
|
||||||
item.Size == 0)
|
item.Size == 0)
|
||||||
break;
|
break;
|
||||||
|
if (!m_TestMode && (*m_ExtractStatuses)[curIndex])
|
||||||
|
numExtractItems++;
|
||||||
}
|
}
|
||||||
if (curIndex > m_CurrentIndex + 1)
|
NumIdenticalFiles = (curIndex - m_CurrentIndex);
|
||||||
|
if (NumIdenticalFiles == 0)
|
||||||
|
NumIdenticalFiles = 1;
|
||||||
|
TempBufMode = false;
|
||||||
|
if (numExtractItems > 1)
|
||||||
{
|
{
|
||||||
size_t oldCapacity = TempBuf.GetCapacity();
|
if (!TempBuf || item.Size > TempBufSize)
|
||||||
IsSupported = (item.Size <= kMaxTempBufSize);
|
|
||||||
if (item.Size > oldCapacity && IsSupported)
|
|
||||||
{
|
{
|
||||||
TempBuf.SetCapacity(0);
|
FreeTempBuf();
|
||||||
TempBuf.SetCapacity(item.Size);
|
TempBuf = (Byte *)MyAlloc(item.Size);
|
||||||
|
TempBufSize = item.Size;
|
||||||
|
if (TempBuf == NULL)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
TempBufMode = true;
|
TempBufMode = true;
|
||||||
m_BufStartFolderOffset = item.Offset;
|
m_BufStartFolderOffset = item.Offset;
|
||||||
}
|
}
|
||||||
|
else if (numExtractItems == 1)
|
||||||
|
{
|
||||||
|
while (NumIdenticalFiles && !(*m_ExtractStatuses)[m_CurrentIndex])
|
||||||
|
{
|
||||||
|
CMyComPtr<ISequentialOutStream> stream;
|
||||||
|
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &stream, NExtract::NAskMode::kSkip));
|
||||||
|
if (stream)
|
||||||
|
return E_FAIL;
|
||||||
|
RINOK(m_ExtractCallback->PrepareOperation(NExtract::NAskMode::kSkip));
|
||||||
|
m_CurrentIndex++;
|
||||||
|
m_FileIsOpen = true;
|
||||||
|
CloseFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||||
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract) :
|
||||||
|
NExtract::NAskMode::kSkip;
|
||||||
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
|
RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode));
|
||||||
if (!m_RealOutStream && !m_TestMode)
|
if (!m_RealOutStream && !m_TestMode)
|
||||||
askMode = NExtract::NAskMode::kSkip;
|
askMode = NExtract::NAskMode::kSkip;
|
||||||
@@ -499,7 +535,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
|||||||
res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
|
res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
|
||||||
numBytesToWrite = processedSizeLocal;
|
numBytesToWrite = processedSizeLocal;
|
||||||
}
|
}
|
||||||
if (TempBufMode && IsSupported)
|
if (TempBufMode && TempBuf)
|
||||||
memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite);
|
memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite);
|
||||||
}
|
}
|
||||||
realProcessed += numBytesToWrite;
|
realProcessed += numBytesToWrite;
|
||||||
@@ -513,39 +549,28 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
|||||||
return res;
|
return res;
|
||||||
if (m_RemainFileSize == 0)
|
if (m_RemainFileSize == 0)
|
||||||
{
|
{
|
||||||
m_RealOutStream.Release();
|
|
||||||
RINOK(CloseFile());
|
RINOK(CloseFile());
|
||||||
|
|
||||||
if (TempBufMode)
|
while (NumIdenticalFiles)
|
||||||
{
|
{
|
||||||
while (m_CurrentIndex < m_ExtractStatuses->Size())
|
|
||||||
{
|
|
||||||
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
|
|
||||||
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
|
||||||
if (item.Offset != m_BufStartFolderOffset)
|
|
||||||
break;
|
|
||||||
HRESULT result = OpenFile();
|
HRESULT result = OpenFile();
|
||||||
m_FileIsOpen = true;
|
m_FileIsOpen = true;
|
||||||
m_CurrentIndex++;
|
m_CurrentIndex++;
|
||||||
m_IsOk = true;
|
if (result == S_OK && m_RealOutStream && TempBuf)
|
||||||
if (result == S_OK && m_RealOutStream && IsSupported)
|
result = WriteStream(m_RealOutStream, TempBuf, (size_t)(m_PosInFolder - m_BufStartFolderOffset));
|
||||||
result = WriteStream(m_RealOutStream, TempBuf, item.Size);
|
|
||||||
|
|
||||||
if (IsSupported)
|
if (!TempBuf && TempBufMode && m_RealOutStream)
|
||||||
{
|
{
|
||||||
RINOK(CloseFile());
|
RINOK(CloseFileWithResOp(NExtract::NOperationResult::kUnSupportedMethod));
|
||||||
RINOK(result);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_RealOutStream.Release();
|
RINOK(CloseFile());
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
|
||||||
m_FileIsOpen = false;
|
|
||||||
}
|
}
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
|
|||||||
{
|
{
|
||||||
InSizes.Reserve(NumInStreams);
|
InSizes.Reserve(NumInStreams);
|
||||||
InSizePointers.Reserve(NumInStreams);
|
InSizePointers.Reserve(NumInStreams);
|
||||||
OutSizePointers.Reserve(NumOutStreams);
|
OutSizes.Reserve(NumOutStreams);
|
||||||
OutSizePointers.Reserve(NumOutStreams);
|
OutSizePointers.Reserve(NumOutStreams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,6 +149,16 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre
|
|||||||
_streamBinders[i].CreateStreams(
|
_streamBinders[i].CreateStreams(
|
||||||
&_coders[inCoderIndex].InStreams[inCoderStreamIndex],
|
&_coders[inCoderIndex].InStreams[inCoderStreamIndex],
|
||||||
&_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
|
&_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
|
||||||
|
|
||||||
|
CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize;
|
||||||
|
_coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize);
|
||||||
|
_coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize);
|
||||||
|
if (inSetSize && outSetSize)
|
||||||
|
{
|
||||||
|
const UInt32 kBufSize = 1 << 19;
|
||||||
|
inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize);
|
||||||
|
outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _bindInfo.InStreams.Size(); i++)
|
for (i = 0; i < _bindInfo.InStreams.Size(); i++)
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSi
|
|||||||
{
|
{
|
||||||
UInt32 realProcessedSize;
|
UInt32 realProcessedSize;
|
||||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||||
|
/*
|
||||||
if (size > 0 && realProcessedSize == 0)
|
if (size > 0 && realProcessedSize == 0)
|
||||||
_wasFinished = true;
|
_wasFinished = true;
|
||||||
|
*/
|
||||||
_size += realProcessedSize;
|
_size += realProcessedSize;
|
||||||
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
||||||
if(processedSize != NULL)
|
if(processedSize != NULL)
|
||||||
|
|||||||
@@ -49,19 +49,19 @@ private:
|
|||||||
CMyComPtr<IInStream> _stream;
|
CMyComPtr<IInStream> _stream;
|
||||||
UInt64 _size;
|
UInt64 _size;
|
||||||
UInt32 _crc;
|
UInt32 _crc;
|
||||||
bool _wasFinished;
|
// bool _wasFinished;
|
||||||
public:
|
public:
|
||||||
void SetStream(IInStream *stream) { _stream = stream; }
|
void SetStream(IInStream *stream) { _stream = stream; }
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_wasFinished = false;
|
// _wasFinished = false;
|
||||||
_crc = CRC_INIT_VAL;
|
_crc = CRC_INIT_VAL;
|
||||||
}
|
}
|
||||||
void ReleaseStream() { _stream.Release(); }
|
void ReleaseStream() { _stream.Release(); }
|
||||||
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
||||||
UInt64 GetSize() const { return _size; }
|
UInt64 GetSize() const { return _size; }
|
||||||
bool WasFinished() const { return _wasFinished; }
|
// bool WasFinished() const { return _wasFinished; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/NewHandler.h"
|
|
||||||
#include "Common/StringConvert.h"
|
#include "Common/StringConvert.h"
|
||||||
#include "Common/StringToInt.h"
|
#include "Common/StringToInt.h"
|
||||||
|
|
||||||
|
|||||||
@@ -578,8 +578,12 @@ HRESULT CDatabase::Open()
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
UInt64 fileSize;
|
UInt64 fileSize;
|
||||||
RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize));
|
RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize));
|
||||||
|
|
||||||
|
/* we comment that check to support truncated images */
|
||||||
|
/*
|
||||||
if (fileSize < Header.GetPhySize())
|
if (fileSize < Header.GetPhySize())
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
*/
|
||||||
|
|
||||||
if (Header.IsFat32())
|
if (Header.IsFat32())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/IntToString.h"
|
#include "Common/IntToString.h"
|
||||||
#include "Common/NewHandler.h"
|
|
||||||
#include "Common/StringConvert.h"
|
#include "Common/StringConvert.h"
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
@@ -26,7 +24,7 @@ using namespace NTime;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NIso {
|
namespace NIso {
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidIsDir, VT_BOOL},
|
{ NULL, kpidIsDir, VT_BOOL},
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
static IInArchive *CreateArc() { return new NArchive::NIso::CHandler; }
|
static IInArchive *CreateArc() { return new NArchive::NIso::CHandler; }
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"Iso", L"iso", 0, 0xE7, { 'C', 'D', '0', '0', '1', 0x1 }, 7, false, CreateArc, 0 };
|
{ L"Iso", L"iso img", 0, 0xE7, { 'C', 'D', '0', '0', '1', 0x1 }, 7, false, CreateArc, 0 };
|
||||||
|
|
||||||
REGISTER_ARC(Iso)
|
REGISTER_ARC(Iso)
|
||||||
|
|||||||
@@ -646,7 +646,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
totalUnPacked += item.Size;
|
totalUnPacked += item.Size;
|
||||||
totalPacked += item.PackSize;
|
totalPacked += item.PackSize;
|
||||||
}
|
}
|
||||||
extractCallback->SetTotal(totalUnPacked);
|
RINOK(extractCallback->SetTotal(totalUnPacked));
|
||||||
|
|
||||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||||
UInt64 currentItemUnPacked, currentItemPacked;
|
UInt64 currentItemUnPacked, currentItemPacked;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace NMacho {
|
|||||||
|
|
||||||
#define MACH_SECT_ATTR_ZEROFILL 1
|
#define MACH_SECT_ATTR_ZEROFILL 1
|
||||||
|
|
||||||
const char *g_SectTypes[] =
|
static const char *g_SectTypes[] =
|
||||||
{
|
{
|
||||||
"REGULAR",
|
"REGULAR",
|
||||||
"ZEROFILL",
|
"ZEROFILL",
|
||||||
@@ -60,7 +60,7 @@ const char *g_SectTypes[] =
|
|||||||
"16BYTE_LITERALS"
|
"16BYTE_LITERALS"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *g_FileTypes[] =
|
static const char *g_FileTypes[] =
|
||||||
{
|
{
|
||||||
"0",
|
"0",
|
||||||
"OBJECT",
|
"OBJECT",
|
||||||
@@ -111,11 +111,18 @@ struct CSection
|
|||||||
char Name[kNameSize];
|
char Name[kNameSize];
|
||||||
char SegName[kNameSize];
|
char SegName[kNameSize];
|
||||||
UInt64 Va;
|
UInt64 Va;
|
||||||
UInt64 Size;
|
UInt64 Pa;
|
||||||
UInt32 Pa;
|
UInt64 VSize;
|
||||||
|
UInt64 PSize;
|
||||||
|
|
||||||
UInt32 Flags;
|
UInt32 Flags;
|
||||||
int SegmentIndex;
|
int SegmentIndex;
|
||||||
UInt64 GetPackSize() const { return Flags == MACH_SECT_ATTR_ZEROFILL ? 0 : Size; }
|
|
||||||
|
bool IsDummy;
|
||||||
|
|
||||||
|
CSection(): IsDummy(false) {}
|
||||||
|
// UInt64 GetPackSize() const { return Flags == MACH_SECT_ATTR_ZEROFILL ? 0 : Size; }
|
||||||
|
UInt64 GetPackSize() const { return PSize; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -195,8 +202,9 @@ bool CHandler::Parse(const Byte *buf, UInt32 size)
|
|||||||
if (cmdSize < offs)
|
if (cmdSize < offs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
{
|
|
||||||
UInt64 vmAddr, vmSize, phAddr, phSize;
|
UInt64 vmAddr, vmSize, phAddr, phSize;
|
||||||
|
|
||||||
|
{
|
||||||
if (cmd == MACH_CMD_SEGMENT_64)
|
if (cmd == MACH_CMD_SEGMENT_64)
|
||||||
{
|
{
|
||||||
vmAddr = Get64(buf + 0x18, be);
|
vmAddr = Get64(buf + 0x18, be);
|
||||||
@@ -226,7 +234,19 @@ bool CHandler::Parse(const Byte *buf, UInt32 size)
|
|||||||
if (numSections > (1 << 8))
|
if (numSections > (1 << 8))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (numSections-- != 0)
|
if (numSections == 0)
|
||||||
|
{
|
||||||
|
CSection section;
|
||||||
|
section.IsDummy = true;
|
||||||
|
section.SegmentIndex = _segments.Size() - 1;
|
||||||
|
section.Va = vmAddr;
|
||||||
|
section.PSize = phSize;
|
||||||
|
section.VSize = vmSize;
|
||||||
|
section.Pa = phAddr;
|
||||||
|
section.Flags = 0;
|
||||||
|
_sections.Add(section);
|
||||||
|
}
|
||||||
|
else do
|
||||||
{
|
{
|
||||||
CSection section;
|
CSection section;
|
||||||
UInt32 headerSize = (cmd == MACH_CMD_SEGMENT_64) ? 0x50 : 0x44;
|
UInt32 headerSize = (cmd == MACH_CMD_SEGMENT_64) ? 0x50 : 0x44;
|
||||||
@@ -236,23 +256,29 @@ bool CHandler::Parse(const Byte *buf, UInt32 size)
|
|||||||
if (cmd == MACH_CMD_SEGMENT_64)
|
if (cmd == MACH_CMD_SEGMENT_64)
|
||||||
{
|
{
|
||||||
section.Va = Get64(p + 0x20, be);
|
section.Va = Get64(p + 0x20, be);
|
||||||
section.Size = Get64(p + 0x28, be);
|
section.VSize = Get64(p + 0x28, be);
|
||||||
section.Pa = Get32(p + 0x30, be);
|
section.Pa = Get32(p + 0x30, be);
|
||||||
section.Flags = Get32(p + 0x40, be);
|
section.Flags = Get32(p + 0x40, be);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
section.Va = Get32(p + 0x20, be);
|
section.Va = Get32(p + 0x20, be);
|
||||||
section.Size = Get32(p + 0x24, be);
|
section.VSize = Get32(p + 0x24, be);
|
||||||
section.Pa = Get32(p + 0x28, be);
|
section.Pa = Get32(p + 0x28, be);
|
||||||
section.Flags = Get32(p + 0x38, be);
|
section.Flags = Get32(p + 0x38, be);
|
||||||
}
|
}
|
||||||
|
if (section.Flags == MACH_SECT_ATTR_ZEROFILL)
|
||||||
|
section.PSize = 0;
|
||||||
|
else
|
||||||
|
section.PSize = section.VSize;
|
||||||
memcpy(section.Name, p, kNameSize);
|
memcpy(section.Name, p, kNameSize);
|
||||||
memcpy(section.SegName, p + kNameSize, kNameSize);
|
memcpy(section.SegName, p + kNameSize, kNameSize);
|
||||||
section.SegmentIndex = _segments.Size() - 1;
|
section.SegmentIndex = _segments.Size() - 1;
|
||||||
_sections.Add(section);
|
_sections.Add(section);
|
||||||
offs += headerSize;
|
offs += headerSize;
|
||||||
}
|
}
|
||||||
|
while (--numSections);
|
||||||
|
|
||||||
if (offs != cmdSize)
|
if (offs != cmdSize)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -263,7 +289,7 @@ bool CHandler::Parse(const Byte *buf, UInt32 size)
|
|||||||
return reduceCommands || (size == 0);
|
return reduceCommands || (size == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
static STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidCpu, VT_BSTR},
|
{ NULL, kpidCpu, VT_BSTR},
|
||||||
{ NULL, kpidBit64, VT_BOOL},
|
{ NULL, kpidBit64, VT_BOOL},
|
||||||
@@ -273,7 +299,7 @@ STATPROPSTG kArcProps[] =
|
|||||||
{ NULL, kpidHeadersSize, VT_UI4}
|
{ NULL, kpidHeadersSize, VT_UI4}
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
@@ -333,10 +359,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
const CSection &item = _sections[index];
|
const CSection &item = _sections[index];
|
||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidPath: StringToProp(GetName(_segments[item.SegmentIndex].Name) + GetName(item.Name), prop); break;
|
case kpidPath:
|
||||||
case kpidSize: prop = (UInt64)item.Size; break;
|
{
|
||||||
|
AString s = GetName(_segments[item.SegmentIndex].Name);
|
||||||
|
if (!item.IsDummy)
|
||||||
|
s += GetName(item.Name);
|
||||||
|
StringToProp(s, prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kpidSize: /* prop = (UInt64)item.VSize; break; */
|
||||||
case kpidPackSize: prop = (UInt64)item.GetPackSize(); break;
|
case kpidPackSize: prop = (UInt64)item.GetPackSize(); break;
|
||||||
case kpidCharacts: StringToProp(SectFlagsToString(item.Flags), prop); break;
|
case kpidCharacts: if (!item.IsDummy) StringToProp(SectFlagsToString(item.Flags), prop); break;
|
||||||
case kpidOffset: prop = item.Pa; break;
|
case kpidOffset: prop = item.Pa; break;
|
||||||
case kpidVa: prop = item.Va; break;
|
case kpidVa: prop = item.Va; break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/IntToString.h"
|
#include "Common/IntToString.h"
|
||||||
#include "Common/NewHandler.h"
|
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
|
|
||||||
@@ -23,20 +22,20 @@ using namespace NWindows;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NNsis {
|
namespace NNsis {
|
||||||
|
|
||||||
static const wchar_t *kBcjMethod = L"BCJ";
|
static const char *kBcjMethod = "BCJ";
|
||||||
static const wchar_t *kUnknownMethod = L"Unknown";
|
static const char *kUnknownMethod = "Unknown";
|
||||||
|
|
||||||
static const wchar_t *kMethods[] =
|
static const char *kMethods[] =
|
||||||
{
|
{
|
||||||
L"Copy",
|
"Copy",
|
||||||
L"Deflate",
|
"Deflate",
|
||||||
L"BZip2",
|
"BZip2",
|
||||||
L"LZMA"
|
"LZMA"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
@@ -46,7 +45,7 @@ STATPROPSTG kProps[] =
|
|||||||
{ NULL, kpidSolid, VT_BOOL}
|
{ NULL, kpidSolid, VT_BOOL}
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
static STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
{ NULL, kpidSolid, VT_BOOL}
|
{ NULL, kpidSolid, VT_BOOL}
|
||||||
@@ -116,50 +115,45 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UString ConvertUInt32ToString(UInt32 value)
|
static AString UInt32ToString(UInt32 value)
|
||||||
{
|
{
|
||||||
wchar_t buffer[32];
|
char buffer[16];
|
||||||
ConvertUInt64ToString(value, buffer);
|
ConvertUInt32ToString(value, buffer);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UString GetStringForSizeValue(UInt32 value)
|
static AString GetStringForSizeValue(UInt32 value)
|
||||||
{
|
{
|
||||||
for (int i = 31; i >= 0; i--)
|
for (int i = 31; i >= 0; i--)
|
||||||
if ((UInt32(1) << i) == value)
|
if (((UInt32)1 << i) == value)
|
||||||
return ConvertUInt32ToString(i);
|
return UInt32ToString(i);
|
||||||
UString result;
|
char c = 'b';
|
||||||
if (value % (1 << 20) == 0)
|
if (value % (1 << 20) == 0)
|
||||||
{
|
{
|
||||||
result += ConvertUInt32ToString(value >> 20);
|
value >>= 20;
|
||||||
result += L"m";
|
c = 'm';
|
||||||
}
|
}
|
||||||
else if (value % (1 << 10) == 0)
|
else if (value % (1 << 10) == 0)
|
||||||
{
|
{
|
||||||
result += ConvertUInt32ToString(value >> 10);
|
value >>= 10;
|
||||||
result += L"k";
|
c = 'k';
|
||||||
}
|
}
|
||||||
else
|
return UInt32ToString(value) + c;
|
||||||
{
|
|
||||||
result += ConvertUInt32ToString(value);
|
|
||||||
result += L"b";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UString CHandler::GetMethod(bool useItemFilter, UInt32 dictionary) const
|
AString CHandler::GetMethod(bool useItemFilter, UInt32 dictionary) const
|
||||||
{
|
{
|
||||||
NMethodType::EEnum methodIndex = _archive.Method;
|
NMethodType::EEnum methodIndex = _archive.Method;
|
||||||
UString method;
|
AString method;
|
||||||
if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter)
|
if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter)
|
||||||
{
|
{
|
||||||
method += kBcjMethod;
|
method += kBcjMethod;
|
||||||
method += L" ";
|
method += ' ';
|
||||||
}
|
}
|
||||||
method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
||||||
if (methodIndex == NMethodType::kLZMA)
|
if (methodIndex == NMethodType::kLZMA)
|
||||||
{
|
{
|
||||||
method += L":";
|
method += ':';
|
||||||
method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary);
|
method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary);
|
||||||
}
|
}
|
||||||
return method;
|
return method;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class CHandler:
|
|||||||
bool GetUncompressedSize(int index, UInt32 &size);
|
bool GetUncompressedSize(int index, UInt32 &size);
|
||||||
bool GetCompressedSize(int index, UInt32 &size);
|
bool GetCompressedSize(int index, UInt32 &size);
|
||||||
|
|
||||||
UString GetMethod(bool useItemFilter, UInt32 dictionary) const;
|
AString GetMethod(bool useItemFilter, UInt32 dictionary) const;
|
||||||
public:
|
public:
|
||||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||||
QUERY_ENTRY_ISetCompressCodecsInfo
|
QUERY_ENTRY_ISetCompressCodecsInfo
|
||||||
|
|||||||
@@ -1290,6 +1290,7 @@ HRESULT CInArchive::Open2(
|
|||||||
_headerIsCompressed = true;
|
_headerIsCompressed = true;
|
||||||
IsSolid = true;
|
IsSolid = true;
|
||||||
FilterFlag = false;
|
FilterFlag = false;
|
||||||
|
DictionarySize = 1;
|
||||||
|
|
||||||
UInt32 compressedHeaderSize = Get32(sig);
|
UInt32 compressedHeaderSize = Get32(sig);
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ struct CItem
|
|||||||
UInt32 DictionarySize;
|
UInt32 DictionarySize;
|
||||||
|
|
||||||
CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false),
|
CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false),
|
||||||
CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0) {}
|
CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0), DictionarySize(1) {}
|
||||||
|
|
||||||
bool IsINSTDIR() const
|
bool IsINSTDIR() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1283,10 +1283,12 @@ HRESULT CDatabase::Open()
|
|||||||
{
|
{
|
||||||
if (OpenCallback)
|
if (OpenCallback)
|
||||||
{
|
{
|
||||||
// Sleep(0);
|
|
||||||
UInt64 numFiles = Recs.Size();
|
UInt64 numFiles = Recs.Size();
|
||||||
|
if ((numFiles & 0x3FF) == 0)
|
||||||
|
{
|
||||||
RINOK(OpenCallback->SetCompleted(&numFiles, &pos64));
|
RINOK(OpenCallback->SetCompleted(&numFiles, &pos64));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
UInt32 readSize = kBufSize;
|
UInt32 readSize = kBufSize;
|
||||||
UInt64 rem = mftSize - pos64;
|
UInt64 rem = mftSize - pos64;
|
||||||
if (readSize > rem)
|
if (readSize > rem)
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ struct COptHeader
|
|||||||
// UInt32 AddressOfEntryPoint;
|
// UInt32 AddressOfEntryPoint;
|
||||||
// UInt32 BaseOfCode;
|
// UInt32 BaseOfCode;
|
||||||
// UInt32 BaseOfData32;
|
// UInt32 BaseOfData32;
|
||||||
// UInt64 ImageBase;
|
UInt64 ImageBase;
|
||||||
|
|
||||||
UInt32 SectAlign;
|
UInt32 SectAlign;
|
||||||
UInt32 FileAlign;
|
UInt32 FileAlign;
|
||||||
@@ -202,8 +202,8 @@ bool COptHeader::Parse(const Byte *p, UInt32 size)
|
|||||||
|
|
||||||
// AddressOfEntryPoint = Get32(p + 16);
|
// AddressOfEntryPoint = Get32(p + 16);
|
||||||
// BaseOfCode = Get32(p + 20);
|
// BaseOfCode = Get32(p + 20);
|
||||||
// BaseOfData32 = Get32(p + 24);
|
// BaseOfData32 = hdr64 ? 0: Get32(p + 24);
|
||||||
// ImageBase = hdr64 ? GetUi64(p + 24) :Get32(p + 28);
|
ImageBase = hdr64 ? GetUi64(p + 24) : Get32(p + 28);
|
||||||
|
|
||||||
SectAlign = Get32(p + 32);
|
SectAlign = Get32(p + 32);
|
||||||
FileAlign = Get32(p + 36);
|
FileAlign = Get32(p + 36);
|
||||||
@@ -625,6 +625,10 @@ enum
|
|||||||
kpidStackCommit,
|
kpidStackCommit,
|
||||||
kpidHeapReserve,
|
kpidHeapReserve,
|
||||||
kpidHeapCommit,
|
kpidHeapCommit,
|
||||||
|
kpidImageBase
|
||||||
|
// kpidAddressOfEntryPoint,
|
||||||
|
// kpidBaseOfCode,
|
||||||
|
// kpidBaseOfData32,
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
STATPROPSTG kArcProps[] =
|
||||||
@@ -652,6 +656,10 @@ STATPROPSTG kArcProps[] =
|
|||||||
{ L"Stack Commit", kpidStackCommit, VT_UI8},
|
{ L"Stack Commit", kpidStackCommit, VT_UI8},
|
||||||
{ L"Heap Reserve", kpidHeapReserve, VT_UI8},
|
{ L"Heap Reserve", kpidHeapReserve, VT_UI8},
|
||||||
{ L"Heap Commit", kpidHeapCommit, VT_UI8},
|
{ L"Heap Commit", kpidHeapCommit, VT_UI8},
|
||||||
|
{ L"Image Base", kpidImageBase, VT_UI8}
|
||||||
|
// { L"Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8},
|
||||||
|
// { L"Base Of Code", kpidBaseOfCode, VT_UI8},
|
||||||
|
// { L"Base Of Data", kpidBaseOfData32, VT_UI8},
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
STATPROPSTG kProps[] =
|
||||||
@@ -720,6 +728,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
case kpidStackCommit: prop = _optHeader.StackCommit; break;
|
case kpidStackCommit: prop = _optHeader.StackCommit; break;
|
||||||
case kpidHeapReserve: prop = _optHeader.HeapReserve; break;
|
case kpidHeapReserve: prop = _optHeader.HeapReserve; break;
|
||||||
case kpidHeapCommit: prop = _optHeader.HeapCommit; break;
|
case kpidHeapCommit: prop = _optHeader.HeapCommit; break;
|
||||||
|
|
||||||
|
case kpidImageBase: prop = _optHeader.ImageBase; break;
|
||||||
|
// case kpidAddressOfEntryPoint: prop = _optHeader.AddressOfEntryPoint; break;
|
||||||
|
// case kpidBaseOfCode: prop = _optHeader.BaseOfCode; break;
|
||||||
|
// case kpidBaseOfData32: if (!_optHeader.Is64Bit()) prop = _optHeader.BaseOfData32; break;
|
||||||
|
|
||||||
case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break;
|
case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break;
|
||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
@@ -1393,7 +1407,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
|||||||
_parseResources = true;
|
_parseResources = true;
|
||||||
|
|
||||||
UInt64 mainSize = 0, mainSize2 = 0;
|
UInt64 mainSize = 0, mainSize2 = 0;
|
||||||
for (int i = 0; i < _sections.Size(); i++)
|
int i;
|
||||||
|
for (i = 0; i < _sections.Size(); i++)
|
||||||
{
|
{
|
||||||
const CSection § = _sections[i];
|
const CSection § = _sections[i];
|
||||||
CMixItem mixItem;
|
CMixItem mixItem;
|
||||||
@@ -1469,8 +1484,20 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
|||||||
}
|
}
|
||||||
_mixItems.Add(mixItem);
|
_mixItems.Add(mixItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainSize2 >= (1 << 20) && mainSize < mainSize2 * 2)
|
if (mainSize2 >= (1 << 20) && mainSize < mainSize2 * 2)
|
||||||
_mainSubfile = -1;
|
_mainSubfile = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < _mixItems.Size(); i++)
|
||||||
|
{
|
||||||
|
const CMixItem &mixItem = _mixItems[i];
|
||||||
|
if (mixItem.StringIndex < 0 && mixItem.ResourceIndex < 0 && _sections[mixItem.SectionIndex].Name == "_winzip_")
|
||||||
|
{
|
||||||
|
_mainSubfile = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
lastIndex = index + 1;
|
lastIndex = index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extractCallback->SetTotal(importantTotalUnPacked);
|
RINOK(extractCallback->SetTotal(importantTotalUnPacked));
|
||||||
UInt64 currentImportantTotalUnPacked = 0;
|
UInt64 currentImportantTotalUnPacked = 0;
|
||||||
UInt64 currentImportantTotalPacked = 0;
|
UInt64 currentImportantTotalPacked = 0;
|
||||||
UInt64 currentUnPackSize, currentPackSize;
|
UInt64 currentUnPackSize, currentPackSize;
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/NewHandler.h"
|
|
||||||
#include "Common/StringConvert.h"
|
#include "Common/StringConvert.h"
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
@@ -23,7 +21,7 @@ using namespace NWindows;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NTar {
|
namespace NTar {
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidIsDir, VT_BOOL},
|
{ NULL, kpidIsDir, VT_BOOL},
|
||||||
|
|||||||
@@ -69,11 +69,20 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
|
|||||||
|
|
||||||
filled = false;
|
filled = false;
|
||||||
|
|
||||||
|
bool thereAreEmptyRecords = false;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
processedSize = NFileHeader::kRecordSize;
|
processedSize = NFileHeader::kRecordSize;
|
||||||
RINOK(ReadStream(stream, buf, &processedSize));
|
RINOK(ReadStream(stream, buf, &processedSize));
|
||||||
if (processedSize == 0 || (processedSize == NFileHeader::kRecordSize && IsRecordLast(buf)))
|
if (processedSize == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
if (processedSize < NFileHeader::kRecordSize)
|
if (processedSize != NFileHeader::kRecordSize)
|
||||||
|
return S_FALSE;
|
||||||
|
if (!IsRecordLast(buf))
|
||||||
|
break;
|
||||||
|
thereAreEmptyRecords = true;
|
||||||
|
}
|
||||||
|
if (thereAreEmptyRecords)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize;
|
ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/NewHandler.h"
|
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
#include "Windows/Time.h"
|
#include "Windows/Time.h"
|
||||||
@@ -34,7 +33,7 @@ void UdfTimeToFileTime(const CTime &t, NWindows::NCOM::CPropVariant &prop)
|
|||||||
prop = ft;
|
prop = ft;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidIsDir, VT_BOOL},
|
{ NULL, kpidIsDir, VT_BOOL},
|
||||||
@@ -44,7 +43,7 @@ STATPROPSTG kProps[] =
|
|||||||
{ NULL, kpidATime, VT_FILETIME}
|
{ NULL, kpidATime, VT_FILETIME}
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
static STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidComment, VT_BSTR},
|
{ NULL, kpidComment, VT_BSTR},
|
||||||
{ NULL, kpidClusterSize, VT_UI4},
|
{ NULL, kpidClusterSize, VT_UI4},
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
static IInArchive *CreateArc() { return new NArchive::NUdf::CHandler; }
|
static IInArchive *CreateArc() { return new NArchive::NUdf::CHandler; }
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"Udf", L"iso", 0, 0xE0, { 0, 'N', 'S', 'R', '0' }, 5, false, CreateArc, 0 };
|
{ L"Udf", L"iso img", 0, 0xE0, { 0, 'N', 'S', 'R', '0' }, 5, false, CreateArc, 0 };
|
||||||
|
|
||||||
REGISTER_ARC(Udf)
|
REGISTER_ARC(Udf)
|
||||||
|
|||||||
@@ -2,18 +2,17 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/IntToString.h"
|
#include "../../../../C/CpuArch.h"
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
|
#include "Common/IntToString.h"
|
||||||
#include "Common/StringToInt.h"
|
#include "Common/StringToInt.h"
|
||||||
#include "Common/UTFConvert.h"
|
#include "Common/UTFConvert.h"
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
|
|
||||||
#include "../../Common/StreamUtils.h"
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
#include "../../Common/ProgressUtils.h"
|
||||||
|
#include "../../Common/StreamUtils.h"
|
||||||
#include "../../../../C/CpuArch.h"
|
|
||||||
|
|
||||||
#include "WimHandler.h"
|
#include "WimHandler.h"
|
||||||
|
|
||||||
@@ -28,17 +27,18 @@ namespace NWim {
|
|||||||
|
|
||||||
#define WIM_DETAILS
|
#define WIM_DETAILS
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidIsDir, VT_BOOL},
|
{ NULL, kpidIsDir, VT_BOOL},
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
{ NULL, kpidPackSize, VT_UI8},
|
{ NULL, kpidPackSize, VT_UI8},
|
||||||
{ NULL, kpidAttrib, VT_UI4},
|
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
|
||||||
{ NULL, kpidMTime, VT_FILETIME},
|
{ NULL, kpidMTime, VT_FILETIME},
|
||||||
{ NULL, kpidCTime, VT_FILETIME},
|
{ NULL, kpidCTime, VT_FILETIME},
|
||||||
{ NULL, kpidATime, VT_FILETIME}
|
{ NULL, kpidATime, VT_FILETIME},
|
||||||
|
{ NULL, kpidAttrib, VT_UI4},
|
||||||
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
|
{ NULL, kpidShortName, VT_BSTR}
|
||||||
|
|
||||||
#ifdef WIM_DETAILS
|
#ifdef WIM_DETAILS
|
||||||
, { NULL, kpidVolume, VT_UI4}
|
, { NULL, kpidVolume, VT_UI4}
|
||||||
@@ -47,14 +47,14 @@ STATPROPSTG kProps[] =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
static STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
{ NULL, kpidPackSize, VT_UI8},
|
{ NULL, kpidPackSize, VT_UI8},
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
{ NULL, kpidCTime, VT_FILETIME},
|
{ NULL, kpidCTime, VT_FILETIME},
|
||||||
{ NULL, kpidMTime, VT_FILETIME},
|
{ NULL, kpidMTime, VT_FILETIME},
|
||||||
{ NULL, kpidComment, VT_FILETIME},
|
{ NULL, kpidComment, VT_BSTR},
|
||||||
{ NULL, kpidIsVolume, VT_BOOL},
|
{ NULL, kpidIsVolume, VT_BOOL},
|
||||||
{ NULL, kpidVolume, VT_UI4},
|
{ NULL, kpidVolume, VT_UI4},
|
||||||
{ NULL, kpidNumVolumes, VT_UI4}
|
{ NULL, kpidNumVolumes, VT_UI4}
|
||||||
@@ -87,49 +87,51 @@ static bool ParseNumber32(const AString &s, UInt32 &res)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseTime(const CXmlItem &item, bool &defined, FILETIME &ft, const AString &s)
|
bool ParseTime(const CXmlItem &item, FILETIME &ft, const char *tag)
|
||||||
{
|
{
|
||||||
defined = false;
|
int index = item.FindSubTag(tag);
|
||||||
int cTimeIndex = item.FindSubTag(s);
|
if (index >= 0)
|
||||||
if (cTimeIndex >= 0)
|
|
||||||
{
|
{
|
||||||
const CXmlItem &timeItem = item.SubItems[cTimeIndex];
|
const CXmlItem &timeItem = item.SubItems[index];
|
||||||
UInt32 high = 0, low = 0;
|
UInt32 low = 0, high = 0;
|
||||||
if (ParseNumber32(timeItem.GetSubStringForTag("HIGHPART"), high) &&
|
if (ParseNumber32(timeItem.GetSubStringForTag("LOWPART"), low) &&
|
||||||
ParseNumber32(timeItem.GetSubStringForTag("LOWPART"), low))
|
ParseNumber32(timeItem.GetSubStringForTag("HIGHPART"), high))
|
||||||
{
|
{
|
||||||
defined = true;
|
|
||||||
ft.dwHighDateTime = high;
|
|
||||||
ft.dwLowDateTime = low;
|
ft.dwLowDateTime = low;
|
||||||
|
ft.dwHighDateTime = high;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageInfo::Parse(const CXmlItem &item)
|
void CImageInfo::Parse(const CXmlItem &item)
|
||||||
{
|
{
|
||||||
ParseTime(item, CTimeDefined, CTime, "CREATIONTIME");
|
CTimeDefined = ParseTime(item, CTime, "CREATIONTIME");
|
||||||
ParseTime(item, MTimeDefined, MTime, "LASTMODIFICATIONTIME");
|
MTimeDefined = ParseTime(item, MTime, "LASTMODIFICATIONTIME");
|
||||||
NameDefined = ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name);
|
NameDefined = ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name);
|
||||||
// IndexDefined = ParseNumber32(item.GetPropertyValue("INDEX"), Index);
|
// IndexDefined = ParseNumber32(item.GetPropertyValue("INDEX"), Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXml::Parse()
|
void CXml::ToUnicode(UString &s)
|
||||||
{
|
{
|
||||||
size_t size = Data.GetCapacity();
|
size_t size = Data.GetCapacity();
|
||||||
if (size < 2 || (size & 1) != 0 || (size > 1 << 24))
|
if (size < 2 || (size & 1) != 0 || size > (1 << 24))
|
||||||
return;
|
return;
|
||||||
const Byte *p = Data;
|
const Byte *p = Data;
|
||||||
if (Get16(p) != 0xFEFF)
|
if (Get16(p) != 0xFEFF)
|
||||||
return;
|
return;
|
||||||
UString s;
|
wchar_t *chars = s.GetBuffer((int)size / 2);
|
||||||
{
|
|
||||||
wchar_t *chars = s.GetBuffer((int)size / 2 + 1);
|
|
||||||
for (size_t i = 2; i < size; i += 2)
|
for (size_t i = 2; i < size; i += 2)
|
||||||
*chars++ = (wchar_t)Get16(p + i);
|
*chars++ = (wchar_t)Get16(p + i);
|
||||||
*chars = 0;
|
*chars = 0;
|
||||||
s.ReleaseBuffer();
|
s.ReleaseBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CXml::Parse()
|
||||||
|
{
|
||||||
|
UString s;
|
||||||
|
ToUnicode(s);
|
||||||
AString utf;
|
AString utf;
|
||||||
if (!ConvertUnicodeToUTF8(s, utf))
|
if (!ConvertUnicodeToUTF8(s, utf))
|
||||||
return;
|
return;
|
||||||
@@ -151,10 +153,9 @@ void CXml::Parse()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const wchar_t *kStreamsNamePrefix = L"Files" WSTRING_PATH_SEPARATOR;
|
static const char *kMethodLZX = "LZX";
|
||||||
static const wchar_t *kMethodLZX = L"LZX";
|
static const char *kMethodXpress = "XPress";
|
||||||
static const wchar_t *kMethodXpress = L"XPress";
|
static const char *kMethodCopy = "Copy";
|
||||||
static const wchar_t *kMethodCopy = L"Copy";
|
|
||||||
|
|
||||||
IMP_IInArchive_Props
|
IMP_IInArchive_Props
|
||||||
IMP_IInArchive_ArcProps
|
IMP_IInArchive_ArcProps
|
||||||
@@ -165,22 +166,22 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
|
||||||
const CImageInfo *image = NULL;
|
const CImageInfo *image = NULL;
|
||||||
if (m_Xmls.Size() == 1)
|
if (_xmls.Size() == 1)
|
||||||
{
|
{
|
||||||
const CXml &xml = m_Xmls[0];
|
const CXml &xml = _xmls[0];
|
||||||
if (xml.Images.Size() == 1)
|
if (xml.Images.Size() == 1)
|
||||||
image = &xml.Images[0];
|
image = &xml.Images[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidSize: prop = m_Database.GetUnpackSize(); break;
|
case kpidSize: prop = _db.GetUnpackSize(); break;
|
||||||
case kpidPackSize: prop = m_Database.GetPackSize(); break;
|
case kpidPackSize: prop = _db.GetPackSize(); break;
|
||||||
|
|
||||||
case kpidCTime:
|
case kpidCTime:
|
||||||
if (m_Xmls.Size() == 1)
|
if (_xmls.Size() == 1)
|
||||||
{
|
{
|
||||||
const CXml &xml = m_Xmls[0];
|
const CXml &xml = _xmls[0];
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int i = 0; i < xml.Images.Size(); i++)
|
for (int i = 0; i < xml.Images.Size(); i++)
|
||||||
{
|
{
|
||||||
@@ -195,9 +196,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case kpidMTime:
|
case kpidMTime:
|
||||||
if (m_Xmls.Size() == 1)
|
if (_xmls.Size() == 1)
|
||||||
{
|
{
|
||||||
const CXml &xml = m_Xmls[0];
|
const CXml &xml = _xmls[0];
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int i = 0; i < xml.Images.Size(); i++)
|
for (int i = 0; i < xml.Images.Size(); i++)
|
||||||
{
|
{
|
||||||
@@ -211,32 +212,43 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kpidComment: if (image != NULL && image->NameDefined) prop = image->Name; break;
|
case kpidComment:
|
||||||
|
if (image != NULL)
|
||||||
|
{
|
||||||
|
if (_xmlInComments)
|
||||||
|
{
|
||||||
|
UString s;
|
||||||
|
_xmls[0].ToUnicode(s);
|
||||||
|
prop = s;
|
||||||
|
}
|
||||||
|
else if (image->NameDefined)
|
||||||
|
prop = image->Name;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case kpidIsVolume:
|
case kpidIsVolume:
|
||||||
if (m_Xmls.Size() > 0)
|
if (_xmls.Size() > 0)
|
||||||
{
|
{
|
||||||
UInt16 volIndex = m_Xmls[0].VolIndex;
|
UInt16 volIndex = _xmls[0].VolIndex;
|
||||||
if (volIndex < m_Volumes.Size())
|
if (volIndex < _volumes.Size())
|
||||||
prop = (m_Volumes[volIndex].Header.NumParts > 1);
|
prop = (_volumes[volIndex].Header.NumParts > 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kpidVolume:
|
case kpidVolume:
|
||||||
if (m_Xmls.Size() > 0)
|
if (_xmls.Size() > 0)
|
||||||
{
|
{
|
||||||
UInt16 volIndex = m_Xmls[0].VolIndex;
|
UInt16 volIndex = _xmls[0].VolIndex;
|
||||||
if (volIndex < m_Volumes.Size())
|
if (volIndex < _volumes.Size())
|
||||||
prop = (UInt32)m_Volumes[volIndex].Header.PartNumber;
|
prop = (UInt32)_volumes[volIndex].Header.PartNumber;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kpidNumVolumes: if (m_Volumes.Size() > 0) prop = (UInt32)(m_Volumes.Size() - 1); break;
|
case kpidNumVolumes: if (_volumes.Size() > 0) prop = (UInt32)(_volumes.Size() - 1); break;
|
||||||
case kpidMethod:
|
case kpidMethod:
|
||||||
{
|
{
|
||||||
bool lzx = false, xpress = false, copy = false;
|
bool lzx = false, xpress = false, copy = false;
|
||||||
for (int i = 0; i < m_Xmls.Size(); i++)
|
for (int i = 0; i < _xmls.Size(); i++)
|
||||||
{
|
{
|
||||||
const CVolume &vol = m_Volumes[m_Xmls[i].VolIndex];
|
const CHeader &header = _volumes[_xmls[i].VolIndex].Header;
|
||||||
const CHeader &header = vol.Header;
|
|
||||||
if (header.IsCompressed())
|
if (header.IsCompressed())
|
||||||
if (header.IsLzxMode())
|
if (header.IsLzxMode())
|
||||||
lzx = true;
|
lzx = true;
|
||||||
@@ -245,19 +257,19 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
else
|
else
|
||||||
copy = true;
|
copy = true;
|
||||||
}
|
}
|
||||||
UString res;
|
AString res;
|
||||||
if (lzx)
|
if (lzx)
|
||||||
res = kMethodLZX;
|
res = kMethodLZX;
|
||||||
if (xpress)
|
if (xpress)
|
||||||
{
|
{
|
||||||
if (!res.IsEmpty())
|
if (!res.IsEmpty())
|
||||||
res += L' ';
|
res += ' ';
|
||||||
res += kMethodXpress;
|
res += kMethodXpress;
|
||||||
}
|
}
|
||||||
if (copy)
|
if (copy)
|
||||||
{
|
{
|
||||||
if (!res.IsEmpty())
|
if (!res.IsEmpty())
|
||||||
res += L' ';
|
res += ' ';
|
||||||
res += kMethodCopy;
|
res += kMethodCopy;
|
||||||
}
|
}
|
||||||
prop = res;
|
prop = res;
|
||||||
@@ -272,35 +284,41 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
if (index < (UInt32)m_Database.Items.Size())
|
if (index < (UInt32)_db.SortedItems.Size())
|
||||||
{
|
{
|
||||||
const CItem &item = m_Database.Items[index];
|
int realIndex = _db.SortedItems[index];
|
||||||
|
const CItem &item = _db.Items[realIndex];
|
||||||
const CStreamInfo *si = NULL;
|
const CStreamInfo *si = NULL;
|
||||||
const CVolume *vol = NULL;
|
const CVolume *vol = NULL;
|
||||||
if (item.StreamIndex >= 0)
|
if (item.StreamIndex >= 0)
|
||||||
{
|
{
|
||||||
si = &m_Database.Streams[item.StreamIndex];
|
si = &_db.Streams[item.StreamIndex];
|
||||||
vol = &m_Volumes[si->PartNumber];
|
vol = &_volumes[si->PartNumber];
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidPath:
|
case kpidPath:
|
||||||
if (item.HasMetadata)
|
if (item.HasMetadata)
|
||||||
prop = item.Name;
|
prop = _db.GetItemPath(realIndex);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wchar_t sz[32];
|
char sz[32];
|
||||||
ConvertUInt64ToString(item.StreamIndex, sz);
|
ConvertUInt64ToString(item.StreamIndex, sz);
|
||||||
UString s = sz;
|
AString s = sz;
|
||||||
while (s.Length() < m_NameLenForStreams)
|
while (s.Length() < _nameLenForStreams)
|
||||||
s = L'0' + s;
|
s = '0' + s;
|
||||||
s = UString(kStreamsNamePrefix) + s;
|
/*
|
||||||
|
if (si->Resource.IsFree())
|
||||||
|
prefix = "[Free]";
|
||||||
|
*/
|
||||||
|
s = "[Files]" STRING_PATH_SEPARATOR + s;
|
||||||
prop = s;
|
prop = s;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kpidIsDir: prop = item.isDir(); break;
|
case kpidShortName: if (item.HasMetadata) prop = item.ShortName; break;
|
||||||
|
|
||||||
|
case kpidIsDir: prop = item.IsDir(); break;
|
||||||
case kpidAttrib: if (item.HasMetadata) prop = item.Attrib; break;
|
case kpidAttrib: if (item.HasMetadata) prop = item.Attrib; break;
|
||||||
case kpidCTime: if (item.HasMetadata) prop = item.CTime; break;
|
case kpidCTime: if (item.HasMetadata) prop = item.CTime; break;
|
||||||
case kpidATime: if (item.HasMetadata) prop = item.ATime; break;
|
case kpidATime: if (item.HasMetadata) prop = item.ATime; break;
|
||||||
@@ -318,22 +336,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
index -= m_Database.Items.Size();
|
index -= _db.SortedItems.Size();
|
||||||
{
|
{
|
||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidPath:
|
case kpidPath:
|
||||||
{
|
{
|
||||||
wchar_t sz[32];
|
char sz[32];
|
||||||
ConvertUInt64ToString(m_Xmls[index].VolIndex, sz);
|
ConvertUInt64ToString(_xmls[index].VolIndex, sz);
|
||||||
UString s = (UString)sz + L".xml";
|
prop = (AString)"[" + (AString)sz + "].xml";
|
||||||
prop = s;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidIsDir: prop = false; break;
|
case kpidIsDir: prop = false; break;
|
||||||
case kpidPackSize:
|
case kpidPackSize:
|
||||||
case kpidSize: prop = (UInt64)m_Xmls[index].Data.GetCapacity(); break;
|
case kpidSize: prop = (UInt64)_xmls[index].Data.GetCapacity(); break;
|
||||||
case kpidMethod: prop = L"Copy"; break;
|
case kpidMethod: prop = kMethodCopy; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -374,7 +391,6 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
Close();
|
Close();
|
||||||
try
|
|
||||||
{
|
{
|
||||||
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
||||||
|
|
||||||
@@ -411,13 +427,13 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (firstVolumeIndex >= 0)
|
if (firstVolumeIndex >= 0)
|
||||||
if (!header.AreFromOnArchive(m_Volumes[firstVolumeIndex].Header))
|
if (!header.AreFromOnArchive(_volumes[firstVolumeIndex].Header))
|
||||||
break;
|
break;
|
||||||
if (m_Volumes.Size() > header.PartNumber && m_Volumes[header.PartNumber].Stream)
|
if (_volumes.Size() > header.PartNumber && _volumes[header.PartNumber].Stream)
|
||||||
break;
|
break;
|
||||||
CXml xml;
|
CXml xml;
|
||||||
xml.VolIndex = header.PartNumber;
|
xml.VolIndex = header.PartNumber;
|
||||||
res = OpenArchive(curStream, header, xml.Data, m_Database);
|
res = _db.Open(curStream, header, xml.Data, openArchiveCallback);
|
||||||
if (res != S_OK)
|
if (res != S_OK)
|
||||||
{
|
{
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
@@ -427,22 +443,22 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (m_Volumes.Size() <= header.PartNumber)
|
while (_volumes.Size() <= header.PartNumber)
|
||||||
m_Volumes.Add(CVolume());
|
_volumes.Add(CVolume());
|
||||||
CVolume &volume = m_Volumes[header.PartNumber];
|
CVolume &volume = _volumes[header.PartNumber];
|
||||||
volume.Header = header;
|
volume.Header = header;
|
||||||
volume.Stream = curStream;
|
volume.Stream = curStream;
|
||||||
|
|
||||||
firstVolumeIndex = header.PartNumber;
|
firstVolumeIndex = header.PartNumber;
|
||||||
|
|
||||||
bool needAddXml = true;
|
bool needAddXml = true;
|
||||||
if (m_Xmls.Size() != 0)
|
if (_xmls.Size() != 0)
|
||||||
if (xml.Data == m_Xmls[0].Data)
|
if (xml.Data == _xmls[0].Data)
|
||||||
needAddXml = false;
|
needAddXml = false;
|
||||||
if (needAddXml)
|
if (needAddXml)
|
||||||
{
|
{
|
||||||
xml.Parse();
|
xml.Parse();
|
||||||
m_Xmls.Add(xml);
|
_xmls.Add(xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
@@ -462,15 +478,14 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(SortDatabase(m_Database));
|
_db.DetectPathMode();
|
||||||
|
RINOK(_db.Sort(_db.SkipRoot));
|
||||||
|
|
||||||
wchar_t sz[32];
|
wchar_t sz[32];
|
||||||
ConvertUInt64ToString(m_Database.Streams.Size(), sz);
|
ConvertUInt64ToString(_db.Streams.Size(), sz);
|
||||||
m_NameLenForStreams = MyStringLen(sz);
|
_nameLenForStreams = MyStringLen(sz);
|
||||||
}
|
|
||||||
catch(...)
|
_xmlInComments = (_xmls.Size() == 1 && !_db.ShowImageNumber);
|
||||||
{
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
@@ -478,10 +493,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::Close()
|
STDMETHODIMP CHandler::Close()
|
||||||
{
|
{
|
||||||
m_Database.Clear();
|
_db.Clear();
|
||||||
m_Volumes.Clear();
|
_volumes.Clear();
|
||||||
m_Xmls.Clear();
|
_xmls.Clear();
|
||||||
m_NameLenForStreams = 0;
|
_nameLenForStreams = 0;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,7 +507,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
bool allFilesMode = (numItems == (UInt32)-1);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
|
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = m_Database.Items.Size() + m_Xmls.Size();
|
numItems = _db.SortedItems.Size() + _xmls.Size();
|
||||||
if (numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
@@ -501,17 +516,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
for (i = 0; i < numItems; i++)
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
UInt32 index = allFilesMode ? i : indices[i];
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
if (index < (UInt32)m_Database.Items.Size())
|
if (index < (UInt32)_db.SortedItems.Size())
|
||||||
{
|
{
|
||||||
int streamIndex = m_Database.Items[index].StreamIndex;
|
int streamIndex = _db.Items[_db.SortedItems[index]].StreamIndex;
|
||||||
if (streamIndex >= 0)
|
if (streamIndex >= 0)
|
||||||
{
|
{
|
||||||
const CStreamInfo &si = m_Database.Streams[streamIndex];
|
const CStreamInfo &si = _db.Streams[streamIndex];
|
||||||
totalSize += si.Resource.UnpackSize;
|
totalSize += si.Resource.UnpackSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
totalSize += m_Xmls[index - (UInt32)m_Database.Items.Size()].Data.GetCapacity();
|
totalSize += _xmls[index - (UInt32)_db.SortedItems.Size()].Data.GetCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(extractCallback->SetTotal(totalSize));
|
RINOK(extractCallback->SetTotal(totalSize));
|
||||||
@@ -546,12 +561,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
if (index >= (UInt32)m_Database.Items.Size())
|
if (index >= (UInt32)_db.SortedItems.Size())
|
||||||
{
|
{
|
||||||
if (!testMode && !realOutStream)
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
const CByteBuffer &data = m_Xmls[index - (UInt32)m_Database.Items.Size()].Data;
|
const CByteBuffer &data = _xmls[index - (UInt32)_db.SortedItems.Size()].Data;
|
||||||
currentItemUnPacked = data.GetCapacity();
|
currentItemUnPacked = data.GetCapacity();
|
||||||
if (realOutStream)
|
if (realOutStream)
|
||||||
{
|
{
|
||||||
@@ -562,7 +577,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CItem &item = m_Database.Items[index];
|
const CItem &item = _db.Items[_db.SortedItems[index]];
|
||||||
int streamIndex = item.StreamIndex;
|
int streamIndex = item.StreamIndex;
|
||||||
if (streamIndex < 0)
|
if (streamIndex < 0)
|
||||||
{
|
{
|
||||||
@@ -576,7 +591,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CStreamInfo &si = m_Database.Streams[streamIndex];
|
const CStreamInfo &si = _db.Streams[streamIndex];
|
||||||
currentItemUnPacked = si.Resource.UnpackSize;
|
currentItemUnPacked = si.Resource.UnpackSize;
|
||||||
currentItemPacked = si.Resource.PackSize;
|
currentItemPacked = si.Resource.PackSize;
|
||||||
|
|
||||||
@@ -587,7 +602,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
if (streamIndex != prevSuccessStreamIndex || realOutStream)
|
if (streamIndex != prevSuccessStreamIndex || realOutStream)
|
||||||
{
|
{
|
||||||
Byte digest[20];
|
Byte digest[20];
|
||||||
const CVolume &vol = m_Volumes[si.PartNumber];
|
const CVolume &vol = _volumes[si.PartNumber];
|
||||||
HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header.IsLzxMode(),
|
HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header.IsLzxMode(),
|
||||||
realOutStream, progress, digest);
|
realOutStream, progress, digest);
|
||||||
if (res == S_OK)
|
if (res == S_OK)
|
||||||
@@ -611,7 +626,9 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
{
|
{
|
||||||
*numItems = m_Database.Items.Size() + m_Xmls.Size();
|
*numItems = _db.SortedItems.Size();
|
||||||
|
if (!_xmlInComments)
|
||||||
|
*numItems += _xmls.Size();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "Common/MyCom.h"
|
#include "Common/MyCom.h"
|
||||||
#include "Common/MyXml.h"
|
#include "Common/MyXml.h"
|
||||||
|
|
||||||
#include "../IArchive.h"
|
|
||||||
#include "WimIn.h"
|
#include "WimIn.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
@@ -40,25 +39,35 @@ struct CXml
|
|||||||
{
|
{
|
||||||
CByteBuffer Data;
|
CByteBuffer Data;
|
||||||
UInt16 VolIndex;
|
UInt16 VolIndex;
|
||||||
|
|
||||||
CObjectVector<CImageInfo> Images;
|
CObjectVector<CImageInfo> Images;
|
||||||
|
|
||||||
|
void ToUnicode(UString &s);
|
||||||
void Parse();
|
void Parse();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
|
CDatabase _db;
|
||||||
|
CObjectVector<CVolume> _volumes;
|
||||||
|
CObjectVector<CXml> _xmls;
|
||||||
|
int _nameLenForStreams;
|
||||||
|
bool _xmlInComments;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP1(IInArchive)
|
MY_UNKNOWN_IMP1(IInArchive)
|
||||||
INTERFACE_IInArchive(;)
|
INTERFACE_IInArchive(;)
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
class COutHandler:
|
||||||
CDatabase m_Database;
|
public IOutArchive,
|
||||||
CObjectVector<CVolume> m_Volumes;
|
public CMyUnknownImp
|
||||||
CObjectVector<CXml> m_Xmls;
|
{
|
||||||
int m_NameLenForStreams;
|
public:
|
||||||
|
MY_UNKNOWN_IMP1(IOutArchive)
|
||||||
|
INTERFACE_IOutArchive(;)
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
651
CPP/7zip/Archive/Wim/WimHandlerOut.cpp
Executable file
651
CPP/7zip/Archive/Wim/WimHandlerOut.cpp
Executable file
@@ -0,0 +1,651 @@
|
|||||||
|
// WimHandlerOut.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../../C/CpuArch.h"
|
||||||
|
|
||||||
|
#include "Common/ComTry.h"
|
||||||
|
#include "Common/IntToString.h"
|
||||||
|
|
||||||
|
#include "Windows/PropVariant.h"
|
||||||
|
#include "Windows/Time.h"
|
||||||
|
|
||||||
|
#include "../../Common/LimitedStreams.h"
|
||||||
|
#include "../../Common/ProgressUtils.h"
|
||||||
|
#include "../../Common/StreamUtils.h"
|
||||||
|
|
||||||
|
#include "../../Crypto/RandGen.h"
|
||||||
|
#include "../../Crypto/Sha1.h"
|
||||||
|
|
||||||
|
#include "WimHandler.h"
|
||||||
|
|
||||||
|
using namespace NWindows;
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NWim {
|
||||||
|
|
||||||
|
struct CSha1Hash
|
||||||
|
{
|
||||||
|
Byte Hash[kHashSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHashList
|
||||||
|
{
|
||||||
|
CRecordVector<CSha1Hash> Digests;
|
||||||
|
CIntVector Sorted;
|
||||||
|
|
||||||
|
int AddUnique(const CSha1Hash &h);
|
||||||
|
};
|
||||||
|
|
||||||
|
int CHashList::AddUnique(const CSha1Hash &h)
|
||||||
|
{
|
||||||
|
int left = 0, right = Sorted.Size();
|
||||||
|
while (left != right)
|
||||||
|
{
|
||||||
|
int mid = (left + right) / 2;
|
||||||
|
int index = Sorted[mid];
|
||||||
|
UInt32 i;
|
||||||
|
const Byte *hash2 = Digests[index].Hash;
|
||||||
|
for (i = 0; i < kHashSize; i++)
|
||||||
|
if (h.Hash[i] != hash2[i])
|
||||||
|
break;
|
||||||
|
if (i == kHashSize)
|
||||||
|
return index;
|
||||||
|
if (h.Hash[i] < hash2[i])
|
||||||
|
right = mid;
|
||||||
|
else
|
||||||
|
left = mid + 1;
|
||||||
|
}
|
||||||
|
Sorted.Insert(left, Digests.Add(h));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CUpdateItem
|
||||||
|
{
|
||||||
|
UString Name;
|
||||||
|
UInt64 Size;
|
||||||
|
FILETIME CTime;
|
||||||
|
FILETIME ATime;
|
||||||
|
FILETIME MTime;
|
||||||
|
UInt32 Attrib;
|
||||||
|
bool IsDir;
|
||||||
|
int HashIndex;
|
||||||
|
|
||||||
|
CUpdateItem(): HashIndex(-1) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CDir
|
||||||
|
{
|
||||||
|
int Index;
|
||||||
|
UString Name;
|
||||||
|
CObjectVector<CDir> Dirs;
|
||||||
|
CIntVector Files;
|
||||||
|
|
||||||
|
CDir(): Index(-1) {}
|
||||||
|
bool IsLeaf() const { return Index >= 0; }
|
||||||
|
UInt64 GetNumDirs() const;
|
||||||
|
UInt64 GetNumFiles() const;
|
||||||
|
CDir* AddDir(CObjectVector<CUpdateItem> &items, const UString &name, int index);
|
||||||
|
};
|
||||||
|
|
||||||
|
UInt64 CDir::GetNumDirs() const
|
||||||
|
{
|
||||||
|
UInt64 num = Dirs.Size();
|
||||||
|
for (int i = 0; i < Dirs.Size(); i++)
|
||||||
|
num += Dirs[i].GetNumDirs();
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 CDir::GetNumFiles() const
|
||||||
|
{
|
||||||
|
UInt64 num = Files.Size();
|
||||||
|
for (int i = 0; i < Dirs.Size(); i++)
|
||||||
|
num += Dirs[i].GetNumFiles();
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDir* CDir::AddDir(CObjectVector<CUpdateItem> &items, const UString &name, int index)
|
||||||
|
{
|
||||||
|
int left = 0, right = Dirs.Size();
|
||||||
|
while (left != right)
|
||||||
|
{
|
||||||
|
int mid = (left + right) / 2;
|
||||||
|
CDir &d = Dirs[mid];
|
||||||
|
int compare = name.CompareNoCase(d.IsLeaf() ? items[Dirs[mid].Index].Name : d.Name);
|
||||||
|
if (compare == 0)
|
||||||
|
{
|
||||||
|
if (index >= 0)
|
||||||
|
d.Index = index;
|
||||||
|
return &d;
|
||||||
|
}
|
||||||
|
if (compare < 0)
|
||||||
|
right = mid;
|
||||||
|
else
|
||||||
|
left = mid + 1;
|
||||||
|
}
|
||||||
|
Dirs.Insert(left, CDir());
|
||||||
|
CDir &d = Dirs[left];
|
||||||
|
d.Index = index;
|
||||||
|
if (index < 0)
|
||||||
|
d.Name = name;
|
||||||
|
return &d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STDMETHODIMP COutHandler::GetFileTimeType(UInt32 *type)
|
||||||
|
{
|
||||||
|
*type = NFileTimeType::kWindows;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT GetTime(IArchiveUpdateCallback *callback, int index, PROPID propID, FILETIME &ft)
|
||||||
|
{
|
||||||
|
ft.dwLowDateTime = ft.dwHighDateTime = 0;
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(callback->GetProperty(index, propID, &prop));
|
||||||
|
if (prop.vt == VT_FILETIME)
|
||||||
|
ft = prop.filetime;
|
||||||
|
else if (prop.vt != VT_EMPTY)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Set16(p, d) SetUi16(p, d)
|
||||||
|
#define Set32(p, d) SetUi32(p, d)
|
||||||
|
#define Set64(p, d) SetUi64(p, d)
|
||||||
|
|
||||||
|
void CResource::WriteTo(Byte *p) const
|
||||||
|
{
|
||||||
|
Set64(p, PackSize);
|
||||||
|
p[7] = Flags;
|
||||||
|
Set64(p + 8, Offset);
|
||||||
|
Set64(p + 16, UnpackSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHeader::WriteTo(Byte *p) const
|
||||||
|
{
|
||||||
|
memcpy(p, kSignature, kSignatureSize);
|
||||||
|
Set32(p + 8, kHeaderSizeMax);
|
||||||
|
Set32(p + 0xC, Version);
|
||||||
|
Set32(p + 0x10, Flags);
|
||||||
|
Set32(p + 0x14, ChunkSize);
|
||||||
|
memcpy(p + 0x18, Guid, 16);
|
||||||
|
Set16(p + 0x28, PartNumber);
|
||||||
|
Set16(p + 0x2A, NumParts);
|
||||||
|
Set32(p + 0x2C, NumImages);
|
||||||
|
OffsetResource.WriteTo(p + 0x30);
|
||||||
|
XmlResource.WriteTo(p + 0x48);
|
||||||
|
MetadataResource.WriteTo(p + 0x60);
|
||||||
|
IntegrityResource.WriteTo(p + 0x7C);
|
||||||
|
Set32(p + 0x78, BootIndex);
|
||||||
|
memset(p + 0x94, 0, 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStreamInfo::WriteTo(Byte *p) const
|
||||||
|
{
|
||||||
|
Resource.WriteTo(p);
|
||||||
|
Set16(p + 0x18, PartNumber);
|
||||||
|
Set32(p + 0x1A, RefCount);
|
||||||
|
memcpy(p + 0x1E, Hash, kHashSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CInStreamWithSha1:
|
||||||
|
public ISequentialInStream,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
CMyComPtr<ISequentialInStream> _stream;
|
||||||
|
UInt64 _size;
|
||||||
|
NCrypto::NSha1::CContext _sha;
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP1(IInStream)
|
||||||
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
|
||||||
|
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
_size = 0;
|
||||||
|
_sha.Init();
|
||||||
|
}
|
||||||
|
void ReleaseStream() { _stream.Release(); }
|
||||||
|
UInt64 GetSize() const { return _size; }
|
||||||
|
void Final(Byte *digest) { _sha.Final(digest); }
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
|
{
|
||||||
|
UInt32 realProcessedSize;
|
||||||
|
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||||
|
_size += realProcessedSize;
|
||||||
|
_sha.Update((const Byte *)data, realProcessedSize);
|
||||||
|
if (processedSize != NULL)
|
||||||
|
*processedSize = realProcessedSize;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetFileTimeToMem(Byte *p, const FILETIME &ft)
|
||||||
|
{
|
||||||
|
Set32(p, ft.dwLowDateTime);
|
||||||
|
Set32(p + 4, ft.dwHighDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t WriteItem(const CUpdateItem &item, Byte *p, const Byte *hash)
|
||||||
|
{
|
||||||
|
int fileNameLen = item.Name.Length() * 2;
|
||||||
|
int fileNameLen2 = (fileNameLen == 0 ? fileNameLen : fileNameLen + 2);
|
||||||
|
|
||||||
|
size_t totalLen = ((kDirRecordSize + fileNameLen2 + 6) & ~7);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
memset(p, 0, totalLen);
|
||||||
|
Set64(p, totalLen);
|
||||||
|
Set64(p + 8, item.Attrib);
|
||||||
|
Set32(p + 0xC, (UInt32)(Int32)-1); // item.SecurityId
|
||||||
|
// Set64(p + 0x10, 0); // subdirOffset
|
||||||
|
SetFileTimeToMem(p + 0x28, item.CTime);
|
||||||
|
SetFileTimeToMem(p + 0x30, item.ATime);
|
||||||
|
SetFileTimeToMem(p + 0x38, item.MTime);
|
||||||
|
if (hash)
|
||||||
|
memcpy(p + 0x40, hash, kHashSize);
|
||||||
|
/*
|
||||||
|
else
|
||||||
|
memset(p + 0x40, 0, kHashSize);
|
||||||
|
*/
|
||||||
|
// Set16(p + 98, 0); // shortNameLen
|
||||||
|
Set16(p + 100, (UInt16)fileNameLen);
|
||||||
|
for (int i = 0; i * 2 < fileNameLen; i++)
|
||||||
|
Set16(p + kDirRecordSize + i * 2, item.Name[i]);
|
||||||
|
}
|
||||||
|
return totalLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteTree(const CDir &tree, CRecordVector<CSha1Hash> &digests,
|
||||||
|
CUpdateItem &defaultDirItem,
|
||||||
|
CObjectVector<CUpdateItem> &updateItems, Byte *dest, size_t &pos)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < tree.Files.Size(); i++)
|
||||||
|
{
|
||||||
|
const CUpdateItem &ui = updateItems[tree.Files[i]];
|
||||||
|
pos += WriteItem(ui, dest ? dest + pos : NULL,
|
||||||
|
ui.HashIndex >= 0 ? digests[ui.HashIndex].Hash : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t posStart = pos;
|
||||||
|
for (i = 0; i < tree.Dirs.Size(); i++)
|
||||||
|
{
|
||||||
|
const CDir &subfolder = tree.Dirs[i];
|
||||||
|
CUpdateItem *item = &defaultDirItem;
|
||||||
|
if (subfolder.IsLeaf())
|
||||||
|
item = &updateItems[subfolder.Index];
|
||||||
|
else
|
||||||
|
defaultDirItem.Name = subfolder.Name;
|
||||||
|
pos += WriteItem(*item, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest)
|
||||||
|
Set64(dest + pos, 0);
|
||||||
|
|
||||||
|
pos += 8;
|
||||||
|
|
||||||
|
for (i = 0; i < tree.Dirs.Size(); i++)
|
||||||
|
{
|
||||||
|
const CDir &subfolder = tree.Dirs[i];
|
||||||
|
if (dest)
|
||||||
|
{
|
||||||
|
CUpdateItem *item = &defaultDirItem;
|
||||||
|
if (subfolder.IsLeaf())
|
||||||
|
item = &updateItems[subfolder.Index];
|
||||||
|
else
|
||||||
|
defaultDirItem.Name = subfolder.Name;
|
||||||
|
size_t len = WriteItem(*item, dest + posStart, NULL);
|
||||||
|
Set64(dest + posStart + 0x10, pos);
|
||||||
|
posStart += len;
|
||||||
|
}
|
||||||
|
WriteTree(subfolder, digests, defaultDirItem, updateItems, dest, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddTag(AString &s, const char *name, const AString &value)
|
||||||
|
{
|
||||||
|
s += "<";
|
||||||
|
s += name;
|
||||||
|
s += ">";
|
||||||
|
s += value;
|
||||||
|
s += "</";
|
||||||
|
s += name;
|
||||||
|
s += ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddTagUInt64(AString &s, const char *name, UInt64 value)
|
||||||
|
{
|
||||||
|
char temp[32];
|
||||||
|
ConvertUInt64ToString(value, temp);
|
||||||
|
AddTag(s, name, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConvertUInt32ToHex(UInt32 value, char *s)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
int t = value & 0xF;
|
||||||
|
value >>= 4;
|
||||||
|
s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
|
||||||
|
}
|
||||||
|
s[8] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static AString TimeToXml(FILETIME &ft)
|
||||||
|
{
|
||||||
|
AString res;
|
||||||
|
char temp[16] = { '0', 'x' };
|
||||||
|
ConvertUInt32ToHex(ft.dwHighDateTime, temp + 2);
|
||||||
|
AddTag(res, "HIGHPART", temp);
|
||||||
|
ConvertUInt32ToHex(ft.dwLowDateTime, temp + 2);
|
||||||
|
AddTag(res, "LOWPART", temp);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHeader::SetDefaultFields(bool useLZX)
|
||||||
|
{
|
||||||
|
Version = kWimVersion;
|
||||||
|
Flags = NHeaderFlags::kRpFix;
|
||||||
|
ChunkSize = 0;
|
||||||
|
if (useLZX)
|
||||||
|
{
|
||||||
|
Flags |= NHeaderFlags::kCompression | NHeaderFlags::kLZX;
|
||||||
|
ChunkSize = kChunkSize;
|
||||||
|
}
|
||||||
|
g_RandomGenerator.Generate(Guid, 16);
|
||||||
|
PartNumber = 1;
|
||||||
|
NumParts = 1;
|
||||||
|
NumImages = 1;
|
||||||
|
BootIndex = 0;
|
||||||
|
OffsetResource.Clear();
|
||||||
|
XmlResource.Clear();
|
||||||
|
MetadataResource.Clear();
|
||||||
|
IntegrityResource.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT UpdateArchive(ISequentialOutStream *seqOutStream,
|
||||||
|
CDir &rootFolder,
|
||||||
|
CObjectVector<CUpdateItem> &updateItems,
|
||||||
|
IArchiveUpdateCallback *callback)
|
||||||
|
{
|
||||||
|
CMyComPtr<IOutStream> outStream;
|
||||||
|
RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
|
||||||
|
if (!outStream)
|
||||||
|
return E_NOTIMPL;
|
||||||
|
|
||||||
|
UInt64 complexity = 0;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < updateItems.Size(); i++)
|
||||||
|
complexity += updateItems[i].Size;
|
||||||
|
|
||||||
|
RINOK(callback->SetTotal(complexity));
|
||||||
|
|
||||||
|
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||||
|
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||||
|
|
||||||
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
|
lps->Init(callback, true);
|
||||||
|
|
||||||
|
complexity = 0;
|
||||||
|
|
||||||
|
bool useCompression = false;
|
||||||
|
|
||||||
|
CHeader header;
|
||||||
|
header.SetDefaultFields(useCompression);
|
||||||
|
Byte buf[kHeaderSizeMax];
|
||||||
|
header.WriteTo(buf);
|
||||||
|
RINOK(WriteStream(outStream, buf, kHeaderSizeMax));
|
||||||
|
|
||||||
|
CHashList hashes;
|
||||||
|
CObjectVector<CStreamInfo> streams;
|
||||||
|
|
||||||
|
UInt64 curPos = kHeaderSizeMax;
|
||||||
|
UInt64 unpackTotalSize = 0;
|
||||||
|
for (i = 0; i < updateItems.Size(); i++)
|
||||||
|
{
|
||||||
|
lps->InSize = lps->OutSize = complexity;
|
||||||
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
|
CUpdateItem &ui = updateItems[i];
|
||||||
|
if (ui.IsDir || ui.Size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CInStreamWithSha1 *inShaStreamSpec = new CInStreamWithSha1;
|
||||||
|
CMyComPtr<ISequentialInStream> inShaStream = inShaStreamSpec;
|
||||||
|
|
||||||
|
{
|
||||||
|
CMyComPtr<ISequentialInStream> fileInStream;
|
||||||
|
HRESULT res = callback->GetStream(i, &fileInStream);
|
||||||
|
if (res != S_FALSE)
|
||||||
|
{
|
||||||
|
RINOK(res);
|
||||||
|
inShaStreamSpec->SetStream(fileInStream);
|
||||||
|
fileInStream.Release();
|
||||||
|
inShaStreamSpec->Init();
|
||||||
|
UInt64 offsetBlockSize = 0;
|
||||||
|
if (useCompression)
|
||||||
|
{
|
||||||
|
for (UInt64 t = kChunkSize; t < ui.Size; t += kChunkSize)
|
||||||
|
{
|
||||||
|
Byte buf[8];
|
||||||
|
SetUi32(buf, (UInt32)t);
|
||||||
|
RINOK(WriteStream(outStream, buf, 4));
|
||||||
|
offsetBlockSize += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RINOK(copyCoder->Code(inShaStream, outStream, NULL, NULL, progress));
|
||||||
|
ui.Size = copyCoderSpec->TotalSize;
|
||||||
|
|
||||||
|
CSha1Hash hash;
|
||||||
|
unpackTotalSize += ui.Size;
|
||||||
|
UInt64 packSize = offsetBlockSize + ui.Size;
|
||||||
|
inShaStreamSpec->Final(hash.Hash);
|
||||||
|
int index = hashes.AddUnique(hash);
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
ui.HashIndex = index;
|
||||||
|
streams[index].RefCount++;
|
||||||
|
outStream->Seek(-(Int64)packSize, STREAM_SEEK_CUR, &curPos);
|
||||||
|
outStream->SetSize(curPos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui.HashIndex = hashes.Digests.Size() - 1;
|
||||||
|
CStreamInfo s;
|
||||||
|
s.Resource.PackSize = packSize;
|
||||||
|
s.Resource.Offset = curPos;
|
||||||
|
s.Resource.UnpackSize = ui.Size;
|
||||||
|
s.Resource.Flags = 0;
|
||||||
|
if (useCompression)
|
||||||
|
s.Resource.Flags = NResourceFlags::Compressed;
|
||||||
|
s.PartNumber = 1;
|
||||||
|
s.RefCount = 1;
|
||||||
|
memcpy(s.Hash, hash.Hash, kHashSize);
|
||||||
|
streams.Add(s);
|
||||||
|
curPos += packSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileInStream.Release();
|
||||||
|
complexity += ui.Size;
|
||||||
|
RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CUpdateItem ri;
|
||||||
|
FILETIME ft;
|
||||||
|
NTime::GetCurUtcFileTime(ft);
|
||||||
|
ri.MTime = ri.ATime = ri.CTime = ft;
|
||||||
|
ri.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
|
||||||
|
const UInt32 kSecuritySize = 8;
|
||||||
|
size_t pos = kSecuritySize;
|
||||||
|
WriteTree(rootFolder, hashes.Digests, ri, updateItems, NULL, pos);
|
||||||
|
|
||||||
|
CByteBuffer meta;
|
||||||
|
meta.SetCapacity(pos);
|
||||||
|
|
||||||
|
// we can write 0 here only if there is no security data, imageX does it,
|
||||||
|
// but some programs expect size = 8
|
||||||
|
Set32((Byte *)meta, 8); // size of security data
|
||||||
|
Set32((Byte *)meta + 4, 0); // num security entries
|
||||||
|
|
||||||
|
pos = kSecuritySize;
|
||||||
|
WriteTree(rootFolder, hashes.Digests, ri, updateItems, (Byte *)meta, pos);
|
||||||
|
|
||||||
|
{
|
||||||
|
NCrypto::NSha1::CContext sha;
|
||||||
|
sha.Init();
|
||||||
|
sha.Update((const Byte *)meta, pos);
|
||||||
|
CSha1Hash digest;
|
||||||
|
sha.Final(digest.Hash);
|
||||||
|
|
||||||
|
CStreamInfo s;
|
||||||
|
s.Resource.PackSize = pos;
|
||||||
|
s.Resource.Offset = curPos;
|
||||||
|
s.Resource.UnpackSize = pos;
|
||||||
|
s.Resource.Flags = NResourceFlags::kMetadata;
|
||||||
|
s.PartNumber = 1;
|
||||||
|
s.RefCount = 1;
|
||||||
|
memcpy(s.Hash, digest.Hash, kHashSize);
|
||||||
|
streams.Add(s);
|
||||||
|
RINOK(WriteStream(outStream, (const Byte *)meta, pos));
|
||||||
|
meta.Free();
|
||||||
|
curPos += pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
header.OffsetResource.UnpackSize = header.OffsetResource.PackSize = (UInt64)streams.Size() * kStreamInfoSize;
|
||||||
|
header.OffsetResource.Offset = curPos;
|
||||||
|
header.OffsetResource.Flags = NResourceFlags::kMetadata;
|
||||||
|
|
||||||
|
for (i = 0; i < streams.Size(); i++)
|
||||||
|
{
|
||||||
|
Byte buf[kStreamInfoSize];
|
||||||
|
streams[i].WriteTo(buf);
|
||||||
|
RINOK(WriteStream(outStream, buf, kStreamInfoSize));
|
||||||
|
curPos += kStreamInfoSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
AString xml = "<WIM>";
|
||||||
|
AddTagUInt64(xml, "TOTALBYTES", curPos);
|
||||||
|
xml += "<IMAGE INDEX=\"1\"><NAME>1</NAME>";
|
||||||
|
AddTagUInt64(xml, "DIRCOUNT", rootFolder.GetNumDirs());
|
||||||
|
AddTagUInt64(xml, "FILECOUNT", rootFolder.GetNumFiles());
|
||||||
|
AddTagUInt64(xml, "TOTALBYTES", unpackTotalSize);
|
||||||
|
NTime::GetCurUtcFileTime(ft);
|
||||||
|
AddTag(xml, "CREATIONTIME", TimeToXml(ft));
|
||||||
|
AddTag(xml, "LASTMODIFICATIONTIME", TimeToXml(ft));
|
||||||
|
xml += "</IMAGE></WIM>";
|
||||||
|
|
||||||
|
size_t xmlSize = (xml.Length() + 1) * 2;
|
||||||
|
meta.SetCapacity(xmlSize);
|
||||||
|
Set16((Byte *)meta, 0xFEFF);
|
||||||
|
for (i = 0; i < xml.Length(); i++)
|
||||||
|
Set16((Byte *)meta + 2 + i * 2, xml[i]);
|
||||||
|
RINOK(WriteStream(outStream, (const Byte *)meta, xmlSize));
|
||||||
|
meta.Free();
|
||||||
|
|
||||||
|
header.XmlResource.UnpackSize = header.XmlResource.PackSize = xmlSize;
|
||||||
|
header.XmlResource.Offset = curPos;
|
||||||
|
header.XmlResource.Flags = NResourceFlags::kMetadata;
|
||||||
|
|
||||||
|
outStream->Seek(0, STREAM_SEEK_SET, NULL);
|
||||||
|
header.WriteTo(buf);
|
||||||
|
return WriteStream(outStream, buf, kHeaderSizeMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP COutHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
|
||||||
|
IArchiveUpdateCallback *callback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
CObjectVector<CUpdateItem> updateItems;
|
||||||
|
CDir tree;
|
||||||
|
tree.Dirs.Add(CDir());
|
||||||
|
CDir &rootFolder = tree.Dirs.Back();
|
||||||
|
|
||||||
|
for (UInt32 i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
CUpdateItem ui;
|
||||||
|
Int32 newData, newProps;
|
||||||
|
UInt32 indexInArchive;
|
||||||
|
if (!callback)
|
||||||
|
return E_FAIL;
|
||||||
|
RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive));
|
||||||
|
|
||||||
|
{
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(callback->GetProperty(i, kpidIsDir, &prop));
|
||||||
|
if (prop.vt == VT_EMPTY)
|
||||||
|
ui.IsDir = false;
|
||||||
|
else if (prop.vt != VT_BOOL)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
else
|
||||||
|
ui.IsDir = (prop.boolVal != VARIANT_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(callback->GetProperty(i, kpidAttrib, &prop));
|
||||||
|
if (prop.vt == VT_EMPTY)
|
||||||
|
ui.Attrib = (ui.IsDir ? FILE_ATTRIBUTE_DIRECTORY : 0);
|
||||||
|
else if (prop.vt != VT_UI4)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
else
|
||||||
|
ui.Attrib = prop.ulVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
RINOK(GetTime(callback, i, kpidCTime, ui.CTime));
|
||||||
|
RINOK(GetTime(callback, i, kpidATime, ui.ATime));
|
||||||
|
RINOK(GetTime(callback, i, kpidMTime, ui.MTime));
|
||||||
|
|
||||||
|
{
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(callback->GetProperty(i, kpidSize, &prop));
|
||||||
|
if (prop.vt != VT_UI8)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
ui.Size = prop.uhVal.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
UString path;
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(callback->GetProperty(i, kpidPath, &prop));
|
||||||
|
if (prop.vt == VT_BSTR)
|
||||||
|
path = prop.bstrVal;
|
||||||
|
else if (prop.vt != VT_EMPTY)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
CDir *curItem = &rootFolder;
|
||||||
|
int len = path.Length();
|
||||||
|
UString fileName;
|
||||||
|
for (int j = 0; j < len; j++)
|
||||||
|
{
|
||||||
|
wchar_t c = path[j];
|
||||||
|
if (c == WCHAR_PATH_SEPARATOR || c == L'/')
|
||||||
|
{
|
||||||
|
curItem = curItem->AddDir(updateItems, fileName, -1);
|
||||||
|
fileName.Empty();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fileName += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Name = fileName;
|
||||||
|
updateItems.Add(ui);
|
||||||
|
if (ui.IsDir)
|
||||||
|
curItem->AddDir(updateItems, fileName, (int)i);
|
||||||
|
else
|
||||||
|
curItem->Files.Add(i);
|
||||||
|
}
|
||||||
|
return UpdateArchive(outStream, tree, updateItems, callback);
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
@@ -21,9 +21,6 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NWim {
|
namespace NWim {
|
||||||
|
|
||||||
static const int kChunkSizeBits = 15;
|
|
||||||
static const UInt32 kChunkSize = (1 << kChunkSizeBits);
|
|
||||||
|
|
||||||
namespace NXpress {
|
namespace NXpress {
|
||||||
|
|
||||||
class CDecoderFlusher
|
class CDecoderFlusher
|
||||||
@@ -44,7 +41,7 @@ HRESULT CDecoder::CodeSpec(UInt32 outSize)
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
Byte levels[kMainTableSize];
|
Byte levels[kMainTableSize];
|
||||||
for (int i = 0; i < kMainTableSize; i += 2)
|
for (unsigned i = 0; i < kMainTableSize; i += 2)
|
||||||
{
|
{
|
||||||
Byte b = m_InBitStream.DirectReadByte();
|
Byte b = m_InBitStream.DirectReadByte();
|
||||||
levels[i] = b & 0xF;
|
levels[i] = b & 0xF;
|
||||||
@@ -128,12 +125,6 @@ HRESULT CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetFileTimeFromMem(const Byte *p, FILETIME *ft)
|
|
||||||
{
|
|
||||||
ft->dwLowDateTime = Get32(p);
|
|
||||||
ft->dwHighDateTime = Get32(p + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, bool lzxMode,
|
HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, bool lzxMode,
|
||||||
ISequentialOutStream *outStream, ICompressProgressInfo *progress)
|
ISequentialOutStream *outStream, ICompressProgressInfo *progress)
|
||||||
{
|
{
|
||||||
@@ -257,9 +248,6 @@ static HRESULT UnpackData(IInStream *inStream, const CResource &resource, bool l
|
|||||||
return unpacker.Unpack(inStream, resource, lzxMode, outStream, NULL, digest);
|
return unpacker.Unpack(inStream, resource, lzxMode, outStream, NULL, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UInt32 kSignatureSize = 8;
|
|
||||||
static const Byte kSignature[kSignatureSize] = { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 };
|
|
||||||
|
|
||||||
void CResource::Parse(const Byte *p)
|
void CResource::Parse(const Byte *p)
|
||||||
{
|
{
|
||||||
Flags = p[7];
|
Flags = p[7];
|
||||||
@@ -278,19 +266,157 @@ static void GetStream(const Byte *p, CStreamInfo &s)
|
|||||||
memcpy(s.Hash, p + 30, kHashSize);
|
memcpy(s.Hash, p + 30, kHashSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT ParseDirItem(const Byte *base, size_t pos, size_t size,
|
static const wchar_t *kLongPath = L"[LongPath]";
|
||||||
const UString &prefix, CObjectVector<CItem> &items)
|
|
||||||
|
UString CDatabase::GetItemPath(const int index1) const
|
||||||
{
|
{
|
||||||
for (;;)
|
int size = 0;
|
||||||
|
int index = index1;
|
||||||
|
int newLevel;
|
||||||
|
for (newLevel = 0;; newLevel = 1)
|
||||||
{
|
{
|
||||||
if (pos + 8 > size)
|
const CItem &item = Items[index];
|
||||||
return S_FALSE;
|
index = item.Parent;
|
||||||
const Byte *p = base + pos;
|
if (index >= 0 || !SkipRoot)
|
||||||
UInt64 length = Get64(p);
|
size += item.Name.Length() + newLevel;
|
||||||
if (length == 0)
|
if (index < 0)
|
||||||
|
break;
|
||||||
|
if ((UInt32)size >= ((UInt32)1 << 16))
|
||||||
|
return kLongPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t temp[16];
|
||||||
|
int imageLen = 0;
|
||||||
|
if (ShowImageNumber)
|
||||||
|
{
|
||||||
|
ConvertUInt32ToString(-1 - index, temp);
|
||||||
|
imageLen = MyStringLen(temp);
|
||||||
|
size += imageLen + 1;
|
||||||
|
}
|
||||||
|
if ((UInt32)size >= ((UInt32)1 << 16))
|
||||||
|
return kLongPath;
|
||||||
|
|
||||||
|
UString path;
|
||||||
|
wchar_t *s = path.GetBuffer(size);
|
||||||
|
s[size] = 0;
|
||||||
|
if (ShowImageNumber)
|
||||||
|
{
|
||||||
|
memcpy(s, temp, imageLen * sizeof(wchar_t));
|
||||||
|
s[imageLen] = WCHAR_PATH_SEPARATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = index1;
|
||||||
|
|
||||||
|
for (newLevel = 0;; newLevel = 1)
|
||||||
|
{
|
||||||
|
const CItem &item = Items[index];
|
||||||
|
index = item.Parent;
|
||||||
|
if (index >= 0 || !SkipRoot)
|
||||||
|
{
|
||||||
|
if (newLevel)
|
||||||
|
s[--size] = WCHAR_PATH_SEPARATOR;
|
||||||
|
size -= item.Name.Length();
|
||||||
|
memcpy(s + size, item.Name, sizeof(wchar_t) * item.Name.Length());
|
||||||
|
}
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
path.ReleaseBuffer();
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetFileTimeFromMem(const Byte *p, FILETIME *ft)
|
||||||
|
{
|
||||||
|
ft->dwLowDateTime = Get32(p);
|
||||||
|
ft->dwHighDateTime = Get32(p + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ReadName(const Byte *p, int size, UString &dest)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
if (pos + 102 > size || pos + length + 8 > size || length > ((UInt64)1 << 62))
|
if (Get16(p + size) != 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
wchar_t *s = dest.GetBuffer(size / 2);
|
||||||
|
for (int i = 0; i <= size; i += 2)
|
||||||
|
*s++ = Get16(p + i);
|
||||||
|
dest.ReleaseBuffer();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDatabase::ParseDirItem(size_t pos, int parent)
|
||||||
|
{
|
||||||
|
if ((pos & 7) != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
int prevIndex = -1;
|
||||||
|
for (int numItems = 0;; numItems++)
|
||||||
|
{
|
||||||
|
if (OpenCallback)
|
||||||
|
{
|
||||||
|
UInt64 numFiles = Items.Size();
|
||||||
|
if ((numFiles & 0x3FF) == 0)
|
||||||
|
{
|
||||||
|
RINOK(OpenCallback->SetCompleted(&numFiles, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t rem = DirSize - pos;
|
||||||
|
if (pos < DirStartOffset || pos > DirSize || rem < 8)
|
||||||
|
return S_FALSE;
|
||||||
|
const Byte *p = DirData + pos;
|
||||||
|
UInt64 len = Get64(p);
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
if (parent < 0 && numItems != 1)
|
||||||
|
SkipRoot = false;
|
||||||
|
DirProcessed += 8;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
if ((len & 7) != 0 || len < 0x28 || rem < len)
|
||||||
|
return S_FALSE;
|
||||||
|
DirProcessed += (size_t)len;
|
||||||
|
if (DirProcessed > DirSize)
|
||||||
|
return S_FALSE;
|
||||||
|
if (Get64(p + 8) == 0)
|
||||||
|
{
|
||||||
|
if (prevIndex == -1)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
UInt32 fileNameLen = Get16(p + 0x24);
|
||||||
|
if ((fileNameLen & 1) != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
/* Probably different versions of ImageX can use different number of
|
||||||
|
additional ZEROs. So we don't use exact check. */
|
||||||
|
UInt32 fileNameLen2 = (fileNameLen == 0 ? fileNameLen : fileNameLen + 2);
|
||||||
|
if (((0x26 + fileNameLen2 + 6) & ~7) > len)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
UString name;
|
||||||
|
RINOK(ReadName(p + 0x26, fileNameLen, name));
|
||||||
|
|
||||||
|
CItem &prevItem = Items[prevIndex];
|
||||||
|
if (name.IsEmpty() && !prevItem.HasStream())
|
||||||
|
memcpy(prevItem.Hash, p + 0x10, kHashSize);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CItem item;
|
||||||
|
item.Name = prevItem.Name + L':' + name;
|
||||||
|
item.CTime = prevItem.CTime;
|
||||||
|
item.ATime = prevItem.ATime;
|
||||||
|
item.MTime = prevItem.MTime;
|
||||||
|
memcpy(item.Hash, p + 0x10, kHashSize);
|
||||||
|
item.Attrib = 0;
|
||||||
|
item.Order = Order++;
|
||||||
|
item.Parent = parent;
|
||||||
|
Items.Add(item);
|
||||||
|
}
|
||||||
|
pos += (size_t)len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (len < kDirRecordSize)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
CItem item;
|
CItem item;
|
||||||
item.Attrib = Get32(p + 8);
|
item.Attrib = Get32(p + 8);
|
||||||
// item.SecurityId = Get32(p + 0xC);
|
// item.SecurityId = Get32(p + 0xC);
|
||||||
@@ -300,43 +426,64 @@ static HRESULT ParseDirItem(const Byte *base, size_t pos, size_t size,
|
|||||||
GetFileTimeFromMem(p + 0x38, &item.MTime);
|
GetFileTimeFromMem(p + 0x38, &item.MTime);
|
||||||
memcpy(item.Hash, p + 0x40, kHashSize);
|
memcpy(item.Hash, p + 0x40, kHashSize);
|
||||||
|
|
||||||
// UInt16 shortNameLen = Get16(p + 98);
|
UInt32 shortNameLen = Get16(p + 98);
|
||||||
UInt16 fileNameLen = Get16(p + 100);
|
UInt32 fileNameLen = Get16(p + 100);
|
||||||
|
if ((shortNameLen & 1) != 0 || (fileNameLen & 1) != 0)
|
||||||
size_t tempPos = pos + 102;
|
|
||||||
if (tempPos + fileNameLen > size)
|
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
wchar_t *sz = item.Name.GetBuffer(prefix.Length() + fileNameLen / 2 + 1);
|
UInt32 shortNameLen2 = (shortNameLen == 0 ? shortNameLen : shortNameLen + 2);
|
||||||
MyStringCopy(sz, (const wchar_t *)prefix);
|
UInt32 fileNameLen2 = (fileNameLen == 0 ? fileNameLen : fileNameLen + 2);
|
||||||
sz += prefix.Length();
|
|
||||||
for (UInt16 i = 0; i + 2 <= fileNameLen; i += 2)
|
if (((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7) > len)
|
||||||
*sz++ = Get16(base + tempPos + i);
|
return S_FALSE;
|
||||||
*sz++ = '\0';
|
|
||||||
item.Name.ReleaseBuffer();
|
p += kDirRecordSize;
|
||||||
if (fileNameLen == 0 && item.isDir() && !item.HasStream())
|
|
||||||
|
RINOK(ReadName(p, fileNameLen, item.Name));
|
||||||
|
RINOK(ReadName(p + fileNameLen2, shortNameLen, item.ShortName));
|
||||||
|
|
||||||
|
if (parent < 0 && (shortNameLen || fileNameLen || !item.IsDir()))
|
||||||
|
SkipRoot = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// there are some extra data for some files.
|
||||||
|
p -= kDirRecordSize;
|
||||||
|
p += ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7);
|
||||||
|
if (((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7) != len)
|
||||||
|
p = p;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (parent >= 0)
|
||||||
{
|
{
|
||||||
|
UString s = GetItemPath(parent) + L"\\" + item.Name;
|
||||||
|
printf("\n%s %8x %S", item.IsDir() ? "D" : " ", (int)subdirOffset, (const wchar_t *)s);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (fileNameLen == 0 && item.IsDir() && !item.HasStream())
|
||||||
item.Attrib = 0x10; // some swm archives have system/hidden attributes for root
|
item.Attrib = 0x10; // some swm archives have system/hidden attributes for root
|
||||||
item.Name.Delete(item.Name.Length() - 1);
|
|
||||||
}
|
item.Parent = parent;
|
||||||
items.Add(item);
|
prevIndex = Items.Add(item);
|
||||||
pos += (size_t)length;
|
if (item.IsDir() && subdirOffset != 0)
|
||||||
if (item.isDir() && (subdirOffset != 0))
|
|
||||||
{
|
{
|
||||||
if (subdirOffset >= size)
|
RINOK(ParseDirItem((size_t)subdirOffset, prevIndex));
|
||||||
return S_FALSE;
|
|
||||||
RINOK(ParseDirItem(base, (size_t)subdirOffset, size, item.Name + WCHAR_PATH_SEPARATOR, items));
|
|
||||||
}
|
}
|
||||||
|
Items[prevIndex].Order = Order++;
|
||||||
|
pos += (size_t)len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT ParseDir(const Byte *base, size_t size,
|
HRESULT CDatabase::ParseImageDirs(const CByteBuffer &buf, int parent)
|
||||||
const UString &prefix, CObjectVector<CItem> &items)
|
|
||||||
{
|
{
|
||||||
|
DirData = buf;
|
||||||
|
DirSize = buf.GetCapacity();
|
||||||
|
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
if (pos + 8 > size)
|
if (DirSize < 8)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
const Byte *p = base + pos;
|
const Byte *p = DirData;
|
||||||
UInt32 totalLength = Get32(p);
|
UInt32 totalLength = Get32(p);
|
||||||
// UInt32 numEntries = Get32(p + 4);
|
// UInt32 numEntries = Get32(p + 4);
|
||||||
pos += 8;
|
pos += 8;
|
||||||
@@ -346,7 +493,7 @@ static HRESULT ParseDir(const Byte *base, size_t size,
|
|||||||
UInt64 sum = 0;
|
UInt64 sum = 0;
|
||||||
for (UInt32 i = 0; i < numEntries; i++)
|
for (UInt32 i = 0; i < numEntries; i++)
|
||||||
{
|
{
|
||||||
if (pos + 8 > size)
|
if (pos + 8 > DirSize)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
UInt64 len = Get64(p + pos);
|
UInt64 len = Get64(p + pos);
|
||||||
entryLens.Add(len);
|
entryLens.Add(len);
|
||||||
@@ -359,16 +506,124 @@ static HRESULT ParseDir(const Byte *base, size_t size,
|
|||||||
if (pos != totalLength)
|
if (pos != totalLength)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
*/
|
*/
|
||||||
|
if (totalLength == 0)
|
||||||
|
pos = 8;
|
||||||
|
else if (totalLength < 8)
|
||||||
|
return S_FALSE;
|
||||||
|
else
|
||||||
pos = totalLength;
|
pos = totalLength;
|
||||||
}
|
}
|
||||||
return ParseDirItem(base, pos, size, prefix, items);
|
DirStartOffset = DirProcessed = pos;
|
||||||
|
RINOK(ParseDirItem(pos, parent));
|
||||||
|
if (DirProcessed == DirSize)
|
||||||
|
return S_OK;
|
||||||
|
/* Original program writes additional 8 bytes (END_OF_ROOT_FOLDER), but
|
||||||
|
reference to that folder is empty */
|
||||||
|
if (DirProcessed == DirSize - 8 && DirProcessed - DirStartOffset == 112 &&
|
||||||
|
Get64(p + DirSize - 8) == 0)
|
||||||
|
return S_OK;
|
||||||
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CompareHashRefs(const int *p1, const int *p2, void *param)
|
HRESULT CHeader::Parse(const Byte *p)
|
||||||
{
|
{
|
||||||
const CRecordVector<CStreamInfo> &streams = *(const CRecordVector<CStreamInfo> *)param;
|
UInt32 haderSize = Get32(p + 8);
|
||||||
return memcmp(streams[*p1].Hash, streams[*p2].Hash, kHashSize);
|
if (haderSize < 0x74)
|
||||||
|
return S_FALSE;
|
||||||
|
Version = Get32(p + 0x0C);
|
||||||
|
Flags = Get32(p + 0x10);
|
||||||
|
if (!IsSupported())
|
||||||
|
return S_FALSE;
|
||||||
|
ChunkSize = Get32(p + 0x14);
|
||||||
|
if (ChunkSize != kChunkSize && ChunkSize != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
memcpy(Guid, p + 0x18, 16);
|
||||||
|
PartNumber = Get16(p + 0x28);
|
||||||
|
NumParts = Get16(p + 0x2A);
|
||||||
|
int offset = 0x2C;
|
||||||
|
if (IsNewVersion())
|
||||||
|
{
|
||||||
|
NumImages = Get32(p + offset);
|
||||||
|
offset += 4;
|
||||||
}
|
}
|
||||||
|
GetResource(p + offset, OffsetResource);
|
||||||
|
GetResource(p + offset + 0x18, XmlResource);
|
||||||
|
GetResource(p + offset + 0x30, MetadataResource);
|
||||||
|
if (IsNewVersion())
|
||||||
|
{
|
||||||
|
if (haderSize < 0xD0)
|
||||||
|
return S_FALSE;
|
||||||
|
BootIndex = Get32(p + 0x48);
|
||||||
|
IntegrityResource.Parse(p + offset + 0x4C);
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Byte kSignature[kSignatureSize] = { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 };
|
||||||
|
|
||||||
|
HRESULT ReadHeader(IInStream *inStream, CHeader &h)
|
||||||
|
{
|
||||||
|
Byte p[kHeaderSizeMax];
|
||||||
|
RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax));
|
||||||
|
if (memcmp(p, kSignature, kSignatureSize) != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
return h.Parse(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ReadStreams(IInStream *inStream, const CHeader &h, CDatabase &db)
|
||||||
|
{
|
||||||
|
CByteBuffer offsetBuf;
|
||||||
|
RINOK(UnpackData(inStream, h.OffsetResource, h.IsLzxMode(), offsetBuf, NULL));
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; offsetBuf.GetCapacity() - i >= kStreamInfoSize; i += kStreamInfoSize)
|
||||||
|
{
|
||||||
|
CStreamInfo s;
|
||||||
|
GetStream((const Byte *)offsetBuf + i, s);
|
||||||
|
if (s.PartNumber == h.PartNumber)
|
||||||
|
db.Streams.Add(s);
|
||||||
|
}
|
||||||
|
return (i == offsetBuf.GetCapacity()) ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDatabase::Open(IInStream *inStream, const CHeader &h, CByteBuffer &xml, IArchiveOpenCallback *openCallback)
|
||||||
|
{
|
||||||
|
OpenCallback = openCallback;
|
||||||
|
RINOK(UnpackData(inStream, h.XmlResource, h.IsLzxMode(), xml, NULL));
|
||||||
|
RINOK(ReadStreams(inStream, h, *this));
|
||||||
|
bool needBootMetadata = !h.MetadataResource.IsEmpty();
|
||||||
|
Order = 0;
|
||||||
|
if (h.PartNumber == 1)
|
||||||
|
{
|
||||||
|
int imageIndex = 1;
|
||||||
|
for (int i = 0; i < Streams.Size(); i++)
|
||||||
|
{
|
||||||
|
// if (imageIndex > 1) break;
|
||||||
|
const CStreamInfo &si = Streams[i];
|
||||||
|
if (!si.Resource.IsMetadata() || si.PartNumber != h.PartNumber)
|
||||||
|
continue;
|
||||||
|
Byte hash[kHashSize];
|
||||||
|
CByteBuffer metadata;
|
||||||
|
RINOK(UnpackData(inStream, si.Resource, h.IsLzxMode(), metadata, hash));
|
||||||
|
if (memcmp(hash, si.Hash, kHashSize) != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
NumImages++;
|
||||||
|
RINOK(ParseImageDirs(metadata, -(int)(++imageIndex)));
|
||||||
|
if (needBootMetadata)
|
||||||
|
if (h.MetadataResource.Offset == si.Resource.Offset)
|
||||||
|
needBootMetadata = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needBootMetadata)
|
||||||
|
{
|
||||||
|
CByteBuffer metadata;
|
||||||
|
RINOK(UnpackData(inStream, h.MetadataResource, h.IsLzxMode(), metadata, NULL));
|
||||||
|
RINOK(ParseImageDirs(metadata, -1));
|
||||||
|
NumImages++;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int CompareStreamsByPos(const CStreamInfo *p1, const CStreamInfo *p2, void * /* param */)
|
static int CompareStreamsByPos(const CStreamInfo *p1, const CStreamInfo *p2, void * /* param */)
|
||||||
{
|
{
|
||||||
@@ -378,24 +633,14 @@ static int CompareStreamsByPos(const CStreamInfo *p1, const CStreamInfo *p2, voi
|
|||||||
return MyCompare(p1->Resource.Offset, p2->Resource.Offset);
|
return MyCompare(p1->Resource.Offset, p2->Resource.Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CompareItems(void *const *a1, void *const *a2, void * /* param */)
|
static int CompareHashRefs(const int *p1, const int *p2, void *param)
|
||||||
{
|
{
|
||||||
const CItem &i1 = **((const CItem **)a1);
|
const CRecordVector<CStreamInfo> &streams = *(const CRecordVector<CStreamInfo> *)param;
|
||||||
const CItem &i2 = **((const CItem **)a2);
|
return memcmp(streams[*p1].Hash, streams[*p2].Hash, kHashSize);
|
||||||
|
|
||||||
if (i1.isDir() != i2.isDir())
|
|
||||||
return (i1.isDir()) ? 1 : -1;
|
|
||||||
if (i1.isDir())
|
|
||||||
return -MyStringCompareNoCase(i1.Name, i2.Name);
|
|
||||||
|
|
||||||
int res = MyCompare(i1.StreamIndex, i2.StreamIndex);
|
|
||||||
if (res != 0)
|
|
||||||
return res;
|
|
||||||
return MyStringCompareNoCase(i1.Name, i2.Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FindHash(const CRecordVector<CStreamInfo> &streams,
|
static int FindHash(const CRecordVector<CStreamInfo> &streams,
|
||||||
const CRecordVector<int> &sortedByHash, const Byte *hash)
|
const CIntVector &sortedByHash, const Byte *hash)
|
||||||
{
|
{
|
||||||
int left = 0, right = streams.Size();
|
int left = 0, right = streams.Size();
|
||||||
while (left != right)
|
while (left != right)
|
||||||
@@ -417,153 +662,70 @@ static int FindHash(const CRecordVector<CStreamInfo> &streams,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CHeader::Parse(const Byte *p)
|
static int CompareItems(const int *a1, const int *a2, void *param)
|
||||||
{
|
{
|
||||||
UInt32 haderSize = Get32(p + 8);
|
const CObjectVector<CItem> &items = ((CDatabase *)param)->Items;
|
||||||
if (haderSize < 0x74)
|
const CItem &i1 = items[*a1];
|
||||||
return S_FALSE;
|
const CItem &i2 = items[*a2];
|
||||||
Version = Get32(p + 0x0C);
|
|
||||||
Flags = Get32(p + 0x10);
|
if (i1.IsDir() != i2.IsDir())
|
||||||
if (!IsSupported())
|
return i1.IsDir() ? 1 : -1;
|
||||||
return S_FALSE;
|
int res = MyCompare(i1.StreamIndex, i2.StreamIndex);
|
||||||
UInt32 chunkSize = Get32(p + 0x14);
|
if (res != 0)
|
||||||
if (chunkSize != kChunkSize && chunkSize != 0)
|
return res;
|
||||||
return S_FALSE;
|
return MyCompare(i1.Order, i2.Order);
|
||||||
memcpy(Guid, p + 0x18, 16);
|
|
||||||
PartNumber = Get16(p + 0x28);
|
|
||||||
NumParts = Get16(p + 0x2A);
|
|
||||||
int offset = 0x2C;
|
|
||||||
if (IsNewVersion())
|
|
||||||
{
|
|
||||||
NumImages = Get32(p + offset);
|
|
||||||
offset += 4;
|
|
||||||
}
|
|
||||||
GetResource(p + offset, OffsetResource);
|
|
||||||
GetResource(p + offset + 0x18, XmlResource);
|
|
||||||
GetResource(p + offset + 0x30, MetadataResource);
|
|
||||||
/*
|
|
||||||
if (IsNewVersion())
|
|
||||||
{
|
|
||||||
if (haderSize < 0xD0)
|
|
||||||
return S_FALSE;
|
|
||||||
IntegrityResource.Parse(p + offset + 0x4C);
|
|
||||||
BootIndex = Get32(p + 0x48);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT ReadHeader(IInStream *inStream, CHeader &h)
|
HRESULT CDatabase::Sort(bool skipRootDir)
|
||||||
{
|
{
|
||||||
const UInt32 kHeaderSizeMax = 0xD0;
|
Streams.Sort(CompareStreamsByPos, NULL);
|
||||||
Byte p[kHeaderSizeMax];
|
|
||||||
RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax));
|
|
||||||
if (memcmp(p, kSignature, kSignatureSize) != 0)
|
|
||||||
return S_FALSE;
|
|
||||||
return h.Parse(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ReadStreams(IInStream *inStream, const CHeader &h, CDatabase &db)
|
|
||||||
{
|
|
||||||
CByteBuffer offsetBuf;
|
|
||||||
RINOK(UnpackData(inStream, h.OffsetResource, h.IsLzxMode(), offsetBuf, NULL));
|
|
||||||
for (size_t i = 0; i + kStreamInfoSize <= offsetBuf.GetCapacity(); i += kStreamInfoSize)
|
|
||||||
{
|
|
||||||
CStreamInfo s;
|
|
||||||
GetStream((const Byte *)offsetBuf + i, s);
|
|
||||||
if (s.PartNumber == h.PartNumber)
|
|
||||||
db.Streams.Add(s);
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT OpenArchive(IInStream *inStream, const CHeader &h, CByteBuffer &xml, CDatabase &db)
|
|
||||||
{
|
|
||||||
RINOK(UnpackData(inStream, h.XmlResource, h.IsLzxMode(), xml, NULL));
|
|
||||||
|
|
||||||
RINOK(ReadStreams(inStream, h, db));
|
|
||||||
bool needBootMetadata = !h.MetadataResource.IsEmpty();
|
|
||||||
if (h.PartNumber == 1)
|
|
||||||
{
|
|
||||||
int imageIndex = 1;
|
|
||||||
for (int j = 0; j < db.Streams.Size(); j++)
|
|
||||||
{
|
|
||||||
// if (imageIndex > 1) break;
|
|
||||||
const CStreamInfo &si = db.Streams[j];
|
|
||||||
if (!si.Resource.IsMetadata() || si.PartNumber != h.PartNumber)
|
|
||||||
continue;
|
|
||||||
Byte hash[kHashSize];
|
|
||||||
CByteBuffer metadata;
|
|
||||||
RINOK(UnpackData(inStream, si.Resource, h.IsLzxMode(), metadata, hash));
|
|
||||||
if (memcmp(hash, si.Hash, kHashSize) != 0)
|
|
||||||
return S_FALSE;
|
|
||||||
wchar_t sz[16];
|
|
||||||
ConvertUInt32ToString(imageIndex++, sz);
|
|
||||||
UString s = sz;
|
|
||||||
s += WCHAR_PATH_SEPARATOR;
|
|
||||||
RINOK(ParseDir(metadata, metadata.GetCapacity(), s, db.Items));
|
|
||||||
if (needBootMetadata)
|
|
||||||
if (h.MetadataResource.Offset == si.Resource.Offset)
|
|
||||||
needBootMetadata = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needBootMetadata)
|
|
||||||
{
|
|
||||||
CByteBuffer metadata;
|
|
||||||
RINOK(UnpackData(inStream, h.MetadataResource, h.IsLzxMode(), metadata, NULL));
|
|
||||||
RINOK(ParseDir(metadata, metadata.GetCapacity(), L"0" WSTRING_PATH_SEPARATOR, db.Items));
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT SortDatabase(CDatabase &db)
|
|
||||||
{
|
|
||||||
db.Streams.Sort(CompareStreamsByPos, NULL);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
CRecordVector<int> sortedByHash;
|
CIntVector sortedByHash;
|
||||||
{
|
{
|
||||||
for (int j = 0; j < db.Streams.Size(); j++)
|
for (int i = 0; i < Streams.Size(); i++)
|
||||||
sortedByHash.Add(j);
|
sortedByHash.Add(i);
|
||||||
sortedByHash.Sort(CompareHashRefs, &db.Streams);
|
sortedByHash.Sort(CompareHashRefs, &Streams);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < db.Items.Size(); i++)
|
for (int i = 0; i < Items.Size(); i++)
|
||||||
{
|
{
|
||||||
CItem &item = db.Items[i];
|
CItem &item = Items[i];
|
||||||
item.StreamIndex = -1;
|
item.StreamIndex = -1;
|
||||||
if (item.HasStream())
|
if (item.HasStream())
|
||||||
item.StreamIndex = FindHash(db.Streams, sortedByHash, item.Hash);
|
item.StreamIndex = FindHash(Streams, sortedByHash, item.Hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
CRecordVector<bool> used;
|
CRecordVector<bool> used;
|
||||||
int j;
|
int i;
|
||||||
for (j = 0; j < db.Streams.Size(); j++)
|
for (i = 0; i < Streams.Size(); i++)
|
||||||
{
|
{
|
||||||
const CStreamInfo &s = db.Streams[j];
|
const CStreamInfo &s = Streams[i];
|
||||||
used.Add(s.Resource.IsMetadata() && s.PartNumber == 1);
|
used.Add(s.Resource.IsMetadata() && s.PartNumber == 1);
|
||||||
|
// used.Add(false);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < db.Items.Size(); i++)
|
for (i = 0; i < Items.Size(); i++)
|
||||||
{
|
{
|
||||||
CItem &item = db.Items[i];
|
CItem &item = Items[i];
|
||||||
if (item.StreamIndex >= 0)
|
if (item.StreamIndex >= 0)
|
||||||
used[item.StreamIndex] = true;
|
used[item.StreamIndex] = true;
|
||||||
}
|
}
|
||||||
for (j = 0; j < db.Streams.Size(); j++)
|
for (i = 0; i < Streams.Size(); i++)
|
||||||
if (!used[j])
|
if (!used[i])
|
||||||
{
|
{
|
||||||
CItem item;
|
CItem item;
|
||||||
item.StreamIndex = j;
|
item.StreamIndex = i;
|
||||||
item.HasMetadata = false;
|
item.HasMetadata = false;
|
||||||
db.Items.Add(item);
|
Items.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
db.Items.Sort(CompareItems, NULL);
|
SortedItems.Reserve(Items.Size());
|
||||||
|
for (int i = (skipRootDir ? 1 : 0); i < Items.Size(); i++)
|
||||||
|
SortedItems.Add(i);
|
||||||
|
SortedItems.Sort(CompareItems, this);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "../../Compress/CopyCoder.h"
|
#include "../../Compress/CopyCoder.h"
|
||||||
#include "../../Compress/LzxDecoder.h"
|
#include "../../Compress/LzxDecoder.h"
|
||||||
|
|
||||||
|
#include "../IArchive.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NWim {
|
namespace NWim {
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const int kNumHuffmanBits = 16;
|
const unsigned kNumHuffmanBits = 16;
|
||||||
const UInt32 kMatchMinLen = 3;
|
const UInt32 kMatchMinLen = 3;
|
||||||
const UInt32 kNumLenSlots = 16;
|
const UInt32 kNumLenSlots = 16;
|
||||||
const UInt32 kNumPosSlots = 16;
|
const UInt32 kNumPosSlots = 16;
|
||||||
@@ -85,8 +87,10 @@ public:
|
|||||||
|
|
||||||
namespace NResourceFlags
|
namespace NResourceFlags
|
||||||
{
|
{
|
||||||
const Byte Compressed = 4;
|
const Byte kFree = 1;
|
||||||
const Byte kMetadata = 2;
|
const Byte kMetadata = 2;
|
||||||
|
const Byte Compressed = 4;
|
||||||
|
const Byte Spanned = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CResource
|
struct CResource
|
||||||
@@ -96,9 +100,18 @@ struct CResource
|
|||||||
UInt64 UnpackSize;
|
UInt64 UnpackSize;
|
||||||
Byte Flags;
|
Byte Flags;
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
PackSize = 0;
|
||||||
|
Offset = 0;
|
||||||
|
UnpackSize = 0;
|
||||||
|
Flags = 0;
|
||||||
|
}
|
||||||
void Parse(const Byte *p);
|
void Parse(const Byte *p);
|
||||||
bool IsCompressed() const { return (Flags & NResourceFlags::Compressed) != 0; }
|
void WriteTo(Byte *p) const;
|
||||||
|
bool IsFree() const { return (Flags & NResourceFlags::kFree) != 0; }
|
||||||
bool IsMetadata() const { return (Flags & NResourceFlags::kMetadata) != 0; }
|
bool IsMetadata() const { return (Flags & NResourceFlags::kMetadata) != 0; }
|
||||||
|
bool IsCompressed() const { return (Flags & NResourceFlags::Compressed) != 0; }
|
||||||
bool IsEmpty() const { return (UnpackSize == 0); }
|
bool IsEmpty() const { return (UnpackSize == 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,30 +124,37 @@ namespace NHeaderFlags
|
|||||||
const UInt32 kLZX = 0x40000;
|
const UInt32 kLZX = 0x40000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UInt32 kWimVersion = 0x010D00;
|
||||||
|
const UInt32 kHeaderSizeMax = 0xD0;
|
||||||
|
const UInt32 kSignatureSize = 8;
|
||||||
|
extern const Byte kSignature[kSignatureSize];
|
||||||
|
const unsigned kChunkSizeBits = 15;
|
||||||
|
const UInt32 kChunkSize = (1 << kChunkSizeBits);
|
||||||
|
|
||||||
struct CHeader
|
struct CHeader
|
||||||
{
|
{
|
||||||
UInt32 Flags;
|
|
||||||
UInt32 Version;
|
UInt32 Version;
|
||||||
// UInt32 ChunkSize;
|
UInt32 Flags;
|
||||||
|
UInt32 ChunkSize;
|
||||||
|
Byte Guid[16];
|
||||||
UInt16 PartNumber;
|
UInt16 PartNumber;
|
||||||
UInt16 NumParts;
|
UInt16 NumParts;
|
||||||
UInt32 NumImages;
|
UInt32 NumImages;
|
||||||
Byte Guid[16];
|
|
||||||
|
|
||||||
CResource OffsetResource;
|
CResource OffsetResource;
|
||||||
CResource XmlResource;
|
CResource XmlResource;
|
||||||
CResource MetadataResource;
|
CResource MetadataResource;
|
||||||
/*
|
|
||||||
CResource IntegrityResource;
|
CResource IntegrityResource;
|
||||||
UInt32 BootIndex;
|
UInt32 BootIndex;
|
||||||
*/
|
|
||||||
|
|
||||||
|
void SetDefaultFields(bool useLZX);
|
||||||
|
|
||||||
|
void WriteTo(Byte *p) const;
|
||||||
HRESULT Parse(const Byte *p);
|
HRESULT Parse(const Byte *p);
|
||||||
bool IsCompressed() const { return (Flags & NHeaderFlags::kCompression) != 0; }
|
bool IsCompressed() const { return (Flags & NHeaderFlags::kCompression) != 0; }
|
||||||
bool IsSupported() const { return (!IsCompressed() || (Flags & NHeaderFlags::kLZX) != 0 || (Flags & NHeaderFlags::kXPRESS) != 0 ) ; }
|
bool IsSupported() const { return (!IsCompressed() || (Flags & NHeaderFlags::kLZX) != 0 || (Flags & NHeaderFlags::kXPRESS) != 0 ) ; }
|
||||||
bool IsLzxMode() const { return (Flags & NHeaderFlags::kLZX) != 0; }
|
bool IsLzxMode() const { return (Flags & NHeaderFlags::kLZX) != 0; }
|
||||||
bool IsSpanned() const { return (!IsCompressed() || (Flags & NHeaderFlags::kSpanned) != 0); }
|
bool IsSpanned() const { return (!IsCompressed() || (Flags & NHeaderFlags::kSpanned) != 0); }
|
||||||
|
|
||||||
bool IsNewVersion()const { return (Version > 0x010C00); }
|
bool IsNewVersion()const { return (Version > 0x010C00); }
|
||||||
|
|
||||||
bool AreFromOnArchive(const CHeader &h)
|
bool AreFromOnArchive(const CHeader &h)
|
||||||
@@ -152,11 +172,16 @@ struct CStreamInfo
|
|||||||
UInt16 PartNumber;
|
UInt16 PartNumber;
|
||||||
UInt32 RefCount;
|
UInt32 RefCount;
|
||||||
BYTE Hash[kHashSize];
|
BYTE Hash[kHashSize];
|
||||||
|
|
||||||
|
void WriteTo(Byte *p) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const UInt32 kDirRecordSize = 102;
|
||||||
|
|
||||||
struct CItem
|
struct CItem
|
||||||
{
|
{
|
||||||
UString Name;
|
UString Name;
|
||||||
|
UString ShortName;
|
||||||
UInt32 Attrib;
|
UInt32 Attrib;
|
||||||
// UInt32 SecurityId;
|
// UInt32 SecurityId;
|
||||||
BYTE Hash[kHashSize];
|
BYTE Hash[kHashSize];
|
||||||
@@ -168,22 +193,39 @@ struct CItem
|
|||||||
// UInt16 NumStreams;
|
// UInt16 NumStreams;
|
||||||
// UInt16 ShortNameLen;
|
// UInt16 ShortNameLen;
|
||||||
int StreamIndex;
|
int StreamIndex;
|
||||||
|
int Parent;
|
||||||
|
unsigned Order;
|
||||||
bool HasMetadata;
|
bool HasMetadata;
|
||||||
CItem(): HasMetadata(true), StreamIndex(-1) {}
|
CItem(): HasMetadata(true), StreamIndex(-1) {}
|
||||||
bool isDir() const { return HasMetadata && ((Attrib & 0x10) != 0); }
|
bool IsDir() const { return HasMetadata && ((Attrib & 0x10) != 0); }
|
||||||
bool HasStream() const
|
bool HasStream() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < kHashSize; i++)
|
for (unsigned i = 0; i < kHashSize; i++)
|
||||||
if (Hash[i] != 0)
|
if (Hash[i] != 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CDatabase
|
class CDatabase
|
||||||
{
|
{
|
||||||
|
const Byte *DirData;
|
||||||
|
size_t DirSize;
|
||||||
|
size_t DirProcessed;
|
||||||
|
size_t DirStartOffset;
|
||||||
|
int Order;
|
||||||
|
IArchiveOpenCallback *OpenCallback;
|
||||||
|
|
||||||
|
HRESULT ParseDirItem(size_t pos, int parent);
|
||||||
|
HRESULT ParseImageDirs(const CByteBuffer &buf, int parent);
|
||||||
|
|
||||||
|
public:
|
||||||
CRecordVector<CStreamInfo> Streams;
|
CRecordVector<CStreamInfo> Streams;
|
||||||
CObjectVector<CItem> Items;
|
CObjectVector<CItem> Items;
|
||||||
|
CIntVector SortedItems;
|
||||||
|
int NumImages;
|
||||||
|
bool SkipRoot;
|
||||||
|
bool ShowImageNumber;
|
||||||
|
|
||||||
UInt64 GetUnpackSize() const
|
UInt64 GetUnpackSize() const
|
||||||
{
|
{
|
||||||
@@ -205,12 +247,26 @@ struct CDatabase
|
|||||||
{
|
{
|
||||||
Streams.Clear();
|
Streams.Clear();
|
||||||
Items.Clear();
|
Items.Clear();
|
||||||
|
SortedItems.Clear();
|
||||||
|
NumImages = 0;
|
||||||
|
|
||||||
|
SkipRoot = true;
|
||||||
|
ShowImageNumber = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UString GetItemPath(int index) const;
|
||||||
|
|
||||||
|
HRESULT Open(IInStream *inStream, const CHeader &h, CByteBuffer &xml, IArchiveOpenCallback *openCallback);
|
||||||
|
|
||||||
|
void DetectPathMode()
|
||||||
|
{
|
||||||
|
ShowImageNumber = (NumImages != 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Sort(bool skipRootDir);
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT ReadHeader(IInStream *inStream, CHeader &header);
|
HRESULT ReadHeader(IInStream *inStream, CHeader &header);
|
||||||
HRESULT OpenArchive(IInStream *inStream, const CHeader &header, CByteBuffer &xml, CDatabase &database);
|
|
||||||
HRESULT SortDatabase(CDatabase &database);
|
|
||||||
|
|
||||||
class CUnpacker
|
class CUnpacker
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,8 +6,13 @@
|
|||||||
|
|
||||||
#include "WimHandler.h"
|
#include "WimHandler.h"
|
||||||
static IInArchive *CreateArc() { return new NArchive::NWim::CHandler; }
|
static IInArchive *CreateArc() { return new NArchive::NWim::CHandler; }
|
||||||
|
#ifndef EXTRACT_ONLY
|
||||||
|
static IOutArchive *CreateArcOut() { return new NArchive::NWim::COutHandler; }
|
||||||
|
#else
|
||||||
|
#define CreateArcOut 0
|
||||||
|
#endif
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"Wim", L"wim swm", 0, 0xE6, { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 }, 8, false, CreateArc, 0 };
|
{ L"wim", L"wim swm", 0, 0xE6, { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 }, 8, false, CreateArc, CreateArcOut };
|
||||||
|
|
||||||
REGISTER_ARC(Wim)
|
REGISTER_ARC(Wim)
|
||||||
|
|||||||
@@ -128,7 +128,9 @@ static STATPROPSTG kProps[] =
|
|||||||
static STATPROPSTG kArcProps[] =
|
static STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidBit64, VT_BOOL},
|
{ NULL, kpidBit64, VT_BOOL},
|
||||||
{ NULL, kpidComment, VT_BSTR}
|
{ NULL, kpidComment, VT_BSTR},
|
||||||
|
{ NULL, kpidPhySize, VT_UI8},
|
||||||
|
{ NULL, kpidOffset, VT_UI8}
|
||||||
};
|
};
|
||||||
|
|
||||||
CHandler::CHandler()
|
CHandler::CHandler()
|
||||||
@@ -160,9 +162,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break;
|
case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break;
|
||||||
case kpidComment:
|
case kpidComment: prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break;
|
||||||
prop = MultiByteToUnicodeString(BytesToString(m_Archive.m_ArchiveInfo.Comment), CP_ACP);
|
case kpidPhySize: prop = m_Archive.ArcInfo.GetPhySize(); break;
|
||||||
break;
|
case kpidOffset: if (m_Archive.ArcInfo.StartPosition != 0) prop = m_Archive.ArcInfo.StartPosition; break;
|
||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ private:
|
|||||||
Byte m_AesKeyMode;
|
Byte m_AesKeyMode;
|
||||||
|
|
||||||
bool m_WriteNtfsTimeExtra;
|
bool m_WriteNtfsTimeExtra;
|
||||||
bool m_ForseLocal;
|
bool m_ForceLocal;
|
||||||
bool m_ForseUtf8;
|
bool m_ForceUtf8;
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
UInt32 _numThreads;
|
UInt32 _numThreads;
|
||||||
@@ -87,9 +87,9 @@ private:
|
|||||||
m_ForceAesMode = false;
|
m_ForceAesMode = false;
|
||||||
m_IsAesMode = false;
|
m_IsAesMode = false;
|
||||||
m_AesKeyMode = 3; // aes-256
|
m_AesKeyMode = 3; // aes-256
|
||||||
m_WriteNtfsTimeExtra = false;
|
m_WriteNtfsTimeExtra = true;
|
||||||
m_ForseLocal = false;
|
m_ForceLocal = false;
|
||||||
m_ForseUtf8 = false;
|
m_ForceUtf8 = false;
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -189,11 +189,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
name += kSlash;
|
name += kSlash;
|
||||||
|
|
||||||
bool tryUtf8 = true;
|
bool tryUtf8 = true;
|
||||||
if (m_ForseLocal || !m_ForseUtf8)
|
if (m_ForceLocal || !m_ForceUtf8)
|
||||||
{
|
{
|
||||||
bool defaultCharWasUsed;
|
bool defaultCharWasUsed;
|
||||||
ui.Name = UnicodeStringToMultiByte(name, CP_OEMCP, '_', defaultCharWasUsed);
|
ui.Name = UnicodeStringToMultiByte(name, CP_OEMCP, '_', defaultCharWasUsed);
|
||||||
tryUtf8 = (!m_ForseLocal && (defaultCharWasUsed ||
|
tryUtf8 = (!m_ForceLocal && (defaultCharWasUsed ||
|
||||||
MultiByteToUnicodeString(ui.Name, CP_OEMCP) != name));
|
MultiByteToUnicodeString(ui.Name, CP_OEMCP) != name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,15 +512,15 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
}
|
}
|
||||||
else if (name.CompareNoCase(L"CL") == 0)
|
else if (name.CompareNoCase(L"CL") == 0)
|
||||||
{
|
{
|
||||||
RINOK(SetBoolProperty(m_ForseLocal, prop));
|
RINOK(SetBoolProperty(m_ForceLocal, prop));
|
||||||
if (m_ForseLocal)
|
if (m_ForceLocal)
|
||||||
m_ForseUtf8 = false;
|
m_ForceUtf8 = false;
|
||||||
}
|
}
|
||||||
else if (name.CompareNoCase(L"CU") == 0)
|
else if (name.CompareNoCase(L"CU") == 0)
|
||||||
{
|
{
|
||||||
RINOK(SetBoolProperty(m_ForseUtf8, prop));
|
RINOK(SetBoolProperty(m_ForceUtf8, prop));
|
||||||
if (m_ForseUtf8)
|
if (m_ForceUtf8)
|
||||||
m_ForseLocal = false;
|
m_ForceLocal = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ static inline bool TestMarkerCandidate2(const Byte *p, UInt32 &value)
|
|||||||
|
|
||||||
HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
||||||
{
|
{
|
||||||
m_ArchiveInfo.Clear();
|
ArcInfo.Clear();
|
||||||
m_Position = m_StreamStartPosition;
|
m_Position = m_StreamStartPosition;
|
||||||
|
|
||||||
Byte marker[NSignature::kMarkerSize];
|
Byte marker[NSignature::kMarkerSize];
|
||||||
@@ -99,7 +99,7 @@ HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHea
|
|||||||
if (TestMarkerCandidate2(buffer + pos, m_Signature))
|
if (TestMarkerCandidate2(buffer + pos, m_Signature))
|
||||||
{
|
{
|
||||||
curTestPos += pos;
|
curTestPos += pos;
|
||||||
m_ArchiveInfo.StartPosition = curTestPos;
|
ArcInfo.StartPosition = curTestPos;
|
||||||
m_Position = curTestPos + NSignature::kMarkerSize;
|
m_Position = curTestPos + NSignature::kMarkerSize;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -208,11 +208,6 @@ void CInArchive::ReadFileName(UInt32 nameSize, AString &dest)
|
|||||||
dest.ReleaseBuffer();
|
dest.ReleaseBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
|
|
||||||
{
|
|
||||||
archiveInfo = m_ArchiveInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
|
void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
|
||||||
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber)
|
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber)
|
||||||
{
|
{
|
||||||
@@ -332,7 +327,7 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RINOK(Seek(m_ArchiveInfo.Base + item.LocalHeaderPosition));
|
RINOK(Seek(ArcInfo.Base + item.LocalHeaderPosition));
|
||||||
CItemEx localItem;
|
CItemEx localItem;
|
||||||
if (ReadUInt32() != NSignature::kLocalFileHeader)
|
if (ReadUInt32() != NSignature::kLocalFileHeader)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
@@ -419,7 +414,7 @@ HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item)
|
|||||||
RINOK(ReadLocalItemAfterCdItem(item));
|
RINOK(ReadLocalItemAfterCdItem(item));
|
||||||
if (item.HasDescriptor())
|
if (item.HasDescriptor())
|
||||||
{
|
{
|
||||||
RINOK(Seek(m_ArchiveInfo.Base + item.GetDataPosition() + item.PackSize));
|
RINOK(Seek(ArcInfo.Base + item.GetDataPosition() + item.PackSize));
|
||||||
if (ReadUInt32() != NSignature::kDataDescriptor)
|
if (ReadUInt32() != NSignature::kDataDescriptor)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
UInt32 crc = ReadUInt32();
|
UInt32 crc = ReadUInt32();
|
||||||
@@ -534,9 +529,9 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo)
|
|||||||
UInt64 ecd64Offset = Get64(locator + 8);
|
UInt64 ecd64Offset = Get64(locator + 8);
|
||||||
if (TryEcd64(ecd64Offset, cdInfo) == S_OK)
|
if (TryEcd64(ecd64Offset, cdInfo) == S_OK)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
if (TryEcd64(m_ArchiveInfo.StartPosition + ecd64Offset, cdInfo) == S_OK)
|
if (TryEcd64(ArcInfo.StartPosition + ecd64Offset, cdInfo) == S_OK)
|
||||||
{
|
{
|
||||||
m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
|
ArcInfo.Base = ArcInfo.StartPosition;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -548,8 +543,8 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo)
|
|||||||
cdInfo.Offset = Get32(buf + i + 16);
|
cdInfo.Offset = Get32(buf + i + 16);
|
||||||
UInt64 curPos = endPosition - bufSize + i;
|
UInt64 curPos = endPosition - bufSize + i;
|
||||||
UInt64 cdEnd = cdInfo.Size + cdInfo.Offset;
|
UInt64 cdEnd = cdInfo.Size + cdInfo.Offset;
|
||||||
if (curPos > cdEnd)
|
if (curPos != cdEnd)
|
||||||
m_ArchiveInfo.Base = curPos - cdEnd;
|
ArcInfo.Base = curPos - cdEnd;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -585,18 +580,18 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UI
|
|||||||
|
|
||||||
HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress)
|
HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress)
|
||||||
{
|
{
|
||||||
m_ArchiveInfo.Base = 0;
|
ArcInfo.Base = 0;
|
||||||
CCdInfo cdInfo;
|
CCdInfo cdInfo;
|
||||||
RINOK(FindCd(cdInfo));
|
RINOK(FindCd(cdInfo));
|
||||||
HRESULT res = S_FALSE;
|
HRESULT res = S_FALSE;
|
||||||
cdSize = cdInfo.Size;
|
cdSize = cdInfo.Size;
|
||||||
cdOffset = cdInfo.Offset;
|
cdOffset = cdInfo.Offset;
|
||||||
res = TryReadCd(items, m_ArchiveInfo.Base + cdOffset, cdSize, progress);
|
res = TryReadCd(items, ArcInfo.Base + cdOffset, cdSize, progress);
|
||||||
if (res == S_FALSE && m_ArchiveInfo.Base == 0)
|
if (res == S_FALSE && ArcInfo.Base == 0)
|
||||||
{
|
{
|
||||||
res = TryReadCd(items, cdInfo.Offset + m_ArchiveInfo.StartPosition, cdSize, progress);
|
res = TryReadCd(items, cdInfo.Offset + ArcInfo.StartPosition, cdSize, progress);
|
||||||
if (res == S_OK)
|
if (res == S_OK)
|
||||||
m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
|
ArcInfo.Base = ArcInfo.StartPosition;
|
||||||
}
|
}
|
||||||
if (!ReadUInt32(m_Signature))
|
if (!ReadUInt32(m_Signature))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
@@ -645,7 +640,7 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt
|
|||||||
CItemEx &item = items[j];
|
CItemEx &item = items[j];
|
||||||
if (item.Name == cdItem.Name)
|
if (item.Name == cdItem.Name)
|
||||||
{
|
{
|
||||||
m_ArchiveInfo.Base = item.LocalHeaderPosition - cdItem.LocalHeaderPosition;
|
ArcInfo.Base = item.LocalHeaderPosition - cdItem.LocalHeaderPosition;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -660,7 +655,7 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt
|
|||||||
if (left >= right)
|
if (left >= right)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
index = (left + right) / 2;
|
index = (left + right) / 2;
|
||||||
UInt64 position = items[index].LocalHeaderPosition - m_ArchiveInfo.Base;
|
UInt64 position = items[index].LocalHeaderPosition - ArcInfo.Base;
|
||||||
if (cdItem.LocalHeaderPosition == position)
|
if (cdItem.LocalHeaderPosition == position)
|
||||||
break;
|
break;
|
||||||
if (cdItem.LocalHeaderPosition < position)
|
if (cdItem.LocalHeaderPosition < position)
|
||||||
@@ -693,7 +688,7 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
for (i = 0; i < items.Size(); i++)
|
for (i = 0; i < items.Size(); i++)
|
||||||
items[i].LocalHeaderPosition -= m_ArchiveInfo.Base;
|
items[i].LocalHeaderPosition -= ArcInfo.Base;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,20 +776,20 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
|
|||||||
if (res == S_FALSE)
|
if (res == S_FALSE)
|
||||||
{
|
{
|
||||||
_inBufMode = false;
|
_inBufMode = false;
|
||||||
m_ArchiveInfo.Base = 0;
|
ArcInfo.Base = 0;
|
||||||
RINOK(m_Stream->Seek(m_ArchiveInfo.StartPosition, STREAM_SEEK_SET, &m_Position));
|
RINOK(m_Stream->Seek(ArcInfo.StartPosition, STREAM_SEEK_SET, &m_Position));
|
||||||
if (m_Position != m_ArchiveInfo.StartPosition)
|
if (m_Position != ArcInfo.StartPosition)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if (!ReadUInt32(m_Signature))
|
if (!ReadUInt32(m_Signature))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
RINOK(ReadLocalsAndCd(items, progress, cdStartOffset, numCdItems));
|
RINOK(ReadLocalsAndCd(items, progress, cdStartOffset, numCdItems));
|
||||||
cdSize = (m_Position - 4) - cdStartOffset;
|
cdSize = (m_Position - 4) - cdStartOffset;
|
||||||
cdStartOffset -= m_ArchiveInfo.Base;
|
cdStartOffset -= ArcInfo.Base;
|
||||||
}
|
}
|
||||||
|
|
||||||
CEcd64 ecd64;
|
CEcd64 ecd64;
|
||||||
bool isZip64 = false;
|
bool isZip64 = false;
|
||||||
UInt64 zip64EcdStartOffset = m_Position - 4 - m_ArchiveInfo.Base;
|
UInt64 zip64EcdStartOffset = m_Position - 4 - ArcInfo.Base;
|
||||||
if (m_Signature == NSignature::kZip64EndOfCentralDir)
|
if (m_Signature == NSignature::kZip64EndOfCentralDir)
|
||||||
{
|
{
|
||||||
IsZip64 = isZip64 = true;
|
IsZip64 = isZip64 = true;
|
||||||
@@ -843,7 +838,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
|
|||||||
COPY_ECD_ITEM_32(cdSize);
|
COPY_ECD_ITEM_32(cdSize);
|
||||||
COPY_ECD_ITEM_32(cdStartOffset);
|
COPY_ECD_ITEM_32(cdStartOffset);
|
||||||
|
|
||||||
ReadBuffer(m_ArchiveInfo.Comment, ecd.commentSize);
|
ReadBuffer(ArcInfo.Comment, ecd.commentSize);
|
||||||
|
|
||||||
if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0)
|
if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0)
|
||||||
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
|
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
|
||||||
@@ -857,6 +852,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
|
|||||||
_inBufMode = false;
|
_inBufMode = false;
|
||||||
_inBuffer.Free();
|
_inBuffer.Free();
|
||||||
IsOkHeaders = (numCdItems == items.Size());
|
IsOkHeaders = (numCdItems == items.Size());
|
||||||
|
ArcInfo.FinishPosition = m_Position;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -864,7 +860,7 @@ ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 siz
|
|||||||
{
|
{
|
||||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||||
CMyComPtr<ISequentialInStream> stream(streamSpec);
|
CMyComPtr<ISequentialInStream> stream(streamSpec);
|
||||||
SeekInArchive(m_ArchiveInfo.Base + position);
|
SeekInArchive(ArcInfo.Base + position);
|
||||||
streamSpec->SetStream(m_Stream);
|
streamSpec->SetStream(m_Stream);
|
||||||
streamSpec->Init(size);
|
streamSpec->Init(size);
|
||||||
return stream.Detach();
|
return stream.Detach();
|
||||||
|
|||||||
@@ -38,8 +38,11 @@ class CInArchiveInfo
|
|||||||
public:
|
public:
|
||||||
UInt64 Base;
|
UInt64 Base;
|
||||||
UInt64 StartPosition;
|
UInt64 StartPosition;
|
||||||
|
UInt64 FinishPosition;
|
||||||
CByteBuffer Comment;
|
CByteBuffer Comment;
|
||||||
|
|
||||||
CInArchiveInfo(): Base(0), StartPosition(0) {}
|
CInArchiveInfo(): Base(0), StartPosition(0) {}
|
||||||
|
UInt64 GetPhySize() const { return FinishPosition - StartPosition; }
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
Base = 0;
|
Base = 0;
|
||||||
@@ -101,7 +104,7 @@ class CInArchive
|
|||||||
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress);
|
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress);
|
||||||
HRESULT ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset, int &numCdItems);
|
HRESULT ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset, int &numCdItems);
|
||||||
public:
|
public:
|
||||||
CInArchiveInfo m_ArchiveInfo;
|
CInArchiveInfo ArcInfo;
|
||||||
bool IsZip64;
|
bool IsZip64;
|
||||||
bool IsOkHeaders;
|
bool IsOkHeaders;
|
||||||
|
|
||||||
@@ -110,7 +113,6 @@ public:
|
|||||||
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
|
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
|
||||||
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
|
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
|
||||||
void Close();
|
void Close();
|
||||||
void GetArchiveInfo(CInArchiveInfo &archiveInfo) const;
|
|
||||||
bool SeekInArchive(UInt64 position);
|
bool SeekInArchive(UInt64 position);
|
||||||
ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size);
|
ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size);
|
||||||
IInStream* CreateStream();
|
IInStream* CreateStream();
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ void COutArchive::WriteCentralHeader(const CItem &item)
|
|||||||
WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity());
|
WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment)
|
void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer *comment)
|
||||||
{
|
{
|
||||||
SeekTo(m_BasePosition);
|
SeekTo(m_BasePosition);
|
||||||
|
|
||||||
@@ -260,10 +260,10 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByte
|
|||||||
WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size()));
|
WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size()));
|
||||||
WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize);
|
WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize);
|
||||||
WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset);
|
WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset);
|
||||||
UInt16 commentSize = (UInt16)comment.GetCapacity();
|
UInt32 commentSize = (UInt32)(comment ? comment->GetCapacity() : 0);
|
||||||
WriteUInt16(commentSize);
|
WriteUInt16((UInt16)commentSize);
|
||||||
if (commentSize > 0)
|
if (commentSize > 0)
|
||||||
WriteBytes((const Byte *)comment, commentSize);
|
WriteBytes((const Byte *)*comment, commentSize);
|
||||||
m_OutBuffer.FlushWithCheck();
|
m_OutBuffer.FlushWithCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption);
|
void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption);
|
||||||
void WriteLocalHeader(const CLocalItem &item);
|
void WriteLocalHeader(const CLocalItem &item);
|
||||||
|
|
||||||
void WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment);
|
void WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer *comment);
|
||||||
|
|
||||||
void CreateStreamForCompressing(IOutStream **outStream);
|
void CreateStreamForCompressing(IOutStream **outStream);
|
||||||
void CreateStreamForCopying(ISequentialOutStream **outStream);
|
void CreateStreamForCopying(ISequentialOutStream **outStream);
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ static HRESULT Update2St(
|
|||||||
const CObjectVector<CItemEx> &inputItems,
|
const CObjectVector<CItemEx> &inputItems,
|
||||||
const CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
const CCompressionMethodMode *options,
|
const CCompressionMethodMode *options,
|
||||||
const CByteBuffer &comment,
|
const CByteBuffer *comment,
|
||||||
IArchiveUpdateCallback *updateCallback)
|
IArchiveUpdateCallback *updateCallback)
|
||||||
{
|
{
|
||||||
CLocalProgress *lps = new CLocalProgress;
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
@@ -482,7 +482,7 @@ static HRESULT Update2(
|
|||||||
const CObjectVector<CItemEx> &inputItems,
|
const CObjectVector<CItemEx> &inputItems,
|
||||||
const CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
const CCompressionMethodMode *options,
|
const CCompressionMethodMode *options,
|
||||||
const CByteBuffer &comment,
|
const CByteBuffer *comment,
|
||||||
IArchiveUpdateCallback *updateCallback)
|
IArchiveUpdateCallback *updateCallback)
|
||||||
{
|
{
|
||||||
UInt64 complexity = 0;
|
UInt64 complexity = 0;
|
||||||
@@ -515,8 +515,8 @@ static HRESULT Update2(
|
|||||||
complexity += NFileHeader::kCentralBlockSize;
|
complexity += NFileHeader::kCentralBlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comment != 0)
|
if (comment)
|
||||||
complexity += comment.GetCapacity();
|
complexity += comment->GetCapacity();
|
||||||
complexity++; // end of central
|
complexity++; // end of central
|
||||||
updateCallback->SetTotal(complexity);
|
updateCallback->SetTotal(complexity);
|
||||||
|
|
||||||
@@ -812,27 +812,27 @@ HRESULT Update(
|
|||||||
if (!outStream)
|
if (!outStream)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
|
||||||
CInArchiveInfo archiveInfo;
|
if (inArchive)
|
||||||
if(inArchive != 0)
|
|
||||||
{
|
{
|
||||||
inArchive->GetArchiveInfo(archiveInfo);
|
if (inArchive->ArcInfo.Base != 0 ||
|
||||||
if (archiveInfo.Base != 0 || !inArchive->IsOkHeaders)
|
inArchive->ArcInfo.StartPosition != 0 ||
|
||||||
|
!inArchive->IsOkHeaders)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
archiveInfo.StartPosition = 0;
|
|
||||||
|
|
||||||
COutArchive outArchive;
|
COutArchive outArchive;
|
||||||
outArchive.Create(outStream);
|
outArchive.Create(outStream);
|
||||||
if (archiveInfo.StartPosition > 0)
|
/*
|
||||||
|
if (inArchive && inArchive->ArcInfo.StartPosition > 0)
|
||||||
{
|
{
|
||||||
CMyComPtr<ISequentialInStream> inStream;
|
CMyComPtr<ISequentialInStream> inStream;
|
||||||
inStream.Attach(inArchive->CreateLimitedStream(0, archiveInfo.StartPosition));
|
inStream.Attach(inArchive->CreateLimitedStream(0, inArchive->ArcInfo.StartPosition));
|
||||||
RINOK(CopyBlockToArchive(inStream, outArchive, NULL));
|
RINOK(CopyBlockToArchive(inStream, outArchive, NULL));
|
||||||
outArchive.MoveBasePosition(archiveInfo.StartPosition);
|
outArchive.MoveBasePosition(inArchive->ArcInfo.StartPosition);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
CMyComPtr<IInStream> inStream;
|
CMyComPtr<IInStream> inStream;
|
||||||
if(inArchive != 0)
|
if (inArchive)
|
||||||
inStream.Attach(inArchive->CreateStream());
|
inStream.Attach(inArchive->CreateStream());
|
||||||
|
|
||||||
return Update2(
|
return Update2(
|
||||||
@@ -840,7 +840,8 @@ HRESULT Update(
|
|||||||
outArchive, inArchive, inStream,
|
outArchive, inArchive, inStream,
|
||||||
inputItems, updateItems,
|
inputItems, updateItems,
|
||||||
compressionMethodMode,
|
compressionMethodMode,
|
||||||
archiveInfo.Comment, updateCallback);
|
inArchive ? &inArchive->ArcInfo.Comment : NULL,
|
||||||
|
updateCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ AR_OBJS = \
|
|||||||
$O\DeflateProps.obj \
|
$O\DeflateProps.obj \
|
||||||
$O\GzHandler.obj \
|
$O\GzHandler.obj \
|
||||||
$O\LzmaHandler.obj \
|
$O\LzmaHandler.obj \
|
||||||
$O\PpmdHandler.obj \
|
|
||||||
$O\SplitHandler.obj \
|
$O\SplitHandler.obj \
|
||||||
$O\XzHandler.obj \
|
$O\XzHandler.obj \
|
||||||
$O\ZHandler.obj \
|
$O\ZHandler.obj \
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#include "../../MyVersionInfo.rc"
|
#include "../../MyVersionInfo.rc"
|
||||||
|
|
||||||
MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za")
|
MY_VERSION_INFO_APP("7-Zip Standalone Console", "7zr")
|
||||||
|
|||||||
@@ -440,14 +440,6 @@ SOURCE=..\..\UI\FileManager\OptionsDialog.cpp
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\UI\FileManager\PluginsPage.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\UI\FileManager\PluginsPage.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\UI\FileManager\SettingsPage.cpp
|
SOURCE=..\..\UI\FileManager\SettingsPage.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ FM_OBJS = \
|
|||||||
$O\MessagesDialog.obj \
|
$O\MessagesDialog.obj \
|
||||||
$O\OverwriteDialog.obj \
|
$O\OverwriteDialog.obj \
|
||||||
$O\PasswordDialog.obj \
|
$O\PasswordDialog.obj \
|
||||||
$O\PluginsPage.obj \
|
|
||||||
$O\ProgressDialog2.obj \
|
$O\ProgressDialog2.obj \
|
||||||
$O\SettingsPage.obj \
|
$O\SettingsPage.obj \
|
||||||
$O\SplitDialog.obj \
|
$O\SplitDialog.obj \
|
||||||
@@ -323,6 +322,7 @@ UDF_OBJS = \
|
|||||||
|
|
||||||
WIM_OBJS = \
|
WIM_OBJS = \
|
||||||
$O\WimHandler.obj \
|
$O\WimHandler.obj \
|
||||||
|
$O\WimHandlerOut.obj \
|
||||||
$O\WimIn.obj \
|
$O\WimIn.obj \
|
||||||
$O\WimRegister.obj \
|
$O\WimRegister.obj \
|
||||||
|
|
||||||
|
|||||||
@@ -2229,6 +2229,10 @@ SOURCE=..\..\Archive\Wim\WimHandler.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Archive\Wim\WimHandlerOut.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Archive\Wim\WimIn.cpp
|
SOURCE=..\..\Archive\Wim\WimIn.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ UDF_OBJS = \
|
|||||||
|
|
||||||
WIM_OBJS = \
|
WIM_OBJS = \
|
||||||
$O\WimHandler.obj \
|
$O\WimHandler.obj \
|
||||||
|
$O\WimHandlerOut.obj \
|
||||||
$O\WimIn.obj \
|
$O\WimIn.obj \
|
||||||
$O\WimRegister.obj \
|
$O\WimRegister.obj \
|
||||||
|
|
||||||
|
|||||||
@@ -57,12 +57,8 @@ HRESULT CEncoder::Flush()
|
|||||||
|
|
||||||
const UInt32 kDefaultLimit = (1 << 24);
|
const UInt32 kDefaultLimit = (1 << 24);
|
||||||
|
|
||||||
HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
|
HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
|
||||||
const UInt64 **inSizes,
|
ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams,
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 ** /* outSizes */,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress)
|
ICompressProgressInfo *progress)
|
||||||
{
|
{
|
||||||
if (numInStreams != 1 || numOutStreams != 4)
|
if (numInStreams != 1 || numOutStreams != 4)
|
||||||
@@ -81,6 +77,8 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
|
|||||||
sizeIsDefined = true;
|
sizeIsDefined = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CCoderReleaser releaser(this);
|
||||||
|
|
||||||
ISequentialInStream *inStream = inStreams[0];
|
ISequentialInStream *inStream = inStreams[0];
|
||||||
|
|
||||||
_mainStream.SetStream(outStreams[0]);
|
_mainStream.SetStream(outStreams[0]);
|
||||||
@@ -93,7 +91,6 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
|
|||||||
_rangeEncoder.Init();
|
_rangeEncoder.Init();
|
||||||
for (int i = 0; i < 256 + 2; i++)
|
for (int i = 0; i < 256 + 2; i++)
|
||||||
_statusEncoder[i].Init();
|
_statusEncoder[i].Init();
|
||||||
CCoderReleaser releaser(this);
|
|
||||||
|
|
||||||
CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
|
CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
|
||||||
{
|
{
|
||||||
@@ -253,18 +250,13 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams,
|
STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
|
||||||
const UInt64 **inSizes,
|
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 **outSizes,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress)
|
ICompressProgressInfo *progress)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return CodeReal(inStreams, inSizes, numInStreams,
|
return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress);
|
||||||
outStreams, outSizes,numOutStreams, progress);
|
|
||||||
}
|
}
|
||||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||||
catch(...) { return S_FALSE; }
|
catch(...) { return S_FALSE; }
|
||||||
@@ -272,28 +264,39 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams,
|
|
||||||
const UInt64 ** /* inSizes */,
|
STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _inBufSizes[streamIndex] = size; return S_OK; }
|
||||||
UInt32 numInStreams,
|
STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 ** /* outSizes */,
|
CDecoder::CDecoder():
|
||||||
UInt32 numOutStreams,
|
_outBufSize(1 << 16)
|
||||||
|
{
|
||||||
|
_inBufSizes[0] = 1 << 20;
|
||||||
|
_inBufSizes[1] = 1 << 20;
|
||||||
|
_inBufSizes[2] = 1 << 20;
|
||||||
|
_inBufSizes[3] = 1 << 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* inSizes */, UInt32 numInStreams,
|
||||||
|
ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams,
|
||||||
ICompressProgressInfo *progress)
|
ICompressProgressInfo *progress)
|
||||||
{
|
{
|
||||||
if (numInStreams != 4 || numOutStreams != 1)
|
if (numInStreams != 4 || numOutStreams != 1)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (!_mainInStream.Create(1 << 16))
|
if (!_mainInStream.Create(_inBufSizes[0]))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
if (!_callStream.Create(1 << 20))
|
if (!_callStream.Create(_inBufSizes[1]))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
if (!_jumpStream.Create(1 << 16))
|
if (!_jumpStream.Create(_inBufSizes[2]))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
if (!_rangeDecoder.Create(1 << 20))
|
if (!_rangeDecoder.Create(_inBufSizes[3]))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
if (!_outStream.Create(1 << 16))
|
if (!_outStream.Create(_outBufSize))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
CCoderReleaser releaser(this);
|
||||||
|
|
||||||
_mainInStream.SetStream(inStreams[0]);
|
_mainInStream.SetStream(inStreams[0]);
|
||||||
_callStream.SetStream(inStreams[1]);
|
_callStream.SetStream(inStreams[1]);
|
||||||
_jumpStream.SetStream(inStreams[2]);
|
_jumpStream.SetStream(inStreams[2]);
|
||||||
@@ -309,8 +312,6 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams,
|
|||||||
for (int i = 0; i < 256 + 2; i++)
|
for (int i = 0; i < 256 + 2; i++)
|
||||||
_statusDecoder[i].Init();
|
_statusDecoder[i].Init();
|
||||||
|
|
||||||
CCoderReleaser releaser(this);
|
|
||||||
|
|
||||||
Byte prevByte = 0;
|
Byte prevByte = 0;
|
||||||
UInt32 processedBytes = 0;
|
UInt32 processedBytes = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -369,18 +370,13 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams,
|
STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
|
||||||
const UInt64 **inSizes,
|
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 **outSizes,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress)
|
ICompressProgressInfo *progress)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return CodeReal(inStreams, inSizes, numInStreams,
|
return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress);
|
||||||
outStreams, outSizes,numOutStreams, progress);
|
|
||||||
}
|
}
|
||||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ class CEncoder:
|
|||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
Byte *_buffer;
|
Byte *_buffer;
|
||||||
public:
|
|
||||||
CEncoder(): _buffer(0) {};
|
|
||||||
~CEncoder();
|
|
||||||
bool Create();
|
bool Create();
|
||||||
|
|
||||||
COutBuffer _mainStream;
|
COutBuffer _mainStream;
|
||||||
@@ -33,6 +30,7 @@ public:
|
|||||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];
|
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];
|
||||||
|
|
||||||
HRESULT Flush();
|
HRESULT Flush();
|
||||||
|
public:
|
||||||
void ReleaseStreams()
|
void ReleaseStreams()
|
||||||
{
|
{
|
||||||
_mainStream.ReleaseStream();
|
_mainStream.ReleaseStream();
|
||||||
@@ -50,32 +48,25 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
|
|
||||||
HRESULT CodeReal(ISequentialInStream **inStreams,
|
HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
|
||||||
const UInt64 **inSizes,
|
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 **outSizes,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress);
|
ICompressProgressInfo *progress);
|
||||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
|
||||||
const UInt64 **inSizes,
|
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 **outSizes,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress);
|
ICompressProgressInfo *progress);
|
||||||
|
CEncoder(): _buffer(0) {};
|
||||||
|
~CEncoder();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class CDecoder:
|
class CDecoder:
|
||||||
public ICompressCoder2,
|
public ICompressCoder2,
|
||||||
|
public ICompressSetBufSize,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
CInBuffer _mainInStream;
|
CInBuffer _mainInStream;
|
||||||
CInBuffer _callStream;
|
CInBuffer _callStream;
|
||||||
CInBuffer _jumpStream;
|
CInBuffer _jumpStream;
|
||||||
@@ -83,7 +74,10 @@ public:
|
|||||||
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];
|
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];
|
||||||
|
|
||||||
COutBuffer _outStream;
|
COutBuffer _outStream;
|
||||||
|
UInt32 _inBufSizes[4];
|
||||||
|
UInt32 _outBufSize;
|
||||||
|
|
||||||
|
public:
|
||||||
void ReleaseStreams()
|
void ReleaseStreams()
|
||||||
{
|
{
|
||||||
_mainInStream.ReleaseStream();
|
_mainInStream.ReleaseStream();
|
||||||
@@ -103,21 +97,17 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP1(ICompressSetBufSize);
|
||||||
HRESULT CodeReal(ISequentialInStream **inStreams,
|
HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
|
||||||
const UInt64 **inSizes,
|
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 **outSizes,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress);
|
ICompressProgressInfo *progress);
|
||||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
|
||||||
const UInt64 **inSizes,
|
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
|
||||||
UInt32 numInStreams,
|
|
||||||
ISequentialOutStream **outStreams,
|
|
||||||
const UInt64 **outSizes,
|
|
||||||
UInt32 numOutStreams,
|
|
||||||
ICompressProgressInfo *progress);
|
ICompressProgressInfo *progress);
|
||||||
|
|
||||||
|
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
|
||||||
|
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
|
||||||
|
CDecoder();
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -24,9 +24,10 @@ static HRESULT SResToHRESULT(SRes res)
|
|||||||
namespace NCompress {
|
namespace NCompress {
|
||||||
namespace NLzma {
|
namespace NLzma {
|
||||||
|
|
||||||
static const UInt32 kInBufSize = 1 << 20;
|
CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false),
|
||||||
|
_inBufSize(1 << 20),
|
||||||
CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false), FinishStream(false)
|
_outBufSize(1 << 22),
|
||||||
|
FinishStream(false)
|
||||||
{
|
{
|
||||||
_inSizeProcessed = 0;
|
_inSizeProcessed = 0;
|
||||||
_inPos = _inSize = 0;
|
_inPos = _inSize = 0;
|
||||||
@@ -43,13 +44,18 @@ CDecoder::~CDecoder()
|
|||||||
MyFree(_inBuf);
|
MyFree(_inBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }
|
||||||
|
STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }
|
||||||
|
|
||||||
HRESULT CDecoder::CreateInputBuffer()
|
HRESULT CDecoder::CreateInputBuffer()
|
||||||
{
|
{
|
||||||
if (_inBuf == 0)
|
if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)
|
||||||
{
|
{
|
||||||
_inBuf = (Byte *)MyAlloc(kInBufSize);
|
MyFree(_inBuf);
|
||||||
|
_inBuf = (Byte *)MyAlloc(_inBufSize);
|
||||||
if (_inBuf == 0)
|
if (_inBuf == 0)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
_inBufSizeAllocated = _inBufSize;
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -67,6 +73,7 @@ void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize)
|
|||||||
if (_outSizeDefined)
|
if (_outSizeDefined)
|
||||||
_outSize = *outSize;
|
_outSize = *outSize;
|
||||||
_outSizeProcessed = 0;
|
_outSizeProcessed = 0;
|
||||||
|
_wrPos = 0;
|
||||||
LzmaDec_Init(&_state);
|
LzmaDec_Init(&_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,19 +92,17 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
|||||||
|
|
||||||
UInt64 startInProgress = _inSizeProcessed;
|
UInt64 startInProgress = _inSizeProcessed;
|
||||||
|
|
||||||
|
SizeT next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (_inPos == _inSize)
|
if (_inPos == _inSize)
|
||||||
{
|
{
|
||||||
_inPos = _inSize = 0;
|
_inPos = _inSize = 0;
|
||||||
RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize));
|
RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
SizeT dicPos = _state.dicPos;
|
SizeT dicPos = _state.dicPos;
|
||||||
SizeT curSize = _state.dicBufSize - dicPos;
|
SizeT curSize = next - dicPos;
|
||||||
const UInt32 kStepSize = ((UInt32)1 << 22);
|
|
||||||
if (curSize > kStepSize)
|
|
||||||
curSize = (SizeT)kStepSize;
|
|
||||||
|
|
||||||
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
|
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
|
||||||
if (_outSizeDefined)
|
if (_outSizeDefined)
|
||||||
@@ -123,9 +128,18 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
|||||||
bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);
|
bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);
|
||||||
bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);
|
bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);
|
||||||
|
|
||||||
if (res != 0 || _state.dicPos == _state.dicBufSize || finished || stopDecoding)
|
if (res != 0 || _state.dicPos == next || finished || stopDecoding)
|
||||||
{
|
{
|
||||||
HRESULT res2 = WriteStream(outStream, _state.dic, _state.dicPos);
|
HRESULT res2 = WriteStream(outStream, _state.dic + _wrPos, _state.dicPos - _wrPos);
|
||||||
|
|
||||||
|
_wrPos = _state.dicPos;
|
||||||
|
if (_state.dicPos == _state.dicBufSize)
|
||||||
|
{
|
||||||
|
_state.dicPos = 0;
|
||||||
|
_wrPos = 0;
|
||||||
|
}
|
||||||
|
next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);
|
||||||
|
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
RINOK(res2);
|
RINOK(res2);
|
||||||
@@ -134,9 +148,6 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
|||||||
if (finished)
|
if (finished)
|
||||||
return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);
|
return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);
|
||||||
}
|
}
|
||||||
if (_state.dicPos == _state.dicBufSize)
|
|
||||||
_state.dicPos = 0;
|
|
||||||
|
|
||||||
if (progress)
|
if (progress)
|
||||||
{
|
{
|
||||||
UInt64 inSize = _inSizeProcessed - startInProgress;
|
UInt64 inSize = _inSizeProcessed - startInProgress;
|
||||||
@@ -148,6 +159,8 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
|||||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||||
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
|
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||||
{
|
{
|
||||||
|
if (_inBuf == 0)
|
||||||
|
return E_INVALIDARG;
|
||||||
SetOutStreamSize(outSize);
|
SetOutStreamSize(outSize);
|
||||||
return CodeSpec(inStream, outStream, progress);
|
return CodeSpec(inStream, outStream, progress);
|
||||||
}
|
}
|
||||||
@@ -166,7 +179,7 @@ STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
|
|||||||
if (_inPos == _inSize)
|
if (_inPos == _inSize)
|
||||||
{
|
{
|
||||||
_inPos = _inSize = 0;
|
_inPos = _inSize = 0;
|
||||||
RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));
|
RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SizeT inProcessed = _inSize - _inPos;
|
SizeT inProcessed = _inSize - _inPos;
|
||||||
@@ -214,7 +227,7 @@ HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processed
|
|||||||
if (_inPos == _inSize)
|
if (_inPos == _inSize)
|
||||||
{
|
{
|
||||||
_inPos = _inSize = 0;
|
_inPos = _inSize = 0;
|
||||||
RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));
|
RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
|
||||||
if (_inSize == 0)
|
if (_inSize == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace NLzma {
|
|||||||
class CDecoder:
|
class CDecoder:
|
||||||
public ICompressCoder,
|
public ICompressCoder,
|
||||||
public ICompressSetDecoderProperties2,
|
public ICompressSetDecoderProperties2,
|
||||||
|
public ICompressSetBufSize,
|
||||||
#ifndef NO_READ_FROM_CODER
|
#ifndef NO_READ_FROM_CODER
|
||||||
public ICompressSetInStream,
|
public ICompressSetInStream,
|
||||||
public ICompressSetOutStreamSize,
|
public ICompressSetOutStreamSize,
|
||||||
@@ -32,6 +33,11 @@ class CDecoder:
|
|||||||
UInt64 _inSizeProcessed;
|
UInt64 _inSizeProcessed;
|
||||||
UInt64 _outSizeProcessed;
|
UInt64 _outSizeProcessed;
|
||||||
|
|
||||||
|
UInt32 _inBufSizeAllocated;
|
||||||
|
UInt32 _inBufSize;
|
||||||
|
UInt32 _outBufSize;
|
||||||
|
SizeT _wrPos;
|
||||||
|
|
||||||
HRESULT CreateInputBuffer();
|
HRESULT CreateInputBuffer();
|
||||||
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
|
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
|
||||||
void SetOutStreamSizeResume(const UInt64 *outSize);
|
void SetOutStreamSizeResume(const UInt64 *outSize);
|
||||||
@@ -39,6 +45,7 @@ class CDecoder:
|
|||||||
public:
|
public:
|
||||||
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
|
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
|
||||||
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
|
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
|
||||||
|
MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
|
||||||
#ifndef NO_READ_FROM_CODER
|
#ifndef NO_READ_FROM_CODER
|
||||||
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
|
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
|
||||||
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
|
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
|
||||||
@@ -51,6 +58,8 @@ public:
|
|||||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
||||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||||
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
|
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
|
||||||
|
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
|
||||||
|
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
|
||||||
|
|
||||||
#ifndef NO_READ_FROM_CODER
|
#ifndef NO_READ_FROM_CODER
|
||||||
|
|
||||||
@@ -68,7 +77,6 @@ public:
|
|||||||
|
|
||||||
CDecoder();
|
CDecoder();
|
||||||
virtual ~CDecoder();
|
virtual ~CDecoder();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
#ifndef __COMPRESS_PPMD_ZIP_H
|
#ifndef __COMPRESS_PPMD_ZIP_H
|
||||||
#define __COMPRESS_PPMD_ZIP_H
|
#define __COMPRESS_PPMD_ZIP_H
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "../../../C/Alloc.h"
|
#include "../../../C/Alloc.h"
|
||||||
#include "../../../C/Ppmd8.h"
|
#include "../../../C/Ppmd8.h"
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,9 @@
|
|||||||
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
|
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
|
||||||
0A IOutFolderArchive
|
0A IOutFolderArchive
|
||||||
0B IFolderArchiveUpdateCallback
|
0B IFolderArchiveUpdateCallback
|
||||||
0<EFBFBD> Agent.h::IArchiveFolderInternal
|
0C Agent.h::IArchiveFolderInternal
|
||||||
0D IInFolderArchive
|
0D
|
||||||
|
0E IInFolderArchive
|
||||||
|
|
||||||
03 IStream.h
|
03 IStream.h
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
32 ICompressSetOutStream
|
32 ICompressSetOutStream
|
||||||
33 ICompressSetInStreamSize
|
33 ICompressSetInStreamSize
|
||||||
34 ICompressSetOutStreamSize
|
34 ICompressSetOutStreamSize
|
||||||
|
35 ICompressSetBufSize
|
||||||
40 ICompressFilter
|
40 ICompressFilter
|
||||||
60 ICompressCodecsInfo
|
60 ICompressCodecsInfo
|
||||||
61 ISetCompressCodecsInfo
|
61 ISetCompressCodecsInfo
|
||||||
@@ -88,24 +90,24 @@
|
|||||||
09 IFolderClone
|
09 IFolderClone
|
||||||
0A IFolderSetFlatMode
|
0A IFolderSetFlatMode
|
||||||
0B IFolderOperationsExtractCallback
|
0B IFolderOperationsExtractCallback
|
||||||
0C IFolderArchiveProperties
|
0C //
|
||||||
0D IGetFolderArchiveProperties
|
0D //
|
||||||
0E IFolderProperties
|
0E IFolderProperties
|
||||||
|
0F
|
||||||
|
10 IFolderArcProps
|
||||||
|
11 IGetFolderArcProps
|
||||||
|
|
||||||
|
|
||||||
09 IFolder.h :: FOLDER_MANAGER_INTERFACE
|
09 IFolder.h :: FOLDER_MANAGER_INTERFACE
|
||||||
|
|
||||||
00 - 03 // old IFolderManager
|
00 - 04 // old IFolderManager
|
||||||
04 IFolderManager
|
05 IFolderManager
|
||||||
|
|
||||||
|
|
||||||
|
// 0A PluginInterface.h
|
||||||
------------------
|
00 IInitContextMenu
|
||||||
|
01 IPluginOptionsCallback
|
||||||
|
02 IPluginOptions
|
||||||
{23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu
|
|
||||||
{23170F69-40C1-278D-0000-000100020100} PluginInterface::IPluginOptionsCallback
|
|
||||||
{23170F69-40C1-278D-0000-000100020000} PluginInterface::IPluginOptions
|
|
||||||
|
|
||||||
|
|
||||||
Handler GUIDs:
|
Handler GUIDs:
|
||||||
|
|||||||
@@ -107,6 +107,12 @@ CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
|
|||||||
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
|
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CODER_INTERFACE(ICompressSetBufSize, 0x35)
|
||||||
|
{
|
||||||
|
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size) PURE;
|
||||||
|
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE;
|
||||||
|
};
|
||||||
|
|
||||||
CODER_INTERFACE(ICompressFilter, 0x40)
|
CODER_INTERFACE(ICompressFilter, 0x40)
|
||||||
{
|
{
|
||||||
STDMETHOD(Init)() PURE;
|
STDMETHOD(Init)() PURE;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#define MY_VER_MAJOR 9
|
#define MY_VER_MAJOR 9
|
||||||
#define MY_VER_MINOR 12
|
#define MY_VER_MINOR 15
|
||||||
#define MY_VER_BUILD 0
|
#define MY_VER_BUILD 0
|
||||||
#define MY_VERSION "9.12 beta"
|
#define MY_VERSION "9.15 beta"
|
||||||
#define MY_7ZIP_VERSION "7-Zip 9.12 beta"
|
#define MY_7ZIP_VERSION "7-Zip 9.15 beta"
|
||||||
#define MY_DATE "2010-03-24"
|
#define MY_DATE "2010-06-20"
|
||||||
#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov"
|
#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov"
|
||||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
|
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
|
||||||
|
|||||||
@@ -278,15 +278,15 @@ struct CArchiveItemPropertyTemp
|
|||||||
VARTYPE Type;
|
VARTYPE Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP CAgentFolder::GetNumberOfProperties(UInt32 *numProperties)
|
STDMETHODIMP CAgentFolder::GetNumberOfProperties(UInt32 *numProps)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProperties));
|
RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProps));
|
||||||
*numProperties += kNumProperties;
|
*numProps += kNumProperties;
|
||||||
if (!_flatMode)
|
if (!_flatMode)
|
||||||
(*numProperties)--;
|
(*numProps)--;
|
||||||
if (!_agentSpec->_proxyArchive->ThereIsPathProp)
|
if (!_agentSpec->_proxyArchive->ThereIsPathProp)
|
||||||
(*numProperties)++;
|
(*numProps)++;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
@@ -294,8 +294,8 @@ STDMETHODIMP CAgentFolder::GetNumberOfProperties(UInt32 *numProperties)
|
|||||||
STDMETHODIMP CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
|
STDMETHODIMP CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
UInt32 numProperties;
|
UInt32 numProps;
|
||||||
_agentSpec->GetArchive()->GetNumberOfProperties(&numProperties);
|
_agentSpec->GetArchive()->GetNumberOfProperties(&numProps);
|
||||||
if (!_agentSpec->_proxyArchive->ThereIsPathProp)
|
if (!_agentSpec->_proxyArchive->ThereIsPathProp)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
@@ -308,7 +308,7 @@ STDMETHODIMP CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *pro
|
|||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < numProperties)
|
if (index < numProps)
|
||||||
{
|
{
|
||||||
RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType));
|
RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType));
|
||||||
if (*propID == kpidPath)
|
if (*propID == kpidPath)
|
||||||
@@ -316,7 +316,7 @@ STDMETHODIMP CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *pro
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const STATPROPSTG &srcItem = kProperties[index - numProperties];
|
const STATPROPSTG &srcItem = kProperties[index - numProps];
|
||||||
*propID = srcItem.propid;
|
*propID = srcItem.propid;
|
||||||
*varType = srcItem.vt;
|
*varType = srcItem.vt;
|
||||||
*name = 0;
|
*name = 0;
|
||||||
@@ -356,9 +356,9 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CAgentFolder::GetNumberOfFolderProperties(UInt32 *numProperties)
|
STDMETHODIMP CAgentFolder::GetNumberOfFolderProperties(UInt32 *numProps)
|
||||||
{
|
{
|
||||||
*numProperties = kNumFolderProps;
|
*numProps = kNumFolderProps;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,9 +374,9 @@ STDMETHODIMP CAgentFolder::GetFolderPropertyInfo(UInt32 index, BSTR *name, PROPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CAgentFolder::GetFolderArchiveProperties(IFolderArchiveProperties **object)
|
STDMETHODIMP CAgentFolder::GetFolderArcProps(IFolderArcProps **object)
|
||||||
{
|
{
|
||||||
CMyComPtr<IFolderArchiveProperties> temp = _agentSpec;
|
CMyComPtr<IFolderArcProps> temp = _agentSpec;
|
||||||
*object = temp.Detach();
|
*object = temp.Detach();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -468,6 +468,7 @@ CAgent::~CAgent()
|
|||||||
STDMETHODIMP CAgent::Open(
|
STDMETHODIMP CAgent::Open(
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
const wchar_t *filePath,
|
const wchar_t *filePath,
|
||||||
|
const wchar_t *arcFormat,
|
||||||
BSTR *archiveType,
|
BSTR *archiveType,
|
||||||
IArchiveOpenCallback *openArchiveCallback)
|
IArchiveOpenCallback *openArchiveCallback)
|
||||||
{
|
{
|
||||||
@@ -488,7 +489,11 @@ STDMETHODIMP CAgent::Open(
|
|||||||
_compressCodecsInfo = _codecs;
|
_compressCodecsInfo = _codecs;
|
||||||
RINOK(_codecs->Load());
|
RINOK(_codecs->Load());
|
||||||
|
|
||||||
RINOK(_archiveLink.Open(_codecs, CIntVector(), false, inStream, _archiveFilePath, openArchiveCallback));
|
CIntVector formatIndices;
|
||||||
|
if (!_codecs->FindFormatForArchiveType(arcFormat, formatIndices))
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
RINOK(_archiveLink.Open(_codecs, formatIndices, false, inStream, _archiveFilePath, openArchiveCallback));
|
||||||
|
|
||||||
CArc &arc = _archiveLink.Arcs.Back();
|
CArc &arc = _archiveLink.Arcs.Back();
|
||||||
if (!inStream)
|
if (!inStream)
|
||||||
@@ -573,10 +578,10 @@ STDMETHODIMP CAgent::Extract(
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CAgent::GetNumberOfProperties(UInt32 *numProperties)
|
STDMETHODIMP CAgent::GetNumberOfProperties(UInt32 *numProps)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
return GetArchive()->GetNumberOfProperties(numProperties);
|
return GetArchive()->GetNumberOfProperties(numProps);
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,25 +596,50 @@ STDMETHODIMP CAgent::GetPropertyInfo(UInt32 index,
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CAgent::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
STDMETHODIMP CAgent::GetArcNumLevels(UInt32 *numLevels)
|
||||||
|
{
|
||||||
|
*numLevels = _archiveLink.Arcs.Size();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
return GetArchive()->GetArchiveProperty(propID, value);
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
CArc &arc = _archiveLink.Arcs[level];
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidType: prop = _codecs->Formats[arc.FormatIndex].Name; break;
|
||||||
|
case kpidPath: prop = arc.Path; break;
|
||||||
|
default: return arc.Archive->GetArchiveProperty(propID, value);
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
STDMETHODIMP CAgent::GetArcNumProps(UInt32 level, UInt32 *numProps)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
return _archiveLink.Arcs[level].Archive->GetNumberOfArchiveProperties(numProps);
|
||||||
return GetArchive()->GetNumberOfArchiveProperties(numProperties);
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CAgent::GetArchivePropertyInfo(UInt32 index,
|
STDMETHODIMP CAgent::GetArcPropInfo(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
return _archiveLink.Arcs[level].Archive->GetArchivePropertyInfo(index, name, propID, varType);
|
||||||
return GetArchive()->GetArchivePropertyInfo(index,
|
}
|
||||||
name, propID, varType);
|
|
||||||
COM_TRY_END
|
// MainItemProperty
|
||||||
|
STDMETHODIMP CAgent::GetArcProp2(UInt32 level, PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
return _archiveLink.Arcs[level - 1].Archive->GetProperty(_archiveLink.Arcs[level].SubfileIndex, propID, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CAgent::GetArcNumProps2(UInt32 level, UInt32 *numProps)
|
||||||
|
{
|
||||||
|
return _archiveLink.Arcs[level - 1].Archive->GetNumberOfProperties(numProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CAgent::GetArcPropInfo2(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||||
|
{
|
||||||
|
return _archiveLink.Arcs[level - 1].Archive->GetPropertyInfo(index, name, propID, varType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class CAgent;
|
|||||||
class CAgentFolder:
|
class CAgentFolder:
|
||||||
public IFolderFolder,
|
public IFolderFolder,
|
||||||
public IFolderProperties,
|
public IFolderProperties,
|
||||||
public IGetFolderArchiveProperties,
|
public IGetFolderArcProps,
|
||||||
public IArchiveFolder,
|
public IArchiveFolder,
|
||||||
public IArchiveFolderInternal,
|
public IArchiveFolderInternal,
|
||||||
public IInArchiveGetStream,
|
public IInArchiveGetStream,
|
||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
|
|
||||||
MY_QUERYINTERFACE_BEGIN2(IFolderFolder)
|
MY_QUERYINTERFACE_BEGIN2(IFolderFolder)
|
||||||
MY_QUERYINTERFACE_ENTRY(IFolderProperties)
|
MY_QUERYINTERFACE_ENTRY(IFolderProperties)
|
||||||
MY_QUERYINTERFACE_ENTRY(IGetFolderArchiveProperties)
|
MY_QUERYINTERFACE_ENTRY(IGetFolderArcProps)
|
||||||
MY_QUERYINTERFACE_ENTRY(IArchiveFolder)
|
MY_QUERYINTERFACE_ENTRY(IArchiveFolder)
|
||||||
MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal)
|
MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal)
|
||||||
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
||||||
@@ -68,7 +68,7 @@ public:
|
|||||||
INTERFACE_FolderFolder(;)
|
INTERFACE_FolderFolder(;)
|
||||||
INTERFACE_FolderProperties(;)
|
INTERFACE_FolderProperties(;)
|
||||||
|
|
||||||
STDMETHOD(GetFolderArchiveProperties)(IFolderArchiveProperties **object);
|
STDMETHOD(GetFolderArcProps)(IFolderArcProps **object);
|
||||||
|
|
||||||
// IArchiveFolder
|
// IArchiveFolder
|
||||||
STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
|
STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
|
||||||
@@ -132,7 +132,7 @@ private:
|
|||||||
|
|
||||||
class CAgent:
|
class CAgent:
|
||||||
public IInFolderArchive,
|
public IInFolderArchive,
|
||||||
public IFolderArchiveProperties,
|
public IFolderArcProps,
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
public IOutFolderArchive,
|
public IOutFolderArchive,
|
||||||
public ISetProperties,
|
public ISetProperties,
|
||||||
@@ -142,7 +142,7 @@ class CAgent:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
MY_QUERYINTERFACE_BEGIN2(IInFolderArchive)
|
MY_QUERYINTERFACE_BEGIN2(IInFolderArchive)
|
||||||
MY_QUERYINTERFACE_ENTRY(IFolderArchiveProperties)
|
MY_QUERYINTERFACE_ENTRY(IFolderArcProps)
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
MY_QUERYINTERFACE_ENTRY(IOutFolderArchive)
|
MY_QUERYINTERFACE_ENTRY(IOutFolderArchive)
|
||||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||||
@@ -151,7 +151,7 @@ public:
|
|||||||
MY_ADDREF_RELEASE
|
MY_ADDREF_RELEASE
|
||||||
|
|
||||||
INTERFACE_IInFolderArchive(;)
|
INTERFACE_IInFolderArchive(;)
|
||||||
INTERFACE_IFolderArchiveProperties(;)
|
INTERFACE_IFolderArcProps(;)
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
INTERFACE_IOutFolderArchive(;)
|
INTERFACE_IOutFolderArchive(;)
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ int CArchiveFolderManager::FindFormat(const UString &type)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CArchiveFolderManager::OpenFolderFile(IInStream *inStream, const wchar_t *filePath,
|
STDMETHODIMP CArchiveFolderManager::OpenFolderFile(IInStream *inStream,
|
||||||
|
const wchar_t *filePath, const wchar_t *arcFormat,
|
||||||
IFolderFolder **resultFolder, IProgress *progress)
|
IFolderFolder **resultFolder, IProgress *progress)
|
||||||
{
|
{
|
||||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallback;
|
CMyComPtr<IArchiveOpenCallback> openArchiveCallback;
|
||||||
@@ -45,7 +46,7 @@ STDMETHODIMP CArchiveFolderManager::OpenFolderFile(IInStream *inStream, const wc
|
|||||||
}
|
}
|
||||||
CAgent *agent = new CAgent();
|
CAgent *agent = new CAgent();
|
||||||
CMyComPtr<IInFolderArchive> archive = agent;
|
CMyComPtr<IInFolderArchive> archive = agent;
|
||||||
RINOK(agent->Open(inStream, filePath, NULL, openArchiveCallback));
|
RINOK(agent->Open(inStream, filePath, arcFormat, NULL, openArchiveCallback));
|
||||||
return agent->BindToRootFolder(resultFolder);
|
return agent->BindToRootFolder(resultFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ FOLDER_ARCHIVE_INTERFACE(IArchiveFolder, 0x05)
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define INTERFACE_IInFolderArchive(x) \
|
#define INTERFACE_IInFolderArchive(x) \
|
||||||
STDMETHOD(Open)(IInStream *inStream, const wchar_t *filePath, BSTR *archiveType, IArchiveOpenCallback *openArchiveCallback) x; \
|
STDMETHOD(Open)(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveTypeRes, IArchiveOpenCallback *openArchiveCallback) x; \
|
||||||
STDMETHOD(ReOpen)(IArchiveOpenCallback *openArchiveCallback) x; \
|
STDMETHOD(ReOpen)(IArchiveOpenCallback *openArchiveCallback) x; \
|
||||||
STDMETHOD(Close)() x; \
|
STDMETHOD(Close)() x; \
|
||||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \
|
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \
|
||||||
@@ -37,7 +37,7 @@ FOLDER_ARCHIVE_INTERFACE(IArchiveFolder, 0x05)
|
|||||||
NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, \
|
NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, \
|
||||||
Int32 testMode, IFolderArchiveExtractCallback *extractCallback2) x; \
|
Int32 testMode, IFolderArchiveExtractCallback *extractCallback2) x; \
|
||||||
|
|
||||||
FOLDER_ARCHIVE_INTERFACE(IInFolderArchive, 0x0D)
|
FOLDER_ARCHIVE_INTERFACE(IInFolderArchive, 0x0E)
|
||||||
{
|
{
|
||||||
INTERFACE_IInFolderArchive(PURE)
|
INTERFACE_IInFolderArchive(PURE)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -696,9 +696,13 @@ HRESULT LzmaBench(
|
|||||||
|
|
||||||
const UInt32 kLzmaId = 0x030101;
|
const UInt32 kLzmaId = 0x030101;
|
||||||
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.encoder, true));
|
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.encoder, true));
|
||||||
|
if (!encoder.encoder)
|
||||||
|
return E_NOTIMPL;
|
||||||
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
|
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
|
||||||
{
|
{
|
||||||
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.decoders[j], false));
|
RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.decoders[j], false));
|
||||||
|
if (!encoder.decoders[j])
|
||||||
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,27 @@ void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
|
|||||||
s[8] = L'\0';
|
s[8] = L'\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
|
||||||
|
/*
|
||||||
|
0 READONLY
|
||||||
|
1 HIDDEN
|
||||||
|
3 SYSTEM
|
||||||
|
|
||||||
|
4 DIRECTORY
|
||||||
|
5 ARCHIVE
|
||||||
|
6 DEVICE
|
||||||
|
7 NORMAL
|
||||||
|
8 TEMPORARY
|
||||||
|
9 SPARSE_FILE
|
||||||
|
10 REPARSE_POINT
|
||||||
|
11 COMPRESSED
|
||||||
|
12 OFFLINE
|
||||||
|
13 NOT_CONTENT_INDEXED
|
||||||
|
14 ENCRYPTED
|
||||||
|
|
||||||
|
16 VIRTUAL
|
||||||
|
*/
|
||||||
|
|
||||||
#define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';
|
#define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';
|
||||||
|
|
||||||
UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
|
UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
|
||||||
@@ -55,16 +76,14 @@ UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool ful
|
|||||||
{
|
{
|
||||||
if (prop.vt != VT_UI4)
|
if (prop.vt != VT_UI4)
|
||||||
break;
|
break;
|
||||||
UString res;
|
|
||||||
UInt32 a = prop.ulVal;
|
UInt32 a = prop.ulVal;
|
||||||
if (NFile::NFind::NAttributes::IsReadOnly(a)) res += L'R';
|
wchar_t sz[32];
|
||||||
if (NFile::NFind::NAttributes::IsHidden(a)) res += L'H';
|
int pos = 0;
|
||||||
if (NFile::NFind::NAttributes::IsSystem(a)) res += L'S';
|
for (int i = 0; i < 16; i++)
|
||||||
if (NFile::NFind::NAttributes::IsDir(a)) res += L'D';
|
if (a & (1 << i) && i != 7)
|
||||||
if (NFile::NFind::NAttributes::IsArchived(a)) res += L'A';
|
sz[pos++] = g_WinAttrib[i];
|
||||||
if (NFile::NFind::NAttributes::IsCompressed(a)) res += L'C';
|
sz[pos] = '\0';
|
||||||
if (NFile::NFind::NAttributes::IsEncrypted(a)) res += L'E';
|
return sz;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
case kpidPosixAttrib:
|
case kpidPosixAttrib:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -160,6 +160,14 @@ SOURCE=.\StdAfx.h
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\BenchCon.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\BenchCon.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\ConsoleClose.cpp
|
SOURCE=.\ConsoleClose.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -184,14 +192,6 @@ SOURCE=.\List.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\BenchCon.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\BenchCon.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\Main.cpp
|
SOURCE=.\Main.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -364,10 +364,6 @@ SOURCE=..\..\..\Common\Defs.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\Exception.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\IntToString.cpp
|
SOURCE=..\..\..\Common\IntToString.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -488,7 +484,11 @@ SOURCE=..\Common\ArchiveOpenCallback.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Common\CompressionMode.h
|
SOURCE=..\Common\Bench.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\Bench.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
@@ -532,10 +532,6 @@ SOURCE=..\Common\ExtractingFilePath.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Common\HandlerLoader.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\IFileExtractCallback.h
|
SOURCE=..\Common\IFileExtractCallback.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -548,14 +544,6 @@ SOURCE=..\Common\LoadCodecs.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\Common\Bench.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\Bench.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\Common\OpenArchive.cpp
|
SOURCE=..\Common\OpenArchive.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
|
|||||||
{
|
{
|
||||||
const CArc &arc = archiveLink.Arcs[i];
|
const CArc &arc = archiveLink.Arcs[i];
|
||||||
|
|
||||||
g_StdOut << "----\n";
|
g_StdOut << "--\n";
|
||||||
PrintPropPair(L"Path", arc.Path);
|
PrintPropPair(L"Path", arc.Path);
|
||||||
PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);
|
PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);
|
||||||
UInt32 numProps;
|
UInt32 numProps;
|
||||||
@@ -514,16 +514,36 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
|
|||||||
CMyComBSTR name;
|
CMyComBSTR name;
|
||||||
PROPID propID;
|
PROPID propID;
|
||||||
VARTYPE vt;
|
VARTYPE vt;
|
||||||
if (archive->GetArchivePropertyInfo(j, &name, &propID, &vt) != S_OK)
|
RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt));
|
||||||
continue;
|
|
||||||
NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
if (archive->GetArchiveProperty(propID, &prop) != S_OK)
|
RINOK(archive->GetArchiveProperty(propID, &prop));
|
||||||
continue;
|
|
||||||
UString s = ConvertPropertyToString(prop, propID);
|
UString s = ConvertPropertyToString(prop, propID);
|
||||||
if (!s.IsEmpty())
|
if (!s.IsEmpty())
|
||||||
PrintPropPair(GetPropName(propID, name), s);
|
PrintPropPair(GetPropName(propID, name), s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (i != archiveLink.Arcs.Size() - 1)
|
||||||
|
{
|
||||||
|
UInt32 numProps;
|
||||||
|
g_StdOut << "----\n";
|
||||||
|
if (archive->GetNumberOfProperties(&numProps) == S_OK)
|
||||||
|
{
|
||||||
|
UInt32 mainIndex = archiveLink.Arcs[i + 1].SubfileIndex;
|
||||||
|
for (UInt32 j = 0; j < numProps; j++)
|
||||||
|
{
|
||||||
|
CMyComBSTR name;
|
||||||
|
PROPID propID;
|
||||||
|
VARTYPE vt;
|
||||||
|
RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt));
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(archive->GetProperty(mainIndex, propID, &prop));
|
||||||
|
UString s = ConvertPropertyToString(prop, propID);
|
||||||
|
if (!s.IsEmpty())
|
||||||
|
PrintPropPair(GetPropName(propID, name), s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
g_StdOut << endl;
|
g_StdOut << endl;
|
||||||
if (techMode)
|
if (techMode)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
(*outStream) << kHelpQuestionMessage;
|
(*outStream) << kHelpQuestionMessage;
|
||||||
|
outStream->Flush();
|
||||||
AString scannedString = g_StdIn.ScanStringUntilNewLine();
|
AString scannedString = g_StdIn.ScanStringUntilNewLine();
|
||||||
scannedString.Trim();
|
scannedString.Trim();
|
||||||
if (!scannedString.IsEmpty())
|
if (!scannedString.IsEmpty())
|
||||||
|
|||||||
@@ -94,11 +94,10 @@ STDMETHODIMP CZipContextMenu::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT
|
|||||||
return GetFileNames(dataObject, _fileNames);
|
return GetFileNames(dataObject, _fileNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CZipContextMenu::InitContextMenu(const wchar_t * /* folder */,
|
HRESULT CZipContextMenu::InitContextMenu(const wchar_t * /* folder */, const wchar_t **names, UInt32 numFiles)
|
||||||
const wchar_t **names, UINT32 numFiles)
|
|
||||||
{
|
{
|
||||||
_fileNames.Clear();
|
_fileNames.Clear();
|
||||||
for (UINT32 i = 0; i < numFiles; i++)
|
for (UInt32 i = 0; i < numFiles; i++)
|
||||||
_fileNames.Add(names[i]);
|
_fileNames.Add(names[i]);
|
||||||
_dropMode = false;
|
_dropMode = false;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -124,12 +123,12 @@ static LPCTSTR kCompressToEmailVerb = TEXT("SevenCompressToEmail");
|
|||||||
|
|
||||||
struct CContextMenuCommand
|
struct CContextMenuCommand
|
||||||
{
|
{
|
||||||
UINT32 flag;
|
UInt32 flag;
|
||||||
CZipContextMenu::ECommandInternalID CommandInternalID;
|
CZipContextMenu::ECommandInternalID CommandInternalID;
|
||||||
LPCWSTR Verb;
|
LPCWSTR Verb;
|
||||||
UINT ResourceID;
|
UINT ResourceID;
|
||||||
UINT ResourceHelpID;
|
UINT ResourceHelpID;
|
||||||
UINT32 LangID;
|
UInt32 LangID;
|
||||||
};
|
};
|
||||||
|
|
||||||
static CContextMenuCommand g_Commands[] =
|
static CContextMenuCommand g_Commands[] =
|
||||||
@@ -224,7 +223,7 @@ static CContextMenuCommand g_Commands[] =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int FindCommand(CZipContextMenu::ECommandInternalID &id)
|
static int FindCommand(CZipContextMenu::ECommandInternalID &id)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < sizeof(g_Commands) / sizeof(g_Commands[0]); i++)
|
for (int i = 0; i < sizeof(g_Commands) / sizeof(g_Commands[0]); i++)
|
||||||
if (g_Commands[i].CommandInternalID == id)
|
if (g_Commands[i].CommandInternalID == id)
|
||||||
@@ -336,6 +335,9 @@ static const char *kExtractExludeExtensions =
|
|||||||
" xml xsd xsl xslt"
|
" xml xsd xsl xslt"
|
||||||
" ";
|
" ";
|
||||||
|
|
||||||
|
static const char *kNoOpenAsExtensions =
|
||||||
|
" 7z arj bz2 cab chm cpio dmg flv gz lha lzh lzma rar swm tar tbz2 tgz wim xar xz z zip ";
|
||||||
|
|
||||||
static bool FindExt(const char *p, const UString &name)
|
static bool FindExt(const char *p, const UString &name)
|
||||||
{
|
{
|
||||||
int extPos = name.ReverseFind('.');
|
int extPos = name.ReverseFind('.');
|
||||||
@@ -415,19 +417,22 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
|||||||
if (!fileInfo.IsDir() && DoNeedExtract(fileInfo.Name))
|
if (!fileInfo.IsDir() && DoNeedExtract(fileInfo.Name))
|
||||||
{
|
{
|
||||||
// Open
|
// Open
|
||||||
if ((contextMenuFlags & NContextMenuFlags::kOpen) != 0)
|
bool thereIsMainOpenItem = ((contextMenuFlags & NContextMenuFlags::kOpen) != 0);
|
||||||
|
if (thereIsMainOpenItem)
|
||||||
{
|
{
|
||||||
CCommandMapItem commandMapItem;
|
CCommandMapItem commandMapItem;
|
||||||
FillCommand(kOpen, mainString, commandMapItem);
|
FillCommand(kOpen, mainString, commandMapItem);
|
||||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
|
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
|
||||||
_commandMap.Add(commandMapItem);
|
_commandMap.Add(commandMapItem);
|
||||||
|
}
|
||||||
/*
|
if ((contextMenuFlags & NContextMenuFlags::kOpenAs) != 0 &&
|
||||||
if (FindExt(" exe dll ", fileInfo.Name))
|
(!thereIsMainOpenItem || !FindExt(kNoOpenAsExtensions, fileInfo.Name)))
|
||||||
{
|
{
|
||||||
CMenu subMenu;
|
CMenu subMenu;
|
||||||
if (subMenu.CreatePopup())
|
if (subMenu.CreatePopup())
|
||||||
{
|
{
|
||||||
|
CCommandMapItem commandMapItem;
|
||||||
|
|
||||||
CMenuItem menuItem;
|
CMenuItem menuItem;
|
||||||
menuItem.fType = MFT_STRING;
|
menuItem.fType = MFT_STRING;
|
||||||
menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
|
menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
|
||||||
@@ -435,21 +440,33 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
|||||||
menuItem.hSubMenu = subMenu;
|
menuItem.hSubMenu = subMenu;
|
||||||
menuItem.StringValue = LangString(IDS_CONTEXT_OPEN, 0x02000103);
|
menuItem.StringValue = LangString(IDS_CONTEXT_OPEN, 0x02000103);
|
||||||
popupMenu.InsertItem(subIndex++, true, menuItem);
|
popupMenu.InsertItem(subIndex++, true, menuItem);
|
||||||
const wchar_t *exts[] = { L"7z", L"cab", L"rar", L"zip", L"pe" };
|
|
||||||
for (int i = 0; i < sizeof(exts) / sizeof(exts[0]); i++)
|
commandMapItem.CommandInternalID = kCommandNULL;
|
||||||
|
commandMapItem.Verb = kMainVerb;
|
||||||
|
commandMapItem.HelpString = LangString(IDS_CONTEXT_OPEN_HELP, 0x02000104);
|
||||||
|
_commandMap.Add(commandMapItem);
|
||||||
|
|
||||||
|
UINT subIndex2 = 0;
|
||||||
|
const wchar_t *exts[] = { L"", L"*", L"7z", L"zip", L"cab", L"rar" };
|
||||||
|
for (int i = (thereIsMainOpenItem ? 1 : 0); i < sizeof(exts) / sizeof(exts[0]); i++)
|
||||||
{
|
{
|
||||||
CCommandMapItem commandMapItem;
|
CCommandMapItem commandMapItem;
|
||||||
FillCommand(kOpenAs, mainString, commandMapItem);
|
if (i == 0)
|
||||||
|
FillCommand(kOpen, mainString, commandMapItem);
|
||||||
|
else
|
||||||
|
{
|
||||||
mainString = exts[i];
|
mainString = exts[i];
|
||||||
commandMapItem.ArchiveType = mainString;
|
commandMapItem.CommandInternalID = kOpen;
|
||||||
MyInsertMenu(subMenu, subIndex++, currentCommandID++, mainString);
|
commandMapItem.Verb = (UString)kMainVerb + L".Open." + mainString;
|
||||||
|
commandMapItem.HelpString = mainString;
|
||||||
|
commandMapItem.ArcType = mainString;
|
||||||
|
}
|
||||||
|
MyInsertMenu(subMenu, subIndex2++, currentCommandID++, mainString);
|
||||||
_commandMap.Add(commandMapItem);
|
_commandMap.Add(commandMapItem);
|
||||||
}
|
}
|
||||||
subMenu.Detach();
|
subMenu.Detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +559,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
|||||||
commandMapItem.Folder = _dropPath;
|
commandMapItem.Folder = _dropPath;
|
||||||
else
|
else
|
||||||
commandMapItem.Folder = archivePathPrefix;
|
commandMapItem.Folder = archivePathPrefix;
|
||||||
commandMapItem.Archive = archiveName;
|
commandMapItem.ArcName = archiveName;
|
||||||
FillCommand(kCompress, mainString, commandMapItem);
|
FillCommand(kCompress, mainString, commandMapItem);
|
||||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
|
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
|
||||||
_commandMap.Add(commandMapItem);
|
_commandMap.Add(commandMapItem);
|
||||||
@@ -553,7 +570,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
|||||||
if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0 && !_dropMode)
|
if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0 && !_dropMode)
|
||||||
{
|
{
|
||||||
CCommandMapItem commandMapItem;
|
CCommandMapItem commandMapItem;
|
||||||
commandMapItem.Archive = archiveName;
|
commandMapItem.ArcName = archiveName;
|
||||||
FillCommand(kCompressEmail, mainString, commandMapItem);
|
FillCommand(kCompressEmail, mainString, commandMapItem);
|
||||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
|
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
|
||||||
_commandMap.Add(commandMapItem);
|
_commandMap.Add(commandMapItem);
|
||||||
@@ -570,8 +587,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
|||||||
commandMapItem.Folder = _dropPath;
|
commandMapItem.Folder = _dropPath;
|
||||||
else
|
else
|
||||||
commandMapItem.Folder = archivePathPrefix;
|
commandMapItem.Folder = archivePathPrefix;
|
||||||
commandMapItem.Archive = archiveName7z;
|
commandMapItem.ArcName = archiveName7z;
|
||||||
commandMapItem.ArchiveType = L"7z";
|
commandMapItem.ArcType = L"7z";
|
||||||
s = MyFormatNew(s, GetQuotedReducedString(archiveName7z));
|
s = MyFormatNew(s, GetQuotedReducedString(archiveName7z));
|
||||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
|
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
|
||||||
_commandMap.Add(commandMapItem);
|
_commandMap.Add(commandMapItem);
|
||||||
@@ -584,8 +601,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
|||||||
CCommandMapItem commandMapItem;
|
CCommandMapItem commandMapItem;
|
||||||
UString s;
|
UString s;
|
||||||
FillCommand(kCompressTo7zEmail, s, commandMapItem);
|
FillCommand(kCompressTo7zEmail, s, commandMapItem);
|
||||||
commandMapItem.Archive = archiveName7z;
|
commandMapItem.ArcName = archiveName7z;
|
||||||
commandMapItem.ArchiveType = L"7z";
|
commandMapItem.ArcType = L"7z";
|
||||||
s = MyFormatNew(s, GetQuotedReducedString(archiveName7z));
|
s = MyFormatNew(s, GetQuotedReducedString(archiveName7z));
|
||||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
|
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
|
||||||
_commandMap.Add(commandMapItem);
|
_commandMap.Add(commandMapItem);
|
||||||
@@ -602,8 +619,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
|||||||
commandMapItem.Folder = _dropPath;
|
commandMapItem.Folder = _dropPath;
|
||||||
else
|
else
|
||||||
commandMapItem.Folder = archivePathPrefix;
|
commandMapItem.Folder = archivePathPrefix;
|
||||||
commandMapItem.Archive = archiveNameZip;
|
commandMapItem.ArcName = archiveNameZip;
|
||||||
commandMapItem.ArchiveType = L"zip";
|
commandMapItem.ArcType = L"zip";
|
||||||
s = MyFormatNew(s, GetQuotedReducedString(archiveNameZip));
|
s = MyFormatNew(s, GetQuotedReducedString(archiveNameZip));
|
||||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
|
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
|
||||||
_commandMap.Add(commandMapItem);
|
_commandMap.Add(commandMapItem);
|
||||||
@@ -616,8 +633,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
|||||||
CCommandMapItem commandMapItem;
|
CCommandMapItem commandMapItem;
|
||||||
UString s;
|
UString s;
|
||||||
FillCommand(kCompressToZipEmail, s, commandMapItem);
|
FillCommand(kCompressToZipEmail, s, commandMapItem);
|
||||||
commandMapItem.Archive = archiveNameZip;
|
commandMapItem.ArcName = archiveNameZip;
|
||||||
commandMapItem.ArchiveType = L"zip";
|
commandMapItem.ArcType = L"zip";
|
||||||
s = MyFormatNew(s, GetQuotedReducedString(archiveNameZip));
|
s = MyFormatNew(s, GetQuotedReducedString(archiveNameZip));
|
||||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
|
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
|
||||||
_commandMap.Add(commandMapItem);
|
_commandMap.Add(commandMapItem);
|
||||||
@@ -691,15 +708,21 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
const CCommandMapItem commandMapItem = _commandMap[commandOffset];
|
const CCommandMapItem commandMapItem = _commandMap[commandOffset];
|
||||||
ECommandInternalID commandInternalID = commandMapItem.CommandInternalID;
|
ECommandInternalID cmdID = commandMapItem.CommandInternalID;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch(commandInternalID)
|
switch(cmdID)
|
||||||
{
|
{
|
||||||
case kOpen:
|
case kOpen:
|
||||||
{
|
{
|
||||||
UString params = GetQuotedString(_fileNames[0]);
|
UString params;
|
||||||
|
params = GetQuotedString(_fileNames[0]);
|
||||||
|
if (commandMapItem.ArcType)
|
||||||
|
{
|
||||||
|
params += L" -t";
|
||||||
|
params += commandMapItem.ArcType;
|
||||||
|
}
|
||||||
MyCreateProcess(Get7zFmPath(), params);
|
MyCreateProcess(Get7zFmPath(), params);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -707,7 +730,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
|||||||
case kExtractHere:
|
case kExtractHere:
|
||||||
case kExtractTo:
|
case kExtractTo:
|
||||||
{
|
{
|
||||||
ExtractArchives(_fileNames, commandMapItem.Folder, (commandInternalID == kExtract));
|
ExtractArchives(_fileNames, commandMapItem.Folder, (cmdID == kExtract));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kTest:
|
case kTest:
|
||||||
@@ -723,14 +746,14 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
|||||||
case kCompressToZipEmail:
|
case kCompressToZipEmail:
|
||||||
{
|
{
|
||||||
bool email =
|
bool email =
|
||||||
(commandInternalID == kCompressEmail) ||
|
(cmdID == kCompressEmail) ||
|
||||||
(commandInternalID == kCompressTo7zEmail) ||
|
(cmdID == kCompressTo7zEmail) ||
|
||||||
(commandInternalID == kCompressToZipEmail);
|
(cmdID == kCompressToZipEmail);
|
||||||
bool showDialog =
|
bool showDialog =
|
||||||
(commandInternalID == kCompress) ||
|
(cmdID == kCompress) ||
|
||||||
(commandInternalID == kCompressEmail);
|
(cmdID == kCompressEmail);
|
||||||
CompressFiles(commandMapItem.Folder,
|
CompressFiles(commandMapItem.Folder,
|
||||||
commandMapItem.Archive, commandMapItem.ArchiveType,
|
commandMapItem.ArcName, commandMapItem.ArcType,
|
||||||
_fileNames, email, showDialog, false);
|
_fileNames, email, showDialog, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,20 +3,13 @@
|
|||||||
#ifndef __CONTEXT_MENU_H
|
#ifndef __CONTEXT_MENU_H
|
||||||
#define __CONTEXT_MENU_H
|
#define __CONTEXT_MENU_H
|
||||||
|
|
||||||
// {23170F69-40C1-278A-1000-000100020000}
|
|
||||||
DEFINE_GUID(CLSID_CZipContextMenu,
|
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
|
|
||||||
|
|
||||||
#include "Common/MyString.h"
|
#include "Common/MyString.h"
|
||||||
|
|
||||||
#include "../FileManager/PluginInterface.h"
|
|
||||||
#include "../FileManager/MyCom2.h"
|
#include "../FileManager/MyCom2.h"
|
||||||
|
|
||||||
|
|
||||||
class CZipContextMenu:
|
class CZipContextMenu:
|
||||||
public IContextMenu,
|
public IContextMenu,
|
||||||
public IShellExtInit,
|
public IShellExtInit,
|
||||||
public IInitContextMenu,
|
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -37,17 +30,7 @@ public:
|
|||||||
kCompressToZipEmail
|
kCompressToZipEmail
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CCommandMapItem
|
MY_UNKNOWN_IMP2_MT(IContextMenu, IShellExtInit)
|
||||||
{
|
|
||||||
ECommandInternalID CommandInternalID;
|
|
||||||
UString Verb;
|
|
||||||
UString HelpString;
|
|
||||||
UString Folder;
|
|
||||||
UString Archive;
|
|
||||||
UString ArchiveType;
|
|
||||||
};
|
|
||||||
|
|
||||||
MY_UNKNOWN_IMP3_MT(IContextMenu, IShellExtInit, IInitContextMenu)
|
|
||||||
|
|
||||||
// IShellExtInit
|
// IShellExtInit
|
||||||
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY hkeyProgID);
|
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY hkeyProgID);
|
||||||
@@ -57,22 +40,31 @@ public:
|
|||||||
STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici);
|
STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici);
|
||||||
STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax);
|
STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax);
|
||||||
|
|
||||||
// IInitContextMenu
|
HRESULT InitContextMenu(const wchar_t *folder, const wchar_t **names, UINT32 numFiles);
|
||||||
STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t **names, UINT32 numFiles);
|
|
||||||
|
CZipContextMenu();
|
||||||
|
~CZipContextMenu();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
struct CCommandMapItem
|
||||||
|
{
|
||||||
|
ECommandInternalID CommandInternalID;
|
||||||
|
UString Verb;
|
||||||
|
UString HelpString;
|
||||||
|
UString Folder;
|
||||||
|
UString ArcName;
|
||||||
|
UString ArcType;
|
||||||
|
};
|
||||||
|
|
||||||
UStringVector _fileNames;
|
UStringVector _fileNames;
|
||||||
bool _dropMode;
|
bool _dropMode;
|
||||||
UString _dropPath;
|
UString _dropPath;
|
||||||
CObjectVector<CCommandMapItem> _commandMap;
|
CObjectVector<CCommandMapItem> _commandMap;
|
||||||
|
|
||||||
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
|
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
|
||||||
|
|
||||||
int FindVerb(const UString &verb);
|
int FindVerb(const UString &verb);
|
||||||
|
|
||||||
void FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem);
|
void FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem);
|
||||||
public:
|
|
||||||
CZipContextMenu();
|
|
||||||
~CZipContextMenu();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,34 +1,24 @@
|
|||||||
// ContextMenuFlags.h
|
// ContextMenuFlags.h
|
||||||
|
|
||||||
#ifndef __SEVENZIP_CONTEXTMENUFLAGS_H
|
#ifndef __CONTEXT_MENU_FLAGS_H
|
||||||
#define __SEVENZIP_CONTEXTMENUFLAGS_H
|
#define __CONTEXT_MENU_FLAGS_H
|
||||||
|
|
||||||
namespace NContextMenuFlags
|
namespace NContextMenuFlags
|
||||||
{
|
{
|
||||||
const UINT32 kExtract = 1 << 0;
|
const UInt32 kExtract = 1 << 0;
|
||||||
const UINT32 kExtractHere = 1 << 1;
|
const UInt32 kExtractHere = 1 << 1;
|
||||||
const UINT32 kExtractTo = 1 << 2;
|
const UInt32 kExtractTo = 1 << 2;
|
||||||
// const UINT32 kExtractEach = 1 << 3;
|
|
||||||
|
|
||||||
const UINT32 kTest = 1 << 4;
|
const UInt32 kTest = 1 << 4;
|
||||||
|
const UInt32 kOpen = 1 << 5;
|
||||||
|
const UInt32 kOpenAs = 1 << 6;
|
||||||
|
|
||||||
const UINT32 kOpen = 1 << 5;
|
const UInt32 kCompress = 1 << 8;
|
||||||
|
const UInt32 kCompressTo7z = 1 << 9;
|
||||||
const UINT32 kCompress = 1 << 8;
|
const UInt32 kCompressEmail = 1 << 10;
|
||||||
const UINT32 kCompressTo7z = 1 << 9;
|
const UInt32 kCompressTo7zEmail = 1 << 11;
|
||||||
const UINT32 kCompressEmail = 1 << 10;
|
const UInt32 kCompressToZip = 1 << 12;
|
||||||
const UINT32 kCompressTo7zEmail = 1 << 11;
|
const UInt32 kCompressToZipEmail = 1 << 13;
|
||||||
|
|
||||||
const UINT32 kCompressToZip = 1 << 12;
|
|
||||||
const UINT32 kCompressToZipEmail = 1 << 13;
|
|
||||||
|
|
||||||
inline UINT32 GetDefaultFlags() {
|
|
||||||
return
|
|
||||||
kOpen | kTest |
|
|
||||||
kExtract | kExtractHere | kExtractTo |
|
|
||||||
kCompress | kCompressEmail |
|
|
||||||
kCompressTo7z | kCompressTo7zEmail |
|
|
||||||
kCompressToZip | kCompressToZipEmail; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,6 +26,10 @@
|
|||||||
|
|
||||||
#include "ContextMenu.h"
|
#include "ContextMenu.h"
|
||||||
|
|
||||||
|
// {23170F69-40C1-278A-1000-000100020000}
|
||||||
|
DEFINE_GUID(CLSID_CZipContextMenu,
|
||||||
|
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
HINSTANCE g_hInstance = 0;
|
HINSTANCE g_hInstance = 0;
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ static HANDLE MyOpenFilePlugin(const char *name)
|
|||||||
archiveHandler = new CAgent;
|
archiveHandler = new CAgent;
|
||||||
CMyComBSTR archiveType;
|
CMyComBSTR archiveType;
|
||||||
HRESULT result = archiveHandler->Open(NULL,
|
HRESULT result = archiveHandler->Open(NULL,
|
||||||
GetUnicodeString(fullName, CP_OEMCP), &archiveType, openArchiveCallback);
|
GetUnicodeString(fullName, CP_OEMCP), UString(), &archiveType, openArchiveCallback);
|
||||||
/*
|
/*
|
||||||
HRESULT result = ::OpenArchive(fullName, &archiveHandler,
|
HRESULT result = ::OpenArchive(fullName, &archiveHandler,
|
||||||
archiverInfoResult, defaultName, openArchiveCallback);
|
archiverInfoResult, defaultName, openArchiveCallback);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ enum EEnum
|
|||||||
kYes,
|
kYes,
|
||||||
kNo,
|
kNo,
|
||||||
|
|
||||||
|
kPath,
|
||||||
kName,
|
kName,
|
||||||
kExtension,
|
kExtension,
|
||||||
kIsFolder,
|
kIsFolder,
|
||||||
|
|||||||
@@ -275,6 +275,7 @@ struct CPROPIDToName
|
|||||||
|
|
||||||
static CPROPIDToName kPROPIDToName[] =
|
static CPROPIDToName kPROPIDToName[] =
|
||||||
{
|
{
|
||||||
|
{ kpidPath, NMessageID::kPath },
|
||||||
{ kpidName, NMessageID::kName },
|
{ kpidName, NMessageID::kName },
|
||||||
{ kpidExtension, NMessageID::kExtension },
|
{ kpidExtension, NMessageID::kExtension },
|
||||||
{ kpidIsDir, NMessageID::kIsFolder },
|
{ kpidIsDir, NMessageID::kIsFolder },
|
||||||
@@ -501,6 +502,32 @@ static AString PropToString2(const NCOM::CPropVariant &prop, PROPID propID)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AddPropertyString(InfoPanelLine *lines, int &numItems, PROPID propID, const wchar_t *name,
|
||||||
|
const NCOM::CPropVariant &prop)
|
||||||
|
{
|
||||||
|
if (prop.vt != VT_EMPTY)
|
||||||
|
{
|
||||||
|
AString val = PropToString2(prop, propID);
|
||||||
|
if (!val.IsEmpty())
|
||||||
|
{
|
||||||
|
InfoPanelLine &item = lines[numItems++];
|
||||||
|
COPY_STR_LIMITED(item.Text, GetNameOfProp2(propID, name));
|
||||||
|
COPY_STR_LIMITED(item.Data, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InsertSeparator(InfoPanelLine *lines, int &numItems)
|
||||||
|
{
|
||||||
|
if (numItems < kNumInfoLinesMax)
|
||||||
|
{
|
||||||
|
InfoPanelLine &item = lines[numItems++];
|
||||||
|
MyStringCopy(item.Text, "");
|
||||||
|
MyStringCopy(item.Data, "");
|
||||||
|
item.Separator = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
|
void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
|
||||||
{
|
{
|
||||||
info->StructSize = sizeof(*info);
|
info->StructSize = sizeof(*info);
|
||||||
@@ -574,44 +601,71 @@ void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (numItems < kNumInfoLinesMax)
|
if (numItems < kNumInfoLinesMax)
|
||||||
{
|
{
|
||||||
InfoPanelLine &item = m_InfoLines[numItems++];
|
InsertSeparator(m_InfoLines, numItems);
|
||||||
MyStringCopy(item.Text, "");
|
|
||||||
MyStringCopy(item.Data, "");
|
|
||||||
item.Separator = TRUE;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
{
|
{
|
||||||
CMyComPtr<IGetFolderArchiveProperties> getFolderArchiveProperties;
|
CMyComPtr<IGetFolderArcProps> getFolderArcProps;
|
||||||
_folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties);
|
_folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps);
|
||||||
if (getFolderArchiveProperties)
|
if (getFolderArcProps)
|
||||||
{
|
{
|
||||||
CMyComPtr<IFolderArchiveProperties> getProps;
|
CMyComPtr<IFolderArcProps> getProps;
|
||||||
getFolderArchiveProperties->GetFolderArchiveProperties(&getProps);
|
getFolderArcProps->GetFolderArcProps(&getProps);
|
||||||
if (getProps)
|
if (getProps)
|
||||||
{
|
{
|
||||||
UInt32 numProps;
|
UInt32 numLevels;
|
||||||
if (getProps->GetNumberOfArchiveProperties(&numProps) == S_OK)
|
if (getProps->GetArcNumLevels(&numLevels) != S_OK)
|
||||||
|
numLevels = 0;
|
||||||
|
for (UInt32 level2 = 0; level2 < numLevels; level2++)
|
||||||
{
|
{
|
||||||
/*
|
{
|
||||||
if (numProps > 0)
|
UInt32 level = numLevels - 1 - level2;
|
||||||
message += kSeparator;
|
UInt32 numProps;
|
||||||
*/
|
if (getProps->GetArcNumProps(level, &numProps) == S_OK)
|
||||||
for (UInt32 i = 0; i < numProps && numItems < kNumInfoLinesMax; i++)
|
{
|
||||||
|
InsertSeparator(m_InfoLines, numItems);
|
||||||
|
for (Int32 i = -2; i < (Int32)numProps && numItems < kNumInfoLinesMax; i++)
|
||||||
{
|
{
|
||||||
CMyComBSTR name;
|
CMyComBSTR name;
|
||||||
PROPID propID;
|
PROPID propID;
|
||||||
VARTYPE vt;
|
VARTYPE vt;
|
||||||
if (getProps->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK)
|
if (i == -2)
|
||||||
|
propID = kpidPath;
|
||||||
|
else if (i == -1)
|
||||||
|
propID = kpidType;
|
||||||
|
else if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK)
|
||||||
continue;
|
continue;
|
||||||
NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
if (getProps->GetArchiveProperty(propID, &prop) != S_OK || prop.vt == VT_EMPTY)
|
if (getProps->GetArcProp(level, propID, &prop) != S_OK)
|
||||||
continue;
|
continue;
|
||||||
InfoPanelLine &item = m_InfoLines[numItems++];
|
AddPropertyString(m_InfoLines, numItems, propID, name, prop);
|
||||||
COPY_STR_LIMITED(item.Text, GetNameOfProp2(propID, name));
|
}
|
||||||
COPY_STR_LIMITED(item.Data, PropToString2(prop, propID));
|
}
|
||||||
|
}
|
||||||
|
if (level2 != numLevels - 1)
|
||||||
|
{
|
||||||
|
UInt32 level = numLevels - 1 - level2;
|
||||||
|
UInt32 numProps;
|
||||||
|
if (getProps->GetArcNumProps2(level, &numProps) == S_OK)
|
||||||
|
{
|
||||||
|
InsertSeparator(m_InfoLines, numItems);
|
||||||
|
for (Int32 i = 0; i < (Int32)numProps && numItems < kNumInfoLinesMax; i++)
|
||||||
|
{
|
||||||
|
CMyComBSTR name;
|
||||||
|
PROPID propID;
|
||||||
|
VARTYPE vt;
|
||||||
|
if (getProps->GetArcPropInfo2(level, i, &name, &propID, &vt) != S_OK)
|
||||||
|
continue;
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
if (getProps->GetArcProp2(level, propID, &prop) != S_OK)
|
||||||
|
continue;
|
||||||
|
AddPropertyString(m_InfoLines, numItems, propID, name, prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -692,7 +692,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
|
|||||||
// CLSID realClassID;
|
// CLSID realClassID;
|
||||||
CMyComBSTR archiveType;
|
CMyComBSTR archiveType;
|
||||||
RINOK(agentSpec->Open(NULL,
|
RINOK(agentSpec->Open(NULL,
|
||||||
GetUnicodeString(fullArchiveName, CP_OEMCP),
|
GetUnicodeString(fullArchiveName, CP_OEMCP), UString(),
|
||||||
// &realClassID,
|
// &realClassID,
|
||||||
&archiveType,
|
&archiveType,
|
||||||
NULL));
|
NULL));
|
||||||
|
|||||||
@@ -21,6 +21,6 @@ CAPTION "About 7-Zip"
|
|||||||
ICON IDI_LOGO, -1, m, m, 32, 32, SS_REALSIZEIMAGE
|
ICON IDI_LOGO, -1, m, m, 32, 32, SS_REALSIZEIMAGE
|
||||||
LTEXT MY_7ZIP_VERSION, -1, m, 54, xc, 8
|
LTEXT MY_7ZIP_VERSION, -1, m, 54, xc, 8
|
||||||
LTEXT MY_COPYRIGHT, -1, m, 67, xc, 8
|
LTEXT MY_COPYRIGHT, -1, m, 67, xc, 8
|
||||||
LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering.",
|
LTEXT "7-Zip is free software",
|
||||||
IDC_ABOUT_STATIC_REGISTER_INFO, m, y, xc, (by - y - 1)
|
IDC_ABOUT_STATIC_REGISTER_INFO, m, y, xc, (by - y - 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ void CApp::SetShowSystemMenu()
|
|||||||
#define ILC_COLOR32 0x0020
|
#define ILC_COLOR32 0x0020
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted)
|
HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat,
|
||||||
|
bool &archiveIsOpened, bool &encrypted)
|
||||||
{
|
{
|
||||||
if (PanelsCreated[panelIndex])
|
if (PanelsCreated[panelIndex])
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -122,7 +123,7 @@ HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, bool &arch
|
|||||||
path = mainPath;
|
path = mainPath;
|
||||||
int id = 1000 + 100 * panelIndex;
|
int id = 1000 + 100 * panelIndex;
|
||||||
RINOK(Panels[panelIndex].Create(_window, _window,
|
RINOK(Panels[panelIndex].Create(_window, _window,
|
||||||
id, path, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted));
|
id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted));
|
||||||
PanelsCreated[panelIndex] = true;
|
PanelsCreated[panelIndex] = true;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -269,7 +270,7 @@ void CApp::SaveToolbarChanges()
|
|||||||
|
|
||||||
void MyLoadMenu();
|
void MyLoadMenu();
|
||||||
|
|
||||||
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted)
|
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool &archiveIsOpened, bool &encrypted)
|
||||||
{
|
{
|
||||||
_window.Attach(hwnd);
|
_window.Attach(hwnd);
|
||||||
#ifdef UNDER_CE
|
#ifdef UNDER_CE
|
||||||
@@ -310,7 +311,7 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &ar
|
|||||||
bool archiveIsOpened2 = false;
|
bool archiveIsOpened2 = false;
|
||||||
bool encrypted2 = false;
|
bool encrypted2 = false;
|
||||||
bool mainPanel = (i == LastFocusedPanel);
|
bool mainPanel = (i == LastFocusedPanel);
|
||||||
RINOK(CreateOnePanel(i, mainPanel ? mainPath : L"", archiveIsOpened2, encrypted2));
|
RINOK(CreateOnePanel(i, mainPanel ? mainPath : L"", arcFormat, archiveIsOpened2, encrypted2));
|
||||||
if (mainPanel)
|
if (mainPanel)
|
||||||
{
|
{
|
||||||
archiveIsOpened = archiveIsOpened2;
|
archiveIsOpened = archiveIsOpened2;
|
||||||
@@ -328,7 +329,7 @@ HRESULT CApp::SwitchOnOffOnePanel()
|
|||||||
{
|
{
|
||||||
NumPanels++;
|
NumPanels++;
|
||||||
bool archiveIsOpened, encrypted;
|
bool archiveIsOpened, encrypted;
|
||||||
RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), archiveIsOpened, encrypted));
|
RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), UString(), archiveIsOpened, encrypted));
|
||||||
Panels[1 - LastFocusedPanel].Enable(true);
|
Panels[1 - LastFocusedPanel].Enable(true);
|
||||||
Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL);
|
Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL);
|
||||||
}
|
}
|
||||||
@@ -596,8 +597,10 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (indices.Size() > 1 || (!destPath.IsEmpty() && destPath.Back() == WCHAR_PATH_SEPARATOR) ||
|
if (indices.Size() > 1 ||
|
||||||
NFind::DoesDirExist(destPath))
|
(!destPath.IsEmpty() && destPath.Back() == WCHAR_PATH_SEPARATOR) ||
|
||||||
|
NFind::DoesDirExist(destPath) ||
|
||||||
|
srcPanel.IsArcFolder())
|
||||||
{
|
{
|
||||||
NDirectory::CreateComplexDirectory(destPath);
|
NDirectory::CreateComplexDirectory(destPath);
|
||||||
NName::NormalizeDirPathPrefix(destPath);
|
NName::NormalizeDirPathPrefix(destPath);
|
||||||
|
|||||||
@@ -161,8 +161,8 @@ public:
|
|||||||
void OnSetSameFolder(int srcPanelIndex);
|
void OnSetSameFolder(int srcPanelIndex);
|
||||||
void OnSetSubFolder(int srcPanelIndex);
|
void OnSetSubFolder(int srcPanelIndex);
|
||||||
|
|
||||||
HRESULT CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted);
|
HRESULT CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted);
|
||||||
HRESULT Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted);
|
HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool &archiveIsOpened, bool &encrypted);
|
||||||
void Read();
|
void Read();
|
||||||
void Save();
|
void Save();
|
||||||
void Release();
|
void Release();
|
||||||
|
|||||||
@@ -4,8 +4,4 @@
|
|||||||
|
|
||||||
#include "Common/MyInitGuid.h"
|
#include "Common/MyInitGuid.h"
|
||||||
|
|
||||||
#include "PluginInterface.h"
|
|
||||||
#include "../Agent/Agent.h"
|
#include "../Agent/Agent.h"
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_CZipContextMenu,
|
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ HINSTANCE g_hInstance;
|
|||||||
HWND g_HWND;
|
HWND g_HWND;
|
||||||
bool g_OpenArchive = false;
|
bool g_OpenArchive = false;
|
||||||
static UString g_MainPath;
|
static UString g_MainPath;
|
||||||
|
static UString g_ArcFormat;
|
||||||
static bool g_Maximized = false;
|
static bool g_Maximized = false;
|
||||||
|
|
||||||
#ifndef UNDER_CE
|
#ifndef UNDER_CE
|
||||||
@@ -443,7 +444,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
|
|||||||
UString paramString, tailString;
|
UString paramString, tailString;
|
||||||
SplitStringToTwoStrings(commandsString, paramString, tailString);
|
SplitStringToTwoStrings(commandsString, paramString, tailString);
|
||||||
paramString.Trim();
|
paramString.Trim();
|
||||||
|
tailString.Trim();
|
||||||
|
if (tailString.Left(2) == L"-t")
|
||||||
|
g_ArcFormat = tailString.Mid(2);
|
||||||
if (!paramString.IsEmpty())
|
if (!paramString.IsEmpty())
|
||||||
{
|
{
|
||||||
g_MainPath = paramString;
|
g_MainPath = paramString;
|
||||||
@@ -639,7 +642,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
if (NFile::NFind::DoesFileExist(g_MainPath))
|
if (NFile::NFind::DoesFileExist(g_MainPath))
|
||||||
needOpenFile = true;
|
needOpenFile = true;
|
||||||
}
|
}
|
||||||
HRESULT res = g_App.Create(hWnd, g_MainPath, xSizes, archiveIsOpened, encrypted);
|
HRESULT res = g_App.Create(hWnd, g_MainPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted);
|
||||||
|
|
||||||
if (res == E_ABORT)
|
if (res == E_ABORT)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -442,14 +442,6 @@ SOURCE=.\OptionsDialog.cpp
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\PluginsPage.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\PluginsPage.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\SettingsPage.cpp
|
SOURCE=.\SettingsPage.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ using namespace NRegistryAssociations;
|
|||||||
struct CThreadArchiveOpen
|
struct CThreadArchiveOpen
|
||||||
{
|
{
|
||||||
UString Path;
|
UString Path;
|
||||||
|
UString ArcFormat;
|
||||||
CMyComPtr<IInStream> InStream;
|
CMyComPtr<IInStream> InStream;
|
||||||
CMyComPtr<IFolderManager> FolderManager;
|
CMyComPtr<IFolderManager> FolderManager;
|
||||||
CMyComPtr<IProgress> OpenCallback;
|
CMyComPtr<IProgress> OpenCallback;
|
||||||
@@ -33,7 +34,7 @@ struct CThreadArchiveOpen
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
CProgressCloser closer(OpenCallbackSpec->ProgressDialog);
|
CProgressCloser closer(OpenCallbackSpec->ProgressDialog);
|
||||||
Result = FolderManager->OpenFolderFile(InStream, Path, &Folder, OpenCallback);
|
Result = FolderManager->OpenFolderFile(InStream, Path, ArcFormat, &Folder, OpenCallback);
|
||||||
}
|
}
|
||||||
catch(...) { Result = E_FAIL; }
|
catch(...) { Result = E_FAIL; }
|
||||||
}
|
}
|
||||||
@@ -58,6 +59,7 @@ static int FindPlugin(const CObjectVector<CPluginInfo> &plugins, const UString &
|
|||||||
HRESULT OpenFileFolderPlugin(
|
HRESULT OpenFileFolderPlugin(
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
const UString &path,
|
const UString &path,
|
||||||
|
const UString &arcFormat,
|
||||||
HMODULE *module,
|
HMODULE *module,
|
||||||
IFolderFolder **resultFolder,
|
IFolderFolder **resultFolder,
|
||||||
HWND parentWindow,
|
HWND parentWindow,
|
||||||
@@ -128,6 +130,7 @@ HRESULT OpenFileFolderPlugin(
|
|||||||
|
|
||||||
t.InStream = inStream;
|
t.InStream = inStream;
|
||||||
t.Path = path;
|
t.Path = path;
|
||||||
|
t.ArcFormat = arcFormat;
|
||||||
|
|
||||||
UString progressTitle = LangString(IDS_OPENNING, 0x03020283);
|
UString progressTitle = LangString(IDS_OPENNING, 0x03020283);
|
||||||
t.OpenCallbackSpec->ProgressDialog.MainWindow = parentWindow;
|
t.OpenCallbackSpec->ProgressDialog.MainWindow = parentWindow;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#ifndef __FILE_FOLDER_PLUGIN_OPEN_H
|
#ifndef __FILE_FOLDER_PLUGIN_OPEN_H
|
||||||
#define __FILE_FOLDER_PLUGIN_OPEN_H
|
#define __FILE_FOLDER_PLUGIN_OPEN_H
|
||||||
|
|
||||||
HRESULT OpenFileFolderPlugin(IInStream *inStream, const UString &path,
|
HRESULT OpenFileFolderPlugin(IInStream *inStream, const UString &path, const UString &arcFormat,
|
||||||
HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow, bool &encrypted, UString &password);
|
HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow, bool &encrypted, UString &password);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -112,32 +112,36 @@ FOLDER_INTERFACE(IFolderProperties, 0x0E)
|
|||||||
INTERFACE_FolderProperties(PURE)
|
INTERFACE_FolderProperties(PURE)
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INTERFACE_IFolderArchiveProperties(x) \
|
#define INTERFACE_IFolderArcProps(x) \
|
||||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \
|
STDMETHOD(GetArcNumLevels)(UInt32 *numLevels) x; \
|
||||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \
|
STDMETHOD(GetArcProp)(UInt32 level, PROPID propID, PROPVARIANT *value) x; \
|
||||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x;
|
STDMETHOD(GetArcNumProps)(UInt32 level, UInt32 *numProps) x; \
|
||||||
|
STDMETHOD(GetArcPropInfo)(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \
|
||||||
|
STDMETHOD(GetArcProp2)(UInt32 level, PROPID propID, PROPVARIANT *value) x; \
|
||||||
|
STDMETHOD(GetArcNumProps2)(UInt32 level, UInt32 *numProps) x; \
|
||||||
|
STDMETHOD(GetArcPropInfo2)(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \
|
||||||
|
|
||||||
FOLDER_INTERFACE(IFolderArchiveProperties, 0x0C)
|
FOLDER_INTERFACE(IFolderArcProps, 0x10)
|
||||||
{
|
{
|
||||||
INTERFACE_IFolderArchiveProperties(PURE)
|
INTERFACE_IFolderArcProps(PURE)
|
||||||
};
|
};
|
||||||
|
|
||||||
FOLDER_INTERFACE(IGetFolderArchiveProperties, 0x0D)
|
FOLDER_INTERFACE(IGetFolderArcProps, 0x11)
|
||||||
{
|
{
|
||||||
STDMETHOD(GetFolderArchiveProperties)(IFolderArchiveProperties **object) PURE;
|
STDMETHOD(GetFolderArcProps)(IFolderArcProps **object) PURE;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FOLDER_MANAGER_INTERFACE(i, x) DECL_INTERFACE(i, 9, x)
|
#define FOLDER_MANAGER_INTERFACE(i, x) DECL_INTERFACE(i, 9, x)
|
||||||
|
|
||||||
#define INTERFACE_IFolderManager(x) \
|
#define INTERFACE_IFolderManager(x) \
|
||||||
STDMETHOD(OpenFolderFile)(IInStream *inStream, const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) x; \
|
STDMETHOD(OpenFolderFile)(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, IFolderFolder **resultFolder, IProgress *progress) x; \
|
||||||
STDMETHOD(GetExtensions)(BSTR *extensions) x; \
|
STDMETHOD(GetExtensions)(BSTR *extensions) x; \
|
||||||
STDMETHOD(GetIconPath)(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex) x; \
|
STDMETHOD(GetIconPath)(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex) x; \
|
||||||
|
|
||||||
// STDMETHOD(GetTypes)(BSTR *types) PURE;
|
// STDMETHOD(GetTypes)(BSTR *types) PURE;
|
||||||
// STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) PURE;
|
// STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) PURE;
|
||||||
|
|
||||||
FOLDER_MANAGER_INTERFACE(IFolderManager, 0x04)
|
FOLDER_MANAGER_INTERFACE(IFolderManager, 0x05)
|
||||||
{
|
{
|
||||||
INTERFACE_IFolderManager(PURE);
|
INTERFACE_IFolderManager(PURE);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ struct CContextMenuItem
|
|||||||
static CContextMenuItem kMenuItems[] =
|
static CContextMenuItem kMenuItems[] =
|
||||||
{
|
{
|
||||||
{ IDS_CONTEXT_OPEN, 0x02000103, kOpen},
|
{ IDS_CONTEXT_OPEN, 0x02000103, kOpen},
|
||||||
|
{ IDS_CONTEXT_OPEN, 0x02000103, kOpenAs},
|
||||||
{ IDS_CONTEXT_EXTRACT, 0x02000105, kExtract},
|
{ IDS_CONTEXT_EXTRACT, 0x02000105, kExtract},
|
||||||
{ IDS_CONTEXT_EXTRACT_HERE, 0x0200010B, kExtractHere },
|
{ IDS_CONTEXT_EXTRACT_HERE, 0x0200010B, kExtractHere },
|
||||||
{ IDS_CONTEXT_EXTRACT_TO, 0x0200010D, kExtractTo },
|
{ IDS_CONTEXT_EXTRACT_TO, 0x0200010D, kExtractTo },
|
||||||
@@ -83,6 +84,8 @@ bool CMenuPage::OnInit()
|
|||||||
CContextMenuItem &menuItem = kMenuItems[i];
|
CContextMenuItem &menuItem = kMenuItems[i];
|
||||||
|
|
||||||
UString s = LangString(menuItem.ControlID, menuItem.LangID);
|
UString s = LangString(menuItem.ControlID, menuItem.LangID);
|
||||||
|
if (menuItem.Flag == kOpenAs)
|
||||||
|
s += L" >";
|
||||||
|
|
||||||
switch(menuItem.ControlID)
|
switch(menuItem.ControlID)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "../../GuiCommon.rc"
|
#include "../../GuiCommon.rc"
|
||||||
|
|
||||||
#define xc 196
|
#define xc 196
|
||||||
#define yc 164
|
#define yc 174
|
||||||
|
|
||||||
IDD_MENU MY_PAGE
|
IDD_MENU MY_PAGE
|
||||||
#include "MenuPage2.rc"
|
#include "MenuPage2.rc"
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ static LPCWSTR kClassName = L"7-Zip::Panel";
|
|||||||
|
|
||||||
|
|
||||||
HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
|
HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
|
||||||
const UString ¤tFolderPrefix, CPanelCallback *panelCallback, CAppState *appState,
|
const UString ¤tFolderPrefix,
|
||||||
|
const UString &arcFormat,
|
||||||
|
CPanelCallback *panelCallback, CAppState *appState,
|
||||||
bool &archiveIsOpened, bool &encrypted)
|
bool &archiveIsOpened, bool &encrypted)
|
||||||
{
|
{
|
||||||
_mainWindow = mainWindow;
|
_mainWindow = mainWindow;
|
||||||
@@ -91,7 +93,7 @@ HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
|
|||||||
if (currentFolderPrefix[0] == L'.')
|
if (currentFolderPrefix[0] == L'.')
|
||||||
if (!NFile::NDirectory::MyGetFullPathName(currentFolderPrefix, cfp))
|
if (!NFile::NDirectory::MyGetFullPathName(currentFolderPrefix, cfp))
|
||||||
cfp = currentFolderPrefix;
|
cfp = currentFolderPrefix;
|
||||||
RINOK(BindToPath(cfp, archiveIsOpened, encrypted));
|
RINOK(BindToPath(cfp, arcFormat, archiveIsOpened, encrypted));
|
||||||
|
|
||||||
if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE,
|
if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE,
|
||||||
0, 0, _xSize, 260,
|
0, 0, _xSize, 260,
|
||||||
@@ -715,19 +717,18 @@ UString CPanel::GetFolderTypeID() const
|
|||||||
return L"";
|
return L"";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPanel::IsRootFolder() const
|
bool CPanel::IsFolderTypeEqTo(const wchar_t *s) const
|
||||||
{
|
{
|
||||||
return (GetFolderTypeID() == L"RootFolder");
|
return GetFolderTypeID() == s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPanel::IsFSFolder() const
|
bool CPanel::IsRootFolder() const { return IsFolderTypeEqTo(L"RootFolder"); }
|
||||||
|
bool CPanel::IsFSFolder() const { return IsFolderTypeEqTo(L"FSFolder"); }
|
||||||
|
bool CPanel::IsFSDrivesFolder() const { return IsFolderTypeEqTo(L"FSDrives"); }
|
||||||
|
bool CPanel::IsArcFolder() const
|
||||||
{
|
{
|
||||||
return (GetFolderTypeID() == L"FSFolder");
|
UString s = GetFolderTypeID();
|
||||||
}
|
return s.Left(5) == L"7-Zip";
|
||||||
|
|
||||||
bool CPanel::IsFSDrivesFolder() const
|
|
||||||
{
|
|
||||||
return (GetFolderTypeID() == L"FSDrives");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UString CPanel::GetFsPath() const
|
UString CPanel::GetFsPath() const
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user