mirror of
https://github.com/ip7z/7zip.git
synced 2025-12-06 07:12:00 +01:00
Merge branch 'ip7z:main' into main
This commit is contained in:
commit
299982cc8d
|
|
@ -1,5 +1,5 @@
|
||||||
; LzFindOpt.asm -- ASM version of GetMatchesSpecN_2() function
|
; LzFindOpt.asm -- ASM version of GetMatchesSpecN_2() function
|
||||||
; 2021-07-21: Igor Pavlov : Public domain
|
; 2024-06-18: Igor Pavlov : Public domain
|
||||||
;
|
;
|
||||||
|
|
||||||
ifndef x64
|
ifndef x64
|
||||||
|
|
@ -11,10 +11,31 @@ include 7zAsm.asm
|
||||||
|
|
||||||
MY_ASM_START
|
MY_ASM_START
|
||||||
|
|
||||||
_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE'
|
ifndef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
|
||||||
|
if (IS_LINUX gt 0)
|
||||||
|
Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1
|
||||||
|
else
|
||||||
|
Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
|
||||||
|
_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE'
|
||||||
MY_ALIGN macro num:req
|
MY_ALIGN macro num:req
|
||||||
align num
|
align num
|
||||||
|
; align 16
|
||||||
|
endm
|
||||||
|
else
|
||||||
|
MY_ALIGN macro num:req
|
||||||
|
; We expect that ".text" is aligned for 16-bytes.
|
||||||
|
; So we don't need large alignment inside our function.
|
||||||
|
align 16
|
||||||
|
endm
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
MY_ALIGN_16 macro
|
||||||
|
MY_ALIGN 16
|
||||||
endm
|
endm
|
||||||
|
|
||||||
MY_ALIGN_32 macro
|
MY_ALIGN_32 macro
|
||||||
|
|
@ -136,7 +157,11 @@ COPY_VAR_64 macro dest_var, src_var
|
||||||
endm
|
endm
|
||||||
|
|
||||||
|
|
||||||
|
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
|
||||||
; MY_ALIGN_64
|
; MY_ALIGN_64
|
||||||
|
else
|
||||||
|
MY_ALIGN_16
|
||||||
|
endif
|
||||||
MY_PROC GetMatchesSpecN_2, 13
|
MY_PROC GetMatchesSpecN_2, 13
|
||||||
MY_PUSH_PRESERVED_ABI_REGS
|
MY_PUSH_PRESERVED_ABI_REGS
|
||||||
mov r0, RSP
|
mov r0, RSP
|
||||||
|
|
@ -508,6 +533,8 @@ fin:
|
||||||
MY_POP_PRESERVED_ABI_REGS
|
MY_POP_PRESERVED_ABI_REGS
|
||||||
MY_ENDP
|
MY_ENDP
|
||||||
|
|
||||||
|
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
|
||||||
_TEXT$LZFINDOPT ENDS
|
_TEXT$LZFINDOPT ENDS
|
||||||
|
endif
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
; LzmaDecOpt.asm -- ASM version of LzmaDec_DecodeReal_3() function
|
; LzmaDecOpt.asm -- ASM version of LzmaDec_DecodeReal_3() function
|
||||||
; 2021-02-23: Igor Pavlov : Public domain
|
; 2024-06-18: Igor Pavlov : Public domain
|
||||||
;
|
;
|
||||||
; 3 - is the code compatibility version of LzmaDec_DecodeReal_*()
|
; 3 - is the code compatibility version of LzmaDec_DecodeReal_*()
|
||||||
; function for check at link time.
|
; function for check at link time.
|
||||||
|
|
@ -17,11 +17,41 @@ include 7zAsm.asm
|
||||||
|
|
||||||
MY_ASM_START
|
MY_ASM_START
|
||||||
|
|
||||||
_TEXT$LZMADECOPT SEGMENT ALIGN(64) 'CODE'
|
; if Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT is defined, we use additional SEGMENT with 64-byte alignment.
|
||||||
|
; if Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT is not defined, we use default SEGMENT (where default 16-byte alignment of segment is expected).
|
||||||
|
; The performance is almost identical in our tests.
|
||||||
|
; But the performance can depend from position of lzmadec code inside instruction cache
|
||||||
|
; or micro-op cache line (depending from low address bits in 32-byte/64-byte cache lines).
|
||||||
|
; And 64-byte alignment provides a more consistent speed regardless
|
||||||
|
; of the code's position in the executable.
|
||||||
|
; But also it's possible that code without Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT can be
|
||||||
|
; slightly faster than 64-bytes aligned code in some cases, if offset of lzmadec
|
||||||
|
; code in 64-byte block after compilation provides better speed by some reason.
|
||||||
|
; Note that Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT adds an extra section to the ELF file.
|
||||||
|
; If you don't want to get that extra section, do not define Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT.
|
||||||
|
|
||||||
|
ifndef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT
|
||||||
|
if (IS_LINUX gt 0)
|
||||||
|
Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT equ 1
|
||||||
|
else
|
||||||
|
Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT equ 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT
|
||||||
|
_TEXT$LZMADECOPT SEGMENT ALIGN(64) 'CODE'
|
||||||
MY_ALIGN macro num:req
|
MY_ALIGN macro num:req
|
||||||
align num
|
align num
|
||||||
|
; align 16
|
||||||
endm
|
endm
|
||||||
|
else
|
||||||
|
MY_ALIGN macro num:req
|
||||||
|
; We expect that ".text" is aligned for 16-bytes.
|
||||||
|
; So we don't need large alignment inside out function.
|
||||||
|
align 16
|
||||||
|
endm
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
MY_ALIGN_16 macro
|
MY_ALIGN_16 macro
|
||||||
MY_ALIGN 16
|
MY_ALIGN 16
|
||||||
|
|
@ -610,7 +640,11 @@ PARAM_lzma equ REG_ABI_PARAM_0
|
||||||
PARAM_limit equ REG_ABI_PARAM_1
|
PARAM_limit equ REG_ABI_PARAM_1
|
||||||
PARAM_bufLimit equ REG_ABI_PARAM_2
|
PARAM_bufLimit equ REG_ABI_PARAM_2
|
||||||
|
|
||||||
|
ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT
|
||||||
; MY_ALIGN_64
|
; MY_ALIGN_64
|
||||||
|
else
|
||||||
|
MY_ALIGN_16
|
||||||
|
endif
|
||||||
MY_PROC LzmaDec_DecodeReal_3, 3
|
MY_PROC LzmaDec_DecodeReal_3, 3
|
||||||
MY_PUSH_PRESERVED_ABI_REGS
|
MY_PUSH_PRESERVED_ABI_REGS
|
||||||
|
|
||||||
|
|
@ -1298,6 +1332,8 @@ fin:
|
||||||
MY_POP_PRESERVED_ABI_REGS
|
MY_POP_PRESERVED_ABI_REGS
|
||||||
MY_ENDP
|
MY_ENDP
|
||||||
|
|
||||||
|
ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT
|
||||||
_TEXT$LZMADECOPT ENDS
|
_TEXT$LZMADECOPT ENDS
|
||||||
|
endif
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
; Sha1Opt.asm -- SHA-1 optimized code for SHA-1 x86 hardware instructions
|
; Sha1Opt.asm -- SHA-1 optimized code for SHA-1 x86 hardware instructions
|
||||||
; 2021-03-10 : Igor Pavlov : Public domain
|
; 2024-06-16 : Igor Pavlov : Public domain
|
||||||
|
|
||||||
include 7zAsm.asm
|
include 7zAsm.asm
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ MY_ASM_START
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CONST SEGMENT
|
CONST SEGMENT READONLY
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
Reverse_Endian_Mask db 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0
|
Reverse_Endian_Mask db 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
; Sha256Opt.asm -- SHA-256 optimized code for SHA-256 x86 hardware instructions
|
; Sha256Opt.asm -- SHA-256 optimized code for SHA-256 x86 hardware instructions
|
||||||
; 2022-04-17 : Igor Pavlov : Public domain
|
; 2024-06-16 : Igor Pavlov : Public domain
|
||||||
|
|
||||||
include 7zAsm.asm
|
include 7zAsm.asm
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ endif
|
||||||
EXTRN K_CONST:xmmword
|
EXTRN K_CONST:xmmword
|
||||||
@
|
@
|
||||||
|
|
||||||
CONST SEGMENT
|
CONST SEGMENT READONLY
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
Reverse_Endian_Mask db 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12
|
Reverse_Endian_Mask db 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* 7zDec.c -- Decoding from 7z folder
|
/* 7zDec.c -- Decoding from 7z folder
|
||||||
2024-03-01 : Igor Pavlov : Public domain */
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
|
@ -312,9 +312,10 @@ static BoolInt IS_MAIN_METHOD(UInt32 m)
|
||||||
case k_PPMD:
|
case k_PPMD:
|
||||||
#endif
|
#endif
|
||||||
return True;
|
return True;
|
||||||
}
|
default:
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#define MY_VER_MAJOR 24
|
#define MY_VER_MAJOR 24
|
||||||
#define MY_VER_MINOR 06
|
#define MY_VER_MINOR 9
|
||||||
#define MY_VER_BUILD 0
|
#define MY_VER_BUILD 0
|
||||||
#define MY_VERSION_NUMBERS "24.06"
|
#define MY_VERSION_NUMBERS "24.09"
|
||||||
#define MY_VERSION MY_VERSION_NUMBERS
|
#define MY_VERSION MY_VERSION_NUMBERS
|
||||||
|
|
||||||
#ifdef MY_CPU_NAME
|
#ifdef MY_CPU_NAME
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#define MY_VERSION_CPU MY_VERSION
|
#define MY_VERSION_CPU MY_VERSION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MY_DATE "2024-05-26"
|
#define MY_DATE "2024-11-29"
|
||||||
#undef MY_COPYRIGHT
|
#undef MY_COPYRIGHT
|
||||||
#undef MY_VERSION_COPYRIGHT_DATE
|
#undef MY_VERSION_COPYRIGHT_DATE
|
||||||
#define MY_AUTHOR_NAME "Igor Pavlov"
|
#define MY_AUTHOR_NAME "Igor Pavlov"
|
||||||
|
|
|
||||||
203
C/AesOpt.c
203
C/AesOpt.c
|
|
@ -1,5 +1,5 @@
|
||||||
/* AesOpt.c -- AES optimized code for x86 AES hardware instructions
|
/* AesOpt.c -- AES optimized code for x86 AES hardware instructions
|
||||||
2024-03-01 : Igor Pavlov : Public domain */
|
Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
|
@ -80,7 +80,27 @@ AES_FUNC_START (name)
|
||||||
|
|
||||||
#define MM_XOR( dest, src) MM_OP(_mm_xor_si128, dest, src)
|
#define MM_XOR( dest, src) MM_OP(_mm_xor_si128, dest, src)
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// use aligned SSE load/store for data.
|
||||||
|
// It is required for our Aes functions, that data is aligned for 16-bytes.
|
||||||
|
// So we can use this branch of code.
|
||||||
|
// and compiler can use fused load-op SSE instructions:
|
||||||
|
// xorps xmm0, XMMWORD PTR [rdx]
|
||||||
|
#define LOAD_128(pp) (*(__m128i *)(void *)(pp))
|
||||||
|
#define STORE_128(pp, _v) *(__m128i *)(void *)(pp) = _v
|
||||||
|
// use aligned SSE load/store for data. Alternative code with direct access
|
||||||
|
// #define LOAD_128(pp) _mm_load_si128(pp)
|
||||||
|
// #define STORE_128(pp, _v) _mm_store_si128(pp, _v)
|
||||||
|
#else
|
||||||
|
// use unaligned load/store for data: movdqu XMMWORD PTR [rdx]
|
||||||
|
#define LOAD_128(pp) _mm_loadu_si128(pp)
|
||||||
|
#define STORE_128(pp, _v) _mm_storeu_si128(pp, _v)
|
||||||
|
#endif
|
||||||
|
|
||||||
AES_FUNC_START2 (AesCbc_Encode_HW)
|
AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
|
{
|
||||||
|
if (numBlocks == 0)
|
||||||
|
return;
|
||||||
{
|
{
|
||||||
__m128i *p = (__m128i *)(void *)ivAes;
|
__m128i *p = (__m128i *)(void *)ivAes;
|
||||||
__m128i *data = (__m128i *)(void *)data8;
|
__m128i *data = (__m128i *)(void *)data8;
|
||||||
|
|
@ -88,11 +108,11 @@ AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
const __m128i k0 = p[2];
|
const __m128i k0 = p[2];
|
||||||
const __m128i k1 = p[3];
|
const __m128i k1 = p[3];
|
||||||
const UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
|
const UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
|
||||||
for (; numBlocks != 0; numBlocks--, data++)
|
do
|
||||||
{
|
{
|
||||||
UInt32 r = numRounds2;
|
UInt32 r = numRounds2;
|
||||||
const __m128i *w = p + 4;
|
const __m128i *w = p + 4;
|
||||||
__m128i temp = *data;
|
__m128i temp = LOAD_128(data);
|
||||||
MM_XOR (temp, k0)
|
MM_XOR (temp, k0)
|
||||||
MM_XOR (m, temp)
|
MM_XOR (m, temp)
|
||||||
MM_OP_m (_mm_aesenc_si128, k1)
|
MM_OP_m (_mm_aesenc_si128, k1)
|
||||||
|
|
@ -104,10 +124,13 @@ AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
}
|
}
|
||||||
while (--r);
|
while (--r);
|
||||||
MM_OP_m (_mm_aesenclast_si128, w[0])
|
MM_OP_m (_mm_aesenclast_si128, w[0])
|
||||||
*data = m;
|
STORE_128(data, m);
|
||||||
|
data++;
|
||||||
}
|
}
|
||||||
|
while (--numBlocks);
|
||||||
*p = m;
|
*p = m;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define WOP_1(op)
|
#define WOP_1(op)
|
||||||
|
|
@ -139,12 +162,12 @@ AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
|
|
||||||
#define WOP(op) op (m0, 0) WOP_M1(op)
|
#define WOP(op) op (m0, 0) WOP_M1(op)
|
||||||
|
|
||||||
|
|
||||||
#define DECLARE_VAR(reg, ii) __m128i reg;
|
#define DECLARE_VAR(reg, ii) __m128i reg;
|
||||||
#define LOAD_data( reg, ii) reg = data[ii];
|
#define LOAD_data_ii(ii) LOAD_128(data + (ii))
|
||||||
#define STORE_data( reg, ii) data[ii] = reg;
|
#define LOAD_data( reg, ii) reg = LOAD_data_ii(ii);
|
||||||
|
#define STORE_data( reg, ii) STORE_128(data + (ii), reg);
|
||||||
#if (NUM_WAYS > 1)
|
#if (NUM_WAYS > 1)
|
||||||
#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1])
|
#define XOR_data_M1(reg, ii) MM_XOR (reg, LOAD_128(data + (ii- 1)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MM_OP_key(op, reg) MM_OP(op, reg, key);
|
#define MM_OP_key(op, reg) MM_OP(op, reg, key);
|
||||||
|
|
@ -156,25 +179,22 @@ AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
#define AES_XOR( reg, ii) MM_OP_key (_mm_xor_si128, reg)
|
#define AES_XOR( reg, ii) MM_OP_key (_mm_xor_si128, reg)
|
||||||
|
|
||||||
#define CTR_START(reg, ii) MM_OP (_mm_add_epi64, ctr, one) reg = ctr;
|
#define CTR_START(reg, ii) MM_OP (_mm_add_epi64, ctr, one) reg = ctr;
|
||||||
#define CTR_END( reg, ii) MM_XOR (data[ii], reg)
|
#define CTR_END( reg, ii) STORE_128(data + (ii), _mm_xor_si128(reg, \
|
||||||
|
LOAD_128 (data + (ii))));
|
||||||
#define WOP_KEY(op, n) { \
|
#define WOP_KEY(op, n) { \
|
||||||
const __m128i key = w[n]; \
|
const __m128i key = w[n]; \
|
||||||
WOP(op); }
|
WOP(op) }
|
||||||
|
|
||||||
|
|
||||||
#define WIDE_LOOP_START \
|
#define WIDE_LOOP_START \
|
||||||
dataEnd = data + numBlocks; \
|
dataEnd = data + numBlocks; \
|
||||||
if (numBlocks >= NUM_WAYS) \
|
if (numBlocks >= NUM_WAYS) \
|
||||||
{ dataEnd -= NUM_WAYS; do { \
|
{ dataEnd -= NUM_WAYS; do { \
|
||||||
|
|
||||||
|
|
||||||
#define WIDE_LOOP_END \
|
#define WIDE_LOOP_END \
|
||||||
data += NUM_WAYS; \
|
data += NUM_WAYS; \
|
||||||
} while (data <= dataEnd); \
|
} while (data <= dataEnd); \
|
||||||
dataEnd += NUM_WAYS; } \
|
dataEnd += NUM_WAYS; } \
|
||||||
|
|
||||||
|
|
||||||
#define SINGLE_LOOP \
|
#define SINGLE_LOOP \
|
||||||
for (; data < dataEnd; data++)
|
for (; data < dataEnd; data++)
|
||||||
|
|
||||||
|
|
@ -184,34 +204,54 @@ AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
|
|
||||||
#define AVX_XOR(dest, src) MM_OP(_mm256_xor_si256, dest, src)
|
#define AVX_XOR(dest, src) MM_OP(_mm256_xor_si256, dest, src)
|
||||||
#define AVX_DECLARE_VAR(reg, ii) __m256i reg;
|
#define AVX_DECLARE_VAR(reg, ii) __m256i reg;
|
||||||
#define AVX_LOAD_data( reg, ii) reg = ((const __m256i *)(const void *)data)[ii];
|
|
||||||
#define AVX_STORE_data( reg, ii) ((__m256i *)(void *)data)[ii] = reg;
|
#if 1
|
||||||
|
// use unaligned AVX load/store for data.
|
||||||
|
// It is required for our Aes functions, that data is aligned for 16-bytes.
|
||||||
|
// But we need 32-bytes reading.
|
||||||
|
// So we use intrinsics for unaligned AVX load/store.
|
||||||
|
// notes for _mm256_storeu_si256:
|
||||||
|
// msvc2022: uses vmovdqu and keeps the order of instruction sequence.
|
||||||
|
// new gcc11 uses vmovdqu
|
||||||
|
// old gcc9 could use pair of instructions:
|
||||||
|
// vmovups %xmm7, -224(%rax)
|
||||||
|
// vextracti128 $0x1, %ymm7, -208(%rax)
|
||||||
|
#define AVX_LOAD(p) _mm256_loadu_si256((const __m256i *)(const void *)(p))
|
||||||
|
#define AVX_STORE(p, _v) _mm256_storeu_si256((__m256i *)(void *)(p), _v);
|
||||||
|
#else
|
||||||
|
// use aligned AVX load/store for data.
|
||||||
|
// for debug: we can use this branch, if we are sure that data is aligned for 32-bytes.
|
||||||
|
// msvc2022 uses vmovdqu still
|
||||||
|
// gcc uses vmovdqa (that requires 32-bytes alignment)
|
||||||
|
#define AVX_LOAD(p) (*(const __m256i *)(const void *)(p))
|
||||||
|
#define AVX_STORE(p, _v) (*(__m256i *)(void *)(p)) = _v;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AVX_LOAD_data( reg, ii) reg = AVX_LOAD((const __m256i *)(const void *)data + (ii));
|
||||||
|
#define AVX_STORE_data( reg, ii) AVX_STORE((__m256i *)(void *)data + (ii), reg)
|
||||||
/*
|
/*
|
||||||
AVX_XOR_data_M1() needs unaligned memory load
|
AVX_XOR_data_M1() needs unaligned memory load, even if (data)
|
||||||
if (we don't use _mm256_loadu_si256() here)
|
is aligned for 256-bits, because we read 32-bytes chunk that
|
||||||
{
|
crosses (data) position: from (data - 16bytes) to (data + 16bytes).
|
||||||
Most compilers with enabled optimizations generate fused AVX (LOAD + OP)
|
|
||||||
instruction that can load unaligned data.
|
|
||||||
But GCC and CLANG without -O2 or -O1 optimizations can generate separated
|
|
||||||
LOAD-ALIGNED (vmovdqa) instruction that will fail on execution.
|
|
||||||
}
|
|
||||||
Note: some compilers generate more instructions, if we use _mm256_loadu_si256() here.
|
|
||||||
v23.02: we use _mm256_loadu_si256() here, because we need compatibility with any compiler.
|
|
||||||
*/
|
*/
|
||||||
#define AVX_XOR_data_M1(reg, ii) AVX_XOR (reg, _mm256_loadu_si256(&(((const __m256i *)(const void *)(data - 1))[ii])))
|
#define AVX_XOR_data_M1(reg, ii) AVX_XOR (reg, _mm256_loadu_si256((const __m256i *)(const void *)(data - 1) + (ii)))
|
||||||
// for debug only: the following code will fail on execution, if compiled by some compilers:
|
|
||||||
// #define AVX_XOR_data_M1(reg, ii) AVX_XOR (reg, (((const __m256i *)(const void *)(data - 1))[ii]))
|
|
||||||
|
|
||||||
#define AVX_AES_DEC( reg, ii) MM_OP_key (_mm256_aesdec_epi128, reg)
|
#define AVX_AES_DEC( reg, ii) MM_OP_key (_mm256_aesdec_epi128, reg)
|
||||||
#define AVX_AES_DEC_LAST( reg, ii) MM_OP_key (_mm256_aesdeclast_epi128, reg)
|
#define AVX_AES_DEC_LAST( reg, ii) MM_OP_key (_mm256_aesdeclast_epi128, reg)
|
||||||
#define AVX_AES_ENC( reg, ii) MM_OP_key (_mm256_aesenc_epi128, reg)
|
#define AVX_AES_ENC( reg, ii) MM_OP_key (_mm256_aesenc_epi128, reg)
|
||||||
#define AVX_AES_ENC_LAST( reg, ii) MM_OP_key (_mm256_aesenclast_epi128, reg)
|
#define AVX_AES_ENC_LAST( reg, ii) MM_OP_key (_mm256_aesenclast_epi128, reg)
|
||||||
#define AVX_AES_XOR( reg, ii) MM_OP_key (_mm256_xor_si256, reg)
|
#define AVX_AES_XOR( reg, ii) MM_OP_key (_mm256_xor_si256, reg)
|
||||||
#define AVX_CTR_START(reg, ii) MM_OP (_mm256_add_epi64, ctr2, two) reg = _mm256_xor_si256(ctr2, key);
|
#define AVX_CTR_START(reg, ii) \
|
||||||
#define AVX_CTR_END( reg, ii) AVX_XOR (((__m256i *)(void *)data)[ii], reg)
|
MM_OP (_mm256_add_epi64, ctr2, two) \
|
||||||
|
reg = _mm256_xor_si256(ctr2, key);
|
||||||
|
|
||||||
|
#define AVX_CTR_END(reg, ii) \
|
||||||
|
AVX_STORE((__m256i *)(void *)data + (ii), _mm256_xor_si256(reg, \
|
||||||
|
AVX_LOAD ((__m256i *)(void *)data + (ii))));
|
||||||
|
|
||||||
#define AVX_WOP_KEY(op, n) { \
|
#define AVX_WOP_KEY(op, n) { \
|
||||||
const __m256i key = w[n]; \
|
const __m256i key = w[n]; \
|
||||||
WOP(op); }
|
WOP(op) }
|
||||||
|
|
||||||
#define NUM_AES_KEYS_MAX 15
|
#define NUM_AES_KEYS_MAX 15
|
||||||
|
|
||||||
|
|
@ -219,12 +259,11 @@ v23.02: we use _mm256_loadu_si256() here, because we need compatibility with any
|
||||||
dataEnd = data + numBlocks; \
|
dataEnd = data + numBlocks; \
|
||||||
if (numBlocks >= NUM_WAYS * 2) \
|
if (numBlocks >= NUM_WAYS * 2) \
|
||||||
{ __m256i keys[NUM_AES_KEYS_MAX]; \
|
{ __m256i keys[NUM_AES_KEYS_MAX]; \
|
||||||
UInt32 ii; \
|
|
||||||
OP \
|
OP \
|
||||||
for (ii = 0; ii < numRounds; ii++) \
|
{ UInt32 ii; for (ii = 0; ii < numRounds; ii++) \
|
||||||
keys[ii] = _mm256_broadcastsi128_si256(p[ii]); \
|
keys[ii] = _mm256_broadcastsi128_si256(p[ii]); } \
|
||||||
dataEnd -= NUM_WAYS * 2; do { \
|
dataEnd -= NUM_WAYS * 2; \
|
||||||
|
do { \
|
||||||
|
|
||||||
#define WIDE_LOOP_END_AVX(OP) \
|
#define WIDE_LOOP_END_AVX(OP) \
|
||||||
data += NUM_WAYS * 2; \
|
data += NUM_WAYS * 2; \
|
||||||
|
|
@ -246,21 +285,20 @@ AES_FUNC_START2 (AesCbc_Decode_HW)
|
||||||
__m128i *p = (__m128i *)(void *)ivAes;
|
__m128i *p = (__m128i *)(void *)ivAes;
|
||||||
__m128i *data = (__m128i *)(void *)data8;
|
__m128i *data = (__m128i *)(void *)data8;
|
||||||
__m128i iv = *p;
|
__m128i iv = *p;
|
||||||
const __m128i *wStart = p + *(const UInt32 *)(p + 1) * 2 + 2 - 1;
|
const __m128i * const wStart = p + (size_t)*(const UInt32 *)(p + 1) * 2 + 2 - 1;
|
||||||
const __m128i *dataEnd;
|
const __m128i *dataEnd;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
WIDE_LOOP_START
|
WIDE_LOOP_START
|
||||||
{
|
{
|
||||||
const __m128i *w = wStart;
|
const __m128i *w = wStart;
|
||||||
|
|
||||||
WOP (DECLARE_VAR)
|
WOP (DECLARE_VAR)
|
||||||
WOP (LOAD_data)
|
WOP (LOAD_data)
|
||||||
WOP_KEY (AES_XOR, 1)
|
WOP_KEY (AES_XOR, 1)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
WOP_KEY (AES_DEC, 0)
|
WOP_KEY (AES_DEC, 0)
|
||||||
|
|
||||||
w--;
|
w--;
|
||||||
}
|
}
|
||||||
while (w != p);
|
while (w != p);
|
||||||
|
|
@ -268,7 +306,7 @@ AES_FUNC_START2 (AesCbc_Decode_HW)
|
||||||
|
|
||||||
MM_XOR (m0, iv)
|
MM_XOR (m0, iv)
|
||||||
WOP_M1 (XOR_data_M1)
|
WOP_M1 (XOR_data_M1)
|
||||||
iv = data[NUM_WAYS - 1];
|
LOAD_data(iv, NUM_WAYS - 1)
|
||||||
WOP (STORE_data)
|
WOP (STORE_data)
|
||||||
}
|
}
|
||||||
WIDE_LOOP_END
|
WIDE_LOOP_END
|
||||||
|
|
@ -276,7 +314,8 @@ AES_FUNC_START2 (AesCbc_Decode_HW)
|
||||||
SINGLE_LOOP
|
SINGLE_LOOP
|
||||||
{
|
{
|
||||||
const __m128i *w = wStart - 1;
|
const __m128i *w = wStart - 1;
|
||||||
__m128i m = _mm_xor_si128 (w[2], *data);
|
__m128i m = _mm_xor_si128 (w[2], LOAD_data_ii(0));
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
MM_OP_m (_mm_aesdec_si128, w[1])
|
MM_OP_m (_mm_aesdec_si128, w[1])
|
||||||
|
|
@ -286,10 +325,9 @@ AES_FUNC_START2 (AesCbc_Decode_HW)
|
||||||
while (w != p);
|
while (w != p);
|
||||||
MM_OP_m (_mm_aesdec_si128, w[1])
|
MM_OP_m (_mm_aesdec_si128, w[1])
|
||||||
MM_OP_m (_mm_aesdeclast_si128, w[0])
|
MM_OP_m (_mm_aesdeclast_si128, w[0])
|
||||||
|
|
||||||
MM_XOR (m, iv)
|
MM_XOR (m, iv)
|
||||||
iv = *data;
|
LOAD_data(iv, 0)
|
||||||
*data = m;
|
STORE_data(m, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
p[-2] = iv;
|
p[-2] = iv;
|
||||||
|
|
@ -301,9 +339,9 @@ AES_FUNC_START2 (AesCtr_Code_HW)
|
||||||
__m128i *p = (__m128i *)(void *)ivAes;
|
__m128i *p = (__m128i *)(void *)ivAes;
|
||||||
__m128i *data = (__m128i *)(void *)data8;
|
__m128i *data = (__m128i *)(void *)data8;
|
||||||
__m128i ctr = *p;
|
__m128i ctr = *p;
|
||||||
UInt32 numRoundsMinus2 = *(const UInt32 *)(p + 1) * 2 - 1;
|
const UInt32 numRoundsMinus2 = *(const UInt32 *)(p + 1) * 2 - 1;
|
||||||
const __m128i *dataEnd;
|
const __m128i *dataEnd;
|
||||||
__m128i one = _mm_cvtsi32_si128(1);
|
const __m128i one = _mm_cvtsi32_si128(1);
|
||||||
|
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
|
|
@ -322,7 +360,6 @@ AES_FUNC_START2 (AesCtr_Code_HW)
|
||||||
}
|
}
|
||||||
while (--r);
|
while (--r);
|
||||||
WOP_KEY (AES_ENC_LAST, 0)
|
WOP_KEY (AES_ENC_LAST, 0)
|
||||||
|
|
||||||
WOP (CTR_END)
|
WOP (CTR_END)
|
||||||
}
|
}
|
||||||
WIDE_LOOP_END
|
WIDE_LOOP_END
|
||||||
|
|
@ -344,7 +381,7 @@ AES_FUNC_START2 (AesCtr_Code_HW)
|
||||||
while (--numRounds2);
|
while (--numRounds2);
|
||||||
MM_OP_m (_mm_aesenc_si128, w[0])
|
MM_OP_m (_mm_aesenc_si128, w[0])
|
||||||
MM_OP_m (_mm_aesenclast_si128, w[1])
|
MM_OP_m (_mm_aesenclast_si128, w[1])
|
||||||
MM_XOR (*data, m)
|
CTR_END (m, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
p[-2] = ctr;
|
p[-2] = ctr;
|
||||||
|
|
@ -421,7 +458,7 @@ VAES_FUNC_START2 (AesCbc_Decode_HW_256)
|
||||||
__m128i *data = (__m128i *)(void *)data8;
|
__m128i *data = (__m128i *)(void *)data8;
|
||||||
__m128i iv = *p;
|
__m128i iv = *p;
|
||||||
const __m128i *dataEnd;
|
const __m128i *dataEnd;
|
||||||
UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1;
|
const UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
WIDE_LOOP_START_AVX(;)
|
WIDE_LOOP_START_AVX(;)
|
||||||
|
|
@ -440,17 +477,17 @@ VAES_FUNC_START2 (AesCbc_Decode_HW_256)
|
||||||
while (w != keys);
|
while (w != keys);
|
||||||
AVX_WOP_KEY (AVX_AES_DEC_LAST, 0)
|
AVX_WOP_KEY (AVX_AES_DEC_LAST, 0)
|
||||||
|
|
||||||
AVX_XOR (m0, _mm256_setr_m128i(iv, data[0]))
|
AVX_XOR (m0, _mm256_setr_m128i(iv, LOAD_data_ii(0)))
|
||||||
WOP_M1 (AVX_XOR_data_M1)
|
WOP_M1 (AVX_XOR_data_M1)
|
||||||
iv = data[NUM_WAYS * 2 - 1];
|
LOAD_data (iv, NUM_WAYS * 2 - 1)
|
||||||
WOP (AVX_STORE_data)
|
WOP (AVX_STORE_data)
|
||||||
}
|
}
|
||||||
WIDE_LOOP_END_AVX(;)
|
WIDE_LOOP_END_AVX(;)
|
||||||
|
|
||||||
SINGLE_LOOP
|
SINGLE_LOOP
|
||||||
{
|
{
|
||||||
const __m128i *w = p + *(const UInt32 *)(p + 1 - 2) * 2 + 1 - 3;
|
const __m128i *w = p - 2 + (size_t)*(const UInt32 *)(p + 1 - 2) * 2;
|
||||||
__m128i m = _mm_xor_si128 (w[2], *data);
|
__m128i m = _mm_xor_si128 (w[2], LOAD_data_ii(0));
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
MM_OP_m (_mm_aesdec_si128, w[1])
|
MM_OP_m (_mm_aesdec_si128, w[1])
|
||||||
|
|
@ -462,8 +499,8 @@ VAES_FUNC_START2 (AesCbc_Decode_HW_256)
|
||||||
MM_OP_m (_mm_aesdeclast_si128, w[0])
|
MM_OP_m (_mm_aesdeclast_si128, w[0])
|
||||||
|
|
||||||
MM_XOR (m, iv)
|
MM_XOR (m, iv)
|
||||||
iv = *data;
|
LOAD_data(iv, 0)
|
||||||
*data = m;
|
STORE_data(m, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
p[-2] = iv;
|
p[-2] = iv;
|
||||||
|
|
@ -493,9 +530,9 @@ VAES_FUNC_START2 (AesCtr_Code_HW_256)
|
||||||
__m128i *p = (__m128i *)(void *)ivAes;
|
__m128i *p = (__m128i *)(void *)ivAes;
|
||||||
__m128i *data = (__m128i *)(void *)data8;
|
__m128i *data = (__m128i *)(void *)data8;
|
||||||
__m128i ctr = *p;
|
__m128i ctr = *p;
|
||||||
UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1;
|
const UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1;
|
||||||
const __m128i *dataEnd;
|
const __m128i *dataEnd;
|
||||||
__m128i one = _mm_cvtsi32_si128(1);
|
const __m128i one = _mm_cvtsi32_si128(1);
|
||||||
__m256i ctr2, two;
|
__m256i ctr2, two;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
|
|
@ -536,7 +573,7 @@ VAES_FUNC_START2 (AesCtr_Code_HW_256)
|
||||||
while (--numRounds2);
|
while (--numRounds2);
|
||||||
MM_OP_m (_mm_aesenc_si128, w[0])
|
MM_OP_m (_mm_aesenc_si128, w[0])
|
||||||
MM_OP_m (_mm_aesenclast_si128, w[1])
|
MM_OP_m (_mm_aesenclast_si128, w[1])
|
||||||
MM_XOR (*data, m)
|
CTR_END (m, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
p[-2] = ctr;
|
p[-2] = ctr;
|
||||||
|
|
@ -730,10 +767,15 @@ AES_FUNC_START (name)
|
||||||
|
|
||||||
|
|
||||||
AES_FUNC_START2 (AesCbc_Encode_HW)
|
AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
|
{
|
||||||
|
if (numBlocks == 0)
|
||||||
|
return;
|
||||||
{
|
{
|
||||||
v128 * const p = (v128 *)(void *)ivAes;
|
v128 * const p = (v128 *)(void *)ivAes;
|
||||||
v128 *data = (v128 *)(void *)data8;
|
v128 *data = (v128 *)(void *)data8;
|
||||||
v128 m = *p;
|
v128 m = *p;
|
||||||
|
const UInt32 numRounds2 = *(const UInt32 *)(p + 1);
|
||||||
|
const v128 *w = p + (size_t)numRounds2 * 2;
|
||||||
const v128 k0 = p[2];
|
const v128 k0 = p[2];
|
||||||
const v128 k1 = p[3];
|
const v128 k1 = p[3];
|
||||||
const v128 k2 = p[4];
|
const v128 k2 = p[4];
|
||||||
|
|
@ -744,11 +786,14 @@ AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
const v128 k7 = p[9];
|
const v128 k7 = p[9];
|
||||||
const v128 k8 = p[10];
|
const v128 k8 = p[10];
|
||||||
const v128 k9 = p[11];
|
const v128 k9 = p[11];
|
||||||
const UInt32 numRounds2 = *(const UInt32 *)(p + 1);
|
const v128 k_z4 = w[-2];
|
||||||
const v128 *w = p + ((size_t)numRounds2 * 2);
|
const v128 k_z3 = w[-1];
|
||||||
|
const v128 k_z2 = w[0];
|
||||||
const v128 k_z1 = w[1];
|
const v128 k_z1 = w[1];
|
||||||
const v128 k_z0 = w[2];
|
const v128 k_z0 = w[2];
|
||||||
for (; numBlocks != 0; numBlocks--, data++)
|
// we don't use optimization veorq_u8(*data, k_z0) that can reduce one cycle,
|
||||||
|
// because gcc/clang compilers are not good for that optimization.
|
||||||
|
do
|
||||||
{
|
{
|
||||||
MM_XOR_m (*data)
|
MM_XOR_m (*data)
|
||||||
AES_E_MC_m (k0)
|
AES_E_MC_m (k0)
|
||||||
|
|
@ -757,25 +802,27 @@ AES_FUNC_START2 (AesCbc_Encode_HW)
|
||||||
AES_E_MC_m (k3)
|
AES_E_MC_m (k3)
|
||||||
AES_E_MC_m (k4)
|
AES_E_MC_m (k4)
|
||||||
AES_E_MC_m (k5)
|
AES_E_MC_m (k5)
|
||||||
AES_E_MC_m (k6)
|
|
||||||
AES_E_MC_m (k7)
|
|
||||||
AES_E_MC_m (k8)
|
|
||||||
if (numRounds2 >= 6)
|
if (numRounds2 >= 6)
|
||||||
{
|
{
|
||||||
AES_E_MC_m (k9)
|
AES_E_MC_m (k6)
|
||||||
AES_E_MC_m (p[12])
|
AES_E_MC_m (k7)
|
||||||
if (numRounds2 != 6)
|
if (numRounds2 != 6)
|
||||||
{
|
{
|
||||||
AES_E_MC_m (p[13])
|
AES_E_MC_m (k8)
|
||||||
AES_E_MC_m (p[14])
|
AES_E_MC_m (k9)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AES_E_MC_m (k_z4)
|
||||||
|
AES_E_MC_m (k_z3)
|
||||||
|
AES_E_MC_m (k_z2)
|
||||||
AES_E_m (k_z1)
|
AES_E_m (k_z1)
|
||||||
MM_XOR_m (k_z0)
|
MM_XOR_m (k_z0)
|
||||||
*data = m;
|
*data++ = m;
|
||||||
}
|
}
|
||||||
|
while (--numBlocks);
|
||||||
*p = m;
|
*p = m;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define WOP_1(op)
|
#define WOP_1(op)
|
||||||
|
|
@ -837,7 +884,7 @@ AES_FUNC_START2 (AesCbc_Decode_HW)
|
||||||
v128 *p = (v128 *)(void *)ivAes;
|
v128 *p = (v128 *)(void *)ivAes;
|
||||||
v128 *data = (v128 *)(void *)data8;
|
v128 *data = (v128 *)(void *)data8;
|
||||||
v128 iv = *p;
|
v128 iv = *p;
|
||||||
const v128 *wStart = p + ((size_t)*(const UInt32 *)(p + 1)) * 2;
|
const v128 * const wStart = p + (size_t)*(const UInt32 *)(p + 1) * 2;
|
||||||
const v128 *dataEnd;
|
const v128 *dataEnd;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
|
|
@ -858,7 +905,7 @@ AES_FUNC_START2 (AesCbc_Decode_HW)
|
||||||
WOP_KEY (AES_XOR, 0)
|
WOP_KEY (AES_XOR, 0)
|
||||||
MM_XOR (m0, iv)
|
MM_XOR (m0, iv)
|
||||||
WOP_M1 (XOR_data_M1)
|
WOP_M1 (XOR_data_M1)
|
||||||
iv = data[NUM_WAYS - 1];
|
LOAD_data(iv, NUM_WAYS - 1)
|
||||||
WOP (STORE_data)
|
WOP (STORE_data)
|
||||||
}
|
}
|
||||||
WIDE_LOOP_END
|
WIDE_LOOP_END
|
||||||
|
|
@ -866,7 +913,7 @@ AES_FUNC_START2 (AesCbc_Decode_HW)
|
||||||
SINGLE_LOOP
|
SINGLE_LOOP
|
||||||
{
|
{
|
||||||
const v128 *w = wStart;
|
const v128 *w = wStart;
|
||||||
v128 m = *data;
|
v128 m; LOAD_data(m, 0)
|
||||||
AES_D_IMC_m (w[2])
|
AES_D_IMC_m (w[2])
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
@ -878,8 +925,8 @@ AES_FUNC_START2 (AesCbc_Decode_HW)
|
||||||
AES_D_m (w[1])
|
AES_D_m (w[1])
|
||||||
MM_XOR_m (w[0])
|
MM_XOR_m (w[0])
|
||||||
MM_XOR_m (iv)
|
MM_XOR_m (iv)
|
||||||
iv = *data;
|
LOAD_data(iv, 0)
|
||||||
*data = m;
|
STORE_data(m, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
p[-2] = iv;
|
p[-2] = iv;
|
||||||
|
|
@ -891,16 +938,14 @@ AES_FUNC_START2 (AesCtr_Code_HW)
|
||||||
v128 *p = (v128 *)(void *)ivAes;
|
v128 *p = (v128 *)(void *)ivAes;
|
||||||
v128 *data = (v128 *)(void *)data8;
|
v128 *data = (v128 *)(void *)data8;
|
||||||
uint64x2_t ctr = vreinterpretq_u64_u8(*p);
|
uint64x2_t ctr = vreinterpretq_u64_u8(*p);
|
||||||
const v128 *wEnd = p + ((size_t)*(const UInt32 *)(p + 1)) * 2;
|
const v128 * const wEnd = p + (size_t)*(const UInt32 *)(p + 1) * 2;
|
||||||
const v128 *dataEnd;
|
const v128 *dataEnd;
|
||||||
uint64x2_t one = vdupq_n_u64(0);
|
|
||||||
|
|
||||||
// the bug in clang:
|
// the bug in clang:
|
||||||
// __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2);
|
// __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2);
|
||||||
#if defined(__clang__) && (__clang_major__ <= 9)
|
#if defined(__clang__) && (__clang_major__ <= 9)
|
||||||
#pragma GCC diagnostic ignored "-Wvector-conversion"
|
#pragma GCC diagnostic ignored "-Wvector-conversion"
|
||||||
#endif
|
#endif
|
||||||
one = vsetq_lane_u64(1, one, 0);
|
const uint64x2_t one = vsetq_lane_u64(1, vdupq_n_u64(0), 0);
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
WIDE_LOOP_START
|
WIDE_LOOP_START
|
||||||
|
|
|
||||||
113
C/CpuArch.c
113
C/CpuArch.c
|
|
@ -1,5 +1,5 @@
|
||||||
/* CpuArch.c -- CPU specific code
|
/* CpuArch.c -- CPU specific code
|
||||||
2024-05-18 : Igor Pavlov : Public domain */
|
Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
/*
|
/*
|
||||||
cpuid instruction supports (subFunction) parameter in ECX,
|
cpuid instruction supports (subFunction) parameter in ECX,
|
||||||
that is used only with some specific (function) parameter values.
|
that is used only with some specific (function) parameter values.
|
||||||
But we always use only (subFunction==0).
|
most functions use only (subFunction==0).
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
__cpuid(): MSVC and GCC/CLANG use same function/macro name
|
__cpuid(): MSVC and GCC/CLANG use same function/macro name
|
||||||
|
|
@ -49,43 +49,49 @@
|
||||||
#if defined(MY_CPU_AMD64) && defined(__PIC__) \
|
#if defined(MY_CPU_AMD64) && defined(__PIC__) \
|
||||||
&& ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__))
|
&& ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__))
|
||||||
|
|
||||||
#define x86_cpuid_MACRO(p, func) { \
|
/* "=&r" selects free register. It can select even rbx, if that register is free.
|
||||||
|
"=&D" for (RDI) also works, but the code can be larger with "=&D"
|
||||||
|
"2"(subFun) : 2 is (zero-based) index in the output constraint list "=c" (ECX). */
|
||||||
|
|
||||||
|
#define x86_cpuid_MACRO_2(p, func, subFunc) { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
ASM_LN "mov %%rbx, %q1" \
|
ASM_LN "mov %%rbx, %q1" \
|
||||||
ASM_LN "cpuid" \
|
ASM_LN "cpuid" \
|
||||||
ASM_LN "xchg %%rbx, %q1" \
|
ASM_LN "xchg %%rbx, %q1" \
|
||||||
: "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); }
|
: "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); }
|
||||||
|
|
||||||
/* "=&r" selects free register. It can select even rbx, if that register is free.
|
|
||||||
"=&D" for (RDI) also works, but the code can be larger with "=&D"
|
|
||||||
"2"(0) means (subFunction = 0),
|
|
||||||
2 is (zero-based) index in the output constraint list "=c" (ECX). */
|
|
||||||
|
|
||||||
#elif defined(MY_CPU_X86) && defined(__PIC__) \
|
#elif defined(MY_CPU_X86) && defined(__PIC__) \
|
||||||
&& ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__))
|
&& ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__))
|
||||||
|
|
||||||
#define x86_cpuid_MACRO(p, func) { \
|
#define x86_cpuid_MACRO_2(p, func, subFunc) { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
ASM_LN "mov %%ebx, %k1" \
|
ASM_LN "mov %%ebx, %k1" \
|
||||||
ASM_LN "cpuid" \
|
ASM_LN "cpuid" \
|
||||||
ASM_LN "xchg %%ebx, %k1" \
|
ASM_LN "xchg %%ebx, %k1" \
|
||||||
: "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); }
|
: "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define x86_cpuid_MACRO(p, func) { \
|
#define x86_cpuid_MACRO_2(p, func, subFunc) { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
ASM_LN "cpuid" \
|
ASM_LN "cpuid" \
|
||||||
: "=a" ((p)[0]), "=b" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); }
|
: "=a" ((p)[0]), "=b" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define x86_cpuid_MACRO(p, func) x86_cpuid_MACRO_2(p, func, 0)
|
||||||
|
|
||||||
void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
|
void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
|
||||||
{
|
{
|
||||||
x86_cpuid_MACRO(p, func)
|
x86_cpuid_MACRO(p, func)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc)
|
||||||
|
{
|
||||||
|
x86_cpuid_MACRO_2(p, func, subFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Z7_NO_INLINE
|
Z7_NO_INLINE
|
||||||
UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void)
|
UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void)
|
||||||
|
|
@ -205,11 +211,39 @@ void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
|
||||||
__asm ret 0
|
__asm ret 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void __declspec(naked) Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc)
|
||||||
|
{
|
||||||
|
UNUSED_VAR(p)
|
||||||
|
UNUSED_VAR(func)
|
||||||
|
UNUSED_VAR(subFunc)
|
||||||
|
__asm push ebx
|
||||||
|
__asm push edi
|
||||||
|
__asm mov edi, ecx // p
|
||||||
|
__asm mov eax, edx // func
|
||||||
|
__asm mov ecx, [esp + 12] // subFunc
|
||||||
|
__asm cpuid
|
||||||
|
__asm mov [edi ], eax
|
||||||
|
__asm mov [edi + 4], ebx
|
||||||
|
__asm mov [edi + 8], ecx
|
||||||
|
__asm mov [edi + 12], edx
|
||||||
|
__asm pop edi
|
||||||
|
__asm pop ebx
|
||||||
|
__asm ret 4
|
||||||
|
}
|
||||||
|
|
||||||
#else // MY_CPU_AMD64
|
#else // MY_CPU_AMD64
|
||||||
|
|
||||||
#if _MSC_VER >= 1600
|
#if _MSC_VER >= 1600
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#define MY_cpuidex __cpuidex
|
#define MY_cpuidex __cpuidex
|
||||||
|
|
||||||
|
static
|
||||||
|
void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc)
|
||||||
|
{
|
||||||
|
__cpuidex((int *)p, func, subFunc);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
__cpuid (func == (0 or 7)) requires subfunction number in ECX.
|
__cpuid (func == (0 or 7)) requires subfunction number in ECX.
|
||||||
|
|
@ -219,7 +253,7 @@ void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
|
||||||
We still can use __cpuid for low (func) values that don't require ECX,
|
We still can use __cpuid for low (func) values that don't require ECX,
|
||||||
but __cpuid() in old MSVC will be incorrect for some func values: (func == 7).
|
but __cpuid() in old MSVC will be incorrect for some func values: (func == 7).
|
||||||
So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction,
|
So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction,
|
||||||
where ECX value is first parameter for FASTCALL / NO_INLINE func,
|
where ECX value is first parameter for FASTCALL / NO_INLINE func.
|
||||||
So the caller of MY_cpuidex_HACK() sets ECX as subFunction, and
|
So the caller of MY_cpuidex_HACK() sets ECX as subFunction, and
|
||||||
old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value.
|
old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value.
|
||||||
|
|
||||||
|
|
@ -233,6 +267,11 @@ Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(Int32 subFunction, Int32 func, Int
|
||||||
}
|
}
|
||||||
#define MY_cpuidex(info, func, func2) MY_cpuidex_HACK(func2, func, info)
|
#define MY_cpuidex(info, func, func2) MY_cpuidex_HACK(func2, func, info)
|
||||||
#pragma message("======== MY_cpuidex_HACK WAS USED ========")
|
#pragma message("======== MY_cpuidex_HACK WAS USED ========")
|
||||||
|
static
|
||||||
|
void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc)
|
||||||
|
{
|
||||||
|
MY_cpuidex_HACK(subFunc, func, (Int32 *)p);
|
||||||
|
}
|
||||||
#endif // _MSC_VER >= 1600
|
#endif // _MSC_VER >= 1600
|
||||||
|
|
||||||
#if !defined(MY_CPU_AMD64)
|
#if !defined(MY_CPU_AMD64)
|
||||||
|
|
@ -445,6 +484,23 @@ BoolInt CPU_IsSupported_SHA(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BoolInt CPU_IsSupported_SHA512(void)
|
||||||
|
{
|
||||||
|
if (!CPU_IsSupported_AVX2()) return False; // maybe CPU_IsSupported_AVX() is enough here
|
||||||
|
|
||||||
|
if (z7_x86_cpuid_GetMaxFunc() < 7)
|
||||||
|
return False;
|
||||||
|
{
|
||||||
|
UInt32 d[4];
|
||||||
|
z7_x86_cpuid_subFunc(d, 7, 0);
|
||||||
|
if (d[0] < 1) // d[0] - is max supported subleaf value
|
||||||
|
return False;
|
||||||
|
z7_x86_cpuid_subFunc(d, 7, 1);
|
||||||
|
return (BoolInt)(d[0]) & 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MSVC: _xgetbv() intrinsic is available since VS2010SP1.
|
MSVC: _xgetbv() intrinsic is available since VS2010SP1.
|
||||||
MSVC also defines (_XCR_XFEATURE_ENABLED_MASK) macro in
|
MSVC also defines (_XCR_XFEATURE_ENABLED_MASK) macro in
|
||||||
|
|
@ -776,6 +832,18 @@ BoolInt CPU_IsSupported_NEON(void)
|
||||||
return z7_sysctlbyname_Get_BoolInt("hw.optional.neon");
|
return z7_sysctlbyname_Get_BoolInt("hw.optional.neon");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoolInt CPU_IsSupported_SHA512(void)
|
||||||
|
{
|
||||||
|
return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha512");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
BoolInt CPU_IsSupported_SHA3(void)
|
||||||
|
{
|
||||||
|
return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha3");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef MY_CPU_ARM64
|
#ifdef MY_CPU_ARM64
|
||||||
#define APPLE_CRYPTO_SUPPORT_VAL 1
|
#define APPLE_CRYPTO_SUPPORT_VAL 1
|
||||||
#else
|
#else
|
||||||
|
|
@ -848,7 +916,11 @@ static unsigned long MY_getauxval(int aux)
|
||||||
|
|
||||||
#define MY_HWCAP_CHECK_FUNC(name) \
|
#define MY_HWCAP_CHECK_FUNC(name) \
|
||||||
BoolInt CPU_IsSupported_ ## name(void) { return 0; }
|
BoolInt CPU_IsSupported_ ## name(void) { return 0; }
|
||||||
|
#if defined(__ARM_NEON)
|
||||||
|
BoolInt CPU_IsSupported_NEON(void) { return True; }
|
||||||
|
#else
|
||||||
MY_HWCAP_CHECK_FUNC(NEON)
|
MY_HWCAP_CHECK_FUNC(NEON)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // USE_HWCAP
|
#endif // USE_HWCAP
|
||||||
|
|
||||||
|
|
@ -856,6 +928,19 @@ MY_HWCAP_CHECK_FUNC (CRC32)
|
||||||
MY_HWCAP_CHECK_FUNC (SHA1)
|
MY_HWCAP_CHECK_FUNC (SHA1)
|
||||||
MY_HWCAP_CHECK_FUNC (SHA2)
|
MY_HWCAP_CHECK_FUNC (SHA2)
|
||||||
MY_HWCAP_CHECK_FUNC (AES)
|
MY_HWCAP_CHECK_FUNC (AES)
|
||||||
|
#ifdef MY_CPU_ARM64
|
||||||
|
// <hwcap.h> supports HWCAP_SHA512 and HWCAP_SHA3 since 2017.
|
||||||
|
// we define them here, if they are not defined
|
||||||
|
#ifndef HWCAP_SHA3
|
||||||
|
// #define HWCAP_SHA3 (1 << 17)
|
||||||
|
#endif
|
||||||
|
#ifndef HWCAP_SHA512
|
||||||
|
// #pragma message("=== HWCAP_SHA512 define === ")
|
||||||
|
#define HWCAP_SHA512 (1 << 21)
|
||||||
|
#endif
|
||||||
|
MY_HWCAP_CHECK_FUNC (SHA512)
|
||||||
|
// MY_HWCAP_CHECK_FUNC (SHA3)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
|
||||||
35
C/CpuArch.h
35
C/CpuArch.h
|
|
@ -1,5 +1,5 @@
|
||||||
/* CpuArch.h -- CPU specific code
|
/* CpuArch.h -- CPU specific code
|
||||||
2024-05-18 : Igor Pavlov : Public domain */
|
Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_CPU_ARCH_H
|
#ifndef ZIP7_INC_CPU_ARCH_H
|
||||||
#define ZIP7_INC_CPU_ARCH_H
|
#define ZIP7_INC_CPU_ARCH_H
|
||||||
|
|
@ -509,11 +509,19 @@ problem-4 : performace:
|
||||||
|
|
||||||
#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED)
|
#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Z7_BSWAP16 can be slow for x86-msvc
|
||||||
|
#define GetBe16_to32(p) (Z7_BSWAP16 (*(const UInt16 *)(const void *)(p)))
|
||||||
|
#else
|
||||||
|
#define GetBe16_to32(p) (Z7_BSWAP32 (*(const UInt16 *)(const void *)(p)) >> 16)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p))
|
#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p))
|
||||||
#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); }
|
#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); }
|
||||||
|
|
||||||
#if defined(MY_CPU_LE_UNALIGN_64)
|
#if defined(MY_CPU_LE_UNALIGN_64)
|
||||||
#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p))
|
#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p))
|
||||||
|
#define SetBe64(p, v) { (*(UInt64 *)(void *)(p)) = Z7_BSWAP64(v); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
@ -536,11 +544,27 @@ problem-4 : performace:
|
||||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SetBe64
|
||||||
|
#define SetBe64(p, v) { Byte *_ppp_ = (Byte *)(p); UInt64 _vvv_ = (v); \
|
||||||
|
_ppp_[0] = (Byte)(_vvv_ >> 56); \
|
||||||
|
_ppp_[1] = (Byte)(_vvv_ >> 48); \
|
||||||
|
_ppp_[2] = (Byte)(_vvv_ >> 40); \
|
||||||
|
_ppp_[3] = (Byte)(_vvv_ >> 32); \
|
||||||
|
_ppp_[4] = (Byte)(_vvv_ >> 24); \
|
||||||
|
_ppp_[5] = (Byte)(_vvv_ >> 16); \
|
||||||
|
_ppp_[6] = (Byte)(_vvv_ >> 8); \
|
||||||
|
_ppp_[7] = (Byte)_vvv_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef GetBe16
|
#ifndef GetBe16
|
||||||
|
#ifdef GetBe16_to32
|
||||||
|
#define GetBe16(p) ( (UInt16) GetBe16_to32(p))
|
||||||
|
#else
|
||||||
#define GetBe16(p) ( (UInt16) ( \
|
#define GetBe16(p) ( (UInt16) ( \
|
||||||
((UInt16)((const Byte *)(p))[0] << 8) | \
|
((UInt16)((const Byte *)(p))[0] << 8) | \
|
||||||
((const Byte *)(p))[1] ))
|
((const Byte *)(p))[1] ))
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_BE)
|
#if defined(MY_CPU_BE)
|
||||||
|
|
@ -564,6 +588,7 @@ problem-4 : performace:
|
||||||
#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
||||||
#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
|
#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
|
||||||
|
|
||||||
|
#define GetUi64a(p) GetUi64(p)
|
||||||
#define GetUi32a(p) GetUi32(p)
|
#define GetUi32a(p) GetUi32(p)
|
||||||
#define GetUi16a(p) GetUi16(p)
|
#define GetUi16a(p) GetUi16(p)
|
||||||
#define SetUi32a(p, v) SetUi32(p, v)
|
#define SetUi32a(p, v) SetUi32(p, v)
|
||||||
|
|
@ -571,6 +596,7 @@ problem-4 : performace:
|
||||||
|
|
||||||
#elif defined(MY_CPU_LE)
|
#elif defined(MY_CPU_LE)
|
||||||
|
|
||||||
|
#define GetUi64a(p) (*(const UInt64 *)(const void *)(p))
|
||||||
#define GetUi32a(p) (*(const UInt32 *)(const void *)(p))
|
#define GetUi32a(p) (*(const UInt32 *)(const void *)(p))
|
||||||
#define GetUi16a(p) (*(const UInt16 *)(const void *)(p))
|
#define GetUi16a(p) (*(const UInt16 *)(const void *)(p))
|
||||||
#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
||||||
|
|
@ -587,6 +613,11 @@ problem-4 : performace:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GetBe16_to32
|
||||||
|
#define GetBe16_to32(p) GetBe16(p)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) \
|
#if defined(MY_CPU_X86_OR_AMD64) \
|
||||||
|| defined(MY_CPU_ARM_OR_ARM64) \
|
|| defined(MY_CPU_ARM_OR_ARM64) \
|
||||||
|| defined(MY_CPU_PPC_OR_PPC64)
|
|| defined(MY_CPU_PPC_OR_PPC64)
|
||||||
|
|
@ -615,6 +646,7 @@ BoolInt CPU_IsSupported_SSE2(void);
|
||||||
BoolInt CPU_IsSupported_SSSE3(void);
|
BoolInt CPU_IsSupported_SSSE3(void);
|
||||||
BoolInt CPU_IsSupported_SSE41(void);
|
BoolInt CPU_IsSupported_SSE41(void);
|
||||||
BoolInt CPU_IsSupported_SHA(void);
|
BoolInt CPU_IsSupported_SHA(void);
|
||||||
|
BoolInt CPU_IsSupported_SHA512(void);
|
||||||
BoolInt CPU_IsSupported_PageGB(void);
|
BoolInt CPU_IsSupported_PageGB(void);
|
||||||
|
|
||||||
#elif defined(MY_CPU_ARM_OR_ARM64)
|
#elif defined(MY_CPU_ARM_OR_ARM64)
|
||||||
|
|
@ -632,6 +664,7 @@ BoolInt CPU_IsSupported_SHA1(void);
|
||||||
BoolInt CPU_IsSupported_SHA2(void);
|
BoolInt CPU_IsSupported_SHA2(void);
|
||||||
BoolInt CPU_IsSupported_AES(void);
|
BoolInt CPU_IsSupported_AES(void);
|
||||||
#endif
|
#endif
|
||||||
|
BoolInt CPU_IsSupported_SHA512(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
16
C/LzmaEnc.c
16
C/LzmaEnc.c
|
|
@ -1,5 +1,5 @@
|
||||||
/* LzmaEnc.c -- LZMA Encoder
|
/* LzmaEnc.c -- LZMA Encoder
|
||||||
2024-01-24: Igor Pavlov : Public domain */
|
Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
|
@ -72,11 +72,11 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
|
||||||
p->level = level;
|
p->level = level;
|
||||||
|
|
||||||
if (p->dictSize == 0)
|
if (p->dictSize == 0)
|
||||||
p->dictSize =
|
p->dictSize = (unsigned)level <= 4 ?
|
||||||
( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) :
|
(UInt32)1 << (level * 2 + 16) :
|
||||||
( level <= 6 ? ((UInt32)1 << (level + 19)) :
|
(unsigned)level <= sizeof(size_t) / 2 + 4 ?
|
||||||
( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26)
|
(UInt32)1 << (level + 20) :
|
||||||
)));
|
(UInt32)1 << (sizeof(size_t) / 2 + 24);
|
||||||
|
|
||||||
if (p->dictSize > p->reduceSize)
|
if (p->dictSize > p->reduceSize)
|
||||||
{
|
{
|
||||||
|
|
@ -92,8 +92,8 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
|
||||||
if (p->lp < 0) p->lp = 0;
|
if (p->lp < 0) p->lp = 0;
|
||||||
if (p->pb < 0) p->pb = 2;
|
if (p->pb < 0) p->pb = 2;
|
||||||
|
|
||||||
if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
|
if (p->algo < 0) p->algo = (unsigned)level < 5 ? 0 : 1;
|
||||||
if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
|
if (p->fb < 0) p->fb = (unsigned)level < 7 ? 32 : 64;
|
||||||
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
|
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
|
||||||
if (p->numHashBytes < 0) p->numHashBytes = (p->btMode ? 4 : 5);
|
if (p->numHashBytes < 0) p->numHashBytes = (p->btMode ? 4 : 5);
|
||||||
if (p->mc == 0) p->mc = (16 + ((unsigned)p->fb >> 1)) >> (p->btMode ? 0 : 1);
|
if (p->mc == 0) p->mc = (16 + ((unsigned)p->fb >> 1)) >> (p->btMode ? 0 : 1);
|
||||||
|
|
|
||||||
206
C/Md5.c
Normal file
206
C/Md5.c
Normal file
|
|
@ -0,0 +1,206 @@
|
||||||
|
/* Md5.c -- MD5 Hash
|
||||||
|
: Igor Pavlov : Public domain
|
||||||
|
This code is based on Colin Plumb's public domain md5.c code */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Md5.h"
|
||||||
|
#include "RotateDefs.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
#define MD5_UPDATE_BLOCKS(p) Md5_UpdateBlocks
|
||||||
|
|
||||||
|
Z7_NO_INLINE
|
||||||
|
void Md5_Init(CMd5 *p)
|
||||||
|
{
|
||||||
|
p->count = 0;
|
||||||
|
p->state[0] = 0x67452301;
|
||||||
|
p->state[1] = 0xefcdab89;
|
||||||
|
p->state[2] = 0x98badcfe;
|
||||||
|
p->state[3] = 0x10325476;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 && !defined(MY_CPU_LE_UNALIGN)
|
||||||
|
// optional optimization for Big-endian processors or processors without unaligned access:
|
||||||
|
// it is intended to reduce the number of complex LE32 memory reading from 64 to 16.
|
||||||
|
// But some compilers (sparc, armt) are better without this optimization.
|
||||||
|
#define Z7_MD5_USE_DATA32_ARRAY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LOAD_DATA(i) GetUi32((const UInt32 *)(const void *)data + (i))
|
||||||
|
|
||||||
|
#ifdef Z7_MD5_USE_DATA32_ARRAY
|
||||||
|
#define D(i) data32[i]
|
||||||
|
#else
|
||||||
|
#define D(i) LOAD_DATA(i)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||||
|
#define F2(x, y, z) F1(z, x, y)
|
||||||
|
#define F3(x, y, z) (x ^ y ^ z)
|
||||||
|
#define F4(x, y, z) (y ^ (x | ~z))
|
||||||
|
|
||||||
|
#define R1(i, f, start, step, w, x, y, z, s, k) \
|
||||||
|
w += D((start + step * (i)) % 16) + k; \
|
||||||
|
w += f(x, y, z); \
|
||||||
|
w = rotlFixed(w, s) + x; \
|
||||||
|
|
||||||
|
#define R4(i4, f, start, step, s0,s1,s2,s3, k0,k1,k2,k3) \
|
||||||
|
R1 (i4*4+0, f, start, step, a,b,c,d, s0, k0) \
|
||||||
|
R1 (i4*4+1, f, start, step, d,a,b,c, s1, k1) \
|
||||||
|
R1 (i4*4+2, f, start, step, c,d,a,b, s2, k2) \
|
||||||
|
R1 (i4*4+3, f, start, step, b,c,d,a, s3, k3) \
|
||||||
|
|
||||||
|
#define R16(f, start, step, s0,s1,s2,s3, k00,k01,k02,k03, k10,k11,k12,k13, k20,k21,k22,k23, k30,k31,k32,k33) \
|
||||||
|
R4 (0, f, start, step, s0,s1,s2,s3, k00,k01,k02,k03) \
|
||||||
|
R4 (1, f, start, step, s0,s1,s2,s3, k10,k11,k12,k13) \
|
||||||
|
R4 (2, f, start, step, s0,s1,s2,s3, k20,k21,k22,k23) \
|
||||||
|
R4 (3, f, start, step, s0,s1,s2,s3, k30,k31,k32,k33) \
|
||||||
|
|
||||||
|
static
|
||||||
|
Z7_NO_INLINE
|
||||||
|
void Z7_FASTCALL Md5_UpdateBlocks(UInt32 state[4], const Byte *data, size_t numBlocks)
|
||||||
|
{
|
||||||
|
UInt32 a, b, c, d;
|
||||||
|
// if (numBlocks == 0) return;
|
||||||
|
a = state[0];
|
||||||
|
b = state[1];
|
||||||
|
c = state[2];
|
||||||
|
d = state[3];
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef Z7_MD5_USE_DATA32_ARRAY
|
||||||
|
UInt32 data32[MD5_NUM_BLOCK_WORDS];
|
||||||
|
{
|
||||||
|
#define LOAD_data32_x4(i) { \
|
||||||
|
data32[i ] = LOAD_DATA(i ); \
|
||||||
|
data32[i + 1] = LOAD_DATA(i + 1); \
|
||||||
|
data32[i + 2] = LOAD_DATA(i + 2); \
|
||||||
|
data32[i + 3] = LOAD_DATA(i + 3); }
|
||||||
|
#if 1
|
||||||
|
LOAD_data32_x4 (0 * 4)
|
||||||
|
LOAD_data32_x4 (1 * 4)
|
||||||
|
LOAD_data32_x4 (2 * 4)
|
||||||
|
LOAD_data32_x4 (3 * 4)
|
||||||
|
#else
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MD5_NUM_BLOCK_WORDS; i += 4)
|
||||||
|
{
|
||||||
|
LOAD_data32_x4(i)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
R16 (F1, 0, 1, 7,12,17,22, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||||
|
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||||
|
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||||
|
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821)
|
||||||
|
R16 (F2, 1, 5, 5, 9,14,20, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||||
|
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||||
|
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||||
|
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a)
|
||||||
|
R16 (F3, 5, 3, 4,11,16,23, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||||
|
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||||
|
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||||
|
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665)
|
||||||
|
R16 (F4, 0, 7, 6,10,15,21, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||||
|
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||||
|
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||||
|
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391)
|
||||||
|
|
||||||
|
a += state[0];
|
||||||
|
b += state[1];
|
||||||
|
c += state[2];
|
||||||
|
d += state[3];
|
||||||
|
|
||||||
|
state[0] = a;
|
||||||
|
state[1] = b;
|
||||||
|
state[2] = c;
|
||||||
|
state[3] = d;
|
||||||
|
|
||||||
|
data += MD5_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
while (--numBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define Md5_UpdateBlock(p) MD5_UPDATE_BLOCKS(p)(p->state, p->buffer, 1)
|
||||||
|
|
||||||
|
void Md5_Update(CMd5 *p, const Byte *data, size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
{
|
||||||
|
const unsigned pos = (unsigned)p->count & (MD5_BLOCK_SIZE - 1);
|
||||||
|
const unsigned num = MD5_BLOCK_SIZE - pos;
|
||||||
|
p->count += size;
|
||||||
|
if (num > size)
|
||||||
|
{
|
||||||
|
memcpy(p->buffer + pos, data, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos != 0)
|
||||||
|
{
|
||||||
|
size -= num;
|
||||||
|
memcpy(p->buffer + pos, data, num);
|
||||||
|
data += num;
|
||||||
|
Md5_UpdateBlock(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const size_t numBlocks = size >> 6;
|
||||||
|
if (numBlocks)
|
||||||
|
MD5_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
|
||||||
|
size &= MD5_BLOCK_SIZE - 1;
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
data += (numBlocks << 6);
|
||||||
|
memcpy(p->buffer, data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Md5_Final(CMd5 *p, Byte *digest)
|
||||||
|
{
|
||||||
|
unsigned pos = (unsigned)p->count & (MD5_BLOCK_SIZE - 1);
|
||||||
|
p->buffer[pos++] = 0x80;
|
||||||
|
if (pos > (MD5_BLOCK_SIZE - 4 * 2))
|
||||||
|
{
|
||||||
|
while (pos != MD5_BLOCK_SIZE) { p->buffer[pos++] = 0; }
|
||||||
|
// memset(&p->buf.buffer[pos], 0, MD5_BLOCK_SIZE - pos);
|
||||||
|
Md5_UpdateBlock(p);
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
memset(&p->buffer[pos], 0, (MD5_BLOCK_SIZE - 4 * 2) - pos);
|
||||||
|
{
|
||||||
|
const UInt64 numBits = p->count << 3;
|
||||||
|
#if defined(MY_CPU_LE_UNALIGN)
|
||||||
|
SetUi64 (p->buffer + MD5_BLOCK_SIZE - 4 * 2, numBits)
|
||||||
|
#else
|
||||||
|
SetUi32a(p->buffer + MD5_BLOCK_SIZE - 4 * 2, (UInt32)(numBits))
|
||||||
|
SetUi32a(p->buffer + MD5_BLOCK_SIZE - 4 * 1, (UInt32)(numBits >> 32))
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Md5_UpdateBlock(p);
|
||||||
|
|
||||||
|
SetUi32(digest, p->state[0])
|
||||||
|
SetUi32(digest + 4, p->state[1])
|
||||||
|
SetUi32(digest + 8, p->state[2])
|
||||||
|
SetUi32(digest + 12, p->state[3])
|
||||||
|
|
||||||
|
Md5_Init(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef R1
|
||||||
|
#undef R4
|
||||||
|
#undef R16
|
||||||
|
#undef D
|
||||||
|
#undef LOAD_DATA
|
||||||
|
#undef LOAD_data32_x4
|
||||||
|
#undef F1
|
||||||
|
#undef F2
|
||||||
|
#undef F3
|
||||||
|
#undef F4
|
||||||
34
C/Md5.h
Normal file
34
C/Md5.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* Md5.h -- MD5 Hash
|
||||||
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef ZIP7_INC_MD5_H
|
||||||
|
#define ZIP7_INC_MD5_H
|
||||||
|
|
||||||
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define MD5_NUM_BLOCK_WORDS 16
|
||||||
|
#define MD5_NUM_DIGEST_WORDS 4
|
||||||
|
|
||||||
|
#define MD5_BLOCK_SIZE (MD5_NUM_BLOCK_WORDS * 4)
|
||||||
|
#define MD5_DIGEST_SIZE (MD5_NUM_DIGEST_WORDS * 4)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 count;
|
||||||
|
UInt64 _pad_1;
|
||||||
|
// we want 16-bytes alignment here
|
||||||
|
UInt32 state[MD5_NUM_DIGEST_WORDS];
|
||||||
|
UInt64 _pad_2[4];
|
||||||
|
// we want 64-bytes alignment here
|
||||||
|
Byte buffer[MD5_BLOCK_SIZE];
|
||||||
|
} CMd5;
|
||||||
|
|
||||||
|
void Md5_Init(CMd5 *p);
|
||||||
|
void Md5_Update(CMd5 *p, const Byte *data, size_t size);
|
||||||
|
void Md5_Final(CMd5 *p, Byte *digest);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
113
C/Sha1.c
113
C/Sha1.c
|
|
@ -1,18 +1,14 @@
|
||||||
/* Sha1.c -- SHA-1 Hash
|
/* Sha1.c -- SHA-1 Hash
|
||||||
2024-03-01 : Igor Pavlov : Public domain
|
: Igor Pavlov : Public domain
|
||||||
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
|
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "CpuArch.h"
|
|
||||||
#include "RotateDefs.h"
|
|
||||||
#include "Sha1.h"
|
#include "Sha1.h"
|
||||||
|
#include "RotateDefs.h"
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
#include "CpuArch.h"
|
||||||
// #define USE_MY_MM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \
|
#if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \
|
||||||
|
|
@ -56,7 +52,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t num
|
||||||
static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks;
|
static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks;
|
||||||
static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS_HW;
|
static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS_HW;
|
||||||
|
|
||||||
#define SHA1_UPDATE_BLOCKS(p) p->func_UpdateBlocks
|
#define SHA1_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks
|
||||||
#else
|
#else
|
||||||
#define SHA1_UPDATE_BLOCKS(p) Sha1_UpdateBlocks
|
#define SHA1_UPDATE_BLOCKS(p) Sha1_UpdateBlocks
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -85,7 +81,7 @@ BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo)
|
||||||
return False;
|
return False;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p->func_UpdateBlocks = func;
|
p->v.vars.func_UpdateBlocks = func;
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,7 +221,7 @@ BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo)
|
||||||
|
|
||||||
void Sha1_InitState(CSha1 *p)
|
void Sha1_InitState(CSha1 *p)
|
||||||
{
|
{
|
||||||
p->count = 0;
|
p->v.vars.count = 0;
|
||||||
p->state[0] = 0x67452301;
|
p->state[0] = 0x67452301;
|
||||||
p->state[1] = 0xEFCDAB89;
|
p->state[1] = 0xEFCDAB89;
|
||||||
p->state[2] = 0x98BADCFE;
|
p->state[2] = 0x98BADCFE;
|
||||||
|
|
@ -235,7 +231,7 @@ void Sha1_InitState(CSha1 *p)
|
||||||
|
|
||||||
void Sha1_Init(CSha1 *p)
|
void Sha1_Init(CSha1 *p)
|
||||||
{
|
{
|
||||||
p->func_UpdateBlocks =
|
p->v.vars.func_UpdateBlocks =
|
||||||
#ifdef Z7_COMPILER_SHA1_SUPPORTED
|
#ifdef Z7_COMPILER_SHA1_SUPPORTED
|
||||||
g_SHA1_FUNC_UPDATE_BLOCKS;
|
g_SHA1_FUNC_UPDATE_BLOCKS;
|
||||||
#else
|
#else
|
||||||
|
|
@ -250,7 +246,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t num
|
||||||
{
|
{
|
||||||
UInt32 a, b, c, d, e;
|
UInt32 a, b, c, d, e;
|
||||||
UInt32 W[kNumW];
|
UInt32 W[kNumW];
|
||||||
// if (numBlocks != 0x1264378347) return;
|
|
||||||
if (numBlocks == 0)
|
if (numBlocks == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -283,7 +279,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t num
|
||||||
state[3] = d;
|
state[3] = d;
|
||||||
state[4] = e;
|
state[4] = e;
|
||||||
|
|
||||||
data += 64;
|
data += SHA1_BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
while (--numBlocks);
|
while (--numBlocks);
|
||||||
}
|
}
|
||||||
|
|
@ -295,20 +291,15 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned pos = (unsigned)p->count & 0x3F;
|
const unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1);
|
||||||
unsigned num;
|
const unsigned num = SHA1_BLOCK_SIZE - pos;
|
||||||
|
p->v.vars.count += size;
|
||||||
p->count += size;
|
|
||||||
|
|
||||||
num = 64 - pos;
|
|
||||||
if (num > size)
|
if (num > size)
|
||||||
{
|
{
|
||||||
memcpy(p->buffer + pos, data, size);
|
memcpy(p->buffer + pos, data, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos != 0)
|
if (pos != 0)
|
||||||
{
|
{
|
||||||
size -= num;
|
size -= num;
|
||||||
|
|
@ -318,9 +309,10 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
size_t numBlocks = size >> 6;
|
const size_t numBlocks = size >> 6;
|
||||||
|
// if (numBlocks)
|
||||||
SHA1_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
|
SHA1_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
|
||||||
size &= 0x3F;
|
size &= SHA1_BLOCK_SIZE - 1;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
data += (numBlocks << 6);
|
data += (numBlocks << 6);
|
||||||
|
|
@ -331,42 +323,21 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
|
||||||
|
|
||||||
void Sha1_Final(CSha1 *p, Byte *digest)
|
void Sha1_Final(CSha1 *p, Byte *digest)
|
||||||
{
|
{
|
||||||
unsigned pos = (unsigned)p->count & 0x3F;
|
unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1);
|
||||||
|
|
||||||
|
|
||||||
p->buffer[pos++] = 0x80;
|
p->buffer[pos++] = 0x80;
|
||||||
|
if (pos > (SHA1_BLOCK_SIZE - 4 * 2))
|
||||||
if (pos > (64 - 8))
|
|
||||||
{
|
{
|
||||||
while (pos != 64) { p->buffer[pos++] = 0; }
|
while (pos != SHA1_BLOCK_SIZE) { p->buffer[pos++] = 0; }
|
||||||
// memset(&p->buf.buffer[pos], 0, 64 - pos);
|
// memset(&p->buf.buffer[pos], 0, SHA1_BLOCK_SIZE - pos);
|
||||||
Sha1_UpdateBlock(p);
|
Sha1_UpdateBlock(p);
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
|
memset(&p->buffer[pos], 0, (SHA1_BLOCK_SIZE - 4 * 2) - pos);
|
||||||
/*
|
|
||||||
if (pos & 3)
|
|
||||||
{
|
{
|
||||||
p->buffer[pos] = 0;
|
const UInt64 numBits = p->v.vars.count << 3;
|
||||||
p->buffer[pos + 1] = 0;
|
SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32))
|
||||||
p->buffer[pos + 2] = 0;
|
SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 1, (UInt32)(numBits))
|
||||||
pos += 3;
|
|
||||||
pos &= ~3;
|
|
||||||
}
|
}
|
||||||
{
|
|
||||||
for (; pos < 64 - 8; pos += 4)
|
|
||||||
*(UInt32 *)(&p->buffer[pos]) = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
memset(&p->buffer[pos], 0, (64 - 8) - pos);
|
|
||||||
|
|
||||||
{
|
|
||||||
const UInt64 numBits = (p->count << 3);
|
|
||||||
SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32))
|
|
||||||
SetBe32(p->buffer + 64 - 4, (UInt32)(numBits))
|
|
||||||
}
|
|
||||||
|
|
||||||
Sha1_UpdateBlock(p);
|
Sha1_UpdateBlock(p);
|
||||||
|
|
||||||
SetBe32(digest, p->state[0])
|
SetBe32(digest, p->state[0])
|
||||||
|
|
@ -375,16 +346,13 @@ void Sha1_Final(CSha1 *p, Byte *digest)
|
||||||
SetBe32(digest + 12, p->state[3])
|
SetBe32(digest + 12, p->state[3])
|
||||||
SetBe32(digest + 16, p->state[4])
|
SetBe32(digest + 16, p->state[4])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Sha1_InitState(p);
|
Sha1_InitState(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size)
|
void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size)
|
||||||
{
|
{
|
||||||
const UInt64 numBits = (p->count + size) << 3;
|
const UInt64 numBits = (p->v.vars.count + size) << 3;
|
||||||
SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32))
|
SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32))
|
||||||
SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits))
|
SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits))
|
||||||
// SetBe32((UInt32 *)(block + size), 0x80000000);
|
// SetBe32((UInt32 *)(block + size), 0x80000000);
|
||||||
|
|
@ -425,44 +393,19 @@ void Sha1Prepare(void)
|
||||||
f = Sha1_UpdateBlocks;
|
f = Sha1_UpdateBlocks;
|
||||||
f_hw = NULL;
|
f_hw = NULL;
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#ifndef USE_MY_MM
|
|
||||||
if (CPU_IsSupported_SHA()
|
if (CPU_IsSupported_SHA()
|
||||||
&& CPU_IsSupported_SSSE3()
|
&& CPU_IsSupported_SSSE3()
|
||||||
// && CPU_IsSupported_SSE41()
|
|
||||||
)
|
)
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
if (CPU_IsSupported_SHA1())
|
if (CPU_IsSupported_SHA1())
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// printf("\n========== HW SHA1 ======== \n");
|
// printf("\n========== HW SHA1 ======== \n");
|
||||||
#if 0 && defined(MY_CPU_ARM_OR_ARM64) && defined(_MSC_VER)
|
#if 1 && defined(MY_CPU_ARM_OR_ARM64) && defined(Z7_MSC_VER_ORIGINAL) && (_MSC_FULL_VER < 192930037)
|
||||||
/* there was bug in MSVC compiler for ARM64 -O2 before version VS2019 16.10 (19.29.30037).
|
/* there was bug in MSVC compiler for ARM64 -O2 before version VS2019 16.10 (19.29.30037).
|
||||||
It generated incorrect SHA-1 code.
|
It generated incorrect SHA-1 code. */
|
||||||
21.03 : we test sha1-hardware code at runtime initialization */
|
#pragma message("== SHA1 code can work incorrectly with this compiler")
|
||||||
|
#error Stop_Compiling_MSC_Compiler_BUG_SHA1
|
||||||
#pragma message("== SHA1 code: MSC compiler : failure-check code was inserted")
|
|
||||||
|
|
||||||
UInt32 state[5] = { 0, 1, 2, 3, 4 } ;
|
|
||||||
Byte data[64];
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < sizeof(data); i += 2)
|
|
||||||
{
|
|
||||||
data[i ] = (Byte)(i);
|
|
||||||
data[i + 1] = (Byte)(i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sha1_UpdateBlocks_HW(state, data, sizeof(data) / 64);
|
|
||||||
|
|
||||||
if ( state[0] != 0x9acd7297
|
|
||||||
|| state[1] != 0x4624d898
|
|
||||||
|| state[2] != 0x0bf079f0
|
|
||||||
|| state[3] != 0x031e61b3
|
|
||||||
|| state[4] != 0x8323fe20)
|
|
||||||
{
|
|
||||||
// printf("\n========== SHA-1 hardware version failure ======== \n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
f = f_hw = Sha1_UpdateBlocks_HW;
|
f = f_hw = Sha1_UpdateBlocks_HW;
|
||||||
|
|
|
||||||
14
C/Sha1.h
14
C/Sha1.h
|
|
@ -1,5 +1,5 @@
|
||||||
/* Sha1.h -- SHA-1 Hash
|
/* Sha1.h -- SHA-1 Hash
|
||||||
2023-04-02 : Igor Pavlov : Public domain */
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_SHA1_H
|
#ifndef ZIP7_INC_SHA1_H
|
||||||
#define ZIP7_INC_SHA1_H
|
#define ZIP7_INC_SHA1_H
|
||||||
|
|
@ -14,6 +14,9 @@ EXTERN_C_BEGIN
|
||||||
#define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4)
|
#define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4)
|
||||||
#define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4)
|
#define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (Z7_FASTCALL *SHA1_FUNC_UPDATE_BLOCKS)(UInt32 state[5], const Byte *data, size_t numBlocks);
|
typedef void (Z7_FASTCALL *SHA1_FUNC_UPDATE_BLOCKS)(UInt32 state[5], const Byte *data, size_t numBlocks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -31,10 +34,17 @@ typedef void (Z7_FASTCALL *SHA1_FUNC_UPDATE_BLOCKS)(UInt32 state[5], const Byte
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
SHA1_FUNC_UPDATE_BLOCKS func_UpdateBlocks;
|
SHA1_FUNC_UPDATE_BLOCKS func_UpdateBlocks;
|
||||||
UInt64 count;
|
UInt64 count;
|
||||||
UInt64 _pad_2[2];
|
} vars;
|
||||||
|
UInt64 _pad_64bit[4];
|
||||||
|
void *_pad_align_ptr[2];
|
||||||
|
} v;
|
||||||
UInt32 state[SHA1_NUM_DIGEST_WORDS];
|
UInt32 state[SHA1_NUM_DIGEST_WORDS];
|
||||||
UInt32 _pad_3[3];
|
UInt32 _pad_3[3];
|
||||||
Byte buffer[SHA1_BLOCK_SIZE];
|
Byte buffer[SHA1_BLOCK_SIZE];
|
||||||
|
|
|
||||||
140
C/Sha1Opt.c
140
C/Sha1Opt.c
|
|
@ -1,18 +1,11 @@
|
||||||
/* Sha1Opt.c -- SHA-1 optimized code for SHA-1 hardware instructions
|
/* Sha1Opt.c -- SHA-1 optimized code for SHA-1 hardware instructions
|
||||||
2024-03-01 : Igor Pavlov : Public domain */
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#if (_MSC_VER < 1900) && (_MSC_VER >= 1200)
|
|
||||||
// #define USE_MY_MM
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// #define Z7_USE_HW_SHA_STUB // for debug
|
// #define Z7_USE_HW_SHA_STUB // for debug
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check
|
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check
|
||||||
#define USE_HW_SHA
|
#define USE_HW_SHA
|
||||||
|
|
@ -20,19 +13,14 @@
|
||||||
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \
|
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \
|
||||||
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900)
|
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900)
|
||||||
#define USE_HW_SHA
|
#define USE_HW_SHA
|
||||||
#if !defined(_INTEL_COMPILER)
|
#if !defined(__INTEL_COMPILER)
|
||||||
// icc defines __GNUC__, but icc doesn't support __attribute__(__target__)
|
// icc defines __GNUC__, but icc doesn't support __attribute__(__target__)
|
||||||
#if !defined(__SHA__) || !defined(__SSSE3__)
|
#if !defined(__SHA__) || !defined(__SSSE3__)
|
||||||
#define ATTRIB_SHA __attribute__((__target__("sha,ssse3")))
|
#define ATTRIB_SHA __attribute__((__target__("sha,ssse3")))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#ifdef USE_MY_MM
|
#if (_MSC_VER >= 1900)
|
||||||
#define USE_VER_MIN 1300
|
|
||||||
#else
|
|
||||||
#define USE_VER_MIN 1900
|
|
||||||
#endif
|
|
||||||
#if (_MSC_VER >= USE_VER_MIN)
|
|
||||||
#define USE_HW_SHA
|
#define USE_HW_SHA
|
||||||
#else
|
#else
|
||||||
#define Z7_USE_HW_SHA_STUB
|
#define Z7_USE_HW_SHA_STUB
|
||||||
|
|
@ -47,23 +35,20 @@
|
||||||
|
|
||||||
// #pragma message("Sha1 HW")
|
// #pragma message("Sha1 HW")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// sse/sse2/ssse3:
|
// sse/sse2/ssse3:
|
||||||
#include <tmmintrin.h>
|
#include <tmmintrin.h>
|
||||||
// sha*:
|
// sha*:
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
|
||||||
#if defined (__clang__) && defined(_MSC_VER)
|
#if defined (__clang__) && defined(_MSC_VER)
|
||||||
// #if !defined(__SSSE3__)
|
|
||||||
// #endif
|
|
||||||
#if !defined(__SHA__)
|
#if !defined(__SHA__)
|
||||||
#include <shaintrin.h>
|
#include <shaintrin.h>
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef USE_MY_MM
|
|
||||||
#include "My_mm.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -84,7 +69,6 @@ SHA:
|
||||||
_mm_sha1*
|
_mm_sha1*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define XOR_SI128(dest, src) dest = _mm_xor_si128(dest, src);
|
#define XOR_SI128(dest, src) dest = _mm_xor_si128(dest, src);
|
||||||
#define SHUFFLE_EPI8(dest, mask) dest = _mm_shuffle_epi8(dest, mask);
|
#define SHUFFLE_EPI8(dest, mask) dest = _mm_shuffle_epi8(dest, mask);
|
||||||
#define SHUFFLE_EPI32(dest, mask) dest = _mm_shuffle_epi32(dest, mask);
|
#define SHUFFLE_EPI32(dest, mask) dest = _mm_shuffle_epi32(dest, mask);
|
||||||
|
|
@ -99,11 +83,12 @@ SHA:
|
||||||
#define SHA1_MSG1(dest, src) dest = _mm_sha1msg1_epu32(dest, src);
|
#define SHA1_MSG1(dest, src) dest = _mm_sha1msg1_epu32(dest, src);
|
||||||
#define SHA1_MSG2(dest, src) dest = _mm_sha1msg2_epu32(dest, src);
|
#define SHA1_MSG2(dest, src) dest = _mm_sha1msg2_epu32(dest, src);
|
||||||
|
|
||||||
|
|
||||||
#define LOAD_SHUFFLE(m, k) \
|
#define LOAD_SHUFFLE(m, k) \
|
||||||
m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \
|
m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \
|
||||||
SHUFFLE_EPI8(m, mask) \
|
SHUFFLE_EPI8(m, mask) \
|
||||||
|
|
||||||
|
#define NNN(m0, m1, m2, m3)
|
||||||
|
|
||||||
#define SM1(m0, m1, m2, m3) \
|
#define SM1(m0, m1, m2, m3) \
|
||||||
SHA1_MSG1(m0, m1) \
|
SHA1_MSG1(m0, m1) \
|
||||||
|
|
||||||
|
|
@ -116,35 +101,19 @@ SHA:
|
||||||
SM1(m0, m1, m2, m3) \
|
SM1(m0, m1, m2, m3) \
|
||||||
SHA1_MSG2(m3, m2) \
|
SHA1_MSG2(m3, m2) \
|
||||||
|
|
||||||
#define NNN(m0, m1, m2, m3)
|
#define R4(k, m0, m1, m2, m3, e0, e1, OP) \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define R4(k, e0, e1, m0, m1, m2, m3, OP) \
|
|
||||||
e1 = abcd; \
|
e1 = abcd; \
|
||||||
SHA1_RND4(abcd, e0, (k) / 5) \
|
SHA1_RND4(abcd, e0, (k) / 5) \
|
||||||
SHA1_NEXTE(e1, m1) \
|
SHA1_NEXTE(e1, m1) \
|
||||||
OP(m0, m1, m2, m3) \
|
OP(m0, m1, m2, m3) \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define R16(k, mx, OP0, OP1, OP2, OP3) \
|
#define R16(k, mx, OP0, OP1, OP2, OP3) \
|
||||||
R4 ( (k)*4+0, e0,e1, m0,m1,m2,m3, OP0 ) \
|
R4 ( (k)*4+0, m0,m1,m2,m3, e0,e1, OP0 ) \
|
||||||
R4 ( (k)*4+1, e1,e0, m1,m2,m3,m0, OP1 ) \
|
R4 ( (k)*4+1, m1,m2,m3,m0, e1,e0, OP1 ) \
|
||||||
R4 ( (k)*4+2, e0,e1, m2,m3,m0,m1, OP2 ) \
|
R4 ( (k)*4+2, m2,m3,m0,m1, e0,e1, OP2 ) \
|
||||||
R4 ( (k)*4+3, e1,e0, m3,mx,m1,m2, OP3 ) \
|
R4 ( (k)*4+3, m3,mx,m1,m2, e1,e0, OP3 ) \
|
||||||
|
|
||||||
#define PREPARE_STATE \
|
#define PREPARE_STATE \
|
||||||
SHUFFLE_EPI32 (abcd, 0x1B) \
|
SHUFFLE_EPI32 (abcd, 0x1B) \
|
||||||
|
|
@ -162,6 +131,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t
|
||||||
{
|
{
|
||||||
const __m128i mask = _mm_set_epi32(0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f);
|
const __m128i mask = _mm_set_epi32(0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f);
|
||||||
|
|
||||||
|
|
||||||
__m128i abcd, e0;
|
__m128i abcd, e0;
|
||||||
|
|
||||||
if (numBlocks == 0)
|
if (numBlocks == 0)
|
||||||
|
|
@ -262,22 +232,10 @@ void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t
|
||||||
#define _ARM_USE_NEW_NEON_INTRINSICS
|
#define _ARM_USE_NEW_NEON_INTRINSICS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64)
|
#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64)
|
||||||
#include <arm64_neon.h>
|
#include <arm64_neon.h>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__clang__) && __clang_major__ < 16
|
#if defined(__clang__) && __clang_major__ < 16
|
||||||
#if !defined(__ARM_FEATURE_SHA2) && \
|
#if !defined(__ARM_FEATURE_SHA2) && \
|
||||||
!defined(__ARM_FEATURE_CRYPTO)
|
!defined(__ARM_FEATURE_CRYPTO)
|
||||||
|
|
@ -329,26 +287,37 @@ typedef uint32x4_t v128;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MY_CPU_BE
|
#ifdef MY_CPU_BE
|
||||||
#define MY_rev32_for_LE(x)
|
#define MY_rev32_for_LE(x) x
|
||||||
#else
|
#else
|
||||||
#define MY_rev32_for_LE(x) x = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(x)))
|
#define MY_rev32_for_LE(x) vrev32q_u8(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOAD_128(_p) (*(const v128 *)(const void *)(_p))
|
#define LOAD_128_32(_p) vld1q_u32(_p)
|
||||||
#define STORE_128(_p, _v) *(v128 *)(void *)(_p) = (_v)
|
#define LOAD_128_8(_p) vld1q_u8 (_p)
|
||||||
|
#define STORE_128_32(_p, _v) vst1q_u32(_p, _v)
|
||||||
|
|
||||||
#define LOAD_SHUFFLE(m, k) \
|
#define LOAD_SHUFFLE(m, k) \
|
||||||
m = LOAD_128((data + (k) * 16)); \
|
m = vreinterpretq_u32_u8( \
|
||||||
MY_rev32_for_LE(m); \
|
MY_rev32_for_LE( \
|
||||||
|
LOAD_128_8(data + (k) * 16))); \
|
||||||
|
|
||||||
#define SU0(dest, src2, src3) dest = vsha1su0q_u32(dest, src2, src3)
|
#define N0(dest, src2, src3)
|
||||||
#define SU1(dest, src) dest = vsha1su1q_u32(dest, src)
|
#define N1(dest, src)
|
||||||
|
#define U0(dest, src2, src3) dest = vsha1su0q_u32(dest, src2, src3);
|
||||||
|
#define U1(dest, src) dest = vsha1su1q_u32(dest, src);
|
||||||
#define C(e) abcd = vsha1cq_u32(abcd, e, t)
|
#define C(e) abcd = vsha1cq_u32(abcd, e, t)
|
||||||
#define P(e) abcd = vsha1pq_u32(abcd, e, t)
|
#define P(e) abcd = vsha1pq_u32(abcd, e, t)
|
||||||
#define M(e) abcd = vsha1mq_u32(abcd, e, t)
|
#define M(e) abcd = vsha1mq_u32(abcd, e, t)
|
||||||
#define H(e) e = vsha1h_u32(vgetq_lane_u32(abcd, 0))
|
#define H(e) e = vsha1h_u32(vgetq_lane_u32(abcd, 0))
|
||||||
#define T(m, c) t = vaddq_u32(m, c)
|
#define T(m, c) t = vaddq_u32(m, c)
|
||||||
|
|
||||||
|
#define R16(d0,d1,d2,d3, f0,z0, f1,z1, f2,z2, f3,z3, w0,w1,w2,w3) \
|
||||||
|
T(m0, d0); f0(m3, m0, m1) z0(m2, m1) H(e1); w0(e0); \
|
||||||
|
T(m1, d1); f1(m0, m1, m2) z1(m3, m2) H(e0); w1(e1); \
|
||||||
|
T(m2, d2); f2(m1, m2, m3) z2(m0, m3) H(e1); w2(e0); \
|
||||||
|
T(m3, d3); f3(m2, m3, m0) z3(m1, m0) H(e0); w3(e1); \
|
||||||
|
|
||||||
|
|
||||||
void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks);
|
void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks);
|
||||||
#ifdef ATTRIB_SHA
|
#ifdef ATTRIB_SHA
|
||||||
ATTRIB_SHA
|
ATTRIB_SHA
|
||||||
|
|
@ -367,7 +336,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t
|
||||||
c2 = vdupq_n_u32(0x8f1bbcdc);
|
c2 = vdupq_n_u32(0x8f1bbcdc);
|
||||||
c3 = vdupq_n_u32(0xca62c1d6);
|
c3 = vdupq_n_u32(0xca62c1d6);
|
||||||
|
|
||||||
abcd = LOAD_128(&state[0]);
|
abcd = LOAD_128_32(&state[0]);
|
||||||
e0 = state[4];
|
e0 = state[4];
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
@ -385,26 +354,11 @@ void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t
|
||||||
LOAD_SHUFFLE (m2, 2)
|
LOAD_SHUFFLE (m2, 2)
|
||||||
LOAD_SHUFFLE (m3, 3)
|
LOAD_SHUFFLE (m3, 3)
|
||||||
|
|
||||||
T(m0, c0); H(e1); C(e0);
|
R16 ( c0,c0,c0,c0, N0,N1, U0,N1, U0,U1, U0,U1, C,C,C,C )
|
||||||
T(m1, c0); SU0(m0, m1, m2); H(e0); C(e1);
|
R16 ( c0,c1,c1,c1, U0,U1, U0,U1, U0,U1, U0,U1, C,P,P,P )
|
||||||
T(m2, c0); SU0(m1, m2, m3); SU1(m0, m3); H(e1); C(e0);
|
R16 ( c1,c1,c2,c2, U0,U1, U0,U1, U0,U1, U0,U1, P,P,M,M )
|
||||||
T(m3, c0); SU0(m2, m3, m0); SU1(m1, m0); H(e0); C(e1);
|
R16 ( c2,c2,c2,c3, U0,U1, U0,U1, U0,U1, U0,U1, M,M,M,P )
|
||||||
T(m0, c0); SU0(m3, m0, m1); SU1(m2, m1); H(e1); C(e0);
|
R16 ( c3,c3,c3,c3, U0,U1, N0,U1, N0,N1, N0,N1, P,P,P,P )
|
||||||
T(m1, c1); SU0(m0, m1, m2); SU1(m3, m2); H(e0); P(e1);
|
|
||||||
T(m2, c1); SU0(m1, m2, m3); SU1(m0, m3); H(e1); P(e0);
|
|
||||||
T(m3, c1); SU0(m2, m3, m0); SU1(m1, m0); H(e0); P(e1);
|
|
||||||
T(m0, c1); SU0(m3, m0, m1); SU1(m2, m1); H(e1); P(e0);
|
|
||||||
T(m1, c1); SU0(m0, m1, m2); SU1(m3, m2); H(e0); P(e1);
|
|
||||||
T(m2, c2); SU0(m1, m2, m3); SU1(m0, m3); H(e1); M(e0);
|
|
||||||
T(m3, c2); SU0(m2, m3, m0); SU1(m1, m0); H(e0); M(e1);
|
|
||||||
T(m0, c2); SU0(m3, m0, m1); SU1(m2, m1); H(e1); M(e0);
|
|
||||||
T(m1, c2); SU0(m0, m1, m2); SU1(m3, m2); H(e0); M(e1);
|
|
||||||
T(m2, c2); SU0(m1, m2, m3); SU1(m0, m3); H(e1); M(e0);
|
|
||||||
T(m3, c3); SU0(m2, m3, m0); SU1(m1, m0); H(e0); P(e1);
|
|
||||||
T(m0, c3); SU0(m3, m0, m1); SU1(m2, m1); H(e1); P(e0);
|
|
||||||
T(m1, c3); SU1(m3, m2); H(e0); P(e1);
|
|
||||||
T(m2, c3); H(e1); P(e0);
|
|
||||||
T(m3, c3); H(e0); P(e1);
|
|
||||||
|
|
||||||
abcd = vaddq_u32(abcd, abcd_save);
|
abcd = vaddq_u32(abcd, abcd_save);
|
||||||
e0 += e0_save;
|
e0 += e0_save;
|
||||||
|
|
@ -413,7 +367,7 @@ void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t
|
||||||
}
|
}
|
||||||
while (--numBlocks);
|
while (--numBlocks);
|
||||||
|
|
||||||
STORE_128(&state[0], abcd);
|
STORE_128_32(&state[0], abcd);
|
||||||
state[4] = e0;
|
state[4] = e0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -421,13 +375,9 @@ void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t
|
||||||
|
|
||||||
#endif // MY_CPU_ARM_OR_ARM64
|
#endif // MY_CPU_ARM_OR_ARM64
|
||||||
|
|
||||||
|
|
||||||
#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB)
|
#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB)
|
||||||
// #error Stop_Compiling_UNSUPPORTED_SHA
|
// #error Stop_Compiling_UNSUPPORTED_SHA
|
||||||
// #include <stdlib.h>
|
// #include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #include "Sha1.h"
|
// #include "Sha1.h"
|
||||||
// #if defined(_MSC_VER)
|
// #if defined(_MSC_VER)
|
||||||
#pragma message("Sha1 HW-SW stub was used")
|
#pragma message("Sha1 HW-SW stub was used")
|
||||||
|
|
@ -447,8 +397,10 @@ void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef SU0
|
#undef U0
|
||||||
#undef SU1
|
#undef U1
|
||||||
|
#undef N0
|
||||||
|
#undef N1
|
||||||
#undef C
|
#undef C
|
||||||
#undef P
|
#undef P
|
||||||
#undef M
|
#undef M
|
||||||
|
|
|
||||||
134
C/Sha256.c
134
C/Sha256.c
|
|
@ -1,18 +1,14 @@
|
||||||
/* Sha256.c -- SHA-256 Hash
|
/* Sha256.c -- SHA-256 Hash
|
||||||
2024-03-01 : Igor Pavlov : Public domain
|
: Igor Pavlov : Public domain
|
||||||
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "CpuArch.h"
|
|
||||||
#include "RotateDefs.h"
|
|
||||||
#include "Sha256.h"
|
#include "Sha256.h"
|
||||||
|
#include "RotateDefs.h"
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
#include "CpuArch.h"
|
||||||
// #define USE_MY_MM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \
|
#if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \
|
||||||
|
|
@ -56,7 +52,7 @@ void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t n
|
||||||
static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks;
|
static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks;
|
||||||
static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS_HW;
|
static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS_HW;
|
||||||
|
|
||||||
#define SHA256_UPDATE_BLOCKS(p) p->func_UpdateBlocks
|
#define SHA256_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks
|
||||||
#else
|
#else
|
||||||
#define SHA256_UPDATE_BLOCKS(p) Sha256_UpdateBlocks
|
#define SHA256_UPDATE_BLOCKS(p) Sha256_UpdateBlocks
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -85,7 +81,7 @@ BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo)
|
||||||
return False;
|
return False;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p->func_UpdateBlocks = func;
|
p->v.vars.func_UpdateBlocks = func;
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +107,7 @@ BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo)
|
||||||
|
|
||||||
void Sha256_InitState(CSha256 *p)
|
void Sha256_InitState(CSha256 *p)
|
||||||
{
|
{
|
||||||
p->count = 0;
|
p->v.vars.count = 0;
|
||||||
p->state[0] = 0x6a09e667;
|
p->state[0] = 0x6a09e667;
|
||||||
p->state[1] = 0xbb67ae85;
|
p->state[1] = 0xbb67ae85;
|
||||||
p->state[2] = 0x3c6ef372;
|
p->state[2] = 0x3c6ef372;
|
||||||
|
|
@ -122,9 +118,16 @@ void Sha256_InitState(CSha256 *p)
|
||||||
p->state[7] = 0x5be0cd19;
|
p->state[7] = 0x5be0cd19;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Sha256_Init(CSha256 *p)
|
void Sha256_Init(CSha256 *p)
|
||||||
{
|
{
|
||||||
p->func_UpdateBlocks =
|
p->v.vars.func_UpdateBlocks =
|
||||||
#ifdef Z7_COMPILER_SHA256_SUPPORTED
|
#ifdef Z7_COMPILER_SHA256_SUPPORTED
|
||||||
g_SHA256_FUNC_UPDATE_BLOCKS;
|
g_SHA256_FUNC_UPDATE_BLOCKS;
|
||||||
#else
|
#else
|
||||||
|
|
@ -224,12 +227,10 @@ void Sha256_Init(CSha256 *p)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// static
|
|
||||||
extern MY_ALIGN(64)
|
|
||||||
const UInt32 SHA256_K_ARRAY[64];
|
|
||||||
|
|
||||||
MY_ALIGN(64)
|
extern
|
||||||
const UInt32 SHA256_K_ARRAY[64] = {
|
MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64];
|
||||||
|
MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[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,
|
||||||
|
|
@ -248,9 +249,12 @@ const UInt32 SHA256_K_ARRAY[64] = {
|
||||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||||
};
|
};
|
||||||
|
|
||||||
#define K SHA256_K_ARRAY
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define K SHA256_K_ARRAY
|
||||||
|
|
||||||
Z7_NO_INLINE
|
Z7_NO_INLINE
|
||||||
void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks)
|
void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks)
|
||||||
{
|
{
|
||||||
|
|
@ -260,15 +264,14 @@ void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t n
|
||||||
#else
|
#else
|
||||||
[16];
|
[16];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned j;
|
unsigned j;
|
||||||
|
|
||||||
UInt32 a,b,c,d,e,f,g,h;
|
UInt32 a,b,c,d,e,f,g,h;
|
||||||
|
|
||||||
#if !defined(Z7_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4)
|
#if !defined(Z7_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4)
|
||||||
UInt32 tmp;
|
UInt32 tmp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (numBlocks == 0) return;
|
||||||
|
|
||||||
a = state[0];
|
a = state[0];
|
||||||
b = state[1];
|
b = state[1];
|
||||||
c = state[2];
|
c = state[2];
|
||||||
|
|
@ -278,7 +281,7 @@ void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t n
|
||||||
g = state[6];
|
g = state[6];
|
||||||
h = state[7];
|
h = state[7];
|
||||||
|
|
||||||
while (numBlocks)
|
do
|
||||||
{
|
{
|
||||||
|
|
||||||
for (j = 0; j < 16; j += STEP_PRE)
|
for (j = 0; j < 16; j += STEP_PRE)
|
||||||
|
|
@ -352,19 +355,11 @@ void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t n
|
||||||
g += state[6]; state[6] = g;
|
g += state[6]; state[6] = g;
|
||||||
h += state[7]; state[7] = h;
|
h += state[7]; state[7] = h;
|
||||||
|
|
||||||
data += 64;
|
data += SHA256_BLOCK_SIZE;
|
||||||
numBlocks--;
|
}
|
||||||
|
while (--numBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wipe variables */
|
|
||||||
/* memset(W, 0, sizeof(W)); */
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef S0
|
|
||||||
#undef S1
|
|
||||||
#undef s0
|
|
||||||
#undef s1
|
|
||||||
#undef K
|
|
||||||
|
|
||||||
#define Sha256_UpdateBlock(p) SHA256_UPDATE_BLOCKS(p)(p->state, p->buffer, 1)
|
#define Sha256_UpdateBlock(p) SHA256_UPDATE_BLOCKS(p)(p->state, p->buffer, 1)
|
||||||
|
|
||||||
|
|
@ -372,20 +367,15 @@ void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned pos = (unsigned)p->count & 0x3F;
|
const unsigned pos = (unsigned)p->v.vars.count & (SHA256_BLOCK_SIZE - 1);
|
||||||
unsigned num;
|
const unsigned num = SHA256_BLOCK_SIZE - pos;
|
||||||
|
p->v.vars.count += size;
|
||||||
p->count += size;
|
|
||||||
|
|
||||||
num = 64 - pos;
|
|
||||||
if (num > size)
|
if (num > size)
|
||||||
{
|
{
|
||||||
memcpy(p->buffer + pos, data, size);
|
memcpy(p->buffer + pos, data, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos != 0)
|
if (pos != 0)
|
||||||
{
|
{
|
||||||
size -= num;
|
size -= num;
|
||||||
|
|
@ -395,9 +385,10 @@ void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
size_t numBlocks = size >> 6;
|
const size_t numBlocks = size >> 6;
|
||||||
|
// if (numBlocks)
|
||||||
SHA256_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
|
SHA256_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
|
||||||
size &= 0x3F;
|
size &= SHA256_BLOCK_SIZE - 1;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
data += (numBlocks << 6);
|
data += (numBlocks << 6);
|
||||||
|
|
@ -408,53 +399,41 @@ 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)
|
||||||
{
|
{
|
||||||
unsigned pos = (unsigned)p->count & 0x3F;
|
unsigned pos = (unsigned)p->v.vars.count & (SHA256_BLOCK_SIZE - 1);
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
p->buffer[pos++] = 0x80;
|
p->buffer[pos++] = 0x80;
|
||||||
|
if (pos > (SHA256_BLOCK_SIZE - 4 * 2))
|
||||||
if (pos > (64 - 8))
|
|
||||||
{
|
{
|
||||||
while (pos != 64) { p->buffer[pos++] = 0; }
|
while (pos != SHA256_BLOCK_SIZE) { p->buffer[pos++] = 0; }
|
||||||
// memset(&p->buf.buffer[pos], 0, 64 - pos);
|
// memset(&p->buf.buffer[pos], 0, SHA256_BLOCK_SIZE - pos);
|
||||||
Sha256_UpdateBlock(p);
|
Sha256_UpdateBlock(p);
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
|
memset(&p->buffer[pos], 0, (SHA256_BLOCK_SIZE - 4 * 2) - pos);
|
||||||
/*
|
|
||||||
if (pos & 3)
|
|
||||||
{
|
{
|
||||||
p->buffer[pos] = 0;
|
const UInt64 numBits = p->v.vars.count << 3;
|
||||||
p->buffer[pos + 1] = 0;
|
SetBe32(p->buffer + SHA256_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32))
|
||||||
p->buffer[pos + 2] = 0;
|
SetBe32(p->buffer + SHA256_BLOCK_SIZE - 4 * 1, (UInt32)(numBits))
|
||||||
pos += 3;
|
|
||||||
pos &= ~3;
|
|
||||||
}
|
}
|
||||||
{
|
|
||||||
for (; pos < 64 - 8; pos += 4)
|
|
||||||
*(UInt32 *)(&p->buffer[pos]) = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
memset(&p->buffer[pos], 0, (64 - 8) - pos);
|
|
||||||
|
|
||||||
{
|
|
||||||
UInt64 numBits = (p->count << 3);
|
|
||||||
SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32))
|
|
||||||
SetBe32(p->buffer + 64 - 4, (UInt32)(numBits))
|
|
||||||
}
|
|
||||||
|
|
||||||
Sha256_UpdateBlock(p);
|
Sha256_UpdateBlock(p);
|
||||||
|
#if 1 && defined(MY_CPU_BE)
|
||||||
|
memcpy(digest, p->state, SHA256_DIGEST_SIZE);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
for (i = 0; i < 8; i += 2)
|
for (i = 0; i < 8; i += 2)
|
||||||
{
|
{
|
||||||
UInt32 v0 = p->state[i];
|
const UInt32 v0 = p->state[i];
|
||||||
UInt32 v1 = p->state[(size_t)i + 1];
|
const UInt32 v1 = p->state[(size_t)i + 1];
|
||||||
SetBe32(digest , v0)
|
SetBe32(digest , v0)
|
||||||
SetBe32(digest + 4, v1)
|
SetBe32(digest + 4, v1)
|
||||||
digest += 8;
|
digest += 4 * 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
Sha256_InitState(p);
|
Sha256_InitState(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -466,12 +445,9 @@ void Sha256Prepare(void)
|
||||||
f = Sha256_UpdateBlocks;
|
f = Sha256_UpdateBlocks;
|
||||||
f_hw = NULL;
|
f_hw = NULL;
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#ifndef USE_MY_MM
|
|
||||||
if (CPU_IsSupported_SHA()
|
if (CPU_IsSupported_SHA()
|
||||||
&& CPU_IsSupported_SSSE3()
|
&& CPU_IsSupported_SSSE3()
|
||||||
// && CPU_IsSupported_SSE41()
|
|
||||||
)
|
)
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
if (CPU_IsSupported_SHA2())
|
if (CPU_IsSupported_SHA2())
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -484,6 +460,8 @@ void Sha256Prepare(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef U64C
|
||||||
|
#undef K
|
||||||
#undef S0
|
#undef S0
|
||||||
#undef S1
|
#undef S1
|
||||||
#undef s0
|
#undef s0
|
||||||
|
|
|
||||||
14
C/Sha256.h
14
C/Sha256.h
|
|
@ -1,5 +1,5 @@
|
||||||
/* Sha256.h -- SHA-256 Hash
|
/* Sha256.h -- SHA-256 Hash
|
||||||
2023-04-02 : Igor Pavlov : Public domain */
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_SHA256_H
|
#ifndef ZIP7_INC_SHA256_H
|
||||||
#define ZIP7_INC_SHA256_H
|
#define ZIP7_INC_SHA256_H
|
||||||
|
|
@ -14,6 +14,9 @@ EXTERN_C_BEGIN
|
||||||
#define SHA256_BLOCK_SIZE (SHA256_NUM_BLOCK_WORDS * 4)
|
#define SHA256_BLOCK_SIZE (SHA256_NUM_BLOCK_WORDS * 4)
|
||||||
#define SHA256_DIGEST_SIZE (SHA256_NUM_DIGEST_WORDS * 4)
|
#define SHA256_DIGEST_SIZE (SHA256_NUM_DIGEST_WORDS * 4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (Z7_FASTCALL *SHA256_FUNC_UPDATE_BLOCKS)(UInt32 state[8], const Byte *data, size_t numBlocks);
|
typedef void (Z7_FASTCALL *SHA256_FUNC_UPDATE_BLOCKS)(UInt32 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -31,10 +34,17 @@ typedef void (Z7_FASTCALL *SHA256_FUNC_UPDATE_BLOCKS)(UInt32 state[8], const Byt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
SHA256_FUNC_UPDATE_BLOCKS func_UpdateBlocks;
|
SHA256_FUNC_UPDATE_BLOCKS func_UpdateBlocks;
|
||||||
UInt64 count;
|
UInt64 count;
|
||||||
UInt64 _pad_2[2];
|
} vars;
|
||||||
|
UInt64 _pad_64bit[4];
|
||||||
|
void *_pad_align_ptr[2];
|
||||||
|
} v;
|
||||||
UInt32 state[SHA256_NUM_DIGEST_WORDS];
|
UInt32 state[SHA256_NUM_DIGEST_WORDS];
|
||||||
|
|
||||||
Byte buffer[SHA256_BLOCK_SIZE];
|
Byte buffer[SHA256_BLOCK_SIZE];
|
||||||
|
|
|
||||||
164
C/Sha256Opt.c
164
C/Sha256Opt.c
|
|
@ -1,18 +1,11 @@
|
||||||
/* Sha256Opt.c -- SHA-256 optimized code for SHA-256 hardware instructions
|
/* Sha256Opt.c -- SHA-256 optimized code for SHA-256 hardware instructions
|
||||||
2024-03-01 : Igor Pavlov : Public domain */
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#if (_MSC_VER < 1900) && (_MSC_VER >= 1200)
|
|
||||||
// #define USE_MY_MM
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// #define Z7_USE_HW_SHA_STUB // for debug
|
// #define Z7_USE_HW_SHA_STUB // for debug
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check
|
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check
|
||||||
#define USE_HW_SHA
|
#define USE_HW_SHA
|
||||||
|
|
@ -20,19 +13,14 @@
|
||||||
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \
|
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \
|
||||||
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900)
|
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900)
|
||||||
#define USE_HW_SHA
|
#define USE_HW_SHA
|
||||||
#if !defined(_INTEL_COMPILER)
|
#if !defined(__INTEL_COMPILER)
|
||||||
// icc defines __GNUC__, but icc doesn't support __attribute__(__target__)
|
// icc defines __GNUC__, but icc doesn't support __attribute__(__target__)
|
||||||
#if !defined(__SHA__) || !defined(__SSSE3__)
|
#if !defined(__SHA__) || !defined(__SSSE3__)
|
||||||
#define ATTRIB_SHA __attribute__((__target__("sha,ssse3")))
|
#define ATTRIB_SHA __attribute__((__target__("sha,ssse3")))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#ifdef USE_MY_MM
|
#if (_MSC_VER >= 1900)
|
||||||
#define USE_VER_MIN 1300
|
|
||||||
#else
|
|
||||||
#define USE_VER_MIN 1900
|
|
||||||
#endif
|
|
||||||
#if (_MSC_VER >= USE_VER_MIN)
|
|
||||||
#define USE_HW_SHA
|
#define USE_HW_SHA
|
||||||
#else
|
#else
|
||||||
#define Z7_USE_HW_SHA_STUB
|
#define Z7_USE_HW_SHA_STUB
|
||||||
|
|
@ -47,23 +35,20 @@
|
||||||
|
|
||||||
// #pragma message("Sha256 HW")
|
// #pragma message("Sha256 HW")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// sse/sse2/ssse3:
|
// sse/sse2/ssse3:
|
||||||
#include <tmmintrin.h>
|
#include <tmmintrin.h>
|
||||||
// sha*:
|
// sha*:
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
|
||||||
#if defined (__clang__) && defined(_MSC_VER)
|
#if defined (__clang__) && defined(_MSC_VER)
|
||||||
// #if !defined(__SSSE3__)
|
|
||||||
// #endif
|
|
||||||
#if !defined(__SHA__)
|
#if !defined(__SHA__)
|
||||||
#include <shaintrin.h>
|
#include <shaintrin.h>
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef USE_MY_MM
|
|
||||||
#include "My_mm.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -91,54 +76,38 @@ SHA:
|
||||||
extern
|
extern
|
||||||
MY_ALIGN(64)
|
MY_ALIGN(64)
|
||||||
const UInt32 SHA256_K_ARRAY[64];
|
const UInt32 SHA256_K_ARRAY[64];
|
||||||
|
|
||||||
#define K SHA256_K_ARRAY
|
#define K SHA256_K_ARRAY
|
||||||
|
|
||||||
|
|
||||||
#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src);
|
#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src);
|
||||||
#define SHA256_MSG1(dest, src) dest = _mm_sha256msg1_epu32(dest, src);
|
#define SHA256_MSG1(dest, src) dest = _mm_sha256msg1_epu32(dest, src);
|
||||||
#define SHA25G_MSG2(dest, src) dest = _mm_sha256msg2_epu32(dest, src);
|
#define SHA256_MSG2(dest, src) dest = _mm_sha256msg2_epu32(dest, src);
|
||||||
|
|
||||||
|
|
||||||
#define LOAD_SHUFFLE(m, k) \
|
#define LOAD_SHUFFLE(m, k) \
|
||||||
m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \
|
m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \
|
||||||
m = _mm_shuffle_epi8(m, mask); \
|
m = _mm_shuffle_epi8(m, mask); \
|
||||||
|
|
||||||
#define SM1(g0, g1, g2, g3) \
|
#define NNN(m0, m1, m2, m3)
|
||||||
SHA256_MSG1(g3, g0); \
|
|
||||||
|
|
||||||
#define SM2(g0, g1, g2, g3) \
|
#define SM1(m1, m2, m3, m0) \
|
||||||
tmp = _mm_alignr_epi8(g1, g0, 4); \
|
SHA256_MSG1(m0, m1); \
|
||||||
ADD_EPI32(g2, tmp) \
|
|
||||||
SHA25G_MSG2(g2, g1); \
|
|
||||||
|
|
||||||
// #define LS0(k, g0, g1, g2, g3) LOAD_SHUFFLE(g0, k)
|
|
||||||
// #define LS1(k, g0, g1, g2, g3) LOAD_SHUFFLE(g1, k+1)
|
|
||||||
|
|
||||||
|
|
||||||
#define NNN(g0, g1, g2, g3)
|
|
||||||
|
|
||||||
|
#define SM2(m2, m3, m0, m1) \
|
||||||
|
ADD_EPI32(m0, _mm_alignr_epi8(m3, m2, 4)) \
|
||||||
|
SHA256_MSG2(m0, m3); \
|
||||||
|
|
||||||
#define RND2(t0, t1) \
|
#define RND2(t0, t1) \
|
||||||
t0 = _mm_sha256rnds2_epu32(t0, t1, msg);
|
t0 = _mm_sha256rnds2_epu32(t0, t1, msg);
|
||||||
|
|
||||||
#define RND2_0(m, k) \
|
|
||||||
msg = _mm_add_epi32(m, *(const __m128i *) (const void *) &K[(k) * 4]); \
|
|
||||||
|
#define R4(k, m0, m1, m2, m3, OP0, OP1) \
|
||||||
|
msg = _mm_add_epi32(m0, *(const __m128i *) (const void *) &K[(k) * 4]); \
|
||||||
RND2(state0, state1); \
|
RND2(state0, state1); \
|
||||||
msg = _mm_shuffle_epi32(msg, 0x0E); \
|
msg = _mm_shuffle_epi32(msg, 0x0E); \
|
||||||
|
OP0(m0, m1, m2, m3) \
|
||||||
|
|
||||||
#define RND2_1 \
|
|
||||||
RND2(state1, state0); \
|
RND2(state1, state0); \
|
||||||
|
OP1(m0, m1, m2, m3) \
|
||||||
|
|
||||||
// We use scheme with 3 rounds ahead for SHA256_MSG1 / 2 rounds ahead for SHA256_MSG2
|
|
||||||
|
|
||||||
#define R4(k, g0, g1, g2, g3, OP0, OP1) \
|
|
||||||
RND2_0(g0, k) \
|
|
||||||
OP0(g0, g1, g2, g3) \
|
|
||||||
RND2_1 \
|
|
||||||
OP1(g0, g1, g2, g3) \
|
|
||||||
|
|
||||||
#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \
|
#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \
|
||||||
R4 ( (k)*4+0, m0,m1,m2,m3, OP0, OP1 ) \
|
R4 ( (k)*4+0, m0,m1,m2,m3, OP0, OP1 ) \
|
||||||
|
|
@ -161,8 +130,9 @@ ATTRIB_SHA
|
||||||
void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks)
|
void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks)
|
||||||
{
|
{
|
||||||
const __m128i mask = _mm_set_epi32(0x0c0d0e0f, 0x08090a0b, 0x04050607, 0x00010203);
|
const __m128i mask = _mm_set_epi32(0x0c0d0e0f, 0x08090a0b, 0x04050607, 0x00010203);
|
||||||
__m128i tmp;
|
|
||||||
__m128i state0, state1;
|
|
||||||
|
__m128i tmp, state0, state1;
|
||||||
|
|
||||||
if (numBlocks == 0)
|
if (numBlocks == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -262,22 +232,10 @@ void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_
|
||||||
#define _ARM_USE_NEW_NEON_INTRINSICS
|
#define _ARM_USE_NEW_NEON_INTRINSICS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64)
|
#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64)
|
||||||
#include <arm64_neon.h>
|
#include <arm64_neon.h>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__clang__) && __clang_major__ < 16
|
#if defined(__clang__) && __clang_major__ < 16
|
||||||
#if !defined(__ARM_FEATURE_SHA2) && \
|
#if !defined(__ARM_FEATURE_SHA2) && \
|
||||||
!defined(__ARM_FEATURE_CRYPTO)
|
!defined(__ARM_FEATURE_CRYPTO)
|
||||||
|
|
@ -324,41 +282,70 @@ typedef uint32x4_t v128;
|
||||||
// typedef __n128 v128; // MSVC
|
// typedef __n128 v128; // MSVC
|
||||||
|
|
||||||
#ifdef MY_CPU_BE
|
#ifdef MY_CPU_BE
|
||||||
#define MY_rev32_for_LE(x)
|
#define MY_rev32_for_LE(x) x
|
||||||
#else
|
#else
|
||||||
#define MY_rev32_for_LE(x) x = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(x)))
|
#define MY_rev32_for_LE(x) vrev32q_u8(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOAD_128(_p) (*(const v128 *)(const void *)(_p))
|
#if 1 // 0 for debug
|
||||||
#define STORE_128(_p, _v) *(v128 *)(void *)(_p) = (_v)
|
// for arm32: it works slower by some reason than direct code
|
||||||
|
/*
|
||||||
|
for arm32 it generates:
|
||||||
|
MSVC-2022, GCC-9:
|
||||||
|
vld1.32 {d18,d19}, [r10]
|
||||||
|
vst1.32 {d4,d5}, [r3]
|
||||||
|
vld1.8 {d20-d21}, [r4]
|
||||||
|
there is no align hint (like [r10:128]). So instruction allows unaligned access
|
||||||
|
*/
|
||||||
|
#define LOAD_128_32(_p) vld1q_u32(_p)
|
||||||
|
#define LOAD_128_8(_p) vld1q_u8 (_p)
|
||||||
|
#define STORE_128_32(_p, _v) vst1q_u32(_p, _v)
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
for arm32:
|
||||||
|
MSVC-2022:
|
||||||
|
vldm r10,{d18,d19}
|
||||||
|
vstm r3,{d4,d5}
|
||||||
|
does it require strict alignment?
|
||||||
|
GCC-9:
|
||||||
|
vld1.64 {d30-d31}, [r0:64]
|
||||||
|
vldr d28, [r0, #16]
|
||||||
|
vldr d29, [r0, #24]
|
||||||
|
vst1.64 {d30-d31}, [r0:64]
|
||||||
|
vstr d28, [r0, #16]
|
||||||
|
vstr d29, [r0, #24]
|
||||||
|
there is hint [r0:64], so does it requires 64-bit alignment.
|
||||||
|
*/
|
||||||
|
#define LOAD_128_32(_p) (*(const v128 *)(const void *)(_p))
|
||||||
|
#define LOAD_128_8(_p) vreinterpretq_u8_u32(*(const v128 *)(const void *)(_p))
|
||||||
|
#define STORE_128_32(_p, _v) *(v128 *)(void *)(_p) = (_v)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define LOAD_SHUFFLE(m, k) \
|
#define LOAD_SHUFFLE(m, k) \
|
||||||
m = LOAD_128((data + (k) * 16)); \
|
m = vreinterpretq_u32_u8( \
|
||||||
MY_rev32_for_LE(m); \
|
MY_rev32_for_LE( \
|
||||||
|
LOAD_128_8(data + (k) * 16))); \
|
||||||
|
|
||||||
// K array must be aligned for 16-bytes at least.
|
// K array must be aligned for 16-bytes at least.
|
||||||
extern
|
extern
|
||||||
MY_ALIGN(64)
|
MY_ALIGN(64)
|
||||||
const UInt32 SHA256_K_ARRAY[64];
|
const UInt32 SHA256_K_ARRAY[64];
|
||||||
|
|
||||||
#define K SHA256_K_ARRAY
|
#define K SHA256_K_ARRAY
|
||||||
|
|
||||||
|
|
||||||
#define SHA256_SU0(dest, src) dest = vsha256su0q_u32(dest, src);
|
#define SHA256_SU0(dest, src) dest = vsha256su0q_u32(dest, src);
|
||||||
#define SHA25G_SU1(dest, src2, src3) dest = vsha256su1q_u32(dest, src2, src3);
|
#define SHA256_SU1(dest, src2, src3) dest = vsha256su1q_u32(dest, src2, src3);
|
||||||
|
|
||||||
#define SM1(g0, g1, g2, g3) SHA256_SU0(g3, g0)
|
#define SM1(m0, m1, m2, m3) SHA256_SU0(m3, m0)
|
||||||
#define SM2(g0, g1, g2, g3) SHA25G_SU1(g2, g0, g1)
|
#define SM2(m0, m1, m2, m3) SHA256_SU1(m2, m0, m1)
|
||||||
#define NNN(g0, g1, g2, g3)
|
#define NNN(m0, m1, m2, m3)
|
||||||
|
|
||||||
|
#define R4(k, m0, m1, m2, m3, OP0, OP1) \
|
||||||
#define R4(k, g0, g1, g2, g3, OP0, OP1) \
|
msg = vaddq_u32(m0, *(const v128 *) (const void *) &K[(k) * 4]); \
|
||||||
msg = vaddq_u32(g0, *(const v128 *) (const void *) &K[(k) * 4]); \
|
|
||||||
tmp = state0; \
|
tmp = state0; \
|
||||||
state0 = vsha256hq_u32( state0, state1, msg ); \
|
state0 = vsha256hq_u32( state0, state1, msg ); \
|
||||||
state1 = vsha256h2q_u32( state1, tmp, msg ); \
|
state1 = vsha256h2q_u32( state1, tmp, msg ); \
|
||||||
OP0(g0, g1, g2, g3); \
|
OP0(m0, m1, m2, m3); \
|
||||||
OP1(g0, g1, g2, g3); \
|
OP1(m0, m1, m2, m3); \
|
||||||
|
|
||||||
|
|
||||||
#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \
|
#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \
|
||||||
|
|
@ -379,8 +366,8 @@ void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_
|
||||||
if (numBlocks == 0)
|
if (numBlocks == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
state0 = LOAD_128(&state[0]);
|
state0 = LOAD_128_32(&state[0]);
|
||||||
state1 = LOAD_128(&state[4]);
|
state1 = LOAD_128_32(&state[4]);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
@ -408,8 +395,8 @@ void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_
|
||||||
}
|
}
|
||||||
while (--numBlocks);
|
while (--numBlocks);
|
||||||
|
|
||||||
STORE_128(&state[0], state0);
|
STORE_128_32(&state[0], state0);
|
||||||
STORE_128(&state[4], state1);
|
STORE_128_32(&state[4], state1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_HW_SHA
|
#endif // USE_HW_SHA
|
||||||
|
|
@ -443,13 +430,10 @@ void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef K
|
#undef K
|
||||||
#undef RND2
|
#undef RND2
|
||||||
#undef RND2_0
|
|
||||||
#undef RND2_1
|
|
||||||
|
|
||||||
#undef MY_rev32_for_LE
|
#undef MY_rev32_for_LE
|
||||||
|
|
||||||
#undef NNN
|
#undef NNN
|
||||||
#undef LOAD_128
|
#undef LOAD_128
|
||||||
#undef STORE_128
|
#undef STORE_128
|
||||||
|
|
@ -457,7 +441,7 @@ void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_
|
||||||
#undef SM1
|
#undef SM1
|
||||||
#undef SM2
|
#undef SM2
|
||||||
|
|
||||||
#undef NNN
|
|
||||||
#undef R4
|
#undef R4
|
||||||
#undef R16
|
#undef R16
|
||||||
#undef PREPARE_STATE
|
#undef PREPARE_STATE
|
||||||
|
|
|
||||||
359
C/Sha3.c
Normal file
359
C/Sha3.c
Normal file
|
|
@ -0,0 +1,359 @@
|
||||||
|
/* Sha3.c -- SHA-3 Hash
|
||||||
|
: Igor Pavlov : Public domain
|
||||||
|
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Sha3.h"
|
||||||
|
#include "RotateDefs.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
#define U64C(x) UINT64_CONST(x)
|
||||||
|
|
||||||
|
static
|
||||||
|
MY_ALIGN(64)
|
||||||
|
const UInt64 SHA3_K_ARRAY[24] =
|
||||||
|
{
|
||||||
|
U64C(0x0000000000000001), U64C(0x0000000000008082),
|
||||||
|
U64C(0x800000000000808a), U64C(0x8000000080008000),
|
||||||
|
U64C(0x000000000000808b), U64C(0x0000000080000001),
|
||||||
|
U64C(0x8000000080008081), U64C(0x8000000000008009),
|
||||||
|
U64C(0x000000000000008a), U64C(0x0000000000000088),
|
||||||
|
U64C(0x0000000080008009), U64C(0x000000008000000a),
|
||||||
|
U64C(0x000000008000808b), U64C(0x800000000000008b),
|
||||||
|
U64C(0x8000000000008089), U64C(0x8000000000008003),
|
||||||
|
U64C(0x8000000000008002), U64C(0x8000000000000080),
|
||||||
|
U64C(0x000000000000800a), U64C(0x800000008000000a),
|
||||||
|
U64C(0x8000000080008081), U64C(0x8000000000008080),
|
||||||
|
U64C(0x0000000080000001), U64C(0x8000000080008008)
|
||||||
|
};
|
||||||
|
|
||||||
|
void Sha3_Init(CSha3 *p)
|
||||||
|
{
|
||||||
|
p->count = 0;
|
||||||
|
memset(p->state, 0, sizeof(p->state));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_state(i, a) UInt64 a = state[i];
|
||||||
|
#define SET_state(i, a) state[i] = a;
|
||||||
|
|
||||||
|
#define LS_5(M, i, a0,a1,a2,a3,a4) \
|
||||||
|
M ((i) * 5 , a0) \
|
||||||
|
M ((i) * 5 + 1, a1) \
|
||||||
|
M ((i) * 5 + 2, a2) \
|
||||||
|
M ((i) * 5 + 3, a3) \
|
||||||
|
M ((i) * 5 + 4, a4) \
|
||||||
|
|
||||||
|
#define LS_25(M) \
|
||||||
|
LS_5 (M, 0, a50, a51, a52, a53, a54) \
|
||||||
|
LS_5 (M, 1, a60, a61, a62, a63, a64) \
|
||||||
|
LS_5 (M, 2, a70, a71, a72, a73, a74) \
|
||||||
|
LS_5 (M, 3, a80, a81, a82, a83, a84) \
|
||||||
|
LS_5 (M, 4, a90, a91, a92, a93, a94) \
|
||||||
|
|
||||||
|
|
||||||
|
#define XOR_1(i, a0) \
|
||||||
|
a0 ^= GetUi64(data + (i) * 8); \
|
||||||
|
|
||||||
|
#define XOR_4(i, a0,a1,a2,a3) \
|
||||||
|
XOR_1 ((i) , a0); \
|
||||||
|
XOR_1 ((i) + 1, a1); \
|
||||||
|
XOR_1 ((i) + 2, a2); \
|
||||||
|
XOR_1 ((i) + 3, a3); \
|
||||||
|
|
||||||
|
#define D(d,b1,b2) \
|
||||||
|
d = b1 ^ Z7_ROTL64(b2, 1);
|
||||||
|
|
||||||
|
#define D5 \
|
||||||
|
D (d0, c4, c1) \
|
||||||
|
D (d1, c0, c2) \
|
||||||
|
D (d2, c1, c3) \
|
||||||
|
D (d3, c2, c4) \
|
||||||
|
D (d4, c3, c0) \
|
||||||
|
|
||||||
|
#define C0(c,a,d) \
|
||||||
|
c = a ^ d; \
|
||||||
|
|
||||||
|
#define C(c,a,d,k) \
|
||||||
|
c = a ^ d; \
|
||||||
|
c = Z7_ROTL64(c, k); \
|
||||||
|
|
||||||
|
#define E4(e1,e2,e3,e4) \
|
||||||
|
e1 = c1 ^ (~c2 & c3); \
|
||||||
|
e2 = c2 ^ (~c3 & c4); \
|
||||||
|
e3 = c3 ^ (~c4 & c0); \
|
||||||
|
e4 = c4 ^ (~c0 & c1); \
|
||||||
|
|
||||||
|
#define CK( v0,w0, \
|
||||||
|
v1,w1,k1, \
|
||||||
|
v2,w2,k2, \
|
||||||
|
v3,w3,k3, \
|
||||||
|
v4,w4,k4, e0,e1,e2,e3,e4, keccak_c) \
|
||||||
|
C0(c0,v0,w0) \
|
||||||
|
C (c1,v1,w1,k1) \
|
||||||
|
C (c2,v2,w2,k2) \
|
||||||
|
C (c3,v3,w3,k3) \
|
||||||
|
C (c4,v4,w4,k4) \
|
||||||
|
e0 = c0 ^ (~c1 & c2) ^ keccak_c; \
|
||||||
|
E4(e1,e2,e3,e4) \
|
||||||
|
|
||||||
|
#define CE( v0,w0,k0, \
|
||||||
|
v1,w1,k1, \
|
||||||
|
v2,w2,k2, \
|
||||||
|
v3,w3,k3, \
|
||||||
|
v4,w4,k4, e0,e1,e2,e3,e4) \
|
||||||
|
C (c0,v0,w0,k0) \
|
||||||
|
C (c1,v1,w1,k1) \
|
||||||
|
C (c2,v2,w2,k2) \
|
||||||
|
C (c3,v3,w3,k3) \
|
||||||
|
C (c4,v4,w4,k4) \
|
||||||
|
e0 = c0 ^ (~c1 & c2); \
|
||||||
|
E4(e1,e2,e3,e4) \
|
||||||
|
|
||||||
|
// numBlocks != 0
|
||||||
|
static
|
||||||
|
Z7_NO_INLINE
|
||||||
|
void Z7_FASTCALL Sha3_UpdateBlocks(UInt64 state[SHA3_NUM_STATE_WORDS],
|
||||||
|
const Byte *data, size_t numBlocks, size_t blockSize)
|
||||||
|
{
|
||||||
|
LS_25 (GET_state)
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned round;
|
||||||
|
XOR_4 ( 0, a50, a51, a52, a53)
|
||||||
|
XOR_4 ( 4, a54, a60, a61, a62)
|
||||||
|
XOR_1 ( 8, a63)
|
||||||
|
if (blockSize > 8 * 9) { XOR_4 ( 9, a64, a70, a71, a72) // sha3-384
|
||||||
|
if (blockSize > 8 * 13) { XOR_4 (13, a73, a74, a80, a81) // sha3-256
|
||||||
|
if (blockSize > 8 * 17) { XOR_1 (17, a82) // sha3-224
|
||||||
|
if (blockSize > 8 * 18) { XOR_1 (18, a83) // shake128
|
||||||
|
XOR_1 (19, a84)
|
||||||
|
XOR_1 (20, a90) }}}}
|
||||||
|
data += blockSize;
|
||||||
|
|
||||||
|
for (round = 0; round < 24; round += 2)
|
||||||
|
{
|
||||||
|
UInt64 c0, c1, c2, c3, c4;
|
||||||
|
UInt64 d0, d1, d2, d3, d4;
|
||||||
|
UInt64 e50, e51, e52, e53, e54;
|
||||||
|
UInt64 e60, e61, e62, e63, e64;
|
||||||
|
UInt64 e70, e71, e72, e73, e74;
|
||||||
|
UInt64 e80, e81, e82, e83, e84;
|
||||||
|
UInt64 e90, e91, e92, e93, e94;
|
||||||
|
|
||||||
|
c0 = a50^a60^a70^a80^a90;
|
||||||
|
c1 = a51^a61^a71^a81^a91;
|
||||||
|
c2 = a52^a62^a72^a82^a92;
|
||||||
|
c3 = a53^a63^a73^a83^a93;
|
||||||
|
c4 = a54^a64^a74^a84^a94;
|
||||||
|
D5
|
||||||
|
CK( a50, d0,
|
||||||
|
a61, d1, 44,
|
||||||
|
a72, d2, 43,
|
||||||
|
a83, d3, 21,
|
||||||
|
a94, d4, 14, e50, e51, e52, e53, e54, SHA3_K_ARRAY[round])
|
||||||
|
CE( a53, d3, 28,
|
||||||
|
a64, d4, 20,
|
||||||
|
a70, d0, 3,
|
||||||
|
a81, d1, 45,
|
||||||
|
a92, d2, 61, e60, e61, e62, e63, e64)
|
||||||
|
CE( a51, d1, 1,
|
||||||
|
a62, d2, 6,
|
||||||
|
a73, d3, 25,
|
||||||
|
a84, d4, 8,
|
||||||
|
a90, d0, 18, e70, e71, e72, e73, e74)
|
||||||
|
CE( a54, d4, 27,
|
||||||
|
a60, d0, 36,
|
||||||
|
a71, d1, 10,
|
||||||
|
a82, d2, 15,
|
||||||
|
a93, d3, 56, e80, e81, e82, e83, e84)
|
||||||
|
CE( a52, d2, 62,
|
||||||
|
a63, d3, 55,
|
||||||
|
a74, d4, 39,
|
||||||
|
a80, d0, 41,
|
||||||
|
a91, d1, 2, e90, e91, e92, e93, e94)
|
||||||
|
|
||||||
|
// ---------- ROUND + 1 ----------
|
||||||
|
|
||||||
|
c0 = e50^e60^e70^e80^e90;
|
||||||
|
c1 = e51^e61^e71^e81^e91;
|
||||||
|
c2 = e52^e62^e72^e82^e92;
|
||||||
|
c3 = e53^e63^e73^e83^e93;
|
||||||
|
c4 = e54^e64^e74^e84^e94;
|
||||||
|
D5
|
||||||
|
CK( e50, d0,
|
||||||
|
e61, d1, 44,
|
||||||
|
e72, d2, 43,
|
||||||
|
e83, d3, 21,
|
||||||
|
e94, d4, 14, a50, a51, a52, a53, a54, SHA3_K_ARRAY[(size_t)round + 1])
|
||||||
|
CE( e53, d3, 28,
|
||||||
|
e64, d4, 20,
|
||||||
|
e70, d0, 3,
|
||||||
|
e81, d1, 45,
|
||||||
|
e92, d2, 61, a60, a61, a62, a63, a64)
|
||||||
|
CE( e51, d1, 1,
|
||||||
|
e62, d2, 6,
|
||||||
|
e73, d3, 25,
|
||||||
|
e84, d4, 8,
|
||||||
|
e90, d0, 18, a70, a71, a72, a73, a74)
|
||||||
|
CE (e54, d4, 27,
|
||||||
|
e60, d0, 36,
|
||||||
|
e71, d1, 10,
|
||||||
|
e82, d2, 15,
|
||||||
|
e93, d3, 56, a80, a81, a82, a83, a84)
|
||||||
|
CE (e52, d2, 62,
|
||||||
|
e63, d3, 55,
|
||||||
|
e74, d4, 39,
|
||||||
|
e80, d0, 41,
|
||||||
|
e91, d1, 2, a90, a91, a92, a93, a94)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (--numBlocks);
|
||||||
|
|
||||||
|
LS_25 (SET_state)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define Sha3_UpdateBlock(p) \
|
||||||
|
Sha3_UpdateBlocks(p->state, p->buffer, 1, p->blockSize)
|
||||||
|
|
||||||
|
void Sha3_Update(CSha3 *p, const Byte *data, size_t size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
unsigned cur = p->blockSize - p->count;
|
||||||
|
if (cur > size)
|
||||||
|
cur = (unsigned)size;
|
||||||
|
size -= cur;
|
||||||
|
unsigned pos = p->count;
|
||||||
|
p->count = pos + cur;
|
||||||
|
while (pos & 7)
|
||||||
|
{
|
||||||
|
if (cur == 0)
|
||||||
|
return;
|
||||||
|
Byte *pb = &(((Byte *)p->state)[pos]);
|
||||||
|
*pb = (Byte)(*pb ^ *data++);
|
||||||
|
cur--;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
if (cur >= 8)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(UInt64 *)(void *)&(((Byte *)p->state)[pos]) ^= GetUi64(data);
|
||||||
|
data += 8;
|
||||||
|
pos += 8;
|
||||||
|
cur -= 8;
|
||||||
|
}
|
||||||
|
while (cur >= 8);
|
||||||
|
}
|
||||||
|
if (pos != p->blockSize)
|
||||||
|
{
|
||||||
|
if (cur)
|
||||||
|
{
|
||||||
|
Byte *pb = &(((Byte *)p->state)[pos]);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*pb = (Byte)(*pb ^ *data++);
|
||||||
|
pb++;
|
||||||
|
}
|
||||||
|
while (--cur);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Sha3_UpdateBlock(p->state);
|
||||||
|
p->count = 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
{
|
||||||
|
const unsigned pos = p->count;
|
||||||
|
const unsigned num = p->blockSize - pos;
|
||||||
|
if (num > size)
|
||||||
|
{
|
||||||
|
p->count = pos + (unsigned)size;
|
||||||
|
memcpy(p->buffer + pos, data, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos != 0)
|
||||||
|
{
|
||||||
|
size -= num;
|
||||||
|
memcpy(p->buffer + pos, data, num);
|
||||||
|
data += num;
|
||||||
|
Sha3_UpdateBlock(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size >= p->blockSize)
|
||||||
|
{
|
||||||
|
const size_t numBlocks = size / p->blockSize;
|
||||||
|
const Byte *dataOld = data;
|
||||||
|
data += numBlocks * p->blockSize;
|
||||||
|
size = (size_t)(dataOld + size - data);
|
||||||
|
Sha3_UpdateBlocks(p->state, dataOld, numBlocks, p->blockSize);
|
||||||
|
}
|
||||||
|
p->count = (unsigned)size;
|
||||||
|
if (size)
|
||||||
|
memcpy(p->buffer, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// we support only (digestSize % 4 == 0) cases
|
||||||
|
void Sha3_Final(CSha3 *p, Byte *digest, unsigned digestSize, unsigned shake)
|
||||||
|
{
|
||||||
|
memset(p->buffer + p->count, 0, p->blockSize - p->count);
|
||||||
|
// we write bits markers from low to higher in current byte:
|
||||||
|
// - if sha-3 : 2 bits : 0,1
|
||||||
|
// - if shake : 4 bits : 1111
|
||||||
|
// then we write bit 1 to same byte.
|
||||||
|
// And we write bit 1 to highest bit of last byte of block.
|
||||||
|
p->buffer[p->count] = (Byte)(shake ? 0x1f : 0x06);
|
||||||
|
// we need xor operation (^= 0x80) here because we must write 0x80 bit
|
||||||
|
// to same byte as (0x1f : 0x06), if (p->count == p->blockSize - 1) !!!
|
||||||
|
p->buffer[p->blockSize - 1] ^= 0x80;
|
||||||
|
/*
|
||||||
|
((Byte *)p->state)[p->count] ^= (Byte)(shake ? 0x1f : 0x06);
|
||||||
|
((Byte *)p->state)[p->blockSize - 1] ^= 0x80;
|
||||||
|
*/
|
||||||
|
Sha3_UpdateBlock(p);
|
||||||
|
#if 1 && defined(MY_CPU_LE)
|
||||||
|
memcpy(digest, p->state, digestSize);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
const unsigned numWords = digestSize >> 3;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < numWords; i++)
|
||||||
|
{
|
||||||
|
const UInt64 v = p->state[i];
|
||||||
|
SetUi64(digest, v)
|
||||||
|
digest += 8;
|
||||||
|
}
|
||||||
|
if (digestSize & 4) // for SHA3-224
|
||||||
|
{
|
||||||
|
const UInt32 v = (UInt32)p->state[numWords];
|
||||||
|
SetUi32(digest, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Sha3_Init(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef GET_state
|
||||||
|
#undef SET_state
|
||||||
|
#undef LS_5
|
||||||
|
#undef LS_25
|
||||||
|
#undef XOR_1
|
||||||
|
#undef XOR_4
|
||||||
|
#undef D
|
||||||
|
#undef D5
|
||||||
|
#undef C0
|
||||||
|
#undef C
|
||||||
|
#undef E4
|
||||||
|
#undef CK
|
||||||
|
#undef CE
|
||||||
36
C/Sha3.h
Normal file
36
C/Sha3.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* Sha3.h -- SHA-3 Hash
|
||||||
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef ZIP7_INC_MD5_H
|
||||||
|
#define ZIP7_INC_MD5_H
|
||||||
|
|
||||||
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define SHA3_NUM_STATE_WORDS 25
|
||||||
|
|
||||||
|
#define SHA3_BLOCK_SIZE_FROM_DIGEST_SIZE(digestSize) \
|
||||||
|
(SHA3_NUM_STATE_WORDS * 8 - (digestSize) * 2)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 count; // < blockSize
|
||||||
|
UInt32 blockSize; // <= SHA3_NUM_STATE_WORDS * 8
|
||||||
|
UInt64 _pad1[3];
|
||||||
|
// we want 32-bytes alignment here
|
||||||
|
UInt64 state[SHA3_NUM_STATE_WORDS];
|
||||||
|
UInt64 _pad2[3];
|
||||||
|
// we want 64-bytes alignment here
|
||||||
|
Byte buffer[SHA3_NUM_STATE_WORDS * 8]; // last bytes will be unused with predefined blockSize values
|
||||||
|
} CSha3;
|
||||||
|
|
||||||
|
#define Sha3_SET_blockSize(p, blockSize) { (p)->blockSize = (blockSize); }
|
||||||
|
|
||||||
|
void Sha3_Init(CSha3 *p);
|
||||||
|
void Sha3_Update(CSha3 *p, const Byte *data, size_t size);
|
||||||
|
void Sha3_Final(CSha3 *p, Byte *digest, unsigned digestSize, unsigned shake);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
618
C/Sha512.c
Normal file
618
C/Sha512.c
Normal file
|
|
@ -0,0 +1,618 @@
|
||||||
|
/* Sha512.c -- SHA-512 Hash
|
||||||
|
: Igor Pavlov : Public domain
|
||||||
|
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Sha512.h"
|
||||||
|
#include "RotateDefs.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
#if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 170001) \
|
||||||
|
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 170001) \
|
||||||
|
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 140000) \
|
||||||
|
|| defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 2400) && (__INTEL_COMPILER <= 9900) \
|
||||||
|
|| defined(_MSC_VER) && (_MSC_VER >= 1940)
|
||||||
|
#define Z7_COMPILER_SHA512_SUPPORTED
|
||||||
|
#endif
|
||||||
|
#elif defined(MY_CPU_ARM64) && defined(MY_CPU_LE)
|
||||||
|
#if defined(__ARM_FEATURE_SHA512)
|
||||||
|
#define Z7_COMPILER_SHA512_SUPPORTED
|
||||||
|
#else
|
||||||
|
#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 130000) \
|
||||||
|
|| defined(__GNUC__) && (__GNUC__ >= 9) \
|
||||||
|
) \
|
||||||
|
|| defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1940) // fix it
|
||||||
|
#define Z7_COMPILER_SHA512_SUPPORTED
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
|
||||||
|
#ifdef Z7_COMPILER_SHA512_SUPPORTED
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
|
||||||
|
static SHA512_FUNC_UPDATE_BLOCKS g_SHA512_FUNC_UPDATE_BLOCKS = Sha512_UpdateBlocks;
|
||||||
|
static SHA512_FUNC_UPDATE_BLOCKS g_SHA512_FUNC_UPDATE_BLOCKS_HW;
|
||||||
|
|
||||||
|
#define SHA512_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks
|
||||||
|
#else
|
||||||
|
#define SHA512_UPDATE_BLOCKS(p) Sha512_UpdateBlocks
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
BoolInt Sha512_SetFunction(CSha512 *p, unsigned algo)
|
||||||
|
{
|
||||||
|
SHA512_FUNC_UPDATE_BLOCKS func = Sha512_UpdateBlocks;
|
||||||
|
|
||||||
|
#ifdef Z7_COMPILER_SHA512_SUPPORTED
|
||||||
|
if (algo != SHA512_ALGO_SW)
|
||||||
|
{
|
||||||
|
if (algo == SHA512_ALGO_DEFAULT)
|
||||||
|
func = g_SHA512_FUNC_UPDATE_BLOCKS;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (algo != SHA512_ALGO_HW)
|
||||||
|
return False;
|
||||||
|
func = g_SHA512_FUNC_UPDATE_BLOCKS_HW;
|
||||||
|
if (!func)
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (algo > 1)
|
||||||
|
return False;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
p->v.vars.func_UpdateBlocks = func;
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* define it for speed optimization */
|
||||||
|
|
||||||
|
#if 0 // 1 for size optimization
|
||||||
|
#define STEP_PRE 1
|
||||||
|
#define STEP_MAIN 1
|
||||||
|
#else
|
||||||
|
#define STEP_PRE 2
|
||||||
|
#define STEP_MAIN 4
|
||||||
|
// #define Z7_SHA512_UNROLL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef Z7_SHA512_BIG_W
|
||||||
|
#if STEP_MAIN != 16
|
||||||
|
#define Z7_SHA512_BIG_W
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define U64C(x) UINT64_CONST(x)
|
||||||
|
|
||||||
|
static MY_ALIGN(64) const UInt64 SHA512_INIT_ARRAYS[4][8] = {
|
||||||
|
{ U64C(0x8c3d37c819544da2), U64C(0x73e1996689dcd4d6), U64C(0x1dfab7ae32ff9c82), U64C(0x679dd514582f9fcf),
|
||||||
|
U64C(0x0f6d2b697bd44da8), U64C(0x77e36f7304c48942), U64C(0x3f9d85a86a1d36c8), U64C(0x1112e6ad91d692a1)
|
||||||
|
},
|
||||||
|
{ U64C(0x22312194fc2bf72c), U64C(0x9f555fa3c84c64c2), U64C(0x2393b86b6f53b151), U64C(0x963877195940eabd),
|
||||||
|
U64C(0x96283ee2a88effe3), U64C(0xbe5e1e2553863992), U64C(0x2b0199fc2c85b8aa), U64C(0x0eb72ddc81c52ca2)
|
||||||
|
},
|
||||||
|
{ U64C(0xcbbb9d5dc1059ed8), U64C(0x629a292a367cd507), U64C(0x9159015a3070dd17), U64C(0x152fecd8f70e5939),
|
||||||
|
U64C(0x67332667ffc00b31), U64C(0x8eb44a8768581511), U64C(0xdb0c2e0d64f98fa7), U64C(0x47b5481dbefa4fa4)
|
||||||
|
},
|
||||||
|
{ U64C(0x6a09e667f3bcc908), U64C(0xbb67ae8584caa73b), U64C(0x3c6ef372fe94f82b), U64C(0xa54ff53a5f1d36f1),
|
||||||
|
U64C(0x510e527fade682d1), U64C(0x9b05688c2b3e6c1f), U64C(0x1f83d9abfb41bd6b), U64C(0x5be0cd19137e2179)
|
||||||
|
}};
|
||||||
|
|
||||||
|
void Sha512_InitState(CSha512 *p, unsigned digestSize)
|
||||||
|
{
|
||||||
|
p->v.vars.count = 0;
|
||||||
|
memcpy(p->state, SHA512_INIT_ARRAYS[(size_t)(digestSize >> 4) - 1], sizeof(p->state));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sha512_Init(CSha512 *p, unsigned digestSize)
|
||||||
|
{
|
||||||
|
p->v.vars.func_UpdateBlocks =
|
||||||
|
#ifdef Z7_COMPILER_SHA512_SUPPORTED
|
||||||
|
g_SHA512_FUNC_UPDATE_BLOCKS;
|
||||||
|
#else
|
||||||
|
NULL;
|
||||||
|
#endif
|
||||||
|
Sha512_InitState(p, digestSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define S0(x) (Z7_ROTR64(x,28) ^ Z7_ROTR64(x,34) ^ Z7_ROTR64(x,39))
|
||||||
|
#define S1(x) (Z7_ROTR64(x,14) ^ Z7_ROTR64(x,18) ^ Z7_ROTR64(x,41))
|
||||||
|
#define s0(x) (Z7_ROTR64(x, 1) ^ Z7_ROTR64(x, 8) ^ (x >> 7))
|
||||||
|
#define s1(x) (Z7_ROTR64(x,19) ^ Z7_ROTR64(x,61) ^ (x >> 6))
|
||||||
|
|
||||||
|
#define Ch(x,y,z) (z^(x&(y^z)))
|
||||||
|
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
|
||||||
|
|
||||||
|
|
||||||
|
#define W_PRE(i) (W[(i) + (size_t)(j)] = GetBe64(data + ((size_t)(j) + i) * 8))
|
||||||
|
|
||||||
|
#define blk2_main(j, i) s1(w(j, (i)-2)) + w(j, (i)-7) + s0(w(j, (i)-15))
|
||||||
|
|
||||||
|
#ifdef Z7_SHA512_BIG_W
|
||||||
|
// we use +i instead of +(i) to change the order to solve CLANG compiler warning for signed/unsigned.
|
||||||
|
#define w(j, i) W[(size_t)(j) + i]
|
||||||
|
#define blk2(j, i) (w(j, i) = w(j, (i)-16) + blk2_main(j, i))
|
||||||
|
#else
|
||||||
|
#if STEP_MAIN == 16
|
||||||
|
#define w(j, i) W[(i) & 15]
|
||||||
|
#else
|
||||||
|
#define w(j, i) W[((size_t)(j) + (i)) & 15]
|
||||||
|
#endif
|
||||||
|
#define blk2(j, i) (w(j, i) += blk2_main(j, i))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define W_MAIN(i) blk2(j, i)
|
||||||
|
|
||||||
|
|
||||||
|
#define T1(wx, i) \
|
||||||
|
tmp = h + S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \
|
||||||
|
h = g; \
|
||||||
|
g = f; \
|
||||||
|
f = e; \
|
||||||
|
e = d + tmp; \
|
||||||
|
tmp += S0(a) + Maj(a, b, c); \
|
||||||
|
d = c; \
|
||||||
|
c = b; \
|
||||||
|
b = a; \
|
||||||
|
a = tmp; \
|
||||||
|
|
||||||
|
#define R1_PRE(i) T1( W_PRE, i)
|
||||||
|
#define R1_MAIN(i) T1( W_MAIN, i)
|
||||||
|
|
||||||
|
#if (!defined(Z7_SHA512_UNROLL) || STEP_MAIN < 8) && (STEP_MAIN >= 4)
|
||||||
|
#define R2_MAIN(i) \
|
||||||
|
R1_MAIN(i) \
|
||||||
|
R1_MAIN(i + 1) \
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(Z7_SHA512_UNROLL) && STEP_MAIN >= 8
|
||||||
|
|
||||||
|
#define T4( a,b,c,d,e,f,g,h, wx, i) \
|
||||||
|
h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \
|
||||||
|
tmp = h; \
|
||||||
|
h += d; \
|
||||||
|
d = tmp + S0(a) + Maj(a, b, c); \
|
||||||
|
|
||||||
|
#define R4( wx, i) \
|
||||||
|
T4 ( a,b,c,d,e,f,g,h, wx, (i )); \
|
||||||
|
T4 ( d,a,b,c,h,e,f,g, wx, (i+1)); \
|
||||||
|
T4 ( c,d,a,b,g,h,e,f, wx, (i+2)); \
|
||||||
|
T4 ( b,c,d,a,f,g,h,e, wx, (i+3)); \
|
||||||
|
|
||||||
|
#define R4_PRE(i) R4( W_PRE, i)
|
||||||
|
#define R4_MAIN(i) R4( W_MAIN, i)
|
||||||
|
|
||||||
|
|
||||||
|
#define T8( a,b,c,d,e,f,g,h, wx, i) \
|
||||||
|
h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \
|
||||||
|
d += h; \
|
||||||
|
h += S0(a) + Maj(a, b, c); \
|
||||||
|
|
||||||
|
#define R8( wx, i) \
|
||||||
|
T8 ( a,b,c,d,e,f,g,h, wx, i ); \
|
||||||
|
T8 ( h,a,b,c,d,e,f,g, wx, i+1); \
|
||||||
|
T8 ( g,h,a,b,c,d,e,f, wx, i+2); \
|
||||||
|
T8 ( f,g,h,a,b,c,d,e, wx, i+3); \
|
||||||
|
T8 ( e,f,g,h,a,b,c,d, wx, i+4); \
|
||||||
|
T8 ( d,e,f,g,h,a,b,c, wx, i+5); \
|
||||||
|
T8 ( c,d,e,f,g,h,a,b, wx, i+6); \
|
||||||
|
T8 ( b,c,d,e,f,g,h,a, wx, i+7); \
|
||||||
|
|
||||||
|
#define R8_PRE(i) R8( W_PRE, i)
|
||||||
|
#define R8_MAIN(i) R8( W_MAIN, i)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern
|
||||||
|
MY_ALIGN(64) const UInt64 SHA512_K_ARRAY[80];
|
||||||
|
MY_ALIGN(64) const UInt64 SHA512_K_ARRAY[80] = {
|
||||||
|
U64C(0x428a2f98d728ae22), U64C(0x7137449123ef65cd), U64C(0xb5c0fbcfec4d3b2f), U64C(0xe9b5dba58189dbbc),
|
||||||
|
U64C(0x3956c25bf348b538), U64C(0x59f111f1b605d019), U64C(0x923f82a4af194f9b), U64C(0xab1c5ed5da6d8118),
|
||||||
|
U64C(0xd807aa98a3030242), U64C(0x12835b0145706fbe), U64C(0x243185be4ee4b28c), U64C(0x550c7dc3d5ffb4e2),
|
||||||
|
U64C(0x72be5d74f27b896f), U64C(0x80deb1fe3b1696b1), U64C(0x9bdc06a725c71235), U64C(0xc19bf174cf692694),
|
||||||
|
U64C(0xe49b69c19ef14ad2), U64C(0xefbe4786384f25e3), U64C(0x0fc19dc68b8cd5b5), U64C(0x240ca1cc77ac9c65),
|
||||||
|
U64C(0x2de92c6f592b0275), U64C(0x4a7484aa6ea6e483), U64C(0x5cb0a9dcbd41fbd4), U64C(0x76f988da831153b5),
|
||||||
|
U64C(0x983e5152ee66dfab), U64C(0xa831c66d2db43210), U64C(0xb00327c898fb213f), U64C(0xbf597fc7beef0ee4),
|
||||||
|
U64C(0xc6e00bf33da88fc2), U64C(0xd5a79147930aa725), U64C(0x06ca6351e003826f), U64C(0x142929670a0e6e70),
|
||||||
|
U64C(0x27b70a8546d22ffc), U64C(0x2e1b21385c26c926), U64C(0x4d2c6dfc5ac42aed), U64C(0x53380d139d95b3df),
|
||||||
|
U64C(0x650a73548baf63de), U64C(0x766a0abb3c77b2a8), U64C(0x81c2c92e47edaee6), U64C(0x92722c851482353b),
|
||||||
|
U64C(0xa2bfe8a14cf10364), U64C(0xa81a664bbc423001), U64C(0xc24b8b70d0f89791), U64C(0xc76c51a30654be30),
|
||||||
|
U64C(0xd192e819d6ef5218), U64C(0xd69906245565a910), U64C(0xf40e35855771202a), U64C(0x106aa07032bbd1b8),
|
||||||
|
U64C(0x19a4c116b8d2d0c8), U64C(0x1e376c085141ab53), U64C(0x2748774cdf8eeb99), U64C(0x34b0bcb5e19b48a8),
|
||||||
|
U64C(0x391c0cb3c5c95a63), U64C(0x4ed8aa4ae3418acb), U64C(0x5b9cca4f7763e373), U64C(0x682e6ff3d6b2b8a3),
|
||||||
|
U64C(0x748f82ee5defb2fc), U64C(0x78a5636f43172f60), U64C(0x84c87814a1f0ab72), U64C(0x8cc702081a6439ec),
|
||||||
|
U64C(0x90befffa23631e28), U64C(0xa4506cebde82bde9), U64C(0xbef9a3f7b2c67915), U64C(0xc67178f2e372532b),
|
||||||
|
U64C(0xca273eceea26619c), U64C(0xd186b8c721c0c207), U64C(0xeada7dd6cde0eb1e), U64C(0xf57d4f7fee6ed178),
|
||||||
|
U64C(0x06f067aa72176fba), U64C(0x0a637dc5a2c898a6), U64C(0x113f9804bef90dae), U64C(0x1b710b35131c471b),
|
||||||
|
U64C(0x28db77f523047d84), U64C(0x32caab7b40c72493), U64C(0x3c9ebe0a15c9bebc), U64C(0x431d67c49c100d4c),
|
||||||
|
U64C(0x4cc5d4becb3e42b6), U64C(0x597f299cfc657e2a), U64C(0x5fcb6fab3ad6faec), U64C(0x6c44198c4a475817)
|
||||||
|
};
|
||||||
|
|
||||||
|
#define K SHA512_K_ARRAY
|
||||||
|
|
||||||
|
Z7_NO_INLINE
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks)
|
||||||
|
{
|
||||||
|
UInt64 W
|
||||||
|
#ifdef Z7_SHA512_BIG_W
|
||||||
|
[80];
|
||||||
|
#else
|
||||||
|
[16];
|
||||||
|
#endif
|
||||||
|
unsigned j;
|
||||||
|
UInt64 a,b,c,d,e,f,g,h;
|
||||||
|
#if !defined(Z7_SHA512_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4)
|
||||||
|
UInt64 tmp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (numBlocks == 0) return;
|
||||||
|
|
||||||
|
a = state[0];
|
||||||
|
b = state[1];
|
||||||
|
c = state[2];
|
||||||
|
d = state[3];
|
||||||
|
e = state[4];
|
||||||
|
f = state[5];
|
||||||
|
g = state[6];
|
||||||
|
h = state[7];
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
|
||||||
|
for (j = 0; j < 16; j += STEP_PRE)
|
||||||
|
{
|
||||||
|
#if STEP_PRE > 4
|
||||||
|
|
||||||
|
#if STEP_PRE < 8
|
||||||
|
R4_PRE(0);
|
||||||
|
#else
|
||||||
|
R8_PRE(0);
|
||||||
|
#if STEP_PRE == 16
|
||||||
|
R8_PRE(8);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
R1_PRE(0)
|
||||||
|
#if STEP_PRE >= 2
|
||||||
|
R1_PRE(1)
|
||||||
|
#if STEP_PRE >= 4
|
||||||
|
R1_PRE(2)
|
||||||
|
R1_PRE(3)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 16; j < 80; j += STEP_MAIN)
|
||||||
|
{
|
||||||
|
#if defined(Z7_SHA512_UNROLL) && STEP_MAIN >= 8
|
||||||
|
|
||||||
|
#if STEP_MAIN < 8
|
||||||
|
R4_MAIN(0)
|
||||||
|
#else
|
||||||
|
R8_MAIN(0)
|
||||||
|
#if STEP_MAIN == 16
|
||||||
|
R8_MAIN(8)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
R1_MAIN(0)
|
||||||
|
#if STEP_MAIN >= 2
|
||||||
|
R1_MAIN(1)
|
||||||
|
#if STEP_MAIN >= 4
|
||||||
|
R2_MAIN(2)
|
||||||
|
#if STEP_MAIN >= 8
|
||||||
|
R2_MAIN(4)
|
||||||
|
R2_MAIN(6)
|
||||||
|
#if STEP_MAIN >= 16
|
||||||
|
R2_MAIN(8)
|
||||||
|
R2_MAIN(10)
|
||||||
|
R2_MAIN(12)
|
||||||
|
R2_MAIN(14)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
a += state[0]; state[0] = a;
|
||||||
|
b += state[1]; state[1] = b;
|
||||||
|
c += state[2]; state[2] = c;
|
||||||
|
d += state[3]; state[3] = d;
|
||||||
|
e += state[4]; state[4] = e;
|
||||||
|
f += state[5]; state[5] = f;
|
||||||
|
g += state[6]; state[6] = g;
|
||||||
|
h += state[7]; state[7] = h;
|
||||||
|
|
||||||
|
data += SHA512_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
while (--numBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define Sha512_UpdateBlock(p) SHA512_UPDATE_BLOCKS(p)(p->state, p->buffer, 1)
|
||||||
|
|
||||||
|
void Sha512_Update(CSha512 *p, const Byte *data, size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
{
|
||||||
|
const unsigned pos = (unsigned)p->v.vars.count & (SHA512_BLOCK_SIZE - 1);
|
||||||
|
const unsigned num = SHA512_BLOCK_SIZE - pos;
|
||||||
|
p->v.vars.count += size;
|
||||||
|
if (num > size)
|
||||||
|
{
|
||||||
|
memcpy(p->buffer + pos, data, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos != 0)
|
||||||
|
{
|
||||||
|
size -= num;
|
||||||
|
memcpy(p->buffer + pos, data, num);
|
||||||
|
data += num;
|
||||||
|
Sha512_UpdateBlock(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const size_t numBlocks = size >> 7;
|
||||||
|
// if (numBlocks)
|
||||||
|
SHA512_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
|
||||||
|
size &= SHA512_BLOCK_SIZE - 1;
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
data += (numBlocks << 7);
|
||||||
|
memcpy(p->buffer, data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Sha512_Final(CSha512 *p, Byte *digest, unsigned digestSize)
|
||||||
|
{
|
||||||
|
unsigned pos = (unsigned)p->v.vars.count & (SHA512_BLOCK_SIZE - 1);
|
||||||
|
p->buffer[pos++] = 0x80;
|
||||||
|
if (pos > (SHA512_BLOCK_SIZE - 8 * 2))
|
||||||
|
{
|
||||||
|
while (pos != SHA512_BLOCK_SIZE) { p->buffer[pos++] = 0; }
|
||||||
|
// memset(&p->buf.buffer[pos], 0, SHA512_BLOCK_SIZE - pos);
|
||||||
|
Sha512_UpdateBlock(p);
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
memset(&p->buffer[pos], 0, (SHA512_BLOCK_SIZE - 8 * 2) - pos);
|
||||||
|
{
|
||||||
|
const UInt64 numBits = p->v.vars.count << 3;
|
||||||
|
SetBe64(p->buffer + SHA512_BLOCK_SIZE - 8 * 2, 0) // = (p->v.vars.count >> (64 - 3)); (high 64-bits)
|
||||||
|
SetBe64(p->buffer + SHA512_BLOCK_SIZE - 8 * 1, numBits)
|
||||||
|
}
|
||||||
|
Sha512_UpdateBlock(p);
|
||||||
|
#if 1 && defined(MY_CPU_BE)
|
||||||
|
memcpy(digest, p->state, digestSize);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
const unsigned numWords = digestSize >> 3;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < numWords; i++)
|
||||||
|
{
|
||||||
|
const UInt64 v = p->state[i];
|
||||||
|
SetBe64(digest, v)
|
||||||
|
digest += 8;
|
||||||
|
}
|
||||||
|
if (digestSize & 4) // digestSize == SHA512_224_DIGEST_SIZE
|
||||||
|
{
|
||||||
|
const UInt32 v = (UInt32)((p->state[numWords]) >> 32);
|
||||||
|
SetBe32(digest, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Sha512_InitState(p, digestSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(Z7_COMPILER_SHA512_SUPPORTED) \
|
||||||
|
&& defined(MY_CPU_ARM64) // we can disable this check to debug in x64
|
||||||
|
|
||||||
|
#if 1 // 0 for debug
|
||||||
|
|
||||||
|
#include "7zWindows.h"
|
||||||
|
// #include <stdio.h>
|
||||||
|
#if 0 && defined(MY_CPU_X86_OR_AMD64)
|
||||||
|
#include <intrin.h> // for debug : for __ud2()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BoolInt CPU_IsSupported_SHA512(void)
|
||||||
|
{
|
||||||
|
#if defined(MY_CPU_ARM64)
|
||||||
|
// we have no SHA512 flag for IsProcessorFeaturePresent() still.
|
||||||
|
if (!CPU_IsSupported_CRYPTO())
|
||||||
|
return False;
|
||||||
|
#endif
|
||||||
|
// printf("\nCPU_IsSupported_SHA512\n");
|
||||||
|
{
|
||||||
|
// we can't read ID_AA64ISAR0_EL1 register from application.
|
||||||
|
// but ID_AA64ISAR0_EL1 register is mapped to "CP 4030" registry value.
|
||||||
|
HKEY key = NULL;
|
||||||
|
LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||||
|
TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
|
||||||
|
0, KEY_READ, &key);
|
||||||
|
if (res != ERROR_SUCCESS)
|
||||||
|
return False;
|
||||||
|
{
|
||||||
|
DWORD type = 0;
|
||||||
|
DWORD count = sizeof(UInt64);
|
||||||
|
UInt64 val = 0;
|
||||||
|
res = RegQueryValueEx(key, TEXT("CP 4030"), NULL,
|
||||||
|
&type, (LPBYTE)&val, &count);
|
||||||
|
RegCloseKey(key);
|
||||||
|
if (res != ERROR_SUCCESS
|
||||||
|
|| type != REG_QWORD
|
||||||
|
|| count != sizeof(UInt64)
|
||||||
|
|| ((unsigned)(val >> 12) & 0xf) != 2)
|
||||||
|
return False;
|
||||||
|
// we parse SHA2 field of ID_AA64ISAR0_EL1 register:
|
||||||
|
// 0 : No SHA2 instructions implemented
|
||||||
|
// 1 : SHA256 implemented
|
||||||
|
// 2 : SHA256 and SHA512 implemented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 1 // 0 for debug to disable SHA512 PROBE code
|
||||||
|
|
||||||
|
/*
|
||||||
|
----- SHA512 PROBE -----
|
||||||
|
|
||||||
|
We suppose that "CP 4030" registry reading is enough.
|
||||||
|
But we use additional SHA512 PROBE code, because
|
||||||
|
we can catch exception here, and we don't catch exceptions,
|
||||||
|
if we call Sha512 functions from main code.
|
||||||
|
|
||||||
|
NOTE: arm64 PROBE code doesn't work, if we call it via Wine in linux-arm64.
|
||||||
|
The program just stops.
|
||||||
|
Also x64 version of PROBE code doesn't work, if we run it via Intel SDE emulator
|
||||||
|
without SHA512 support (-skl switch),
|
||||||
|
The program stops, and we have message from SDE:
|
||||||
|
TID 0 SDE-ERROR: Executed instruction not valid for specified chip (SKYLAKE): vsha512msg1
|
||||||
|
But we still want to catch that exception instead of process stopping.
|
||||||
|
Does this PROBE code work in native Windows-arm64 (with/without sha512 hw instructions)?
|
||||||
|
Are there any ways to fix the problems with arm64-wine and x64-SDE cases?
|
||||||
|
*/
|
||||||
|
|
||||||
|
// printf("\n========== CPU_IsSupported_SHA512 PROBE ========\n");
|
||||||
|
{
|
||||||
|
#ifdef __clang_major__
|
||||||
|
#pragma GCC diagnostic ignored "-Wlanguage-extension-token"
|
||||||
|
#endif
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
#if 0 // 1 : for debug (reduced version to detect sha512)
|
||||||
|
const uint64x2_t a = vdupq_n_u64(1);
|
||||||
|
const uint64x2_t b = vsha512hq_u64(a, a, a);
|
||||||
|
if ((UInt32)vgetq_lane_u64(b, 0) == 0x11800002)
|
||||||
|
return True;
|
||||||
|
#else
|
||||||
|
MY_ALIGN(16)
|
||||||
|
UInt64 temp[SHA512_NUM_DIGEST_WORDS + SHA512_NUM_BLOCK_WORDS];
|
||||||
|
memset(temp, 0x5a, sizeof(temp));
|
||||||
|
#if 0 && defined(MY_CPU_X86_OR_AMD64)
|
||||||
|
__ud2(); // for debug : that exception is not problem for SDE
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
Sha512_UpdateBlocks_HW(temp,
|
||||||
|
(const Byte *)(const void *)(temp + SHA512_NUM_DIGEST_WORDS), 1);
|
||||||
|
// printf("\n==== t = %x\n", (UInt32)temp[0]);
|
||||||
|
if ((UInt32)temp[0] == 0xa33cfdf7)
|
||||||
|
{
|
||||||
|
// printf("\n=== PROBE SHA512: SHA512 supported\n");
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
// printf("\n==== CPU_IsSupported_SHA512 EXCEPTION_EXECUTE_HANDLER\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return False;
|
||||||
|
#else
|
||||||
|
// without SHA512 PROBE code
|
||||||
|
return True;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
BoolInt CPU_IsSupported_SHA512(void)
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif // WIN32 arm64
|
||||||
|
|
||||||
|
|
||||||
|
void Sha512Prepare(void)
|
||||||
|
{
|
||||||
|
#ifdef Z7_COMPILER_SHA512_SUPPORTED
|
||||||
|
SHA512_FUNC_UPDATE_BLOCKS f, f_hw;
|
||||||
|
f = Sha512_UpdateBlocks;
|
||||||
|
f_hw = NULL;
|
||||||
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
if (CPU_IsSupported_SHA512()
|
||||||
|
&& CPU_IsSupported_AVX2()
|
||||||
|
)
|
||||||
|
#else
|
||||||
|
if (CPU_IsSupported_SHA512())
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// printf("\n========== HW SHA512 ======== \n");
|
||||||
|
f = f_hw = Sha512_UpdateBlocks_HW;
|
||||||
|
}
|
||||||
|
g_SHA512_FUNC_UPDATE_BLOCKS = f;
|
||||||
|
g_SHA512_FUNC_UPDATE_BLOCKS_HW = f_hw;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#undef K
|
||||||
|
#undef S0
|
||||||
|
#undef S1
|
||||||
|
#undef s0
|
||||||
|
#undef s1
|
||||||
|
#undef Ch
|
||||||
|
#undef Maj
|
||||||
|
#undef W_MAIN
|
||||||
|
#undef W_PRE
|
||||||
|
#undef w
|
||||||
|
#undef blk2_main
|
||||||
|
#undef blk2
|
||||||
|
#undef T1
|
||||||
|
#undef T4
|
||||||
|
#undef T8
|
||||||
|
#undef R1_PRE
|
||||||
|
#undef R1_MAIN
|
||||||
|
#undef R2_MAIN
|
||||||
|
#undef R4
|
||||||
|
#undef R4_PRE
|
||||||
|
#undef R4_MAIN
|
||||||
|
#undef R8
|
||||||
|
#undef R8_PRE
|
||||||
|
#undef R8_MAIN
|
||||||
|
#undef STEP_PRE
|
||||||
|
#undef STEP_MAIN
|
||||||
|
#undef Z7_SHA512_BIG_W
|
||||||
|
#undef Z7_SHA512_UNROLL
|
||||||
|
#undef Z7_COMPILER_SHA512_SUPPORTED
|
||||||
86
C/Sha512.h
Normal file
86
C/Sha512.h
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* Sha512.h -- SHA-512 Hash
|
||||||
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef ZIP7_INC_SHA512_H
|
||||||
|
#define ZIP7_INC_SHA512_H
|
||||||
|
|
||||||
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define SHA512_NUM_BLOCK_WORDS 16
|
||||||
|
#define SHA512_NUM_DIGEST_WORDS 8
|
||||||
|
|
||||||
|
#define SHA512_BLOCK_SIZE (SHA512_NUM_BLOCK_WORDS * 8)
|
||||||
|
#define SHA512_DIGEST_SIZE (SHA512_NUM_DIGEST_WORDS * 8)
|
||||||
|
#define SHA512_224_DIGEST_SIZE (224 / 8)
|
||||||
|
#define SHA512_256_DIGEST_SIZE (256 / 8)
|
||||||
|
#define SHA512_384_DIGEST_SIZE (384 / 8)
|
||||||
|
|
||||||
|
typedef void (Z7_FASTCALL *SHA512_FUNC_UPDATE_BLOCKS)(UInt64 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (the system supports different SHA512 code implementations)
|
||||||
|
{
|
||||||
|
(CSha512::func_UpdateBlocks) will be used
|
||||||
|
(CSha512::func_UpdateBlocks) can be set by
|
||||||
|
Sha512_Init() - to default (fastest)
|
||||||
|
Sha512_SetFunction() - to any algo
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(CSha512::func_UpdateBlocks) is ignored.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
SHA512_FUNC_UPDATE_BLOCKS func_UpdateBlocks;
|
||||||
|
UInt64 count;
|
||||||
|
} vars;
|
||||||
|
UInt64 _pad_64bit[8];
|
||||||
|
void *_pad_align_ptr[2];
|
||||||
|
} v;
|
||||||
|
UInt64 state[SHA512_NUM_DIGEST_WORDS];
|
||||||
|
|
||||||
|
Byte buffer[SHA512_BLOCK_SIZE];
|
||||||
|
} CSha512;
|
||||||
|
|
||||||
|
|
||||||
|
#define SHA512_ALGO_DEFAULT 0
|
||||||
|
#define SHA512_ALGO_SW 1
|
||||||
|
#define SHA512_ALGO_HW 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sha512_SetFunction()
|
||||||
|
return:
|
||||||
|
0 - (algo) value is not supported, and func_UpdateBlocks was not changed
|
||||||
|
1 - func_UpdateBlocks was set according (algo) value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
BoolInt Sha512_SetFunction(CSha512 *p, unsigned algo);
|
||||||
|
// we support only these (digestSize) values: 224/8, 256/8, 384/8, 512/8
|
||||||
|
void Sha512_InitState(CSha512 *p, unsigned digestSize);
|
||||||
|
void Sha512_Init(CSha512 *p, unsigned digestSize);
|
||||||
|
void Sha512_Update(CSha512 *p, const Byte *data, size_t size);
|
||||||
|
void Sha512_Final(CSha512 *p, Byte *digest, unsigned digestSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
|
||||||
|
/*
|
||||||
|
call Sha512Prepare() once at program start.
|
||||||
|
It prepares all supported implementations, and detects the fastest implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Sha512Prepare(void);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
395
C/Sha512Opt.c
Normal file
395
C/Sha512Opt.c
Normal file
|
|
@ -0,0 +1,395 @@
|
||||||
|
/* Sha512Opt.c -- SHA-512 optimized code for SHA-512 hardware instructions
|
||||||
|
: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
#include "Compiler.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
// #define Z7_USE_HW_SHA_STUB // for debug
|
||||||
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 2400) && (__INTEL_COMPILER <= 9900) // fix it
|
||||||
|
#define USE_HW_SHA
|
||||||
|
#elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 170001) \
|
||||||
|
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 170001) \
|
||||||
|
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 140000)
|
||||||
|
#define USE_HW_SHA
|
||||||
|
#if !defined(__INTEL_COMPILER)
|
||||||
|
// icc defines __GNUC__, but icc doesn't support __attribute__(__target__)
|
||||||
|
#if !defined(__SHA512__) || !defined(__AVX2__)
|
||||||
|
#define ATTRIB_SHA512 __attribute__((__target__("sha512,avx2")))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#elif defined(Z7_MSC_VER_ORIGINAL)
|
||||||
|
#if (_MSC_VER >= 1940)
|
||||||
|
#define USE_HW_SHA
|
||||||
|
#else
|
||||||
|
// #define Z7_USE_HW_SHA_STUB
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
// #endif // MY_CPU_X86_OR_AMD64
|
||||||
|
#ifndef USE_HW_SHA
|
||||||
|
// #define Z7_USE_HW_SHA_STUB // for debug
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_HW_SHA
|
||||||
|
|
||||||
|
// #pragma message("Sha512 HW")
|
||||||
|
|
||||||
|
#include <immintrin.h>
|
||||||
|
|
||||||
|
#if defined (__clang__) && defined(_MSC_VER)
|
||||||
|
#if !defined(__AVX__)
|
||||||
|
#include <avxintrin.h>
|
||||||
|
#endif
|
||||||
|
#if !defined(__AVX2__)
|
||||||
|
#include <avx2intrin.h>
|
||||||
|
#endif
|
||||||
|
#if !defined(__SHA512__)
|
||||||
|
#include <sha512intrin.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
SHA512 uses:
|
||||||
|
AVX:
|
||||||
|
_mm256_loadu_si256 (vmovdqu)
|
||||||
|
_mm256_storeu_si256
|
||||||
|
_mm256_set_epi32 (unused)
|
||||||
|
AVX2:
|
||||||
|
_mm256_add_epi64 : vpaddq
|
||||||
|
_mm256_shuffle_epi8 : vpshufb
|
||||||
|
_mm256_shuffle_epi32 : pshufd
|
||||||
|
_mm256_blend_epi32 : vpblendd
|
||||||
|
_mm256_permute4x64_epi64 : vpermq : 3c
|
||||||
|
_mm256_permute2x128_si256: vperm2i128 : 3c
|
||||||
|
_mm256_extracti128_si256 : vextracti128 : 3c
|
||||||
|
SHA512:
|
||||||
|
_mm256_sha512*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// K array must be aligned for 32-bytes at least.
|
||||||
|
// The compiler can look align attribute and selects
|
||||||
|
// vmovdqu - for code without align attribute
|
||||||
|
// vmovdqa - for code with align attribute
|
||||||
|
extern
|
||||||
|
MY_ALIGN(64)
|
||||||
|
const UInt64 SHA512_K_ARRAY[80];
|
||||||
|
#define K SHA512_K_ARRAY
|
||||||
|
|
||||||
|
|
||||||
|
#define ADD_EPI64(dest, src) dest = _mm256_add_epi64(dest, src);
|
||||||
|
#define SHA512_MSG1(dest, src) dest = _mm256_sha512msg1_epi64(dest, _mm256_extracti128_si256(src, 0));
|
||||||
|
#define SHA512_MSG2(dest, src) dest = _mm256_sha512msg2_epi64(dest, src);
|
||||||
|
|
||||||
|
#define LOAD_SHUFFLE(m, k) \
|
||||||
|
m = _mm256_loadu_si256((const __m256i *)(const void *)(data + (k) * 32)); \
|
||||||
|
m = _mm256_shuffle_epi8(m, mask); \
|
||||||
|
|
||||||
|
#define NNN(m0, m1, m2, m3)
|
||||||
|
|
||||||
|
#define SM1(m1, m2, m3, m0) \
|
||||||
|
SHA512_MSG1(m0, m1); \
|
||||||
|
|
||||||
|
#define SM2(m2, m3, m0, m1) \
|
||||||
|
ADD_EPI64(m0, _mm256_permute4x64_epi64(_mm256_blend_epi32(m2, m3, 3), 0x39)); \
|
||||||
|
SHA512_MSG2(m0, m3); \
|
||||||
|
|
||||||
|
#define RND2(t0, t1, lane) \
|
||||||
|
t0 = _mm256_sha512rnds2_epi64(t0, t1, _mm256_extracti128_si256(msg, lane));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define R4(k, m0, m1, m2, m3, OP0, OP1) \
|
||||||
|
msg = _mm256_add_epi64(m0, *(const __m256i *) (const void *) &K[(k) * 4]); \
|
||||||
|
RND2(state0, state1, 0); OP0(m0, m1, m2, m3) \
|
||||||
|
RND2(state1, state0, 1); OP1(m0, m1, m2, m3) \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \
|
||||||
|
R4 ( (k)*4+0, m0,m1,m2,m3, OP0, OP1 ) \
|
||||||
|
R4 ( (k)*4+1, m1,m2,m3,m0, OP2, OP3 ) \
|
||||||
|
R4 ( (k)*4+2, m2,m3,m0,m1, OP4, OP5 ) \
|
||||||
|
R4 ( (k)*4+3, m3,m0,m1,m2, OP6, OP7 ) \
|
||||||
|
|
||||||
|
#define PREPARE_STATE \
|
||||||
|
state0 = _mm256_shuffle_epi32(state0, 0x4e); /* cdab */ \
|
||||||
|
state1 = _mm256_shuffle_epi32(state1, 0x4e); /* ghef */ \
|
||||||
|
tmp = state0; \
|
||||||
|
state0 = _mm256_permute2x128_si256(state0, state1, 0x13); /* cdgh */ \
|
||||||
|
state1 = _mm256_permute2x128_si256(tmp, state1, 2); /* abef */ \
|
||||||
|
|
||||||
|
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
#ifdef ATTRIB_SHA512
|
||||||
|
ATTRIB_SHA512
|
||||||
|
#endif
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks)
|
||||||
|
{
|
||||||
|
const __m256i mask = _mm256_set_epi32(
|
||||||
|
0x08090a0b,0x0c0d0e0f, 0x00010203,0x04050607,
|
||||||
|
0x08090a0b,0x0c0d0e0f, 0x00010203,0x04050607);
|
||||||
|
__m256i tmp, state0, state1;
|
||||||
|
|
||||||
|
if (numBlocks == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
state0 = _mm256_loadu_si256((const __m256i *) (const void *) &state[0]);
|
||||||
|
state1 = _mm256_loadu_si256((const __m256i *) (const void *) &state[4]);
|
||||||
|
|
||||||
|
PREPARE_STATE
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
__m256i state0_save, state1_save;
|
||||||
|
__m256i m0, m1, m2, m3;
|
||||||
|
__m256i msg;
|
||||||
|
// #define msg tmp
|
||||||
|
|
||||||
|
state0_save = state0;
|
||||||
|
state1_save = state1;
|
||||||
|
|
||||||
|
LOAD_SHUFFLE (m0, 0)
|
||||||
|
LOAD_SHUFFLE (m1, 1)
|
||||||
|
LOAD_SHUFFLE (m2, 2)
|
||||||
|
LOAD_SHUFFLE (m3, 3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 )
|
||||||
|
R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 )
|
||||||
|
R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 )
|
||||||
|
R16 ( 3, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 )
|
||||||
|
R16 ( 4, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN )
|
||||||
|
ADD_EPI64(state0, state0_save)
|
||||||
|
ADD_EPI64(state1, state1_save)
|
||||||
|
|
||||||
|
data += 128;
|
||||||
|
}
|
||||||
|
while (--numBlocks);
|
||||||
|
|
||||||
|
PREPARE_STATE
|
||||||
|
|
||||||
|
_mm256_storeu_si256((__m256i *) (void *) &state[0], state0);
|
||||||
|
_mm256_storeu_si256((__m256i *) (void *) &state[4], state1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_HW_SHA
|
||||||
|
|
||||||
|
// gcc 8.5 also supports sha512, but we need also support in assembler that is called by gcc
|
||||||
|
#elif defined(MY_CPU_ARM64) && defined(MY_CPU_LE)
|
||||||
|
|
||||||
|
#if defined(__ARM_FEATURE_SHA512)
|
||||||
|
#define USE_HW_SHA
|
||||||
|
#else
|
||||||
|
#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 130000) \
|
||||||
|
|| defined(__GNUC__) && (__GNUC__ >= 9) \
|
||||||
|
) \
|
||||||
|
|| defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1940) // fix it
|
||||||
|
#define USE_HW_SHA
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_HW_SHA
|
||||||
|
|
||||||
|
// #pragma message("=== Sha512 HW === ")
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#if !defined(__ARM_FEATURE_SHA512)
|
||||||
|
// #pragma message("=== we define SHA3 ATTRIB_SHA512 === ")
|
||||||
|
#if defined(__clang__)
|
||||||
|
#define ATTRIB_SHA512 __attribute__((__target__("sha3"))) // "armv8.2-a,sha3"
|
||||||
|
#else
|
||||||
|
#define ATTRIB_SHA512 __attribute__((__target__("arch=armv8.2-a+sha3")))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(Z7_MSC_VER_ORIGINAL)
|
||||||
|
#include <arm64_neon.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if defined(__clang__) && __clang_major__ < 16
|
||||||
|
#if !defined(__ARM_FEATURE_SHA512)
|
||||||
|
// #pragma message("=== we set __ARM_FEATURE_SHA512 1 === ")
|
||||||
|
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
|
||||||
|
#define Z7_ARM_FEATURE_SHA512_WAS_SET 1
|
||||||
|
#define __ARM_FEATURE_SHA512 1
|
||||||
|
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
|
||||||
|
#endif
|
||||||
|
#endif // clang
|
||||||
|
|
||||||
|
#include <arm_neon.h>
|
||||||
|
|
||||||
|
#if defined(Z7_ARM_FEATURE_SHA512_WAS_SET) && \
|
||||||
|
defined(__ARM_FEATURE_SHA512)
|
||||||
|
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
|
||||||
|
#undef __ARM_FEATURE_SHA512
|
||||||
|
#undef Z7_ARM_FEATURE_SHA512_WAS_SET
|
||||||
|
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
|
||||||
|
// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // Z7_MSC_VER_ORIGINAL
|
||||||
|
|
||||||
|
typedef uint64x2_t v128_64;
|
||||||
|
// typedef __n128 v128_64; // MSVC
|
||||||
|
|
||||||
|
#ifdef MY_CPU_BE
|
||||||
|
#define MY_rev64_for_LE(x) x
|
||||||
|
#else
|
||||||
|
#define MY_rev64_for_LE(x) vrev64q_u8(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LOAD_128_64(_p) vld1q_u64(_p)
|
||||||
|
#define LOAD_128_8(_p) vld1q_u8 (_p)
|
||||||
|
#define STORE_128_64(_p, _v) vst1q_u64(_p, _v)
|
||||||
|
|
||||||
|
#define LOAD_SHUFFLE(m, k) \
|
||||||
|
m = vreinterpretq_u64_u8( \
|
||||||
|
MY_rev64_for_LE( \
|
||||||
|
LOAD_128_8(data + (k) * 16))); \
|
||||||
|
|
||||||
|
// K array must be aligned for 16-bytes at least.
|
||||||
|
extern
|
||||||
|
MY_ALIGN(64)
|
||||||
|
const UInt64 SHA512_K_ARRAY[80];
|
||||||
|
#define K SHA512_K_ARRAY
|
||||||
|
|
||||||
|
#define NN(m0, m1, m4, m5, m7)
|
||||||
|
#define SM(m0, m1, m4, m5, m7) \
|
||||||
|
m0 = vsha512su1q_u64(vsha512su0q_u64(m0, m1), m7, vextq_u64(m4, m5, 1));
|
||||||
|
|
||||||
|
#define R2(k, m0,m1,m2,m3,m4,m5,m6,m7, a0,a1,a2,a3, OP) \
|
||||||
|
OP(m0, m1, m4, m5, m7) \
|
||||||
|
t = vaddq_u64(m0, vld1q_u64(k)); \
|
||||||
|
t = vaddq_u64(vextq_u64(t, t, 1), a3); \
|
||||||
|
t = vsha512hq_u64(t, vextq_u64(a2, a3, 1), vextq_u64(a1, a2, 1)); \
|
||||||
|
a3 = vsha512h2q_u64(t, a1, a0); \
|
||||||
|
a1 = vaddq_u64(a1, t); \
|
||||||
|
|
||||||
|
#define R8(k, m0,m1,m2,m3,m4,m5,m6,m7, OP) \
|
||||||
|
R2 ( (k)+0*2, m0,m1,m2,m3,m4,m5,m6,m7, a0,a1,a2,a3, OP ) \
|
||||||
|
R2 ( (k)+1*2, m1,m2,m3,m4,m5,m6,m7,m0, a3,a0,a1,a2, OP ) \
|
||||||
|
R2 ( (k)+2*2, m2,m3,m4,m5,m6,m7,m0,m1, a2,a3,a0,a1, OP ) \
|
||||||
|
R2 ( (k)+3*2, m3,m4,m5,m6,m7,m0,m1,m2, a1,a2,a3,a0, OP ) \
|
||||||
|
|
||||||
|
#define R16(k, OP) \
|
||||||
|
R8 ( (k)+0*2, m0,m1,m2,m3,m4,m5,m6,m7, OP ) \
|
||||||
|
R8 ( (k)+4*2, m4,m5,m6,m7,m0,m1,m2,m3, OP ) \
|
||||||
|
|
||||||
|
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
#ifdef ATTRIB_SHA512
|
||||||
|
ATTRIB_SHA512
|
||||||
|
#endif
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks)
|
||||||
|
{
|
||||||
|
v128_64 a0, a1, a2, a3;
|
||||||
|
|
||||||
|
if (numBlocks == 0)
|
||||||
|
return;
|
||||||
|
a0 = LOAD_128_64(&state[0]);
|
||||||
|
a1 = LOAD_128_64(&state[2]);
|
||||||
|
a2 = LOAD_128_64(&state[4]);
|
||||||
|
a3 = LOAD_128_64(&state[6]);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
v128_64 a0_save, a1_save, a2_save, a3_save;
|
||||||
|
v128_64 m0, m1, m2, m3, m4, m5, m6, m7;
|
||||||
|
v128_64 t;
|
||||||
|
unsigned i;
|
||||||
|
const UInt64 *k_ptr;
|
||||||
|
|
||||||
|
LOAD_SHUFFLE (m0, 0)
|
||||||
|
LOAD_SHUFFLE (m1, 1)
|
||||||
|
LOAD_SHUFFLE (m2, 2)
|
||||||
|
LOAD_SHUFFLE (m3, 3)
|
||||||
|
LOAD_SHUFFLE (m4, 4)
|
||||||
|
LOAD_SHUFFLE (m5, 5)
|
||||||
|
LOAD_SHUFFLE (m6, 6)
|
||||||
|
LOAD_SHUFFLE (m7, 7)
|
||||||
|
|
||||||
|
a0_save = a0;
|
||||||
|
a1_save = a1;
|
||||||
|
a2_save = a2;
|
||||||
|
a3_save = a3;
|
||||||
|
|
||||||
|
R16 ( K, NN )
|
||||||
|
k_ptr = K + 16;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
R16 ( k_ptr, SM )
|
||||||
|
k_ptr += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
a0 = vaddq_u64(a0, a0_save);
|
||||||
|
a1 = vaddq_u64(a1, a1_save);
|
||||||
|
a2 = vaddq_u64(a2, a2_save);
|
||||||
|
a3 = vaddq_u64(a3, a3_save);
|
||||||
|
|
||||||
|
data += 128;
|
||||||
|
}
|
||||||
|
while (--numBlocks);
|
||||||
|
|
||||||
|
STORE_128_64(&state[0], a0);
|
||||||
|
STORE_128_64(&state[2], a1);
|
||||||
|
STORE_128_64(&state[4], a2);
|
||||||
|
STORE_128_64(&state[6], a3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_HW_SHA
|
||||||
|
|
||||||
|
#endif // MY_CPU_ARM_OR_ARM64
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB)
|
||||||
|
// #error Stop_Compiling_UNSUPPORTED_SHA
|
||||||
|
// #include <stdlib.h>
|
||||||
|
// We can compile this file with another C compiler,
|
||||||
|
// or we can compile asm version.
|
||||||
|
// So we can generate real code instead of this stub function.
|
||||||
|
// #include "Sha512.h"
|
||||||
|
// #if defined(_MSC_VER)
|
||||||
|
#pragma message("Sha512 HW-SW stub was used")
|
||||||
|
// #endif
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks (UInt64 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks);
|
||||||
|
void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks)
|
||||||
|
{
|
||||||
|
Sha512_UpdateBlocks(state, data, numBlocks);
|
||||||
|
/*
|
||||||
|
UNUSED_VAR(state);
|
||||||
|
UNUSED_VAR(data);
|
||||||
|
UNUSED_VAR(numBlocks);
|
||||||
|
exit(1);
|
||||||
|
return;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#undef K
|
||||||
|
#undef RND2
|
||||||
|
#undef MY_rev64_for_LE
|
||||||
|
#undef NN
|
||||||
|
#undef NNN
|
||||||
|
#undef LOAD_128
|
||||||
|
#undef STORE_128
|
||||||
|
#undef LOAD_SHUFFLE
|
||||||
|
#undef SM1
|
||||||
|
#undef SM2
|
||||||
|
#undef SM
|
||||||
|
#undef R2
|
||||||
|
#undef R4
|
||||||
|
#undef R16
|
||||||
|
#undef PREPARE_STATE
|
||||||
|
#undef USE_HW_SHA
|
||||||
|
#undef ATTRIB_SHA512
|
||||||
|
#undef USE_VER_MIN
|
||||||
|
#undef Z7_USE_HW_SHA_STUB
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* ZstdDec.c -- Zstd Decoder
|
/* ZstdDec.c -- Zstd Decoder
|
||||||
2024-05-26 : the code was developed by Igor Pavlov, using Zstandard format
|
2024-06-18 : the code was developed by Igor Pavlov, using Zstandard format
|
||||||
specification and original zstd decoder code as reference code.
|
specification and original zstd decoder code as reference code.
|
||||||
original zstd decoder code: Copyright (c) Facebook, Inc. All rights reserved.
|
original zstd decoder code: Copyright (c) Facebook, Inc. All rights reserved.
|
||||||
This source code is licensed under BSD 3-Clause License.
|
This source code is licensed under BSD 3-Clause License.
|
||||||
|
|
@ -1308,8 +1308,10 @@ FSE_Decode_SeqTable(CFseRecord * const table,
|
||||||
in->len--;
|
in->len--;
|
||||||
{
|
{
|
||||||
const Byte *ptr = in->ptr;
|
const Byte *ptr = in->ptr;
|
||||||
const Byte sym = ptr[0];
|
const unsigned sym = ptr[0];
|
||||||
in->ptr = ptr + 1;
|
in->ptr = ptr + 1;
|
||||||
|
if (sym >= numSymbolsMax)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
table[0] = (FastInt32)sym
|
table[0] = (FastInt32)sym
|
||||||
#if defined(Z7_ZSTD_DEC_USE_ML_PLUS3)
|
#if defined(Z7_ZSTD_DEC_USE_ML_PLUS3)
|
||||||
+ (numSymbolsMax == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : 0)
|
+ (numSymbolsMax == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : 0)
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,9 @@ endif
|
||||||
|
|
||||||
all: $(O) $(PROGPATH) $(STATIC_TARGET)
|
all: $(O) $(PROGPATH) $(STATIC_TARGET)
|
||||||
|
|
||||||
|
# we need $(O) as order-only-prerequisites:
|
||||||
|
$(OBJS): | $(O)
|
||||||
|
|
||||||
$(O):
|
$(O):
|
||||||
$(MY_MKDIR) $(O)
|
$(MY_MKDIR) $(O)
|
||||||
|
|
||||||
|
|
@ -299,6 +302,8 @@ $O/ListFileUtils.o: ../../../Common/ListFileUtils.cpp
|
||||||
$(CXX) $(CXXFLAGS) $<
|
$(CXX) $(CXXFLAGS) $<
|
||||||
$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp
|
$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp
|
||||||
$(CXX) $(CXXFLAGS) $<
|
$(CXX) $(CXXFLAGS) $<
|
||||||
|
$O/Md5Reg.o: ../../../Common/Md5Reg.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) $<
|
||||||
$O/MyMap.o: ../../../Common/MyMap.cpp
|
$O/MyMap.o: ../../../Common/MyMap.cpp
|
||||||
$(CXX) $(CXXFLAGS) $<
|
$(CXX) $(CXXFLAGS) $<
|
||||||
$O/MyString.o: ../../../Common/MyString.cpp
|
$O/MyString.o: ../../../Common/MyString.cpp
|
||||||
|
|
@ -323,6 +328,12 @@ $O/Sha256Prepare.o: ../../../Common/Sha256Prepare.cpp
|
||||||
$(CXX) $(CXXFLAGS) $<
|
$(CXX) $(CXXFLAGS) $<
|
||||||
$O/Sha256Reg.o: ../../../Common/Sha256Reg.cpp
|
$O/Sha256Reg.o: ../../../Common/Sha256Reg.cpp
|
||||||
$(CXX) $(CXXFLAGS) $<
|
$(CXX) $(CXXFLAGS) $<
|
||||||
|
$O/Sha3Reg.o: ../../../Common/Sha3Reg.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) $<
|
||||||
|
$O/Sha512Prepare.o: ../../../Common/Sha512Prepare.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) $<
|
||||||
|
$O/Sha512Reg.o: ../../../Common/Sha512Reg.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) $<
|
||||||
$O/StdInStream.o: ../../../Common/StdInStream.cpp
|
$O/StdInStream.o: ../../../Common/StdInStream.cpp
|
||||||
$(CXX) $(CXXFLAGS) $<
|
$(CXX) $(CXXFLAGS) $<
|
||||||
$O/StdOutStream.o: ../../../Common/StdOutStream.cpp
|
$O/StdOutStream.o: ../../../Common/StdOutStream.cpp
|
||||||
|
|
@ -1204,6 +1215,8 @@ $O/Lzma2Enc.o: ../../../../C/Lzma2Enc.c
|
||||||
$(CC) $(CFLAGS) $<
|
$(CC) $(CFLAGS) $<
|
||||||
$O/LzmaLib.o: ../../../../C/LzmaLib.c
|
$O/LzmaLib.o: ../../../../C/LzmaLib.c
|
||||||
$(CC) $(CFLAGS) $<
|
$(CC) $(CFLAGS) $<
|
||||||
|
$O/Md5.o: ../../../../C/Md5.c
|
||||||
|
$(CC) $(CFLAGS) $<
|
||||||
$O/MtCoder.o: ../../../../C/MtCoder.c
|
$O/MtCoder.o: ../../../../C/MtCoder.c
|
||||||
$(CC) $(CFLAGS) $<
|
$(CC) $(CFLAGS) $<
|
||||||
$O/MtDec.o: ../../../../C/MtDec.c
|
$O/MtDec.o: ../../../../C/MtDec.c
|
||||||
|
|
@ -1226,6 +1239,12 @@ $O/Sha1.o: ../../../../C/Sha1.c
|
||||||
$(CC) $(CFLAGS) $<
|
$(CC) $(CFLAGS) $<
|
||||||
$O/Sha256.o: ../../../../C/Sha256.c
|
$O/Sha256.o: ../../../../C/Sha256.c
|
||||||
$(CC) $(CFLAGS) $<
|
$(CC) $(CFLAGS) $<
|
||||||
|
$O/Sha3.o: ../../../../C/Sha3.c
|
||||||
|
$(CC) $(CFLAGS) $<
|
||||||
|
$O/Sha512.o: ../../../../C/Sha512.c
|
||||||
|
$(CC) $(CFLAGS) $<
|
||||||
|
$O/Sha512Opt.o: ../../../../C/Sha512Opt.c
|
||||||
|
$(CC) $(CFLAGS) $<
|
||||||
$O/Sort.o: ../../../../C/Sort.c
|
$O/Sort.o: ../../../../C/Sort.c
|
||||||
$(CC) $(CFLAGS) $<
|
$(CC) $(CFLAGS) $<
|
||||||
$O/SwapBytes.o: ../../../../C/SwapBytes.c
|
$O/SwapBytes.o: ../../../../C/SwapBytes.c
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,14 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Filters don't improve the compression ratio for relocatable object files (".o").
|
||||||
|
But we can get compression ratio gain, if we compress object
|
||||||
|
files and executables in same solid block.
|
||||||
|
So we use filters for relocatable object files (".o"):
|
||||||
|
*/
|
||||||
|
// #define Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
|
||||||
|
|
||||||
/* ---------- ELF ---------- */
|
/* ---------- ELF ---------- */
|
||||||
|
|
||||||
#define ELF_SIG 0x464C457F
|
#define ELF_SIG 0x464C457F
|
||||||
|
|
@ -258,6 +266,12 @@ static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
|
||||||
|
#define ELF_ET_REL 1
|
||||||
|
if (Get16(buf + 0x10, be) == ELF_ET_REL)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (Get16(buf + 0x12, be))
|
switch (Get16(buf + 0x12, be))
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
|
|
@ -318,6 +332,12 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
|
||||||
|
#define MACH_TYPE_OBJECT 1
|
||||||
|
if (Get32(buf + 0xC, be) == MACH_TYPE_OBJECT)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (Get32(buf + 4, be))
|
switch (Get32(buf + 4, be))
|
||||||
{
|
{
|
||||||
case MACH_MACHINE_386:
|
case MACH_MACHINE_386:
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "../../Common/ComTry.h"
|
#include "../../Common/ComTry.h"
|
||||||
|
|
||||||
#include "../../Windows/PropVariant.h"
|
|
||||||
#include "../../Windows/PropVariantUtils.h"
|
#include "../../Windows/PropVariantUtils.h"
|
||||||
|
|
||||||
#include "../Common/RegisterArc.h"
|
#include "../Common/RegisterArc.h"
|
||||||
|
|
@ -14,8 +13,7 @@
|
||||||
|
|
||||||
#include "HandlerCont.h"
|
#include "HandlerCont.h"
|
||||||
|
|
||||||
// #define Get16(p) GetBe16(p)
|
#define Get32(p) GetBe32a(p)
|
||||||
#define Get32(p) GetBe32(p)
|
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
|
|
@ -41,8 +39,8 @@ static const CUInt32PCharPair k_Flags[] =
|
||||||
{ 5, "WRITABLE" },
|
{ 5, "WRITABLE" },
|
||||||
{ 6, "OS_PIC_CODE" },
|
{ 6, "OS_PIC_CODE" },
|
||||||
// { 7, "OS_SPECIFIC_2" }, // "Unused"
|
// { 7, "OS_SPECIFIC_2" }, // "Unused"
|
||||||
// { 8, "ChainCompatible" }, // "OS_SPECIFIC_1"
|
{ 8, "ChainCompatible" }, // "OS_SPECIFIC_1"
|
||||||
// { 9, "RealDeviceDriver" },
|
{ 9, "RealDeviceDriver" },
|
||||||
// { 10, "CanChainToNext" },
|
// { 10, "CanChainToNext" },
|
||||||
{ 30, "MOUNTED_AT_STARTUP" },
|
{ 30, "MOUNTED_AT_STARTUP" },
|
||||||
{ 31, "STARTUP" }
|
{ 31, "STARTUP" }
|
||||||
|
|
@ -74,16 +72,16 @@ struct CItem
|
||||||
bool Is_Valid_and_Allocated() const
|
bool Is_Valid_and_Allocated() const
|
||||||
{ return (Flags & (DPME_FLAGS_VALID | DPME_FLAGS_ALLOCATED)) != 0; }
|
{ return (Flags & (DPME_FLAGS_VALID | DPME_FLAGS_ALLOCATED)) != 0; }
|
||||||
|
|
||||||
bool Parse(const Byte *p, UInt32 &numBlocksInMap)
|
bool Parse(const UInt32 *p32, UInt32 &numBlocksInMap)
|
||||||
{
|
{
|
||||||
numBlocksInMap = Get32(p + 4);
|
if (GetUi32a(p32) != 0x4d50) // "PM"
|
||||||
StartBlock = Get32(p + 8);
|
|
||||||
NumBlocks = Get32(p + 0xc);
|
|
||||||
Flags = Get32(p + 0x58);
|
|
||||||
memcpy(Name, p + 0x10, k_Str_Size);
|
|
||||||
memcpy(Type, p + 0x30, k_Str_Size);
|
|
||||||
if (GetUi32(p) != 0x4d50) // "PM"
|
|
||||||
return false;
|
return false;
|
||||||
|
numBlocksInMap = Get32(p32 + 4 / 4);
|
||||||
|
StartBlock = Get32(p32 + 8 / 4);
|
||||||
|
NumBlocks = Get32(p32 + 0xc / 4);
|
||||||
|
Flags = Get32(p32 + 0x58 / 4);
|
||||||
|
memcpy(Name, p32 + 0x10 / 4, k_Str_Size);
|
||||||
|
memcpy(Type, p32 + 0x30 / 4, k_Str_Size);
|
||||||
/*
|
/*
|
||||||
DataStartBlock = Get32(p + 0x50);
|
DataStartBlock = Get32(p + 0x50);
|
||||||
NumDataBlocks = Get32(p + 0x54);
|
NumDataBlocks = Get32(p + 0x54);
|
||||||
|
|
@ -96,7 +94,7 @@ struct CItem
|
||||||
if (Get32(p + 0x70) != 0)
|
if (Get32(p + 0x70) != 0)
|
||||||
return false;
|
return false;
|
||||||
BootChecksum = Get32(p + 0x74);
|
BootChecksum = Get32(p + 0x74);
|
||||||
memcpy(Processor, p + 0x78, 16);
|
memcpy(Processor, p32 + 0x78 / 4, 16);
|
||||||
*/
|
*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -109,9 +107,9 @@ Z7_class_CHandler_final: public CHandlerCont
|
||||||
|
|
||||||
CRecordVector<CItem> _items;
|
CRecordVector<CItem> _items;
|
||||||
unsigned _blockSizeLog;
|
unsigned _blockSizeLog;
|
||||||
UInt32 _numBlocks;
|
|
||||||
UInt64 _phySize;
|
|
||||||
bool _isArc;
|
bool _isArc;
|
||||||
|
// UInt32 _numBlocks;
|
||||||
|
UInt64 _phySize;
|
||||||
|
|
||||||
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
|
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
|
||||||
|
|
||||||
|
|
@ -132,11 +130,11 @@ API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size)
|
||||||
{
|
{
|
||||||
if (size < kSectorSize)
|
if (size < kSectorSize)
|
||||||
return k_IsArc_Res_NEED_MORE;
|
return k_IsArc_Res_NEED_MORE;
|
||||||
if (GetUi64(p + 8) != 0)
|
if (GetUi32(p + 12) != 0)
|
||||||
return k_IsArc_Res_NO;
|
return k_IsArc_Res_NO;
|
||||||
UInt32 v = GetUi32(p); // we read as little-endian
|
UInt32 v = GetUi32(p); // we read as little-endian
|
||||||
v ^= (kSig0 | (unsigned)kSig1 << 8);
|
v ^= kSig0 | (unsigned)kSig1 << 8;
|
||||||
if ((v & ~((UInt32)0xf << 17)))
|
if (v & ~((UInt32)0xf << 17))
|
||||||
return k_IsArc_Res_NO;
|
return k_IsArc_Res_NO;
|
||||||
if ((0x116u >> (v >> 17)) & 1)
|
if ((0x116u >> (v >> 17)) & 1)
|
||||||
return k_IsArc_Res_YES;
|
return k_IsArc_Res_YES;
|
||||||
|
|
@ -149,55 +147,103 @@ Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
Byte buf[kSectorSize];
|
UInt32 buf32[kSectorSize / 4];
|
||||||
unsigned numSectors_in_Cluster;
|
unsigned numPadSectors, blockSizeLog_from_Header;
|
||||||
{
|
{
|
||||||
RINOK(ReadStream_FALSE(stream, buf, kSectorSize))
|
// Driver Descriptor Map (DDM)
|
||||||
if (GetUi64(buf + 8) != 0)
|
RINOK(ReadStream_FALSE(stream, buf32, kSectorSize))
|
||||||
|
// 8: UInt16 sbDevType : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso
|
||||||
|
// 10: UInt16 sbDevId : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso
|
||||||
|
// 12: UInt32 sbData : =0
|
||||||
|
if (buf32[3] != 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
UInt32 v = GetUi32(buf); // we read as little-endian
|
UInt32 v = GetUi32a(buf32); // we read as little-endian
|
||||||
v ^= (kSig0 | (unsigned)kSig1 << 8);
|
v ^= kSig0 | (unsigned)kSig1 << 8;
|
||||||
if ((v & ~((UInt32)0xf << 17)))
|
if (v & ~((UInt32)0xf << 17))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
v >>= 16;
|
v >>= 16;
|
||||||
if (v == 0)
|
if (v == 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if (v & (v - 1))
|
if (v & (v - 1))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
const unsigned a = (0x30210u >> v) & 3;
|
// v == { 16,8,4,2 } : block size (x256 bytes)
|
||||||
// a = 0; // for debug
|
const unsigned a =
|
||||||
numSectors_in_Cluster = 1u << a;
|
#if 1
|
||||||
_blockSizeLog = 9 + a;
|
(0x30210u >> v) & 3;
|
||||||
|
#else
|
||||||
|
0; // for debug : hardcoded switch to 512-bytes mode
|
||||||
|
#endif
|
||||||
|
numPadSectors = (1u << a) - 1;
|
||||||
|
_blockSizeLog = blockSizeLog_from_Header = 9 + a;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 numBlocks = Get32(buf + 4);
|
/*
|
||||||
_numBlocks = numBlocks;
|
some APMs (that are ".iso" macOS installation files) contain
|
||||||
|
(blockSizeLog == 11) in DDM header,
|
||||||
|
and contain 2 overlapping maps:
|
||||||
|
1) map for 512-bytes-step
|
||||||
|
2) map for 2048-bytes-step
|
||||||
|
512-bytes-step map is correct.
|
||||||
|
2048-bytes-step map can be incorrect in some cases.
|
||||||
|
|
||||||
|
macos 8 / OSX DP2 iso:
|
||||||
|
There is shared "hfs" item in both maps.
|
||||||
|
And correct (offset/size) values for "hfs" partition
|
||||||
|
can be calculated only in 512-bytes mode (ignoring blockSizeLog == 11).
|
||||||
|
But some records (Macintosh.Apple_Driver*_)
|
||||||
|
can be correct on both modes: 512-bytes mode / 2048-bytes-step.
|
||||||
|
|
||||||
|
macos 921 ppc / Apple Mac OS X 10.3.0 iso:
|
||||||
|
Both maps are correct.
|
||||||
|
If we use 512-bytes-step, each 4th item is (Apple_Void) with zero size.
|
||||||
|
And these zero size (Apple_Void) items will be first items in 2048-bytes-step map.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// we define Z7_APM_SWITCH_TO_512_BYTES, because
|
||||||
|
// we want to support old MACOS APMs that contain correct value only
|
||||||
|
// for 512-bytes-step mode
|
||||||
|
#define Z7_APM_SWITCH_TO_512_BYTES
|
||||||
|
|
||||||
|
const UInt32 numBlocks_from_Header = Get32(buf32 + 1);
|
||||||
|
UInt32 numBlocks = 0;
|
||||||
{
|
{
|
||||||
for (unsigned k = numSectors_in_Cluster; --k != 0;)
|
for (unsigned k = 0; k < numPadSectors; k++)
|
||||||
{
|
{
|
||||||
RINOK(ReadStream_FALSE(stream, buf, kSectorSize))
|
RINOK(ReadStream_FALSE(stream, buf32, kSectorSize))
|
||||||
|
#ifdef Z7_APM_SWITCH_TO_512_BYTES
|
||||||
|
if (k == 0)
|
||||||
|
{
|
||||||
|
if (GetUi32a(buf32) == 0x4d50 // "PM"
|
||||||
|
// && (Get32(buf32 + 0x58 / 4) & 1) // Flags::VALID
|
||||||
|
// some old APMs don't use VALID flag for Apple_partition_map item
|
||||||
|
&& Get32(buf32 + 8 / 4) == 1) // StartBlock
|
||||||
|
{
|
||||||
|
// we switch the mode to 512-bytes-step map reading:
|
||||||
|
numPadSectors = 0;
|
||||||
|
_blockSizeLog = 9;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 numBlocksInMap = 0;
|
|
||||||
|
|
||||||
for (unsigned i = 0;;)
|
for (unsigned i = 0;;)
|
||||||
{
|
{
|
||||||
RINOK(ReadStream_FALSE(stream, buf, kSectorSize))
|
#ifdef Z7_APM_SWITCH_TO_512_BYTES
|
||||||
|
if (i != 0 || _blockSizeLog == blockSizeLog_from_Header)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
RINOK(ReadStream_FALSE(stream, buf32, kSectorSize))
|
||||||
|
}
|
||||||
|
|
||||||
CItem item;
|
CItem item;
|
||||||
|
UInt32 numBlocksInMap = 0;
|
||||||
UInt32 numBlocksInMap2 = 0;
|
if (!item.Parse(buf32, numBlocksInMap))
|
||||||
if (!item.Parse(buf, numBlocksInMap2))
|
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if (i == 0)
|
// v24.09: we don't check that all entries have same (numBlocksInMap) values,
|
||||||
{
|
// because some APMs have different (numBlocksInMap) values, if (Apple_Void) is used.
|
||||||
numBlocksInMap = numBlocksInMap2;
|
if (numBlocksInMap > (1 << 8) || numBlocksInMap <= i)
|
||||||
if (numBlocksInMap > (1 << 8) || numBlocksInMap == 0)
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
else if (numBlocksInMap2 != numBlocksInMap)
|
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
const UInt32 finish = item.StartBlock + item.NumBlocks;
|
const UInt32 finish = item.StartBlock + item.NumBlocks;
|
||||||
|
|
@ -207,15 +253,19 @@ Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb
|
||||||
numBlocks = finish;
|
numBlocks = finish;
|
||||||
|
|
||||||
_items.Add(item);
|
_items.Add(item);
|
||||||
for (unsigned k = numSectors_in_Cluster; --k != 0;)
|
if (numPadSectors != 0)
|
||||||
{
|
{
|
||||||
RINOK(ReadStream_FALSE(stream, buf, kSectorSize))
|
RINOK(stream->Seek(numPadSectors << 9, STREAM_SEEK_CUR, NULL))
|
||||||
}
|
}
|
||||||
if (++i == numBlocksInMap)
|
if (++i == numBlocksInMap)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_phySize = BlocksToBytes(numBlocks);
|
_phySize = BlocksToBytes(numBlocks);
|
||||||
|
// _numBlocks = numBlocks;
|
||||||
|
const UInt64 physSize = (UInt64)numBlocks_from_Header << blockSizeLog_from_Header;
|
||||||
|
if (_phySize < physSize)
|
||||||
|
_phySize = physSize;
|
||||||
_isArc = true;
|
_isArc = true;
|
||||||
_stream = stream;
|
_stream = stream;
|
||||||
|
|
||||||
|
|
@ -240,22 +290,21 @@ static const Byte kProps[] =
|
||||||
kpidSize,
|
kpidSize,
|
||||||
kpidOffset,
|
kpidOffset,
|
||||||
kpidCharacts
|
kpidCharacts
|
||||||
|
// , kpidCpu
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Byte kArcProps[] =
|
static const Byte kArcProps[] =
|
||||||
{
|
{
|
||||||
kpidClusterSize,
|
kpidClusterSize
|
||||||
kpidNumBlocks
|
// , kpidNumBlocks
|
||||||
};
|
};
|
||||||
|
|
||||||
IMP_IInArchive_Props
|
IMP_IInArchive_Props
|
||||||
IMP_IInArchive_ArcProps
|
IMP_IInArchive_ArcProps
|
||||||
|
|
||||||
static AString GetString(const char *s)
|
static void GetString(AString &dest, const char *src)
|
||||||
{
|
{
|
||||||
AString res;
|
dest.SetFrom_CalcLen(src, k_Str_Size);
|
||||||
res.SetFrom_CalcLen(s, k_Str_Size);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
|
|
@ -272,7 +321,8 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
const CItem &item = _items[i];
|
const CItem &item = _items[i];
|
||||||
if (!item.Is_Valid_and_Allocated())
|
if (!item.Is_Valid_and_Allocated())
|
||||||
continue;
|
continue;
|
||||||
AString s (GetString(item.Type));
|
AString s;
|
||||||
|
GetString(s, item.Type);
|
||||||
if (NDmg::Is_Apple_FS_Or_Unknown(s))
|
if (NDmg::Is_Apple_FS_Or_Unknown(s))
|
||||||
{
|
{
|
||||||
if (mainIndex != -1)
|
if (mainIndex != -1)
|
||||||
|
|
@ -289,7 +339,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
}
|
}
|
||||||
case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break;
|
case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break;
|
||||||
case kpidPhySize: prop = _phySize; break;
|
case kpidPhySize: prop = _phySize; break;
|
||||||
case kpidNumBlocks: prop = _numBlocks; break;
|
// case kpidNumBlocks: prop = _numBlocks; break;
|
||||||
|
|
||||||
case kpidErrorFlags:
|
case kpidErrorFlags:
|
||||||
{
|
{
|
||||||
|
|
@ -319,10 +369,12 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||||
{
|
{
|
||||||
case kpidPath:
|
case kpidPath:
|
||||||
{
|
{
|
||||||
AString s (GetString(item.Name));
|
AString s;
|
||||||
|
GetString(s, item.Name);
|
||||||
if (s.IsEmpty())
|
if (s.IsEmpty())
|
||||||
s.Add_UInt32(index);
|
s.Add_UInt32(index);
|
||||||
AString type (GetString(item.Type));
|
AString type;
|
||||||
|
GetString(type, item.Type);
|
||||||
{
|
{
|
||||||
const char *ext = NDmg::Find_Apple_FS_Ext(type);
|
const char *ext = NDmg::Find_Apple_FS_Ext(type);
|
||||||
if (ext)
|
if (ext)
|
||||||
|
|
@ -336,6 +388,16 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||||
prop = s;
|
prop = s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
case kpidCpu:
|
||||||
|
{
|
||||||
|
AString s;
|
||||||
|
s.SetFrom_CalcLen(item.Processor, sizeof(item.Processor));
|
||||||
|
if (!s.IsEmpty())
|
||||||
|
prop = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
case kpidPackSize:
|
case kpidPackSize:
|
||||||
prop = BlocksToBytes(item.NumBlocks);
|
prop = BlocksToBytes(item.NumBlocks);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ protected:
|
||||||
_numThreads_WasForced = false;
|
_numThreads_WasForced = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28;
|
size_t memAvail = (size_t)sizeof(size_t) << 28;
|
||||||
_memAvail = memAvail;
|
_memAvail = memAvail;
|
||||||
_memUsage_Compress = memAvail;
|
_memUsage_Compress = memAvail;
|
||||||
_memUsage_Decompress = memAvail;
|
_memUsage_Decompress = memAvail;
|
||||||
|
|
@ -55,7 +55,7 @@ public:
|
||||||
bool _memUsage_WasSet;
|
bool _memUsage_WasSet;
|
||||||
UInt64 _memUsage_Compress;
|
UInt64 _memUsage_Compress;
|
||||||
UInt64 _memUsage_Decompress;
|
UInt64 _memUsage_Decompress;
|
||||||
UInt64 _memAvail;
|
size_t _memAvail;
|
||||||
|
|
||||||
bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
|
bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,13 @@
|
||||||
|
|
||||||
#include "../Compress/CopyCoder.h"
|
#include "../Compress/CopyCoder.h"
|
||||||
|
|
||||||
|
// #define Z7_ELF_SHOW_DETAILS
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16(p); return GetUi16(p); }
|
static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16a(p); return GetUi16a(p); }
|
||||||
static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); }
|
static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32a(p); return GetUi32a(p); }
|
||||||
static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64(p); return GetUi64(p); }
|
static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64a(p); return GetUi64a(p); }
|
||||||
|
|
||||||
#define G16(offs, v) v = Get16(p + (offs), be)
|
#define G16(offs, v) v = Get16(p + (offs), be)
|
||||||
#define G32(offs, v) v = Get32(p + (offs), be)
|
#define G32(offs, v) v = Get32(p + (offs), be)
|
||||||
|
|
@ -31,14 +33,51 @@ namespace NArchive {
|
||||||
namespace NElf {
|
namespace NElf {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ELF Structure for most files (real order can be different):
|
ELF Structure example:
|
||||||
|
{
|
||||||
Header
|
Header
|
||||||
Program (segment) header table (used at runtime)
|
Program header table (is used at runtime) (list of segment metadata records)
|
||||||
Segment1 (Section ... Section)
|
{
|
||||||
Segment2
|
Segment (Read)
|
||||||
|
Segment : PT_PHDR : header table itself
|
||||||
|
Segment : PT_INTERP
|
||||||
|
Segment : PT_NOTE
|
||||||
|
.rela.dyn (RELA, ALLOC)
|
||||||
|
Segment (Execute/Read)
|
||||||
|
.text section (PROGBITS, SHF_ALLOC | SHF_EXECINSTR)
|
||||||
|
Segment (Read)
|
||||||
|
.rodata (PROGBITS, SHF_ALLOC | SHF_WRITE)
|
||||||
|
Segment : PT_GNU_EH_FRAME
|
||||||
|
.eh_frame_hdr
|
||||||
|
.eh_frame
|
||||||
|
.gcc_except_table
|
||||||
...
|
...
|
||||||
SegmentN
|
Segment (Write/Read) (VaSize > Size)
|
||||||
|
Segment (Read) : PT_GNU_RELRO
|
||||||
|
Segment (Write/Read)
|
||||||
|
.data
|
||||||
|
.bss (Size == 0) (VSize != 0)
|
||||||
|
}
|
||||||
|
.comment (VA == 0)
|
||||||
|
.shstrtab (VA == 0)
|
||||||
Section header table (the data for linking and relocation)
|
Section header table (the data for linking and relocation)
|
||||||
|
}
|
||||||
|
|
||||||
|
Last top level segment contains .bss section that requires additional VA space.
|
||||||
|
So (VaSize > Size) for that segment.
|
||||||
|
|
||||||
|
Segments can be unsorted (by offset) in table.
|
||||||
|
Top level segments has Type=PT_LOAD : "Loadable segment".
|
||||||
|
Top level segments usually are aligned for page size (4 KB).
|
||||||
|
Another segments (non PT_LOAD segments) are inside PT_LOAD segments.
|
||||||
|
|
||||||
|
(VA-offset == 0) is possible for some sections and segments at the beginning of file.
|
||||||
|
(VA-offset == 4KB*N) for most sections and segments where (Size != 0),
|
||||||
|
(VA-offset != 4KB*N) for .bss section (last section), because (Size == 0),
|
||||||
|
and that section is not mapped from image file.
|
||||||
|
Some files contain additional "virtual" 4 KB page in VA space after
|
||||||
|
end of data of top level segments (PT_LOAD) before new top level segments.
|
||||||
|
So (VA-offset) value can increase by 4 KB step.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ELF_CLASS_32 1
|
#define ELF_CLASS_32 1
|
||||||
|
|
@ -47,14 +86,14 @@ namespace NElf {
|
||||||
#define ELF_DATA_2LSB 1
|
#define ELF_DATA_2LSB 1
|
||||||
#define ELF_DATA_2MSB 2
|
#define ELF_DATA_2MSB 2
|
||||||
|
|
||||||
static const UInt32 kHeaderSize32 = 0x34;
|
static const unsigned kHeaderSize32 = 0x34;
|
||||||
static const UInt32 kHeaderSize64 = 0x40;
|
static const unsigned kHeaderSize64 = 0x40;
|
||||||
|
|
||||||
static const UInt32 kSegmentSize32 = 0x20;
|
static const unsigned kSegmentSize32 = 0x20;
|
||||||
static const UInt32 kSegmentSize64 = 0x38;
|
static const unsigned kSegmentSize64 = 0x38;
|
||||||
|
|
||||||
static const UInt32 kSectionSize32 = 0x28;
|
static const unsigned kSectionSize32 = 0x28;
|
||||||
static const UInt32 kSectionSize64 = 0x40;
|
static const unsigned kSectionSize64 = 0x40;
|
||||||
|
|
||||||
struct CHeader
|
struct CHeader
|
||||||
{
|
{
|
||||||
|
|
@ -78,9 +117,9 @@ struct CHeader
|
||||||
UInt16 NumSections;
|
UInt16 NumSections;
|
||||||
UInt16 NamesSectIndex;
|
UInt16 NamesSectIndex;
|
||||||
|
|
||||||
bool Parse(const Byte *buf);
|
bool Parse(const Byte *p);
|
||||||
|
|
||||||
UInt64 GetHeadersSize() const { return (UInt64)HeaderSize +
|
UInt32 GetHeadersSize() const { return (UInt32)HeaderSize +
|
||||||
(UInt32)NumSegments * SegmentEntrySize +
|
(UInt32)NumSegments * SegmentEntrySize +
|
||||||
(UInt32)NumSections * SectionEntrySize; }
|
(UInt32)NumSections * SectionEntrySize; }
|
||||||
};
|
};
|
||||||
|
|
@ -104,7 +143,7 @@ bool CHeader::Parse(const Byte *p)
|
||||||
if (p[6] != 1) // Version
|
if (p[6] != 1) // Version
|
||||||
return false;
|
return false;
|
||||||
Os = p[7];
|
Os = p[7];
|
||||||
AbiVer = p[8];
|
// AbiVer = p[8];
|
||||||
for (int i = 9; i < 16; i++)
|
for (int i = 9; i < 16; i++)
|
||||||
if (p[i] != 0)
|
if (p[i] != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -117,16 +156,21 @@ bool CHeader::Parse(const Byte *p)
|
||||||
if (Mode64)
|
if (Mode64)
|
||||||
{
|
{
|
||||||
// G64(0x18, EntryVa);
|
// G64(0x18, EntryVa);
|
||||||
G64(0x20, ProgOffset);
|
G64(0x20, ProgOffset); // == kHeaderSize64 == 0x40 usually
|
||||||
G64(0x28, SectOffset);
|
G64(0x28, SectOffset);
|
||||||
p += 0x30;
|
p += 0x30;
|
||||||
|
// we expect that fields are aligned
|
||||||
|
if (ProgOffset & 7) return false;
|
||||||
|
if (SectOffset & 7) return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// G32(0x18, EntryVa);
|
// G32(0x18, EntryVa);
|
||||||
G32(0x1C, ProgOffset);
|
G32(0x1C, ProgOffset); // == kHeaderSize32 == 0x34 usually
|
||||||
G32(0x20, SectOffset);
|
G32(0x20, SectOffset);
|
||||||
p += 0x24;
|
p += 0x24;
|
||||||
|
if (ProgOffset & 3) return false;
|
||||||
|
if (SectOffset & 3) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
G32(0, Flags);
|
G32(0, Flags);
|
||||||
|
|
@ -140,21 +184,20 @@ bool CHeader::Parse(const Byte *p)
|
||||||
G16(12, NumSections);
|
G16(12, NumSections);
|
||||||
G16(14, NamesSectIndex);
|
G16(14, NamesSectIndex);
|
||||||
|
|
||||||
if (ProgOffset < HeaderSize && (ProgOffset != 0 || NumSegments != 0)) return false;
|
if (ProgOffset < HeaderSize && (ProgOffset || NumSegments)) return false;
|
||||||
if (SectOffset < HeaderSize && (SectOffset != 0 || NumSections != 0)) return false;
|
if (SectOffset < HeaderSize && (SectOffset || NumSections)) return false;
|
||||||
|
|
||||||
if (SegmentEntrySize == 0) { if (NumSegments != 0) return false; }
|
if (SegmentEntrySize == 0) { if (NumSegments) return false; }
|
||||||
else if (SegmentEntrySize != (Mode64 ? kSegmentSize64 : kSegmentSize32)) return false;
|
else if (SegmentEntrySize != (Mode64 ? kSegmentSize64 : kSegmentSize32)) return false;
|
||||||
|
|
||||||
if (SectionEntrySize == 0) { if (NumSections != 0) return false; }
|
if (SectionEntrySize == 0) { if (NumSections) return false; }
|
||||||
else if (SectionEntrySize != (Mode64 ? kSectionSize64 : kSectionSize32)) return false;
|
else if (SectionEntrySize != (Mode64 ? kSectionSize64 : kSectionSize32)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The program header table itself.
|
|
||||||
|
|
||||||
#define PT_PHDR 6
|
#define PT_PHDR 6 // The program header table itself.
|
||||||
#define PT_GNU_STACK 0x6474e551
|
#define PT_GNU_STACK 0x6474e551
|
||||||
|
|
||||||
static const CUInt32PCharPair g_SegnmentTypes[] =
|
static const CUInt32PCharPair g_SegnmentTypes[] =
|
||||||
|
|
@ -186,14 +229,16 @@ struct CSegment
|
||||||
UInt32 Flags;
|
UInt32 Flags;
|
||||||
UInt64 Offset;
|
UInt64 Offset;
|
||||||
UInt64 Va;
|
UInt64 Va;
|
||||||
// UInt64 Pa;
|
UInt64 Size; // size in file
|
||||||
UInt64 Size;
|
UInt64 VSize; // size in memory
|
||||||
UInt64 VSize;
|
#ifdef Z7_ELF_SHOW_DETAILS
|
||||||
UInt64 Align;
|
UInt64 Pa; // usually == Va, or == 0
|
||||||
|
UInt64 Align; // if (Align != 0), condition must be met:
|
||||||
|
// (VSize % Align == Offset % Alig)
|
||||||
|
#endif
|
||||||
void UpdateTotalSize(UInt64 &totalSize)
|
void UpdateTotalSize(UInt64 &totalSize)
|
||||||
{
|
{
|
||||||
UInt64 t = Offset + Size;
|
const UInt64 t = Offset + Size;
|
||||||
if (totalSize < t)
|
if (totalSize < t)
|
||||||
totalSize = t;
|
totalSize = t;
|
||||||
}
|
}
|
||||||
|
|
@ -208,20 +253,24 @@ void CSegment::Parse(const Byte *p, bool mode64, bool be)
|
||||||
G32(4, Flags);
|
G32(4, Flags);
|
||||||
G64(8, Offset);
|
G64(8, Offset);
|
||||||
G64(0x10, Va);
|
G64(0x10, Va);
|
||||||
// G64(0x18, Pa);
|
|
||||||
G64(0x20, Size);
|
G64(0x20, Size);
|
||||||
G64(0x28, VSize);
|
G64(0x28, VSize);
|
||||||
|
#ifdef Z7_ELF_SHOW_DETAILS
|
||||||
|
G64(0x18, Pa);
|
||||||
G64(0x30, Align);
|
G64(0x30, Align);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
G32(4, Offset);
|
G32(4, Offset);
|
||||||
G32(8, Va);
|
G32(8, Va);
|
||||||
// G32(0x0C, Pa);
|
|
||||||
G32(0x10, Size);
|
G32(0x10, Size);
|
||||||
G32(0x14, VSize);
|
G32(0x14, VSize);
|
||||||
G32(0x18, Flags);
|
G32(0x18, Flags);
|
||||||
|
#ifdef Z7_ELF_SHOW_DETAILS
|
||||||
|
G32(0x0C, Pa);
|
||||||
G32(0x1C, Align);
|
G32(0x1C, Align);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,6 +339,8 @@ static const CUInt32PCharPair g_SectTypes[] =
|
||||||
{ 0x70000005, "ARM_OVERLAYSECTION" }
|
{ 0x70000005, "ARM_OVERLAYSECTION" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// SHF_ flags
|
||||||
static const CUInt32PCharPair g_SectionFlags[] =
|
static const CUInt32PCharPair g_SectionFlags[] =
|
||||||
{
|
{
|
||||||
{ 0, "WRITE" },
|
{ 0, "WRITE" },
|
||||||
|
|
@ -303,7 +354,7 @@ static const CUInt32PCharPair g_SectionFlags[] =
|
||||||
{ 8, "OS_NONCONFORMING" },
|
{ 8, "OS_NONCONFORMING" },
|
||||||
{ 9, "GROUP" },
|
{ 9, "GROUP" },
|
||||||
{ 10, "TLS" },
|
{ 10, "TLS" },
|
||||||
{ 11, "CP_SECTION" },
|
{ 11, "COMPRESSED" },
|
||||||
{ 12, "DP_SECTION" },
|
{ 12, "DP_SECTION" },
|
||||||
{ 13, "XCORE_SHF_CP_SECTION" },
|
{ 13, "XCORE_SHF_CP_SECTION" },
|
||||||
{ 28, "64_LARGE" },
|
{ 28, "64_LARGE" },
|
||||||
|
|
@ -326,7 +377,7 @@ struct CSection
|
||||||
|
|
||||||
void UpdateTotalSize(UInt64 &totalSize)
|
void UpdateTotalSize(UInt64 &totalSize)
|
||||||
{
|
{
|
||||||
UInt64 t = Offset + GetSize();
|
const UInt64 t = Offset + GetSize();
|
||||||
if (totalSize < t)
|
if (totalSize < t)
|
||||||
totalSize = t;
|
totalSize = t;
|
||||||
}
|
}
|
||||||
|
|
@ -412,7 +463,7 @@ static const char * const g_Machines[] =
|
||||||
, "TRW RH-32"
|
, "TRW RH-32"
|
||||||
, "Motorola RCE"
|
, "Motorola RCE"
|
||||||
, "ARM"
|
, "ARM"
|
||||||
, "Alpha"
|
, "Alpha-STD"
|
||||||
, "Hitachi SH"
|
, "Hitachi SH"
|
||||||
, "SPARC-V9"
|
, "SPARC-V9"
|
||||||
, "Siemens Tricore"
|
, "Siemens Tricore"
|
||||||
|
|
@ -577,8 +628,9 @@ static const char * const g_Machines[] =
|
||||||
static const CUInt32PCharPair g_MachinePairs[] =
|
static const CUInt32PCharPair g_MachinePairs[] =
|
||||||
{
|
{
|
||||||
{ 243, "RISC-V" },
|
{ 243, "RISC-V" },
|
||||||
{ 47787, "Xilinx MicroBlaze" }
|
{ 258, "LoongArch" },
|
||||||
// { 0x9026, "Alpha" }
|
{ 0x9026, "Alpha" }, // EM_ALPHA_EXP, obsolete, (used by NetBSD/alpha) (written in the absence of an ABI)
|
||||||
|
{ 0xbaab, "Xilinx MicroBlaze" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const CUInt32PCharPair g_OS[] =
|
static const CUInt32PCharPair g_OS[] =
|
||||||
|
|
@ -600,6 +652,8 @@ static const CUInt32PCharPair g_OS[] =
|
||||||
{ 14, "HP NSK" },
|
{ 14, "HP NSK" },
|
||||||
{ 15, "AROS" },
|
{ 15, "AROS" },
|
||||||
{ 16, "FenixOS" },
|
{ 16, "FenixOS" },
|
||||||
|
{ 17, "CloudABI" },
|
||||||
|
{ 18, "OpenVOS" },
|
||||||
{ 64, "Bare-metal TMS320C6000" },
|
{ 64, "Bare-metal TMS320C6000" },
|
||||||
{ 65, "Linux TMS320C6000" },
|
{ 65, "Linux TMS320C6000" },
|
||||||
{ 97, "ARM" },
|
{ 97, "ARM" },
|
||||||
|
|
@ -693,7 +747,9 @@ public:
|
||||||
void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const
|
void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const
|
||||||
{
|
{
|
||||||
if (index >= _sections.Size())
|
if (index >= _sections.Size())
|
||||||
return;
|
prop = index; // it's possible for some file, but maybe it's ERROR case
|
||||||
|
else
|
||||||
|
{
|
||||||
const CSection §ion = _sections[index];
|
const CSection §ion = _sections[index];
|
||||||
const UInt32 offset = section.Name;
|
const UInt32 offset = section.Name;
|
||||||
if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */)
|
if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */)
|
||||||
|
|
@ -703,13 +759,15 @@ void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showN
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const Byte *p = _namesData;
|
const Byte *p = _namesData;
|
||||||
size_t size = _namesData.Size();
|
const size_t size = _namesData.Size();
|
||||||
for (size_t i = offset; i < size; i++)
|
for (size_t i = offset; i < size; i++)
|
||||||
if (p[i] == 0)
|
if (p[i] == 0)
|
||||||
{
|
{
|
||||||
prop = (const char *)(p + offset);
|
prop = (const char *)(p + offset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
prop = "ERROR";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Byte kArcProps[] =
|
static const Byte kArcProps[] =
|
||||||
|
|
@ -726,7 +784,14 @@ static const Byte kArcProps[] =
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kpidLinkSection = kpidUserDefined,
|
kpidLinkSection = kpidUserDefined,
|
||||||
kpidInfoSection
|
kpidInfoSection,
|
||||||
|
kpidEntrySize
|
||||||
|
#ifdef Z7_ELF_SHOW_DETAILS
|
||||||
|
// , kpidAlign
|
||||||
|
, kpidPa
|
||||||
|
, kpidDelta
|
||||||
|
, kpidOffsetEnd
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const CStatProp kProps[] =
|
static const CStatProp kProps[] =
|
||||||
|
|
@ -738,6 +803,14 @@ static const CStatProp kProps[] =
|
||||||
{ NULL, kpidVa, VT_UI8 },
|
{ NULL, kpidVa, VT_UI8 },
|
||||||
{ NULL, kpidType, VT_BSTR },
|
{ NULL, kpidType, VT_BSTR },
|
||||||
{ NULL, kpidCharacts, VT_BSTR }
|
{ NULL, kpidCharacts, VT_BSTR }
|
||||||
|
#ifdef Z7_ELF_SHOW_DETAILS
|
||||||
|
// , { "Align", kpidAlign, VT_UI8 }
|
||||||
|
, { NULL, kpidClusterSize, VT_UI8 }
|
||||||
|
, { "PA", kpidPa, VT_UI8 }
|
||||||
|
, { "End offset", kpidOffsetEnd, VT_UI8 }
|
||||||
|
, { "Delta (VA-Offset)", kpidDelta, VT_UI8 }
|
||||||
|
#endif
|
||||||
|
, { "Entry Size", kpidEntrySize, VT_UI8}
|
||||||
, { "Link Section", kpidLinkSection, VT_BSTR}
|
, { "Link Section", kpidLinkSection, VT_BSTR}
|
||||||
, { "Info Section", kpidInfoSection, VT_BSTR}
|
, { "Info Section", kpidInfoSection, VT_BSTR}
|
||||||
};
|
};
|
||||||
|
|
@ -769,7 +842,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
if (s.IsEmpty())
|
if (s.IsEmpty())
|
||||||
s = TypePairToString(g_MachinePairs, Z7_ARRAY_SIZE(g_MachinePairs), _header.Machine);
|
s = TypePairToString(g_MachinePairs, Z7_ARRAY_SIZE(g_MachinePairs), _header.Machine);
|
||||||
UInt32 flags = _header.Flags;
|
UInt32 flags = _header.Flags;
|
||||||
if (flags != 0)
|
if (flags)
|
||||||
{
|
{
|
||||||
s.Add_Space();
|
s.Add_Space();
|
||||||
if (_header.Machine == k_Machine_ARM)
|
if (_header.Machine == k_Machine_ARM)
|
||||||
|
|
@ -781,18 +854,16 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
else if (_header.Machine == k_Machine_MIPS)
|
else if (_header.Machine == k_Machine_MIPS)
|
||||||
{
|
{
|
||||||
const UInt32 ver = flags >> 28;
|
const UInt32 ver = flags >> 28;
|
||||||
s += "v";
|
s.Add_Char('v');
|
||||||
s.Add_UInt32(ver);
|
s.Add_UInt32(ver);
|
||||||
flags &= (((UInt32)1 << 28) - 1);
|
flags &= ((UInt32)1 << 28) - 1;
|
||||||
|
const UInt32 abi = (flags >> 12) & 7;
|
||||||
UInt32 abi = (flags >> 12) & 7;
|
if (abi)
|
||||||
if (abi != 0)
|
|
||||||
{
|
{
|
||||||
s += " ABI:";
|
s += " ABI:";
|
||||||
s.Add_UInt32(abi);
|
s.Add_UInt32(abi);
|
||||||
}
|
}
|
||||||
flags &= ~((UInt32)7 << 12);
|
flags &= ~((UInt32)7 << 12);
|
||||||
|
|
||||||
s.Add_Space();
|
s.Add_Space();
|
||||||
s += FlagsToString(g_MIPS_Flags, Z7_ARRAY_SIZE(g_MIPS_Flags), flags);
|
s += FlagsToString(g_MIPS_Flags, Z7_ARRAY_SIZE(g_MIPS_Flags), flags);
|
||||||
}
|
}
|
||||||
|
|
@ -813,6 +884,31 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
flags &= ~(UInt32)6;
|
flags &= ~(UInt32)6;
|
||||||
s += FlagsToString(g_RISCV_Flags, Z7_ARRAY_SIZE(g_RISCV_Flags), flags);
|
s += FlagsToString(g_RISCV_Flags, Z7_ARRAY_SIZE(g_RISCV_Flags), flags);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
#define k_Machine_LOONGARCH 258
|
||||||
|
else if (_header.Machine == k_Machine_LOONGARCH)
|
||||||
|
{
|
||||||
|
s += "ABI:";
|
||||||
|
s.Add_UInt32((flags >> 6) & 3);
|
||||||
|
s.Add_Dot();
|
||||||
|
s.Add_UInt32((flags >> 3) & 7);
|
||||||
|
s.Add_Dot();
|
||||||
|
#if 1
|
||||||
|
s.Add_UInt32(flags & 7);
|
||||||
|
#else
|
||||||
|
static const char k_LoongArch_Float_Type[8] = { '0', 's', 'f', 'd', '4' ,'5', '6', '7' };
|
||||||
|
s.Add_Char(k_LoongArch_Float_Type[flags & 7]);
|
||||||
|
#endif
|
||||||
|
flags &= ~(UInt32)0xff;
|
||||||
|
if (flags)
|
||||||
|
{
|
||||||
|
s.Add_Colon();
|
||||||
|
char sz[16];
|
||||||
|
ConvertUInt32ToHex(flags, sz);
|
||||||
|
s += sz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char sz[16];
|
char sz[16];
|
||||||
|
|
@ -827,13 +923,39 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break;
|
case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break;
|
||||||
case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break;
|
case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break;
|
||||||
case kpidComment:
|
case kpidComment:
|
||||||
|
{
|
||||||
|
AString s;
|
||||||
if (_stackFlags_Defined)
|
if (_stackFlags_Defined)
|
||||||
{
|
{
|
||||||
AString s ("STACK: ");
|
s += "STACK: ";
|
||||||
s += FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), _stackFlags);
|
s += FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), _stackFlags);
|
||||||
prop = s;
|
s.Add_LF();
|
||||||
|
/*
|
||||||
|
if (_header.EntryVa)
|
||||||
|
{
|
||||||
|
s += "Entry point: 0x";
|
||||||
|
char temp[16 + 4];
|
||||||
|
ConvertUInt64ToHex(_header.EntryVa, temp);
|
||||||
|
s += temp;
|
||||||
|
s.Add_LF();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if (_header.NumSegments)
|
||||||
|
{
|
||||||
|
s += "Segments: ";
|
||||||
|
s.Add_UInt32(_header.NumSegments);
|
||||||
|
s.Add_LF();
|
||||||
|
}
|
||||||
|
if (_header.NumSections)
|
||||||
|
{
|
||||||
|
s += "Sections: ";
|
||||||
|
s.Add_UInt32(_header.NumSections);
|
||||||
|
s.Add_LF();
|
||||||
|
}
|
||||||
|
prop = s;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case kpidExtension:
|
case kpidExtension:
|
||||||
{
|
{
|
||||||
const char *s = NULL;
|
const char *s = NULL;
|
||||||
|
|
@ -878,12 +1000,17 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||||
}
|
}
|
||||||
case kpidOffset: prop = item.Offset; break;
|
case kpidOffset: prop = item.Offset; break;
|
||||||
case kpidVa: prop = item.Va; break;
|
case kpidVa: prop = item.Va; break;
|
||||||
|
#ifdef Z7_ELF_SHOW_DETAILS
|
||||||
|
case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break;
|
||||||
|
case kpidOffsetEnd: prop = item.Offset + item.Size; break;
|
||||||
|
case kpidPa: prop = item.Pa; break;
|
||||||
|
case kpidClusterSize: prop = item.Align; break;
|
||||||
|
#endif
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
case kpidPackSize: prop = (UInt64)item.Size; break;
|
case kpidPackSize: prop = (UInt64)item.Size; break;
|
||||||
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
|
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
|
||||||
case kpidType: PAIR_TO_PROP(g_SegnmentTypes, item.Type, prop); break;
|
case kpidType: PAIR_TO_PROP(g_SegnmentTypes, item.Type, prop); break;
|
||||||
case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break;
|
case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -895,13 +1022,19 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||||
case kpidPath: GetSectionName(index, prop, true); break;
|
case kpidPath: GetSectionName(index, prop, true); break;
|
||||||
case kpidOffset: prop = item.Offset; break;
|
case kpidOffset: prop = item.Offset; break;
|
||||||
case kpidVa: prop = item.Va; break;
|
case kpidVa: prop = item.Va; break;
|
||||||
|
#ifdef Z7_ELF_SHOW_DETAILS
|
||||||
|
case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break;
|
||||||
|
case kpidOffsetEnd: prop = item.Offset + item.GetSize(); break;
|
||||||
|
#endif
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
case kpidPackSize: prop = (UInt64)(item.Type == SHT_NOBITS ? 0 : item.VSize); break;
|
case kpidPackSize: prop = (UInt64)(item.Type == SHT_NOBITS ? 0 : item.VSize); break;
|
||||||
case kpidVirtualSize: prop = item.GetSize(); break;
|
case kpidVirtualSize: prop = item.GetSize(); break;
|
||||||
case kpidType: PAIR_TO_PROP(g_SectTypes, item.Type, prop); break;
|
case kpidType: PAIR_TO_PROP(g_SectTypes, item.Type, prop); break;
|
||||||
case kpidCharacts: FLAGS_TO_PROP(g_SectionFlags, (UInt32)item.Flags, prop); break;
|
case kpidCharacts: FLAGS_TO_PROP(g_SectionFlags, (UInt32)item.Flags, prop); break;
|
||||||
|
// case kpidAlign: prop = item.Align; break;
|
||||||
case kpidLinkSection: GetSectionName(item.Link, prop, false); break;
|
case kpidLinkSection: GetSectionName(item.Link, prop, false); break;
|
||||||
case kpidInfoSection: GetSectionName(item.Info, prop, false); break;
|
case kpidInfoSection: GetSectionName(item.Info, prop, false); break;
|
||||||
|
case kpidEntrySize: prop = (UInt64)item.EntSize; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
|
|
@ -910,43 +1043,47 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CHandler::Open2(IInStream *stream)
|
HRESULT CHandler::Open2(IInStream *stream)
|
||||||
|
{
|
||||||
{
|
{
|
||||||
const UInt32 kStartSize = kHeaderSize64;
|
const UInt32 kStartSize = kHeaderSize64;
|
||||||
Byte h[kStartSize];
|
UInt64 h64[kStartSize / 8];
|
||||||
RINOK(ReadStream_FALSE(stream, h, kStartSize))
|
RINOK(ReadStream_FALSE(stream, h64, kStartSize))
|
||||||
if (h[0] != 0x7F || h[1] != 'E' || h[2] != 'L' || h[3] != 'F')
|
const Byte *h = (const Byte *)(const void *)h64;
|
||||||
|
if (GetUi32a(h) != 0x464c457f)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if (!_header.Parse(h))
|
if (!_header.Parse(h))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
_totalSize = _header.HeaderSize;
|
_totalSize = _header.HeaderSize;
|
||||||
|
|
||||||
bool addSegments = false;
|
bool addSegments = false;
|
||||||
bool addSections = false;
|
bool addSections = false;
|
||||||
|
// first section usually is NULL (with zero offsets and zero sizes).
|
||||||
if (_header.NumSections > 1)
|
if (_header.NumSegments == 0 || _header.NumSections > 1)
|
||||||
addSections = true;
|
addSections = true;
|
||||||
else
|
else
|
||||||
addSegments = true;
|
addSegments = true;
|
||||||
|
#ifdef Z7_ELF_SHOW_DETAILS
|
||||||
|
addSections = true;
|
||||||
|
addSegments = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_header.NumSegments != 0)
|
if (_header.NumSegments)
|
||||||
{
|
{
|
||||||
if (_header.ProgOffset > (UInt64)1 << 60) return S_FALSE;
|
if (_header.ProgOffset > (UInt64)1 << 60) return S_FALSE;
|
||||||
RINOK(InStream_SeekSet(stream, _header.ProgOffset))
|
RINOK(InStream_SeekSet(stream, _header.ProgOffset))
|
||||||
const size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments;
|
const size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments;
|
||||||
|
|
||||||
CByteArr buf(size);
|
CByteArr buf(size);
|
||||||
|
|
||||||
RINOK(ReadStream_FALSE(stream, buf, size))
|
RINOK(ReadStream_FALSE(stream, buf, size))
|
||||||
|
{
|
||||||
const UInt64 total = _header.ProgOffset + size;
|
const UInt64 total = _header.ProgOffset + size;
|
||||||
if (_totalSize < total)
|
if (_totalSize < total)
|
||||||
_totalSize = total;
|
_totalSize = total;
|
||||||
|
}
|
||||||
const Byte *p = buf;
|
|
||||||
|
|
||||||
if (addSegments)
|
if (addSegments)
|
||||||
_segments.ClearAndReserve(_header.NumSegments);
|
_segments.ClearAndReserve(_header.NumSegments);
|
||||||
|
const Byte *p = buf;
|
||||||
for (unsigned i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize)
|
for (unsigned i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize)
|
||||||
{
|
{
|
||||||
CSegment seg;
|
CSegment seg;
|
||||||
|
|
@ -957,29 +1094,29 @@ HRESULT CHandler::Open2(IInStream *stream)
|
||||||
_stackFlags = seg.Flags;
|
_stackFlags = seg.Flags;
|
||||||
_stackFlags_Defined = true;
|
_stackFlags_Defined = true;
|
||||||
}
|
}
|
||||||
if (addSegments && seg.Type != PT_PHDR)
|
if (addSegments
|
||||||
|
// we don't show program header table segment
|
||||||
|
&& seg.Type != PT_PHDR
|
||||||
|
)
|
||||||
_segments.AddInReserved(seg);
|
_segments.AddInReserved(seg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_header.NumSections != 0)
|
if (_header.NumSections)
|
||||||
{
|
{
|
||||||
if (_header.SectOffset > (UInt64)1 << 60) return S_FALSE;
|
if (_header.SectOffset > (UInt64)1 << 60) return S_FALSE;
|
||||||
RINOK(InStream_SeekSet(stream, _header.SectOffset))
|
RINOK(InStream_SeekSet(stream, _header.SectOffset))
|
||||||
size_t size = (size_t)_header.SectionEntrySize * _header.NumSections;
|
const size_t size = (size_t)_header.SectionEntrySize * _header.NumSections;
|
||||||
|
|
||||||
CByteArr buf(size);
|
CByteArr buf(size);
|
||||||
|
|
||||||
RINOK(ReadStream_FALSE(stream, buf, size))
|
RINOK(ReadStream_FALSE(stream, buf, size))
|
||||||
|
{
|
||||||
UInt64 total = _header.SectOffset + size;
|
const UInt64 total = _header.SectOffset + size;
|
||||||
if (_totalSize < total)
|
if (_totalSize < total)
|
||||||
_totalSize = total;
|
_totalSize = total;
|
||||||
|
}
|
||||||
const Byte *p = buf;
|
|
||||||
|
|
||||||
if (addSections)
|
if (addSections)
|
||||||
_sections.ClearAndReserve(_header.NumSections);
|
_sections.ClearAndReserve(_header.NumSections);
|
||||||
|
const Byte *p = buf;
|
||||||
for (unsigned i = 0; i < _header.NumSections; i++, p += _header.SectionEntrySize)
|
for (unsigned i = 0; i < _header.NumSections; i++, p += _header.SectionEntrySize)
|
||||||
{
|
{
|
||||||
CSection sect;
|
CSection sect;
|
||||||
|
|
@ -1000,8 +1137,7 @@ HRESULT CHandler::Open2(IInStream *stream)
|
||||||
{
|
{
|
||||||
const CSection § = _sections[_header.NamesSectIndex];
|
const CSection § = _sections[_header.NamesSectIndex];
|
||||||
const UInt64 size = sect.GetSize();
|
const UInt64 size = sect.GetSize();
|
||||||
if (size != 0
|
if (size && size < ((UInt64)1 << 31)
|
||||||
&& size < ((UInt64)1 << 31)
|
|
||||||
&& (Int64)sect.Offset >= 0)
|
&& (Int64)sect.Offset >= 0)
|
||||||
{
|
{
|
||||||
_namesData.Alloc((size_t)size);
|
_namesData.Alloc((size_t)size);
|
||||||
|
|
@ -1009,9 +1145,9 @@ HRESULT CHandler::Open2(IInStream *stream)
|
||||||
RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size))
|
RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// we will not delete NULL sections, since we have links to section via indexes
|
// we cannot delete "NULL" sections,
|
||||||
|
// because we have links to sections array via indexes
|
||||||
for (int i = _sections.Size() - 1; i >= 0; i--)
|
for (int i = _sections.Size() - 1; i >= 0; i--)
|
||||||
if (_sections[i].Type == SHT_NULL)
|
if (_sections[i].Type == SHT_NULL)
|
||||||
_items.Delete(i);
|
_items.Delete(i);
|
||||||
|
|
@ -1080,7 +1216,7 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
}
|
}
|
||||||
RINOK(extractCallback->SetTotal(totalSize))
|
RINOK(extractCallback->SetTotal(totalSize))
|
||||||
|
|
||||||
UInt64 currentTotalSize = 0;
|
totalSize = 0;
|
||||||
UInt64 currentItemSize;
|
UInt64 currentItemSize;
|
||||||
|
|
||||||
CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
|
CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
|
||||||
|
|
@ -1089,9 +1225,9 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream;
|
CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream;
|
||||||
inStream->SetStream(_inStream);
|
inStream->SetStream(_inStream);
|
||||||
|
|
||||||
for (i = 0;; i++, currentTotalSize += currentItemSize)
|
for (i = 0;; i++, totalSize += currentItemSize)
|
||||||
{
|
{
|
||||||
lps->InSize = lps->OutSize = currentTotalSize;
|
lps->InSize = lps->OutSize = totalSize;
|
||||||
RINOK(lps->SetCur())
|
RINOK(lps->SetCur())
|
||||||
if (i >= numItems)
|
if (i >= numItems)
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,12 @@ static const CPartType kPartTypes[] =
|
||||||
|
|
||||||
{ 0x0FC63DAF, NULL, "Linux Data" },
|
{ 0x0FC63DAF, NULL, "Linux Data" },
|
||||||
{ 0x0657FD6D, NULL, "Linux Swap" },
|
{ 0x0657FD6D, NULL, "Linux Swap" },
|
||||||
|
{ 0x44479540, NULL, "Linux root (x86)" },
|
||||||
|
{ 0x4F68BCE3, NULL, "Linux root (x86-64)" },
|
||||||
|
{ 0x69DAD710, NULL, "Linux root (ARM)" },
|
||||||
|
{ 0xB921B045, NULL, "Linux root (ARM64)" },
|
||||||
|
{ 0x993D8D3D, NULL, "Linux root (IA-64)" },
|
||||||
|
|
||||||
|
|
||||||
{ 0x83BD6B9D, NULL, "FreeBSD Boot" },
|
{ 0x83BD6B9D, NULL, "FreeBSD Boot" },
|
||||||
{ 0x516E7CB4, NULL, "FreeBSD Data" },
|
{ 0x516E7CB4, NULL, "FreeBSD Data" },
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@
|
||||||
#define Get32(p) GetBe32(p)
|
#define Get32(p) GetBe32(p)
|
||||||
#define Get64(p) GetBe64(p)
|
#define Get64(p) GetBe64(p)
|
||||||
|
|
||||||
|
#define Get16a(p) GetBe16a(p)
|
||||||
|
#define Get32a(p) GetBe32a(p)
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NHfs {
|
namespace NHfs {
|
||||||
|
|
||||||
|
|
@ -104,23 +107,21 @@ UInt32 CFork::Calc_NumBlocks_from_Extents() const
|
||||||
{
|
{
|
||||||
UInt32 num = 0;
|
UInt32 num = 0;
|
||||||
FOR_VECTOR (i, Extents)
|
FOR_VECTOR (i, Extents)
|
||||||
{
|
|
||||||
num += Extents[i].NumBlocks;
|
num += Extents[i].NumBlocks;
|
||||||
}
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFork::Check_NumBlocks() const
|
bool CFork::Check_NumBlocks() const
|
||||||
{
|
{
|
||||||
UInt32 num = 0;
|
UInt32 num = NumBlocks;
|
||||||
FOR_VECTOR (i, Extents)
|
FOR_VECTOR (i, Extents)
|
||||||
{
|
{
|
||||||
UInt32 next = num + Extents[i].NumBlocks;
|
const UInt32 cur = Extents[i].NumBlocks;
|
||||||
if (next < num)
|
if (num < cur)
|
||||||
return false;
|
return false;
|
||||||
num = next;
|
num -= cur;
|
||||||
}
|
}
|
||||||
return num == NumBlocks;
|
return num == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CIdIndexPair
|
struct CIdIndexPair
|
||||||
|
|
@ -175,7 +176,7 @@ static int Find_in_IdExtents(const CObjectVector<CIdExtents> &items, UInt32 id)
|
||||||
|
|
||||||
bool CFork::Upgrade(const CObjectVector<CIdExtents> &items, UInt32 id)
|
bool CFork::Upgrade(const CObjectVector<CIdExtents> &items, UInt32 id)
|
||||||
{
|
{
|
||||||
int index = Find_in_IdExtents(items, id);
|
const int index = Find_in_IdExtents(items, id);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return true;
|
return true;
|
||||||
const CIdExtents &item = items[index];
|
const CIdExtents &item = items[index];
|
||||||
|
|
@ -188,8 +189,13 @@ bool CFork::Upgrade(const CObjectVector<CIdExtents> &items, UInt32 id)
|
||||||
|
|
||||||
struct CVolHeader
|
struct CVolHeader
|
||||||
{
|
{
|
||||||
Byte Header[2];
|
unsigned BlockSizeLog;
|
||||||
UInt16 Version;
|
UInt32 NumFiles;
|
||||||
|
UInt32 NumFolders;
|
||||||
|
UInt32 NumBlocks;
|
||||||
|
UInt32 NumFreeBlocks;
|
||||||
|
|
||||||
|
bool Is_Hsfx_ver5;
|
||||||
// UInt32 Attr;
|
// UInt32 Attr;
|
||||||
// UInt32 LastMountedVersion;
|
// UInt32 LastMountedVersion;
|
||||||
// UInt32 JournalInfoBlock;
|
// UInt32 JournalInfoBlock;
|
||||||
|
|
@ -199,19 +205,13 @@ struct CVolHeader
|
||||||
// UInt32 BackupTime;
|
// UInt32 BackupTime;
|
||||||
// UInt32 CheckedTime;
|
// UInt32 CheckedTime;
|
||||||
|
|
||||||
UInt32 NumFiles;
|
|
||||||
UInt32 NumFolders;
|
|
||||||
unsigned BlockSizeLog;
|
|
||||||
UInt32 NumBlocks;
|
|
||||||
UInt32 NumFreeBlocks;
|
|
||||||
|
|
||||||
// UInt32 WriteCount;
|
// UInt32 WriteCount;
|
||||||
// UInt32 FinderInfo[8];
|
// UInt32 FinderInfo[8];
|
||||||
// UInt64 VolID;
|
// UInt64 VolID;
|
||||||
|
|
||||||
UInt64 GetPhySize() const { return (UInt64)NumBlocks << BlockSizeLog; }
|
UInt64 GetPhySize() const { return (UInt64)NumBlocks << BlockSizeLog; }
|
||||||
UInt64 GetFreeSize() const { return (UInt64)NumFreeBlocks << BlockSizeLog; }
|
UInt64 GetFreeSize() const { return (UInt64)NumFreeBlocks << BlockSizeLog; }
|
||||||
bool IsHfsX() const { return Version > 4; }
|
bool IsHfsX() const { return Is_Hsfx_ver5; }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft)
|
inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft)
|
||||||
|
|
@ -463,18 +463,18 @@ public:
|
||||||
bool UnsupportedFeature;
|
bool UnsupportedFeature;
|
||||||
bool ThereAreAltStreams;
|
bool ThereAreAltStreams;
|
||||||
// bool CaseSensetive;
|
// bool CaseSensetive;
|
||||||
|
UInt32 MethodsMask;
|
||||||
UString ResFileName;
|
UString ResFileName;
|
||||||
|
|
||||||
UInt64 SpecOffset;
|
UInt64 SpecOffset;
|
||||||
UInt64 PhySize;
|
// UInt64 PhySize;
|
||||||
UInt64 PhySize2;
|
UInt64 PhySize2;
|
||||||
UInt64 ArcFileSize;
|
UInt64 ArcFileSize;
|
||||||
UInt32 MethodsMask;
|
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
SpecOffset = 0;
|
SpecOffset = 0;
|
||||||
PhySize = 0;
|
// PhySize = 0;
|
||||||
PhySize2 = 0;
|
PhySize2 = 0;
|
||||||
ArcFileSize = 0;
|
ArcFileSize = 0;
|
||||||
MethodsMask = 0;
|
MethodsMask = 0;
|
||||||
|
|
@ -596,7 +596,7 @@ HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inSt
|
||||||
{
|
{
|
||||||
if (fork.NumBlocks >= Header.NumBlocks)
|
if (fork.NumBlocks >= Header.NumBlocks)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if ((ArcFileSize >> Header.BlockSizeLog) + 1 < fork.NumBlocks)
|
if (((ArcFileSize - SpecOffset) >> Header.BlockSizeLog) + 1 < fork.NumBlocks)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
const size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog;
|
const size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog;
|
||||||
|
|
@ -1328,28 +1328,26 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const unsigned kHeaderPadSize = (1 << 10);
|
static const unsigned kHeaderPadSize = 1 << 10;
|
||||||
static const unsigned kMainHeaderSize = 512;
|
static const unsigned kMainHeaderSize = 512;
|
||||||
static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize;
|
static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize;
|
||||||
|
|
||||||
|
static const unsigned k_Signature_LE16_HFS_BD = 'B' + ((unsigned)'D' << 8);
|
||||||
|
static const unsigned k_Signature_LE16_HPLUS = 'H' + ((unsigned)'+' << 8);
|
||||||
|
static const UInt32 k_Signature_LE32_HFSP_VER4 = 'H' + ((UInt32)'+' << 8) + ((UInt32)4 << 24);
|
||||||
|
static const UInt32 k_Signature_LE32_HFSX_VER5 = 'H' + ((UInt32)'X' << 8) + ((UInt32)5 << 24);
|
||||||
|
|
||||||
API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size)
|
API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size)
|
||||||
{
|
{
|
||||||
if (size < kHfsHeaderSize)
|
if (size < kHfsHeaderSize)
|
||||||
return k_IsArc_Res_NEED_MORE;
|
return k_IsArc_Res_NEED_MORE;
|
||||||
p += kHeaderPadSize;
|
p += kHeaderPadSize;
|
||||||
if (p[0] == 'B' && p[1] == 'D')
|
const UInt32 sig = GetUi32(p);
|
||||||
{
|
if (sig != k_Signature_LE32_HFSP_VER4)
|
||||||
if (p[0x7C] != 'H' || p[0x7C + 1] != '+')
|
if (sig != k_Signature_LE32_HFSX_VER5)
|
||||||
|
if ((UInt16)sig != k_Signature_LE16_HFS_BD
|
||||||
|
|| GetUi16(p + 0x7c) != k_Signature_LE16_HPLUS)
|
||||||
return k_IsArc_Res_NO;
|
return k_IsArc_Res_NO;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X'))
|
|
||||||
return k_IsArc_Res_NO;
|
|
||||||
UInt32 version = Get16(p + 2);
|
|
||||||
if (version < 4 || version > 5)
|
|
||||||
return k_IsArc_Res_NO;
|
|
||||||
}
|
|
||||||
return k_IsArc_Res_YES;
|
return k_IsArc_Res_YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1357,30 +1355,42 @@ API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size)
|
||||||
HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
|
HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
Byte buf[kHfsHeaderSize];
|
UInt32 buf32[kHfsHeaderSize / 4];
|
||||||
RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize))
|
RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize))
|
||||||
{
|
const Byte *p = (const Byte *)buf32 + kHeaderPadSize;
|
||||||
for (unsigned i = 0; i < kHeaderPadSize; i++)
|
|
||||||
if (buf[i] != 0)
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
const Byte *p = buf + kHeaderPadSize;
|
|
||||||
CVolHeader &h = Header;
|
CVolHeader &h = Header;
|
||||||
|
|
||||||
h.Header[0] = p[0];
|
if (GetUi16a(p) == k_Signature_LE16_HFS_BD)
|
||||||
h.Header[1] = p[1];
|
|
||||||
|
|
||||||
if (p[0] == 'B' && p[1] == 'D')
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
It's header for old HFS format.
|
It's header for old HFS format.
|
||||||
We don't support old HFS format, but we support
|
We don't support old HFS format, but we support
|
||||||
special HFS volume that contains embedded HFS+ volume
|
special HFS volume that contains embedded HFS+ volume.
|
||||||
|
HFS MDB : Master directory block
|
||||||
|
HFS VIB : Volume information block
|
||||||
|
some old images contain boot data with "LK" signature at start of buf32.
|
||||||
*/
|
*/
|
||||||
|
#if 1
|
||||||
if (p[0x7C] != 'H' || p[0x7C + 1] != '+')
|
// here we check first bytes of archive,
|
||||||
|
// because start data can contain signature of some another
|
||||||
|
// archive type that could have priority over HFS.
|
||||||
|
const void *buf_ptr = (const void *)buf32;
|
||||||
|
const unsigned sig = GetUi16a(buf_ptr);
|
||||||
|
if (sig != 'L' + ((unsigned)'K' << 8))
|
||||||
|
{
|
||||||
|
// some old HFS (non HFS+) files have no "LK" signature,
|
||||||
|
// but have non-zero data after 2 first bytes in start 1 KiB.
|
||||||
|
if (sig != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
/*
|
||||||
|
for (unsigned i = 0; i < kHeaderPadSize / 4; i++)
|
||||||
|
if (buf32[i] != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (GetUi16a(p + 0x7c) != k_Signature_LE16_HPLUS) // signature of embedded HFS+ volume
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
h.CTime = Get32(p + 0x2);
|
h.CTime = Get32(p + 0x2);
|
||||||
h.MTime = Get32(p + 0x6);
|
h.MTime = Get32(p + 0x6);
|
||||||
|
|
@ -1399,80 +1409,104 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
|
||||||
h.NumFreeBlocks = Get16(p + 0x22);
|
h.NumFreeBlocks = Get16(p + 0x22);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UInt32 blockSize = Get32(p + 0x14);
|
// v24.09: blockSize in old HFS image can be non-power of 2.
|
||||||
|
const UInt32 blockSize = Get32a(p + 0x14); // drAlBlkSiz
|
||||||
|
if (blockSize == 0 || (blockSize & 0x1ff))
|
||||||
|
return S_FALSE;
|
||||||
|
const unsigned numBlocks = Get16a(p + 0x12); // drNmAlBlks
|
||||||
|
// UInt16 drFreeBks = Get16a(p + 0x22); // number of unused allocation blocks
|
||||||
|
/*
|
||||||
|
we suppose that it has the following layout:
|
||||||
{
|
{
|
||||||
|
start data with header
|
||||||
|
blocks[h.NumBlocks]
|
||||||
|
end data with header (probably size_of_footer <= blockSize).
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// PhySize2 = ((UInt64)numBlocks + 2) * blockSize;
|
||||||
|
const unsigned sector_of_FirstBlock = Get16a(p + 0x1c); // drAlBlSt : first allocation block in volume
|
||||||
|
const UInt32 startBlock = Get16a(p + 0x7c + 2);
|
||||||
|
const UInt32 blockCount = Get16a(p + 0x7c + 4);
|
||||||
|
SpecOffset = (UInt32)sector_of_FirstBlock << 9; // it's 32-bit here
|
||||||
|
PhySize2 = SpecOffset + (UInt64)numBlocks * blockSize;
|
||||||
|
SpecOffset += (UInt64)startBlock * blockSize;
|
||||||
|
// before v24.09: // SpecOffset = (UInt64)(1 + startBlock) * blockSize;
|
||||||
|
const UInt64 phy = SpecOffset + (UInt64)blockCount * blockSize;
|
||||||
|
if (PhySize2 < phy)
|
||||||
|
PhySize2 = phy;
|
||||||
|
UInt32 tail = 1 << 10; // at least 1 KiB tail (for footer MDB) is expected.
|
||||||
|
if (tail < blockSize)
|
||||||
|
tail = blockSize;
|
||||||
|
RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize))
|
||||||
|
if (ArcFileSize > PhySize2 &&
|
||||||
|
ArcFileSize - PhySize2 <= tail)
|
||||||
|
{
|
||||||
|
// data after blocks[h.NumBlocks] must contain another copy of MDB.
|
||||||
|
// In example where blockSize is not power of 2, we have
|
||||||
|
// (ArcFileSize - PhySize2) < blockSize.
|
||||||
|
// We suppose that data after blocks[h.NumBlocks] is part of HFS archive.
|
||||||
|
// Maybe we should scan for footer MDB data (in last 1 KiB)?
|
||||||
|
PhySize2 = ArcFileSize;
|
||||||
|
}
|
||||||
|
RINOK(InStream_SeekSet(inStream, SpecOffset))
|
||||||
|
RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
// HFS+ / HFSX volume header (starting from offset==1024):
|
||||||
|
{
|
||||||
|
// v24.09: we use strict condition test for pair signature(Version):
|
||||||
|
// H+(4), HX(5):
|
||||||
|
const UInt32 sig = GetUi32a(p);
|
||||||
|
// h.Version = Get16(p + 2);
|
||||||
|
h.Is_Hsfx_ver5 = false;
|
||||||
|
if (sig != k_Signature_LE32_HFSP_VER4)
|
||||||
|
{
|
||||||
|
if (sig != k_Signature_LE32_HFSX_VER5)
|
||||||
|
return S_FALSE;
|
||||||
|
h.Is_Hsfx_ver5 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const UInt32 blockSize = Get32a(p + 0x28);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
|
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
|
||||||
if (i == 31)
|
if (i == 31)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
h.BlockSizeLog = i;
|
h.BlockSizeLog = i;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
h.NumBlocks = Get16(p + 0x12);
|
// HFS Plus DOCs: The first 1024 bytes are reserved for use as boot blocks
|
||||||
/*
|
// v24.09: we don't check starting 1 KiB before old (HFS MDB) block ("BD" signture) .
|
||||||
we suppose that it has the follwing layout
|
// but we still check starting 1 KiB before HFS+ / HFSX volume header.
|
||||||
|
// are there HFS+ / HFSX images with non-zero data in this reserved area?
|
||||||
{
|
{
|
||||||
start block with header
|
for (unsigned i = 0; i < kHeaderPadSize / 4; i++)
|
||||||
[h.NumBlocks]
|
if (buf32[i] != 0)
|
||||||
end block with header
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
PhySize2 = ((UInt64)h.NumBlocks + 2) << h.BlockSizeLog;
|
|
||||||
|
|
||||||
UInt32 startBlock = Get16(p + 0x7C + 2);
|
|
||||||
UInt32 blockCount = Get16(p + 0x7C + 4);
|
|
||||||
SpecOffset = (UInt64)(1 + startBlock) << h.BlockSizeLog;
|
|
||||||
UInt64 phy = SpecOffset + ((UInt64)blockCount << h.BlockSizeLog);
|
|
||||||
if (PhySize2 < phy)
|
|
||||||
PhySize2 = phy;
|
|
||||||
RINOK(InStream_SeekSet(inStream, SpecOffset))
|
|
||||||
RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X'))
|
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
h.Version = Get16(p + 2);
|
}
|
||||||
if (h.Version < 4 || h.Version > 5)
|
#endif
|
||||||
return S_FALSE;
|
// h.Attr = Get32a(p + 4);
|
||||||
|
// h.LastMountedVersion = Get32a(p + 8);
|
||||||
// h.Attr = Get32(p + 4);
|
// h.JournalInfoBlock = Get32a(p + 0xC);
|
||||||
// h.LastMountedVersion = Get32(p + 8);
|
h.CTime = Get32a(p + 0x10);
|
||||||
// h.JournalInfoBlock = Get32(p + 0xC);
|
h.MTime = Get32a(p + 0x14);
|
||||||
|
// h.BackupTime = Get32a(p + 0x18);
|
||||||
h.CTime = Get32(p + 0x10);
|
// h.CheckedTime = Get32a(p + 0x1C);
|
||||||
h.MTime = Get32(p + 0x14);
|
h.NumFiles = Get32a(p + 0x20);
|
||||||
// h.BackupTime = Get32(p + 0x18);
|
h.NumFolders = Get32a(p + 0x24);
|
||||||
// h.CheckedTime = Get32(p + 0x1C);
|
|
||||||
|
|
||||||
h.NumFiles = Get32(p + 0x20);
|
|
||||||
h.NumFolders = Get32(p + 0x24);
|
|
||||||
|
|
||||||
if (h.NumFolders > ((UInt32)1 << 29) ||
|
if (h.NumFolders > ((UInt32)1 << 29) ||
|
||||||
h.NumFiles > ((UInt32)1 << 30))
|
h.NumFiles > ((UInt32)1 << 30))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize))
|
RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize))
|
||||||
|
|
||||||
if (progress)
|
if (progress)
|
||||||
{
|
{
|
||||||
const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1;
|
const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1;
|
||||||
RINOK(progress->SetTotal(&numFiles, NULL))
|
RINOK(progress->SetTotal(&numFiles, NULL))
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 blockSize = Get32(p + 0x28);
|
h.NumBlocks = Get32a(p + 0x2C);
|
||||||
|
h.NumFreeBlocks = Get32a(p + 0x30);
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
|
|
||||||
if (i == 31)
|
|
||||||
return S_FALSE;
|
|
||||||
h.BlockSizeLog = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
h.NumBlocks = Get32(p + 0x2C);
|
|
||||||
h.NumFreeBlocks = Get32(p + 0x30);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
h.NextCalatlogNodeID = Get32(p + 0x40);
|
h.NextCalatlogNodeID = Get32(p + 0x40);
|
||||||
h.WriteCount = Get32(p + 0x44);
|
h.WriteCount = Get32(p + 0x44);
|
||||||
|
|
@ -1495,7 +1529,7 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
|
||||||
HeadersError = true;
|
HeadersError = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents);
|
const HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents);
|
||||||
if (res == S_FALSE)
|
if (res == S_FALSE)
|
||||||
HeadersError = true;
|
HeadersError = true;
|
||||||
else if (res != S_OK)
|
else if (res != S_OK)
|
||||||
|
|
@ -1515,7 +1549,7 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
|
||||||
|
|
||||||
RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress))
|
RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress))
|
||||||
|
|
||||||
PhySize = Header.GetPhySize();
|
// PhySize = Header.GetPhySize();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1591,7 +1625,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
case kpidCharacts: MethodsMaskToProp(MethodsMask, prop); break;
|
case kpidCharacts: MethodsMaskToProp(MethodsMask, prop); break;
|
||||||
case kpidPhySize:
|
case kpidPhySize:
|
||||||
{
|
{
|
||||||
UInt64 v = SpecOffset + PhySize;
|
UInt64 v = SpecOffset + Header.GetPhySize(); // PhySize;
|
||||||
if (v < PhySize2)
|
if (v < PhySize2)
|
||||||
v = PhySize2;
|
v = PhySize2;
|
||||||
prop = v;
|
prop = v;
|
||||||
|
|
@ -2529,7 +2563,7 @@ HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
CSeekExtent se;
|
CSeekExtent se;
|
||||||
se.Phy = (UInt64)e.Pos << Header.BlockSizeLog;
|
se.Phy = SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog);
|
||||||
se.Virt = virt;
|
se.Virt = virt;
|
||||||
virt += cur;
|
virt += cur;
|
||||||
rem -= cur;
|
rem -= cur;
|
||||||
|
|
@ -2540,7 +2574,7 @@ HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
CSeekExtent se;
|
CSeekExtent se;
|
||||||
se.Phy = 0;
|
se.Phy = 0; // = SpecOffset ?
|
||||||
se.Virt = virt;
|
se.Virt = virt;
|
||||||
extentStream->Extents.Add(se);
|
extentStream->Extents.Add(se);
|
||||||
extentStream->Stream = _stream;
|
extentStream->Stream = _stream;
|
||||||
|
|
|
||||||
|
|
@ -460,9 +460,11 @@ struct LpMetadataHeader
|
||||||
|
|
||||||
static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum)
|
static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum)
|
||||||
{
|
{
|
||||||
|
MY_ALIGN (16)
|
||||||
CSha256 sha;
|
CSha256 sha;
|
||||||
Sha256_Init(&sha);
|
Sha256_Init(&sha);
|
||||||
Sha256_Update(&sha, data, size);
|
Sha256_Update(&sha, data, size);
|
||||||
|
MY_ALIGN (16)
|
||||||
Byte calced[32];
|
Byte calced[32];
|
||||||
Sha256_Final(&sha, calced);
|
Sha256_Final(&sha, calced);
|
||||||
return memcmp(checksum, calced, 32) == 0;
|
return memcmp(checksum, calced, 32) == 0;
|
||||||
|
|
@ -470,6 +472,7 @@ static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum)
|
||||||
|
|
||||||
static bool CheckSha256_csOffset(Byte *data, size_t size, unsigned hashOffset)
|
static bool CheckSha256_csOffset(Byte *data, size_t size, unsigned hashOffset)
|
||||||
{
|
{
|
||||||
|
MY_ALIGN (4)
|
||||||
Byte checksum[32];
|
Byte checksum[32];
|
||||||
Byte *shaData = &data[hashOffset];
|
Byte *shaData = &data[hashOffset];
|
||||||
memcpy(checksum, shaData, 32);
|
memcpy(checksum, shaData, 32);
|
||||||
|
|
@ -528,6 +531,7 @@ HRESULT CHandler::Open2(IInStream *stream)
|
||||||
{
|
{
|
||||||
RINOK(InStream_SeekSet(stream, LP_PARTITION_RESERVED_BYTES))
|
RINOK(InStream_SeekSet(stream, LP_PARTITION_RESERVED_BYTES))
|
||||||
{
|
{
|
||||||
|
MY_ALIGN (4)
|
||||||
Byte buf[k_Geometry_Size];
|
Byte buf[k_Geometry_Size];
|
||||||
RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size))
|
RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size))
|
||||||
if (memcmp(buf, k_Signature, k_SignatureSize) != 0)
|
if (memcmp(buf, k_Signature, k_SignatureSize) != 0)
|
||||||
|
|
|
||||||
|
|
@ -473,8 +473,8 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidIsDir: prop = item.IsDir(); break;
|
case kpidIsDir: prop = item.IsDir(); break;
|
||||||
case kpidSize: prop = item.Size; break;
|
case kpidSize: prop = (UInt64)item.Size; break;
|
||||||
case kpidPackSize: prop = item.PackSize; break;
|
case kpidPackSize: prop = (UInt64)item.PackSize; break;
|
||||||
case kpidCRC: prop = (UInt32)item.CRC; break;
|
case kpidCRC: prop = (UInt32)item.CRC; break;
|
||||||
case kpidHostOS: PAIR_TO_PROP(g_OsPairs, item.OsId, prop); break;
|
case kpidHostOS: PAIR_TO_PROP(g_OsPairs, item.OsId, prop); break;
|
||||||
case kpidMTime:
|
case kpidMTime:
|
||||||
|
|
|
||||||
|
|
@ -180,9 +180,32 @@ struct CDirLink
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// IMAGE_DIRECTORY_ENTRY_*
|
||||||
|
static const char * const g_Dir_Names[] =
|
||||||
|
{
|
||||||
|
"EXPORT"
|
||||||
|
, "IMPORT"
|
||||||
|
, "RESOURCE"
|
||||||
|
, "EXCEPTION"
|
||||||
|
, "SECURITY"
|
||||||
|
, "BASERELOC"
|
||||||
|
, "DEBUG"
|
||||||
|
, "ARCHITECTURE" // "COPYRIGHT"
|
||||||
|
, "GLOBALPTR"
|
||||||
|
, "TLS"
|
||||||
|
, "LOAD_CONFIG"
|
||||||
|
, "BOUND_IMPORT"
|
||||||
|
, "IAT"
|
||||||
|
, "DELAY_IMPORT"
|
||||||
|
, "COM_DESCRIPTOR"
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
kDirLink_EXCEPTION = 3,
|
||||||
kDirLink_Certificate = 4,
|
kDirLink_Certificate = 4,
|
||||||
|
kDirLink_BASERELOC = 5,
|
||||||
kDirLink_Debug = 6
|
kDirLink_Debug = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -229,7 +252,7 @@ struct COptHeader
|
||||||
UInt32 UninitDataSize;
|
UInt32 UninitDataSize;
|
||||||
|
|
||||||
// UInt32 AddressOfEntryPoint;
|
// UInt32 AddressOfEntryPoint;
|
||||||
// UInt32 BaseOfCode;
|
// UInt32 BaseOfCode; // VA(.text) == 0x1000 in most cases
|
||||||
// UInt32 BaseOfData32;
|
// UInt32 BaseOfData32;
|
||||||
UInt64 ImageBase;
|
UInt64 ImageBase;
|
||||||
|
|
||||||
|
|
@ -273,6 +296,7 @@ struct COptHeader
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// size is 16-bit
|
||||||
bool COptHeader::Parse(const Byte *p, UInt32 size)
|
bool COptHeader::Parse(const Byte *p, UInt32 size)
|
||||||
{
|
{
|
||||||
if (size < k_OptHeader32_Size_MIN)
|
if (size < k_OptHeader32_Size_MIN)
|
||||||
|
|
@ -334,14 +358,18 @@ bool COptHeader::Parse(const Byte *p, UInt32 size)
|
||||||
pos = 92;
|
pos = 92;
|
||||||
}
|
}
|
||||||
|
|
||||||
G32(pos, NumDirItems);
|
UInt32 numDirItems;
|
||||||
if (NumDirItems > (1 << 16))
|
G32(pos, numDirItems);
|
||||||
|
NumDirItems = numDirItems;
|
||||||
|
if (numDirItems > (1 << 13))
|
||||||
return false;
|
return false;
|
||||||
pos += 4;
|
pos += 4;
|
||||||
if (pos + 8 * NumDirItems > size)
|
if (pos + 8 * numDirItems > size)
|
||||||
return false;
|
return false;
|
||||||
memset((void *)DirItems, 0, sizeof(DirItems));
|
memset((void *)DirItems, 0, sizeof(DirItems));
|
||||||
for (UInt32 i = 0; i < NumDirItems && i < kNumDirItemsMax; i++)
|
if (numDirItems > kNumDirItemsMax)
|
||||||
|
numDirItems = kNumDirItemsMax;
|
||||||
|
for (UInt32 i = 0; i < numDirItems; i++)
|
||||||
DirItems[i].Parse(p + pos + i * 8);
|
DirItems[i].Parse(p + pos + i * 8);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -352,25 +380,39 @@ struct CSection
|
||||||
{
|
{
|
||||||
AString Name;
|
AString Name;
|
||||||
|
|
||||||
|
UInt32 ExtractSize;
|
||||||
UInt32 VSize;
|
UInt32 VSize;
|
||||||
UInt32 Va;
|
UInt32 Va;
|
||||||
UInt32 PSize;
|
UInt32 PSize;
|
||||||
UInt32 Pa;
|
UInt32 Pa;
|
||||||
UInt32 Flags;
|
UInt32 Flags;
|
||||||
UInt32 Time;
|
UInt32 Time;
|
||||||
// UInt16 NumRelocs;
|
// UInt16 NumRelocs; // is set to zero for executable images
|
||||||
bool IsRealSect;
|
bool IsRealSect;
|
||||||
bool IsDebug;
|
bool IsDebug;
|
||||||
bool IsAdditionalSection;
|
bool IsAdditionalSection;
|
||||||
|
|
||||||
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
|
CSection():
|
||||||
|
ExtractSize(0),
|
||||||
|
IsRealSect(false),
|
||||||
|
IsDebug(false),
|
||||||
|
IsAdditionalSection(false)
|
||||||
|
// , NumRelocs(0)
|
||||||
|
{}
|
||||||
|
|
||||||
UInt32 GetSizeExtract() const { return PSize; }
|
void Set_Size_for_all(UInt32 size)
|
||||||
UInt32 GetSizeMin() const { return MyMin(PSize, VSize); }
|
{
|
||||||
|
PSize = VSize = ExtractSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 GetSize_Extract() const
|
||||||
|
{
|
||||||
|
return ExtractSize;
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateTotalSize(UInt32 &totalSize) const
|
void UpdateTotalSize(UInt32 &totalSize) const
|
||||||
{
|
{
|
||||||
UInt32 t = Pa + PSize;
|
const UInt32 t = Pa + PSize;
|
||||||
if (totalSize < t)
|
if (totalSize < t)
|
||||||
totalSize = t;
|
totalSize = t;
|
||||||
}
|
}
|
||||||
|
|
@ -380,8 +422,8 @@ struct CSection
|
||||||
int Compare(const CSection &s) const
|
int Compare(const CSection &s) const
|
||||||
{
|
{
|
||||||
RINOZ(MyCompare(Pa, s.Pa))
|
RINOZ(MyCompare(Pa, s.Pa))
|
||||||
UInt32 size1 = GetSizeExtract();
|
const UInt32 size1 = GetSize_Extract();
|
||||||
UInt32 size2 = s.GetSizeExtract();
|
const UInt32 size2 = s.GetSize_Extract();
|
||||||
return MyCompare(size1, size2);
|
return MyCompare(size1, size2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -402,6 +444,10 @@ void CSection::Parse(const Byte *p)
|
||||||
G32(20, Pa);
|
G32(20, Pa);
|
||||||
// G16(32, NumRelocs);
|
// G16(32, NumRelocs);
|
||||||
G32(36, Flags);
|
G32(36, Flags);
|
||||||
|
// v24.08: we extract only useful data (without extra padding bytes).
|
||||||
|
// VSize == 0 is not expected, but we support that case too.
|
||||||
|
// return (VSize && VSize < PSize) ? VSize : PSize;
|
||||||
|
ExtractSize = (VSize && VSize < PSize) ? VSize : PSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -508,6 +554,7 @@ static const CUInt32PCharPair g_MachinePairs[] =
|
||||||
{ 0x01D3, "AM33" },
|
{ 0x01D3, "AM33" },
|
||||||
{ 0x01F0, "PPC" },
|
{ 0x01F0, "PPC" },
|
||||||
{ 0x01F1, "PPC-FP" },
|
{ 0x01F1, "PPC-FP" },
|
||||||
|
{ 0x01F2, "PPC-BE" },
|
||||||
{ 0x0200, "IA-64" },
|
{ 0x0200, "IA-64" },
|
||||||
{ 0x0266, "MIPS-16" },
|
{ 0x0266, "MIPS-16" },
|
||||||
{ 0x0284, "Alpha-64" },
|
{ 0x0284, "Alpha-64" },
|
||||||
|
|
@ -830,11 +877,11 @@ enum
|
||||||
kpidStackReserve,
|
kpidStackReserve,
|
||||||
kpidStackCommit,
|
kpidStackCommit,
|
||||||
kpidHeapReserve,
|
kpidHeapReserve,
|
||||||
kpidHeapCommit,
|
kpidHeapCommit
|
||||||
kpidImageBase
|
// , kpidImageBase
|
||||||
// kpidAddressOfEntryPoint,
|
// , kpidAddressOfEntryPoint
|
||||||
// kpidBaseOfCode,
|
// , kpidBaseOfCode
|
||||||
// kpidBaseOfData32,
|
// , kpidBaseOfData32
|
||||||
};
|
};
|
||||||
|
|
||||||
static const CStatProp kArcProps[] =
|
static const CStatProp kArcProps[] =
|
||||||
|
|
@ -864,14 +911,16 @@ static const CStatProp kArcProps[] =
|
||||||
{ "Stack Commit", kpidStackCommit, VT_UI8},
|
{ "Stack Commit", kpidStackCommit, VT_UI8},
|
||||||
{ "Heap Reserve", kpidHeapReserve, VT_UI8},
|
{ "Heap Reserve", kpidHeapReserve, VT_UI8},
|
||||||
{ "Heap Commit", kpidHeapCommit, VT_UI8},
|
{ "Heap Commit", kpidHeapCommit, VT_UI8},
|
||||||
{ "Image Base", kpidImageBase, VT_UI8},
|
{ NULL, kpidVa, VT_UI8 }, // "Image Base", kpidImageBase, VT_UI8
|
||||||
{ NULL, kpidComment, VT_BSTR},
|
{ NULL, kpidComment, VT_BSTR}
|
||||||
|
|
||||||
// { "Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8},
|
// , { "Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8}
|
||||||
// { "Base Of Code", kpidBaseOfCode, VT_UI8},
|
// , { "Base Of Code", kpidBaseOfCode, VT_UI8}
|
||||||
// { "Base Of Data", kpidBaseOfData32, VT_UI8},
|
// , { "Base Of Data", kpidBaseOfData32, VT_UI8}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #define kpid_NumRelocs 250
|
||||||
|
|
||||||
static const Byte kProps[] =
|
static const Byte kProps[] =
|
||||||
{
|
{
|
||||||
kpidPath,
|
kpidPath,
|
||||||
|
|
@ -880,7 +929,8 @@ static const Byte kProps[] =
|
||||||
kpidVirtualSize,
|
kpidVirtualSize,
|
||||||
kpidCharacts,
|
kpidCharacts,
|
||||||
kpidOffset,
|
kpidOffset,
|
||||||
kpidVa,
|
kpidVa
|
||||||
|
// , kpid_NumRelocs
|
||||||
};
|
};
|
||||||
|
|
||||||
IMP_IInArchive_Props
|
IMP_IInArchive_Props
|
||||||
|
|
@ -899,7 +949,42 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
switch (propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidPhySize: prop = _totalSize; break;
|
case kpidPhySize: prop = _totalSize; break;
|
||||||
case kpidComment: if (!_versionFullString.IsEmpty()) prop = _versionFullString; break;
|
case kpidComment:
|
||||||
|
{
|
||||||
|
UString s (_versionFullString);
|
||||||
|
s.Add_LF();
|
||||||
|
s += "Data Directories: ";
|
||||||
|
s.Add_UInt32(_optHeader.NumDirItems);
|
||||||
|
s.Add_LF();
|
||||||
|
s.Add_Char('{');
|
||||||
|
s.Add_LF();
|
||||||
|
for (unsigned i = 0; i < _optHeader.NumDirItems
|
||||||
|
&& i < Z7_ARRAY_SIZE(_optHeader.DirItems); i++)
|
||||||
|
{
|
||||||
|
const CDirLink &di = _optHeader.DirItems[i];
|
||||||
|
if (di.Va == 0 && di.Size == 0)
|
||||||
|
continue;
|
||||||
|
s += "index=";
|
||||||
|
s.Add_UInt32(i);
|
||||||
|
|
||||||
|
if (i < Z7_ARRAY_SIZE(g_Dir_Names))
|
||||||
|
{
|
||||||
|
s += " name=";
|
||||||
|
s += g_Dir_Names[i];
|
||||||
|
}
|
||||||
|
s += " VA=0x";
|
||||||
|
char temp[16];
|
||||||
|
ConvertUInt32ToHex(di.Va, temp);
|
||||||
|
s += temp;
|
||||||
|
s += " Size=";
|
||||||
|
s.Add_UInt32(di.Size);
|
||||||
|
s.Add_LF();
|
||||||
|
}
|
||||||
|
s.Add_Char('}');
|
||||||
|
s.Add_LF();
|
||||||
|
prop = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case kpidShortComment:
|
case kpidShortComment:
|
||||||
if (!_versionShortString.IsEmpty())
|
if (!_versionShortString.IsEmpty())
|
||||||
prop = _versionShortString;
|
prop = _versionShortString;
|
||||||
|
|
@ -969,8 +1054,7 @@ Z7_COM7F_IMF(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 kpidVa: prop = _optHeader.ImageBase; break; // kpidImageBase:
|
||||||
case kpidImageBase: prop = _optHeader.ImageBase; break;
|
|
||||||
// case kpidAddressOfEntryPoint: prop = _optHeader.AddressOfEntryPoint; break;
|
// case kpidAddressOfEntryPoint: prop = _optHeader.AddressOfEntryPoint; break;
|
||||||
// case kpidBaseOfCode: prop = _optHeader.BaseOfCode; break;
|
// case kpidBaseOfCode: prop = _optHeader.BaseOfCode; break;
|
||||||
// case kpidBaseOfData32: if (!_optHeader.Is64Bit()) prop = _optHeader.BaseOfData32; break;
|
// case kpidBaseOfData32: if (!_optHeader.Is64Bit()) prop = _optHeader.BaseOfData32; break;
|
||||||
|
|
@ -1130,7 +1214,8 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||||
prop = MultiByteToUnicodeString(s);
|
prop = MultiByteToUnicodeString(s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidSize: prop = (UInt64)item.PSize; break;
|
case kpidSize: prop = (UInt64)item.GetSize_Extract(); break;
|
||||||
|
// case kpid_NumRelocs: prop = (UInt32)item.NumRelocs; break;
|
||||||
case kpidPackSize: prop = (UInt64)item.PSize; break;
|
case kpidPackSize: prop = (UInt64)item.PSize; break;
|
||||||
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
|
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
|
||||||
case kpidOffset: prop = item.Pa; break;
|
case kpidOffset: prop = item.Pa; break;
|
||||||
|
|
@ -1229,7 +1314,7 @@ HRESULT CHandler::LoadDebugSections(IInStream *stream, bool &thereIsSection)
|
||||||
sect.Time = de.Time;
|
sect.Time = de.Time;
|
||||||
sect.Va = de.Va;
|
sect.Va = de.Va;
|
||||||
sect.Pa = de.Pa;
|
sect.Pa = de.Pa;
|
||||||
sect.PSize = sect.VSize = de.Size;
|
sect.Set_Size_for_all(de.Size);
|
||||||
}
|
}
|
||||||
buf += kEntrySize;
|
buf += kEntrySize;
|
||||||
}
|
}
|
||||||
|
|
@ -1757,7 +1842,7 @@ static void CopyToUString(const Byte *p, UString &s)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
wchar_t c = (wchar_t)Get16(p);
|
const wchar_t c = (wchar_t)Get16(p);
|
||||||
p += 2;
|
p += 2;
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1765,6 +1850,16 @@ static void CopyToUString(const Byte *p, UString &s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CopyToUString_ByLen16(const Byte *p, unsigned numChars16, UString &s)
|
||||||
|
{
|
||||||
|
for (; numChars16; numChars16--)
|
||||||
|
{
|
||||||
|
const wchar_t c = (wchar_t)Get16(p);
|
||||||
|
p += 2;
|
||||||
|
s += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool CompareWStrStrings(const Byte *p, const char *s)
|
static bool CompareWStrStrings(const Byte *p, const char *s)
|
||||||
{
|
{
|
||||||
unsigned pos = 0;
|
unsigned pos = 0;
|
||||||
|
|
@ -1783,7 +1878,7 @@ struct CVersionBlock
|
||||||
{
|
{
|
||||||
UInt32 TotalLen;
|
UInt32 TotalLen;
|
||||||
UInt32 ValueLen;
|
UInt32 ValueLen;
|
||||||
bool IsTextValue;
|
unsigned IsTextValue;
|
||||||
unsigned StrSize;
|
unsigned StrSize;
|
||||||
|
|
||||||
bool Parse(const Byte *p, UInt32 size);
|
bool Parse(const Byte *p, UInt32 size);
|
||||||
|
|
@ -1802,6 +1897,23 @@ static int Get_Utf16Str_Len_InBytes(const Byte *p, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Get_Utf16Str_Len_InBytes_AllowNonZeroTail(const Byte *p, size_t size)
|
||||||
|
{
|
||||||
|
unsigned pos = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (pos + 1 >= size)
|
||||||
|
{
|
||||||
|
if (pos == size)
|
||||||
|
return (int)pos;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (Get16(p + pos) == 0)
|
||||||
|
return (int)pos;
|
||||||
|
pos += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const unsigned k_ResoureBlockHeader_Size = 6;
|
static const unsigned k_ResoureBlockHeader_Size = 6;
|
||||||
|
|
||||||
bool CVersionBlock::Parse(const Byte *p, UInt32 size)
|
bool CVersionBlock::Parse(const Byte *p, UInt32 size)
|
||||||
|
|
@ -1812,14 +1924,12 @@ bool CVersionBlock::Parse(const Byte *p, UInt32 size)
|
||||||
ValueLen = Get16(p + 2);
|
ValueLen = Get16(p + 2);
|
||||||
if (TotalLen < k_ResoureBlockHeader_Size || TotalLen > size)
|
if (TotalLen < k_ResoureBlockHeader_Size || TotalLen > size)
|
||||||
return false;
|
return false;
|
||||||
switch (Get16(p + 4))
|
IsTextValue = Get16(p + 4);
|
||||||
{
|
if (IsTextValue > 1)
|
||||||
case 0: IsTextValue = false; break;
|
return false;
|
||||||
case 1: IsTextValue = true; break;
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
StrSize = 0;
|
StrSize = 0;
|
||||||
const int t = Get_Utf16Str_Len_InBytes(p + k_ResoureBlockHeader_Size, TotalLen - k_ResoureBlockHeader_Size);
|
const int t = Get_Utf16Str_Len_InBytes(p + k_ResoureBlockHeader_Size,
|
||||||
|
TotalLen - k_ResoureBlockHeader_Size);
|
||||||
if (t < 0)
|
if (t < 0)
|
||||||
return false;
|
return false;
|
||||||
StrSize = (unsigned)t;
|
StrSize = (unsigned)t;
|
||||||
|
|
@ -1880,7 +1990,7 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
|
||||||
return false;
|
return false;
|
||||||
if (vb.ValueLen != 0)
|
if (vb.ValueLen != 0)
|
||||||
return false;
|
return false;
|
||||||
UInt32 endPos = pos + vb.TotalLen;
|
const UInt32 endPos = pos + vb.TotalLen;
|
||||||
pos += k_ResoureBlockHeader_Size;
|
pos += k_ResoureBlockHeader_Size;
|
||||||
|
|
||||||
f.AddSpaces(2);
|
f.AddSpaces(2);
|
||||||
|
|
@ -1901,7 +2011,7 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
|
||||||
CVersionBlock vb2;
|
CVersionBlock vb2;
|
||||||
if (!vb2.Parse(p + pos, endPos - pos))
|
if (!vb2.Parse(p + pos, endPos - pos))
|
||||||
return false;
|
return false;
|
||||||
UInt32 endPos2 = pos + vb2.TotalLen;
|
const UInt32 endPos2 = pos + vb2.TotalLen;
|
||||||
if (vb2.IsTextValue)
|
if (vb2.IsTextValue)
|
||||||
return false;
|
return false;
|
||||||
pos += k_ResoureBlockHeader_Size;
|
pos += k_ResoureBlockHeader_Size;
|
||||||
|
|
@ -1919,9 +2029,9 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
|
||||||
UInt32 num = (vb2.ValueLen >> 2);
|
UInt32 num = (vb2.ValueLen >> 2);
|
||||||
for (; num != 0; num--, pos += 4)
|
for (; num != 0; num--, pos += 4)
|
||||||
{
|
{
|
||||||
UInt32 dw = Get32(p + pos);
|
const UInt32 dw = Get32(p + pos);
|
||||||
UInt32 lang = LOWORD(dw);
|
const UInt32 lang = LOWORD(dw);
|
||||||
UInt32 codePage = HIWORD(dw);
|
const UInt32 codePage = HIWORD(dw);
|
||||||
|
|
||||||
f.AddString(", ");
|
f.AddString(", ");
|
||||||
PrintHex(f, lang);
|
PrintHex(f, lang);
|
||||||
|
|
@ -1936,7 +2046,6 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
|
||||||
if (!CompareWStrStrings(p + pos, "StringFileInfo"))
|
if (!CompareWStrStrings(p + pos, "StringFileInfo"))
|
||||||
return false;
|
return false;
|
||||||
pos += vb.StrSize + 2;
|
pos += vb.StrSize + 2;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
pos += (4 - pos) & 3;
|
pos += (4 - pos) & 3;
|
||||||
|
|
@ -1945,7 +2054,7 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
|
||||||
CVersionBlock vb2;
|
CVersionBlock vb2;
|
||||||
if (!vb2.Parse(p + pos, endPos - pos))
|
if (!vb2.Parse(p + pos, endPos - pos))
|
||||||
return false;
|
return false;
|
||||||
UInt32 endPos2 = pos + vb2.TotalLen;
|
const UInt32 endPos2 = pos + vb2.TotalLen;
|
||||||
if (vb2.ValueLen != 0)
|
if (vb2.ValueLen != 0)
|
||||||
return false;
|
return false;
|
||||||
pos += k_ResoureBlockHeader_Size;
|
pos += k_ResoureBlockHeader_Size;
|
||||||
|
|
@ -1967,9 +2076,8 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
|
||||||
CVersionBlock vb3;
|
CVersionBlock vb3;
|
||||||
if (!vb3.Parse(p + pos, endPos2 - pos))
|
if (!vb3.Parse(p + pos, endPos2 - pos))
|
||||||
return false;
|
return false;
|
||||||
// ValueLen sometimes is a number of characters (not bytes)?
|
// ValueLen is a number of 16-bit characters (usually it includes zero tail character).
|
||||||
// So we don't use it.
|
const UInt32 endPos3 = pos + vb3.TotalLen;
|
||||||
UInt32 endPos3 = pos + vb3.TotalLen;
|
|
||||||
pos += k_ResoureBlockHeader_Size;
|
pos += k_ResoureBlockHeader_Size;
|
||||||
|
|
||||||
// we don't write string if it's not text
|
// we don't write string if it's not text
|
||||||
|
|
@ -1984,26 +2092,35 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
|
||||||
pos += vb3.StrSize + 2;
|
pos += vb3.StrSize + 2;
|
||||||
|
|
||||||
pos += (4 - pos) & 3;
|
pos += (4 - pos) & 3;
|
||||||
if (vb3.ValueLen > 0 && pos + 2 <= endPos3)
|
if (vb3.ValueLen != 0 && pos /* + 2 */ <= endPos3)
|
||||||
{
|
{
|
||||||
f.AddChar(',');
|
f.AddChar(',');
|
||||||
f.AddSpaces((34 - (int)vb3.StrSize) / 2);
|
f.AddSpaces((34 - (int)vb3.StrSize) / 2);
|
||||||
const int sLen = Get_Utf16Str_Len_InBytes(p + pos, endPos3 - pos);
|
// vb3.TotalLen for some PE files (not from msvc) doesn't include tail zero at the end of Value string.
|
||||||
|
// we allow that minor error.
|
||||||
|
const int sLen = Get_Utf16Str_Len_InBytes_AllowNonZeroTail(p + pos, endPos3 - pos);
|
||||||
if (sLen < 0)
|
if (sLen < 0)
|
||||||
return false;
|
return false;
|
||||||
|
/*
|
||||||
|
if (vb3.ValueLen - 1 != (unsigned)sLen / 2 &&
|
||||||
|
vb3.ValueLen != (unsigned)sLen / 2)
|
||||||
|
return false;
|
||||||
|
*/
|
||||||
AddParamString(f, p + pos, (unsigned)sLen);
|
AddParamString(f, p + pos, (unsigned)sLen);
|
||||||
CopyToUString(p + pos, value);
|
CopyToUString_ByLen16(p + pos, (unsigned)sLen / 2, value);
|
||||||
pos += (unsigned)sLen + 2;
|
// pos += (unsigned)sLen + 2;
|
||||||
}
|
}
|
||||||
AddToUniqueUStringVector(keys, key, value);
|
AddToUniqueUStringVector(keys, key, value);
|
||||||
}
|
}
|
||||||
pos = endPos3;
|
pos = endPos3;
|
||||||
f.NewLine();
|
f.NewLine();
|
||||||
}
|
}
|
||||||
|
pos = endPos2;
|
||||||
f.CloseBlock(4);
|
f.CloseBlock(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.CloseBlock(2);
|
f.CloseBlock(2);
|
||||||
|
pos = endPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
f.CloseBlock(0);
|
f.CloseBlock(0);
|
||||||
|
|
@ -2218,7 +2335,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
|
||||||
|
|
||||||
if (sect2.PSize != 0)
|
if (sect2.PSize != 0)
|
||||||
{
|
{
|
||||||
sect2.VSize = sect2.PSize;
|
sect2.ExtractSize = sect2.VSize = sect2.PSize;
|
||||||
sect2.Name = ".rsrc_1";
|
sect2.Name = ".rsrc_1";
|
||||||
sect2.Time = 0;
|
sect2.Time = 0;
|
||||||
sect2.IsAdditionalSection = true;
|
sect2.IsAdditionalSection = true;
|
||||||
|
|
@ -2337,6 +2454,20 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||||
CSection § = _sections.AddNew();
|
CSection § = _sections.AddNew();
|
||||||
sect.Parse(buffer + pos);
|
sect.Parse(buffer + pos);
|
||||||
sect.IsRealSect = true;
|
sect.IsRealSect = true;
|
||||||
|
if (sect.Name.IsEqualTo(".reloc"))
|
||||||
|
{
|
||||||
|
const CDirLink &dl = _optHeader.DirItems[kDirLink_BASERELOC];
|
||||||
|
if (dl.Va == sect.Va &&
|
||||||
|
dl.Size <= sect.PSize)
|
||||||
|
sect.ExtractSize = dl.Size;
|
||||||
|
}
|
||||||
|
else if (sect.Name.IsEqualTo(".pdata"))
|
||||||
|
{
|
||||||
|
const CDirLink &dl = _optHeader.DirItems[kDirLink_EXCEPTION];
|
||||||
|
if (dl.Va == sect.Va &&
|
||||||
|
dl.Size <= sect.PSize)
|
||||||
|
sect.ExtractSize = dl.Size;
|
||||||
|
}
|
||||||
|
|
||||||
/* PE pre-file in .hxs file has errors:
|
/* PE pre-file in .hxs file has errors:
|
||||||
PSize of resource is larger than real size.
|
PSize of resource is larger than real size.
|
||||||
|
|
@ -2390,7 +2521,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||||
sect.Name = "CERTIFICATE";
|
sect.Name = "CERTIFICATE";
|
||||||
sect.Va = 0;
|
sect.Va = 0;
|
||||||
sect.Pa = certLink.Va;
|
sect.Pa = certLink.Va;
|
||||||
sect.PSize = sect.VSize = certLink.Size;
|
sect.Set_Size_for_all(certLink.Size);
|
||||||
sect.UpdateTotalSize(_totalSize);
|
sect.UpdateTotalSize(_totalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2448,7 +2579,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||||
sect.Name = "COFF_SYMBOLS";
|
sect.Name = "COFF_SYMBOLS";
|
||||||
sect.Va = 0;
|
sect.Va = 0;
|
||||||
sect.Pa = _header.PointerToSymbolTable;
|
sect.Pa = _header.PointerToSymbolTable;
|
||||||
sect.PSize = sect.VSize = size;
|
sect.Set_Size_for_all(size);
|
||||||
sect.UpdateTotalSize(_totalSize);
|
sect.UpdateTotalSize(_totalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2464,11 +2595,11 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||||
{
|
{
|
||||||
CSection &s2 = _sections.AddNew();
|
CSection &s2 = _sections.AddNew();
|
||||||
s2.Pa = s2.Va = limit;
|
s2.Pa = s2.Va = limit;
|
||||||
s2.PSize = s2.VSize = s.Pa - limit;
|
s2.Set_Size_for_all(s.Pa - limit);
|
||||||
s2.IsAdditionalSection = true;
|
s2.IsAdditionalSection = true;
|
||||||
s2.Name = '[';
|
s2.Name.Add_Char('[');
|
||||||
s2.Name.Add_UInt32(num++);
|
s2.Name.Add_UInt32(num++);
|
||||||
s2.Name += ']';
|
s2.Name.Add_Char(']');
|
||||||
limit = s.Pa;
|
limit = s.Pa;
|
||||||
}
|
}
|
||||||
UInt32 next = s.Pa + s.PSize;
|
UInt32 next = s.Pa + s.PSize;
|
||||||
|
|
@ -2700,29 +2831,26 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
else if (mixItem.ResourceIndex >= 0)
|
else if (mixItem.ResourceIndex >= 0)
|
||||||
size = _items[mixItem.ResourceIndex].GetSize();
|
size = _items[mixItem.ResourceIndex].GetSize();
|
||||||
else
|
else
|
||||||
size = _sections[mixItem.SectionIndex].GetSizeExtract();
|
size = _sections[mixItem.SectionIndex].GetSize_Extract();
|
||||||
totalSize += size;
|
totalSize += size;
|
||||||
}
|
}
|
||||||
extractCallback->SetTotal(totalSize);
|
RINOK(extractCallback->SetTotal(totalSize))
|
||||||
|
|
||||||
UInt64 currentTotalSize = 0;
|
CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
|
||||||
|
CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
|
||||||
|
lps->Init(extractCallback, false);
|
||||||
|
CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream;
|
||||||
|
inStream->SetStream(_stream);
|
||||||
|
|
||||||
|
totalSize = 0;
|
||||||
UInt64 currentItemSize;
|
UInt64 currentItemSize;
|
||||||
|
|
||||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
for (i = 0;; i++, totalSize += currentItemSize)
|
||||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
|
||||||
|
|
||||||
CLocalProgress *lps = new CLocalProgress;
|
|
||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
|
||||||
lps->Init(extractCallback, false);
|
|
||||||
|
|
||||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
|
||||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
|
||||||
streamSpec->SetStream(_stream);
|
|
||||||
|
|
||||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
|
||||||
{
|
{
|
||||||
lps->InSize = lps->OutSize = currentTotalSize;
|
lps->InSize = lps->OutSize = totalSize;
|
||||||
RINOK(lps->SetCur())
|
RINOK(lps->SetCur())
|
||||||
|
if (i >= numItems)
|
||||||
|
break;
|
||||||
const Int32 askMode = testMode ?
|
const Int32 askMode = testMode ?
|
||||||
NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NExtract::NAskMode::kExtract;
|
NExtract::NAskMode::kExtract;
|
||||||
|
|
@ -2776,15 +2904,15 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentItemSize = sect.GetSizeExtract();
|
currentItemSize = sect.GetSize_Extract();
|
||||||
if (!testMode && !outStream)
|
if (!testMode && !outStream)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode))
|
RINOK(extractCallback->PrepareOperation(askMode))
|
||||||
RINOK(InStream_SeekSet(_stream, sect.Pa))
|
RINOK(InStream_SeekSet(_stream, sect.Pa))
|
||||||
streamSpec->Init(currentItemSize);
|
inStream->Init(currentItemSize);
|
||||||
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress))
|
RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps))
|
||||||
isOk = (copyCoderSpec->TotalSize == currentItemSize);
|
isOk = (copyCoder->TotalSize == currentItemSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
|
|
@ -2804,7 +2932,7 @@ Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream))
|
||||||
const CMixItem &mixItem = _mixItems[index];
|
const CMixItem &mixItem = _mixItems[index];
|
||||||
const CSection § = _sections[mixItem.SectionIndex];
|
const CSection § = _sections[mixItem.SectionIndex];
|
||||||
if (mixItem.IsSectionItem())
|
if (mixItem.IsSectionItem())
|
||||||
return CreateLimitedInStream(_stream, sect.Pa, sect.PSize, stream);
|
return CreateLimitedInStream(_stream, sect.Pa, sect.GetSize_Extract(), stream);
|
||||||
|
|
||||||
CBufInStream *inStreamSpec = new CBufInStream;
|
CBufInStream *inStreamSpec = new CBufInStream;
|
||||||
CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec;
|
CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec;
|
||||||
|
|
@ -2964,7 +3092,7 @@ bool CHeader::Parse(const Byte *p)
|
||||||
G32(12, BaseOfCode);
|
G32(12, BaseOfCode);
|
||||||
G64(16, ImageBase);
|
G64(16, ImageBase);
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < 2; i++)
|
for (unsigned i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
CDataDir &dd = DataDir[i];
|
CDataDir &dd = DataDir[i];
|
||||||
dd.Parse(p + 24 + i * 8);
|
dd.Parse(p + 24 + i * 8);
|
||||||
|
|
@ -2997,6 +3125,7 @@ struct CSection
|
||||||
{
|
{
|
||||||
Byte Name[NPe::kNameSize];
|
Byte Name[NPe::kNameSize];
|
||||||
|
|
||||||
|
UInt32 ExtractSize;
|
||||||
UInt32 VSize;
|
UInt32 VSize;
|
||||||
UInt32 Va;
|
UInt32 Va;
|
||||||
UInt32 PSize;
|
UInt32 PSize;
|
||||||
|
|
@ -3013,6 +3142,7 @@ struct CSection
|
||||||
G32(20, Pa);
|
G32(20, Pa);
|
||||||
// G32(p + 32, NumRelocs);
|
// G32(p + 32, NumRelocs);
|
||||||
G32(36, Flags);
|
G32(36, Flags);
|
||||||
|
ExtractSize = (VSize && VSize < PSize) ? VSize : PSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Check() const
|
bool Check() const
|
||||||
|
|
@ -3022,10 +3152,15 @@ struct CSection
|
||||||
PSize <= ((UInt32)1 << 30);
|
PSize <= ((UInt32)1 << 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UInt32 GetSize_Extract() const
|
||||||
|
{
|
||||||
|
return ExtractSize;
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateTotalSize(UInt32 &totalSize)
|
void UpdateTotalSize(UInt32 &totalSize)
|
||||||
{
|
{
|
||||||
UInt32 t = Pa + PSize;
|
const UInt32 t = Pa + PSize;
|
||||||
if (t > totalSize)
|
if (totalSize < t)
|
||||||
totalSize = t;
|
totalSize = t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -3050,6 +3185,7 @@ static const Byte kProps[] =
|
||||||
{
|
{
|
||||||
kpidPath,
|
kpidPath,
|
||||||
kpidSize,
|
kpidSize,
|
||||||
|
kpidPackSize,
|
||||||
kpidVirtualSize,
|
kpidVirtualSize,
|
||||||
kpidCharacts,
|
kpidCharacts,
|
||||||
kpidOffset,
|
kpidOffset,
|
||||||
|
|
@ -3108,7 +3244,7 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||||
prop = MultiByteToUnicodeString(name);
|
prop = MultiByteToUnicodeString(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidSize:
|
case kpidSize: prop = (UInt64)item.GetSize_Extract(); break;
|
||||||
case kpidPackSize: prop = (UInt64)item.PSize; break;
|
case kpidPackSize: prop = (UInt64)item.PSize; break;
|
||||||
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
|
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
|
||||||
case kpidOffset: prop = item.Pa; break;
|
case kpidOffset: prop = item.Pa; break;
|
||||||
|
|
@ -3168,13 +3304,13 @@ Z7_COM7F_IMF(CHandler::Open(IInStream *inStream,
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
Close();
|
Close();
|
||||||
try
|
// try
|
||||||
{
|
{
|
||||||
if (Open2(inStream) != S_OK)
|
if (Open2(inStream) != S_OK)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
_stream = inStream;
|
_stream = inStream;
|
||||||
}
|
}
|
||||||
catch(...) { return S_FALSE; }
|
// catch(...) { return S_FALSE; }
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
@ -3205,26 +3341,25 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
UInt64 totalSize = 0;
|
UInt64 totalSize = 0;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < numItems; i++)
|
for (i = 0; i < numItems; i++)
|
||||||
totalSize += _items[allFilesMode ? i : indices[i]].PSize;
|
totalSize += _items[allFilesMode ? i : indices[i]].GetSize_Extract();
|
||||||
extractCallback->SetTotal(totalSize);
|
RINOK(extractCallback->SetTotal(totalSize))
|
||||||
|
|
||||||
UInt64 currentTotalSize = 0;
|
CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
|
||||||
|
CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
|
||||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
|
||||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
|
||||||
|
|
||||||
CLocalProgress *lps = new CLocalProgress;
|
|
||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
|
||||||
lps->Init(extractCallback, false);
|
lps->Init(extractCallback, false);
|
||||||
|
CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream;
|
||||||
|
inStream->SetStream(_stream);
|
||||||
|
|
||||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
totalSize = 0;
|
||||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
|
||||||
streamSpec->SetStream(_stream);
|
|
||||||
|
|
||||||
for (i = 0; i < numItems; i++)
|
for (i = 0;; i++)
|
||||||
{
|
{
|
||||||
lps->InSize = lps->OutSize = currentTotalSize;
|
lps->InSize = lps->OutSize = totalSize;
|
||||||
RINOK(lps->SetCur())
|
RINOK(lps->SetCur())
|
||||||
|
if (i >= numItems)
|
||||||
|
break;
|
||||||
|
int opRes;
|
||||||
|
{
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
const Int32 askMode = testMode ?
|
const Int32 askMode = testMode ?
|
||||||
NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
|
|
@ -3232,21 +3367,22 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
const UInt32 index = allFilesMode ? i : indices[i];
|
const UInt32 index = allFilesMode ? i : indices[i];
|
||||||
const CSection &item = _items[index];
|
const CSection &item = _items[index];
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
|
||||||
currentTotalSize += item.PSize;
|
const UInt32 size = item.GetSize_Extract();
|
||||||
|
totalSize += size;
|
||||||
|
|
||||||
if (!testMode && !realOutStream)
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
RINOK(extractCallback->PrepareOperation(askMode))
|
RINOK(extractCallback->PrepareOperation(askMode))
|
||||||
int res = NExtract::NOperationResult::kDataError;
|
|
||||||
|
|
||||||
RINOK(InStream_SeekSet(_stream, item.Pa))
|
RINOK(InStream_SeekSet(_stream, item.Pa))
|
||||||
streamSpec->Init(item.PSize);
|
inStream->Init(size);
|
||||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress))
|
RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps))
|
||||||
if (copyCoderSpec->TotalSize == item.PSize)
|
|
||||||
res = NExtract::NOperationResult::kOK;
|
|
||||||
|
|
||||||
realOutStream.Release();
|
opRes = (copyCoder->TotalSize == size) ?
|
||||||
RINOK(extractCallback->SetOperationResult(res))
|
NExtract::NOperationResult::kOK : (copyCoder->TotalSize < size) ?
|
||||||
|
NExtract::NOperationResult::kUnexpectedEnd :
|
||||||
|
NExtract::NOperationResult::kDataError;
|
||||||
|
}
|
||||||
|
RINOK(extractCallback->SetOperationResult(opRes))
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|
@ -3256,7 +3392,7 @@ Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream))
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
const CSection &item = _items[index];
|
const CSection &item = _items[index];
|
||||||
return CreateLimitedInStream(_stream, item.Pa, item.PSize, stream);
|
return CreateLimitedInStream(_stream, item.Pa, item.GetSize_Extract(), stream);
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "../../Common/MyBuffer2.h"
|
#include "../../Common/MyBuffer2.h"
|
||||||
|
|
||||||
#include "../../Windows/PropVariant.h"
|
#include "../../Windows/PropVariant.h"
|
||||||
|
#include "../../Windows/PropVariantUtils.h"
|
||||||
|
|
||||||
#include "../Common/RegisterArc.h"
|
#include "../Common/RegisterArc.h"
|
||||||
#include "../Common/StreamObjects.h"
|
#include "../Common/StreamObjects.h"
|
||||||
|
|
@ -20,8 +21,8 @@
|
||||||
|
|
||||||
#include "HandlerCont.h"
|
#include "HandlerCont.h"
|
||||||
|
|
||||||
#define Get32(p) GetBe32(p)
|
#define Get32(p) GetBe32a(p)
|
||||||
#define Get64(p) GetBe64(p)
|
#define Get64(p) GetBe64a(p)
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
|
|
@ -32,9 +33,9 @@ static const Byte k_Signature[] = { 'Q', 'F', 'I', 0xFB, 0, 0, 0 };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
VA to PA maps:
|
VA to PA maps:
|
||||||
high bits (L1) : : in L1 Table : the reference to L1 Table
|
high bits (L1) : : index in L1 (_dir) : _dir[high_index] points to Table.
|
||||||
mid bits (L2) : _numMidBits : in L2 Table : the reference to cluster
|
mid bits (L2) : _numMidBits : index in Table, Table[index] points to cluster start offset in arc file.
|
||||||
low bits : _clusterBits
|
low bits : _clusterBits : offset inside cluster.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Z7_class_CHandler_final: public CHandlerImg
|
Z7_class_CHandler_final: public CHandlerImg
|
||||||
|
|
@ -49,30 +50,27 @@ Z7_class_CHandler_final: public CHandlerImg
|
||||||
|
|
||||||
CObjArray2<UInt32> _dir;
|
CObjArray2<UInt32> _dir;
|
||||||
CAlignedBuffer _table;
|
CAlignedBuffer _table;
|
||||||
UInt64 _cacheCluster;
|
|
||||||
CByteBuffer _cache;
|
CByteBuffer _cache;
|
||||||
CByteBuffer _cacheCompressed;
|
CByteBuffer _cacheCompressed;
|
||||||
|
UInt64 _cacheCluster;
|
||||||
|
|
||||||
UInt64 _comprPos;
|
UInt64 _comprPos;
|
||||||
size_t _comprSize;
|
size_t _comprSize;
|
||||||
|
|
||||||
UInt64 _phySize;
|
bool _needCompression;
|
||||||
|
|
||||||
CBufInStream *_bufInStreamSpec;
|
|
||||||
CMyComPtr<ISequentialInStream> _bufInStream;
|
|
||||||
|
|
||||||
CBufPtrSeqOutStream *_bufOutStreamSpec;
|
|
||||||
CMyComPtr<ISequentialOutStream> _bufOutStream;
|
|
||||||
|
|
||||||
NCompress::NDeflate::NDecoder::CCOMCoder *_deflateDecoderSpec;
|
|
||||||
CMyComPtr<ICompressCoder> _deflateDecoder;
|
|
||||||
|
|
||||||
bool _needDeflate;
|
|
||||||
bool _isArc;
|
bool _isArc;
|
||||||
bool _unsupported;
|
bool _unsupported;
|
||||||
|
Byte _compressionType;
|
||||||
|
|
||||||
|
UInt64 _phySize;
|
||||||
|
|
||||||
|
CMyComPtr2<ISequentialInStream, CBufInStream> _bufInStream;
|
||||||
|
CMyComPtr2<ISequentialOutStream, CBufPtrSeqOutStream> _bufOutStream;
|
||||||
|
CMyComPtr2<ICompressCoder, NCompress::NDeflate::NDecoder::CCOMCoder> _deflateDecoder;
|
||||||
|
|
||||||
UInt32 _version;
|
UInt32 _version;
|
||||||
UInt32 _cryptMethod;
|
UInt32 _cryptMethod;
|
||||||
|
UInt64 _incompatFlags;
|
||||||
|
|
||||||
HRESULT Seek2(UInt64 offset)
|
HRESULT Seek2(UInt64 offset)
|
||||||
{
|
{
|
||||||
|
|
@ -96,13 +94,11 @@ Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize))
|
||||||
{
|
{
|
||||||
if (processedSize)
|
if (processedSize)
|
||||||
*processedSize = 0;
|
*processedSize = 0;
|
||||||
|
|
||||||
// printf("\nRead _virtPos = %6d size = %6d\n", (UInt32)_virtPos, size);
|
// printf("\nRead _virtPos = %6d size = %6d\n", (UInt32)_virtPos, size);
|
||||||
|
|
||||||
if (_virtPos >= _size)
|
if (_virtPos >= _size)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
{
|
{
|
||||||
UInt64 rem = _size - _virtPos;
|
const UInt64 rem = _size - _virtPos;
|
||||||
if (size > rem)
|
if (size > rem)
|
||||||
size = (UInt32)rem;
|
size = (UInt32)rem;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|
@ -115,11 +111,10 @@ Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize))
|
||||||
const size_t clusterSize = (size_t)1 << _clusterBits;
|
const size_t clusterSize = (size_t)1 << _clusterBits;
|
||||||
const size_t lowBits = (size_t)_virtPos & (clusterSize - 1);
|
const size_t lowBits = (size_t)_virtPos & (clusterSize - 1);
|
||||||
{
|
{
|
||||||
size_t rem = clusterSize - lowBits;
|
const size_t rem = clusterSize - lowBits;
|
||||||
if (size > rem)
|
if (size > rem)
|
||||||
size = (UInt32)rem;
|
size = (UInt32)rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cluster == _cacheCluster)
|
if (cluster == _cacheCluster)
|
||||||
{
|
{
|
||||||
memcpy(data, _cache + lowBits, size);
|
memcpy(data, _cache + lowBits, size);
|
||||||
|
|
@ -130,32 +125,29 @@ Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize))
|
||||||
|
|
||||||
if (high < _dir.Size())
|
if (high < _dir.Size())
|
||||||
{
|
{
|
||||||
const UInt32 tabl = _dir[(unsigned)high];
|
const UInt32 tabl = _dir[(size_t)high];
|
||||||
|
|
||||||
if (tabl != kEmptyDirItem)
|
if (tabl != kEmptyDirItem)
|
||||||
{
|
{
|
||||||
const Byte *buffer = _table + ((size_t)tabl << (_numMidBits + 3));
|
|
||||||
const size_t midBits = (size_t)cluster & (((size_t)1 << _numMidBits) - 1);
|
const size_t midBits = (size_t)cluster & (((size_t)1 << _numMidBits) - 1);
|
||||||
const Byte *p = (const Byte *)buffer + (midBits << 3);
|
const Byte *p = _table + ((((size_t)tabl << _numMidBits) + midBits) << 3);
|
||||||
UInt64 v = Get64(p);
|
UInt64 v = Get64(p);
|
||||||
|
|
||||||
if (v != 0)
|
if (v)
|
||||||
{
|
{
|
||||||
if ((v & _compressedFlag) != 0)
|
if (v & _compressedFlag)
|
||||||
{
|
{
|
||||||
if (_version <= 1)
|
if (_version <= 1)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the example of table record for 12-bit clusters (4KB uncompressed).
|
the example of table record for 12-bit clusters (4KB uncompressed):
|
||||||
2 bits : isCompressed status
|
2 bits : isCompressed status
|
||||||
4 bits : num_sectors_minus1; packSize = (num_sectors_minus1 + 1) * 512;
|
(4 == _clusterBits - 8) bits : (num_sectors - 1)
|
||||||
it uses one additional bit over unpacked cluster_bits
|
packSize = num_sectors * 512;
|
||||||
49 bits : offset of 512-sector
|
it uses one additional bit over unpacked cluster_bits.
|
||||||
9 bits : offset in 512-sector
|
(49 == 61 - _clusterBits) bits : offset of 512-byte sector
|
||||||
|
9 bits : offset in 512-byte sector
|
||||||
*/
|
*/
|
||||||
|
const unsigned numOffsetBits = 62 - (_clusterBits - 8);
|
||||||
const unsigned numOffsetBits = (62 - (_clusterBits - 9 + 1));
|
|
||||||
const UInt64 offset = v & (((UInt64)1 << 62) - 1);
|
const UInt64 offset = v & (((UInt64)1 << 62) - 1);
|
||||||
const size_t dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9;
|
const size_t dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9;
|
||||||
UInt64 sectorOffset = offset & (((UInt64)1 << numOffsetBits) - (1 << 9));
|
UInt64 sectorOffset = offset & (((UInt64)1 << numOffsetBits) - (1 << 9));
|
||||||
|
|
@ -167,7 +159,7 @@ Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize))
|
||||||
|
|
||||||
if (sectorOffset >= _comprPos && offset2inCache < _comprSize)
|
if (sectorOffset >= _comprPos && offset2inCache < _comprSize)
|
||||||
{
|
{
|
||||||
if (offset2inCache != 0)
|
if (offset2inCache)
|
||||||
{
|
{
|
||||||
_comprSize -= (size_t)offset2inCache;
|
_comprSize -= (size_t)offset2inCache;
|
||||||
memmove(_cacheCompressed, _cacheCompressed + (size_t)offset2inCache, _comprSize);
|
memmove(_cacheCompressed, _cacheCompressed + (size_t)offset2inCache, _comprSize);
|
||||||
|
|
@ -193,39 +185,34 @@ Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize))
|
||||||
const size_t dataSize3 = dataSize - _comprSize;
|
const size_t dataSize3 = dataSize - _comprSize;
|
||||||
size_t dataSize2 = dataSize3;
|
size_t dataSize2 = dataSize3;
|
||||||
// printf("\n\n=======\nReadStream = %6d _comprPos = %6d \n", (UInt32)dataSize2, (UInt32)_comprPos);
|
// printf("\n\n=======\nReadStream = %6d _comprPos = %6d \n", (UInt32)dataSize2, (UInt32)_comprPos);
|
||||||
RINOK(ReadStream(Stream, _cacheCompressed + _comprSize, &dataSize2))
|
const HRESULT hres = ReadStream(Stream, _cacheCompressed + _comprSize, &dataSize2);
|
||||||
_posInArc += dataSize2;
|
_posInArc += dataSize2;
|
||||||
|
RINOK(hres)
|
||||||
if (dataSize2 != dataSize3)
|
if (dataSize2 != dataSize3)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
_comprSize += dataSize2;
|
_comprSize += dataSize2;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t kSectorMask = (1 << 9) - 1;
|
const size_t kSectorMask = (1 << 9) - 1;
|
||||||
const size_t offsetInSector = ((size_t)offset & kSectorMask);
|
const size_t offsetInSector = (size_t)offset & kSectorMask;
|
||||||
_bufInStreamSpec->Init(_cacheCompressed + offsetInSector, dataSize - offsetInSector);
|
_bufInStream->Init(_cacheCompressed + offsetInSector, dataSize - offsetInSector);
|
||||||
|
|
||||||
_cacheCluster = (UInt64)(Int64)-1;
|
_cacheCluster = (UInt64)(Int64)-1;
|
||||||
if (_cache.Size() < clusterSize)
|
if (_cache.Size() < clusterSize)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
_bufOutStreamSpec->Init(_cache, clusterSize);
|
_bufOutStream->Init(_cache, clusterSize);
|
||||||
|
|
||||||
// Do we need to use smaller block than clusterSize for last cluster?
|
// Do we need to use smaller block than clusterSize for last cluster?
|
||||||
const UInt64 blockSize64 = clusterSize;
|
const UInt64 blockSize64 = clusterSize;
|
||||||
HRESULT res = _deflateDecoder->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL);
|
HRESULT res = _deflateDecoder.Interface()->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (_bufOutStreamSpec->GetPos() != clusterSize)
|
if (_bufOutStreamSpec->GetPos() != clusterSize)
|
||||||
memset(_cache + _bufOutStreamSpec->GetPos(), 0, clusterSize - _bufOutStreamSpec->GetPos());
|
memset(_cache + _bufOutStreamSpec->GetPos(), 0, clusterSize - _bufOutStreamSpec->GetPos());
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (res == S_OK)
|
if (res == S_OK)
|
||||||
if (!_deflateDecoderSpec->IsFinished()
|
if (!_deflateDecoder->IsFinished()
|
||||||
|| _bufOutStreamSpec->GetPos() != clusterSize)
|
|| _bufOutStream->GetPos() != clusterSize)
|
||||||
res = S_FALSE;
|
res = S_FALSE;
|
||||||
|
|
||||||
RINOK(res)
|
RINOK(res)
|
||||||
_cacheCluster = cluster;
|
_cacheCluster = cluster;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
/*
|
/*
|
||||||
memcpy(data, _cache + lowBits, size);
|
memcpy(data, _cache + lowBits, size);
|
||||||
|
|
@ -233,17 +220,17 @@ Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize))
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// version 3 support zero clusters
|
// version_3 supports zero clusters
|
||||||
if (((UInt32)v & 511) != 1)
|
if (((UInt32)v & 511) != 1)
|
||||||
{
|
{
|
||||||
v &= (_compressedFlag - 1);
|
v &= _compressedFlag - 1;
|
||||||
v += lowBits;
|
v += lowBits;
|
||||||
if (v != _posInArc)
|
if (v != _posInArc)
|
||||||
{
|
{
|
||||||
// printf("\n%12I64x\n", v - _posInArc);
|
// printf("\n%12I64x\n", v - _posInArc);
|
||||||
RINOK(Seek2(v))
|
RINOK(Seek2(v))
|
||||||
}
|
}
|
||||||
HRESULT res = Stream->Read(data, size, &size);
|
const HRESULT res = Stream->Read(data, size, &size);
|
||||||
_posInArc += size;
|
_posInArc += size;
|
||||||
_virtPos += size;
|
_virtPos += size;
|
||||||
if (processedSize)
|
if (processedSize)
|
||||||
|
|
@ -274,13 +261,25 @@ static const Byte kProps[] =
|
||||||
static const Byte kArcProps[] =
|
static const Byte kArcProps[] =
|
||||||
{
|
{
|
||||||
kpidClusterSize,
|
kpidClusterSize,
|
||||||
|
kpidSectorSize, // actually we need variable to show table size
|
||||||
|
kpidHeadersSize,
|
||||||
kpidUnpackVer,
|
kpidUnpackVer,
|
||||||
kpidMethod
|
kpidMethod,
|
||||||
|
kpidCharacts
|
||||||
};
|
};
|
||||||
|
|
||||||
IMP_IInArchive_Props
|
IMP_IInArchive_Props
|
||||||
IMP_IInArchive_ArcProps
|
IMP_IInArchive_ArcProps
|
||||||
|
|
||||||
|
static const CUInt32PCharPair g_IncompatFlags_Characts[] =
|
||||||
|
{
|
||||||
|
{ 0, "Dirty" },
|
||||||
|
{ 1, "Corrupt" },
|
||||||
|
{ 2, "External_Data_File" },
|
||||||
|
{ 3, "Compression" },
|
||||||
|
{ 4, "Extended_L2" }
|
||||||
|
};
|
||||||
|
|
||||||
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
|
|
@ -290,28 +289,54 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
{
|
{
|
||||||
case kpidMainSubfile: prop = (UInt32)0; break;
|
case kpidMainSubfile: prop = (UInt32)0; break;
|
||||||
case kpidClusterSize: prop = (UInt32)1 << _clusterBits; break;
|
case kpidClusterSize: prop = (UInt32)1 << _clusterBits; break;
|
||||||
case kpidPhySize: if (_phySize != 0) prop = _phySize; break;
|
case kpidSectorSize: prop = (UInt32)1 << (_numMidBits + 3); break;
|
||||||
|
case kpidHeadersSize: prop = _table.Size() + (UInt64)_dir.Size() * 8; break;
|
||||||
|
case kpidPhySize: if (_phySize) prop = _phySize; break;
|
||||||
case kpidUnpackVer: prop = _version; break;
|
case kpidUnpackVer: prop = _version; break;
|
||||||
|
case kpidCharacts:
|
||||||
|
{
|
||||||
|
if (_incompatFlags)
|
||||||
|
{
|
||||||
|
AString s ("incompatible: ");
|
||||||
|
// we need to show also high 32-bits.
|
||||||
|
s += FlagsToString(g_IncompatFlags_Characts,
|
||||||
|
Z7_ARRAY_SIZE(g_IncompatFlags_Characts), (UInt32)_incompatFlags);
|
||||||
|
prop = s;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case kpidMethod:
|
case kpidMethod:
|
||||||
{
|
{
|
||||||
AString s;
|
AString s;
|
||||||
|
|
||||||
if (_needDeflate)
|
if (_compressionType)
|
||||||
s = "Deflate";
|
{
|
||||||
|
if (_compressionType == 1)
|
||||||
|
s += "ZSTD";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s += "Compression:";
|
||||||
|
s.Add_UInt32(_compressionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_needCompression)
|
||||||
|
s.Add_OptSpaced("Deflate");
|
||||||
|
|
||||||
if (_cryptMethod != 0)
|
if (_cryptMethod)
|
||||||
{
|
{
|
||||||
s.Add_Space_if_NotEmpty();
|
s.Add_Space_if_NotEmpty();
|
||||||
if (_cryptMethod == 1)
|
if (_cryptMethod == 1)
|
||||||
s += "AES";
|
s += "AES";
|
||||||
|
if (_cryptMethod == 2)
|
||||||
|
s += "LUKS";
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
s += "Encryption:";
|
||||||
s.Add_UInt32(_cryptMethod);
|
s.Add_UInt32(_cryptMethod);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!s.IsEmpty())
|
if (!s.IsEmpty())
|
||||||
prop = s;
|
prop = s;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -321,9 +346,9 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
|
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
|
||||||
if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
|
if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
|
||||||
// if (_headerError) v |= kpv_ErrorFlags_HeadersError;
|
// if (_headerError) v |= kpv_ErrorFlags_HeadersError;
|
||||||
if (!Stream && v == 0 && _isArc)
|
if (!Stream && v == 0)
|
||||||
v = kpv_ErrorFlags_HeadersError;
|
v = kpv_ErrorFlags_HeadersError;
|
||||||
if (v != 0)
|
if (v)
|
||||||
prop = v;
|
prop = v;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -355,74 +380,89 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
|
||||||
|
|
||||||
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
|
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
|
||||||
{
|
{
|
||||||
const unsigned kHeaderSize = 18 * 4;
|
UInt64 buf64[0x70 / 8];
|
||||||
Byte buf[kHeaderSize];
|
RINOK(ReadStream_FALSE(stream, buf64, sizeof(buf64)))
|
||||||
RINOK(ReadStream_FALSE(stream, buf, kHeaderSize))
|
const void *buf = (const void *)buf64;
|
||||||
|
// signature: { 'Q', 'F', 'I', 0xFB }
|
||||||
if (memcmp(buf, k_Signature, 4) != 0)
|
if (*(const UInt32 *)buf != Z7_CONV_BE_TO_NATIVE_CONST32(0x514649fb))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
_version = Get32((const Byte *)(const void *)buf64 + 4);
|
||||||
_version = Get32(buf + 4);
|
|
||||||
if (_version < 1 || _version > 3)
|
if (_version < 1 || _version > 3)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
const UInt64 backOffset = Get64(buf + 8);
|
const UInt64 k_UncompressedSize_MAX = (UInt64)1 << 60;
|
||||||
// UInt32 backSize = Get32(buf + 0x10);
|
const UInt64 k_CompressedSize_MAX = (UInt64)1 << 60;
|
||||||
|
|
||||||
UInt64 l1Offset;
|
_size = Get64((const Byte *)(const void *)buf64 + 0x18);
|
||||||
UInt32 l1Size;
|
if (_size > k_UncompressedSize_MAX)
|
||||||
|
return S_FALSE;
|
||||||
|
size_t l1Size;
|
||||||
|
UInt32 headerSize;
|
||||||
|
|
||||||
if (_version == 1)
|
if (_version == 1)
|
||||||
{
|
{
|
||||||
// _mTime = Get32(buf + 0x14); // is unused im most images
|
// _mTime = Get32((const Byte *)(const void *)buf64 + 0x14); // is unused in most images
|
||||||
_size = Get64(buf + 0x18);
|
_clusterBits = ((const Byte *)(const void *)buf64)[0x20];
|
||||||
_clusterBits = buf[0x20];
|
_numMidBits = ((const Byte *)(const void *)buf64)[0x21];
|
||||||
_numMidBits = buf[0x21];
|
|
||||||
if (_clusterBits < 9 || _clusterBits > 30)
|
if (_clusterBits < 9 || _clusterBits > 30)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
if (_numMidBits < 1 || _numMidBits > 28)
|
if (_numMidBits < 1 || _numMidBits > 28)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
_cryptMethod = Get32(buf + 0x24);
|
_cryptMethod = Get32((const Byte *)(const void *)buf64 + 0x24);
|
||||||
l1Offset = Get64(buf + 0x28);
|
const unsigned numBits2 = _clusterBits + _numMidBits;
|
||||||
if (l1Offset < 0x30)
|
|
||||||
return S_FALSE;
|
|
||||||
const unsigned numBits2 = (_clusterBits + _numMidBits);
|
|
||||||
const UInt64 l1Size64 = (_size + (((UInt64)1 << numBits2) - 1)) >> numBits2;
|
const UInt64 l1Size64 = (_size + (((UInt64)1 << numBits2) - 1)) >> numBits2;
|
||||||
if (l1Size64 > ((UInt32)1 << 31))
|
if (l1Size64 > ((UInt32)1 << 31))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
l1Size = (UInt32)l1Size64;
|
l1Size = (size_t)l1Size64;
|
||||||
|
headerSize = 0x30;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_clusterBits = Get32(buf + 0x14);
|
_clusterBits = Get32((const Byte *)(const void *)buf64 + 0x14);
|
||||||
if (_clusterBits < 9 || _clusterBits > 30)
|
if (_clusterBits < 9 || _clusterBits > 30)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
_numMidBits = _clusterBits - 3;
|
_numMidBits = _clusterBits - 3;
|
||||||
_size = Get64(buf + 0x18);
|
_cryptMethod = Get32((const Byte *)(const void *)buf64 + 0x20);
|
||||||
_cryptMethod = Get32(buf + 0x20);
|
l1Size = Get32((const Byte *)(const void *)buf64 + 0x24);
|
||||||
l1Size = Get32(buf + 0x24);
|
headerSize = 0x48;
|
||||||
l1Offset = Get64(buf + 0x28); // must be aligned for cluster
|
if (_version >= 3)
|
||||||
|
{
|
||||||
|
_incompatFlags = Get64((const Byte *)(const void *)buf64 + 0x48);
|
||||||
|
// const UInt64 CompatFlags = Get64((const Byte *)(const void *)buf64 + 0x50);
|
||||||
|
// const UInt64 AutoClearFlags = Get64((const Byte *)(const void *)buf64 + 0x58);
|
||||||
|
// const UInt32 RefCountOrder = Get32((const Byte *)(const void *)buf64 + 0x60);
|
||||||
|
headerSize = 0x68;
|
||||||
|
const UInt32 headerSize2 = Get32((const Byte *)(const void *)buf64 + 0x64);
|
||||||
|
if (headerSize2 > (1u << 30))
|
||||||
|
return S_FALSE;
|
||||||
|
if (headerSize < headerSize2)
|
||||||
|
headerSize = headerSize2;
|
||||||
|
if (headerSize2 >= 0x68 + 1)
|
||||||
|
_compressionType = ((const Byte *)(const void *)buf64)[0x68];
|
||||||
|
}
|
||||||
|
|
||||||
const UInt64 refOffset = Get64(buf + 0x30); // must be aligned for cluster
|
const UInt64 refOffset = Get64((const Byte *)(const void *)buf64 + 0x30); // must be aligned for cluster
|
||||||
const UInt32 refClusters = Get32(buf + 0x38);
|
const UInt32 refClusters = Get32((const Byte *)(const void *)buf64 + 0x38);
|
||||||
|
// UInt32 numSnapshots = Get32((const Byte *)(const void *)buf64 + 0x3C);
|
||||||
// UInt32 numSnapshots = Get32(buf + 0x3C);
|
// UInt64 snapshotsOffset = Get64((const Byte *)(const void *)buf64 + 0x40); // must be aligned for cluster
|
||||||
// UInt64 snapshotsOffset = Get64(buf + 0x40); // must be aligned for cluster
|
|
||||||
/*
|
/*
|
||||||
if (numSnapshots != 0)
|
if (numSnapshots)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
*/
|
*/
|
||||||
|
if (refClusters)
|
||||||
if (refClusters != 0)
|
|
||||||
{
|
{
|
||||||
const size_t numBytes = refClusters << _clusterBits;
|
if (refOffset > k_CompressedSize_MAX)
|
||||||
|
return S_FALSE;
|
||||||
|
const UInt64 numBytes = (UInt64)refClusters << _clusterBits;
|
||||||
|
const UInt64 end = refOffset + numBytes;
|
||||||
|
if (end > k_CompressedSize_MAX)
|
||||||
|
return S_FALSE;
|
||||||
/*
|
/*
|
||||||
CByteBuffer refs;
|
CByteBuffer refs;
|
||||||
refs.Alloc(numBytes);
|
refs.Alloc(numBytes);
|
||||||
RINOK(InStream_SeekSet(stream, refOffset))
|
RINOK(InStream_SeekSet(stream, refOffset))
|
||||||
RINOK(ReadStream_FALSE(stream, refs, numBytes));
|
RINOK(ReadStream_FALSE(stream, refs, numBytes));
|
||||||
*/
|
*/
|
||||||
const UInt64 end = refOffset + numBytes;
|
|
||||||
if (_phySize < end)
|
if (_phySize < end)
|
||||||
_phySize = end;
|
_phySize = end;
|
||||||
/*
|
/*
|
||||||
|
|
@ -436,48 +476,76 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_isArc = true;
|
const UInt64 l1Offset = Get64((const Byte *)(const void *)buf64 + 0x28); // must be aligned for cluster ?
|
||||||
|
if (l1Offset < headerSize || l1Offset > k_CompressedSize_MAX)
|
||||||
|
return S_FALSE;
|
||||||
|
if (_phySize < headerSize)
|
||||||
|
_phySize = headerSize;
|
||||||
|
|
||||||
if (backOffset != 0)
|
_isArc = true;
|
||||||
|
{
|
||||||
|
const UInt64 backOffset = Get64((const Byte *)(const void *)buf64 + 8);
|
||||||
|
// UInt32 backSize = Get32((const Byte *)(const void *)buf64 + 0x10);
|
||||||
|
if (backOffset)
|
||||||
{
|
{
|
||||||
_unsupported = true;
|
_unsupported = true;
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 fileSize = 0;
|
||||||
|
RINOK(InStream_GetSize_SeekToBegin(stream, fileSize))
|
||||||
|
|
||||||
const size_t clusterSize = (size_t)1 << _clusterBits;
|
const size_t clusterSize = (size_t)1 << _clusterBits;
|
||||||
|
|
||||||
CByteBuffer table;
|
|
||||||
{
|
|
||||||
const size_t t1SizeBytes = (size_t)l1Size << 3;
|
const size_t t1SizeBytes = (size_t)l1Size << 3;
|
||||||
if ((t1SizeBytes >> 3) != l1Size)
|
|
||||||
return S_FALSE;
|
|
||||||
table.Alloc(t1SizeBytes);
|
|
||||||
RINOK(InStream_SeekSet(stream, l1Offset))
|
|
||||||
RINOK(ReadStream_FALSE(stream, table, t1SizeBytes))
|
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt64 end = l1Offset + t1SizeBytes;
|
const UInt64 end = l1Offset + t1SizeBytes;
|
||||||
// we need to uses align end for empty qcow files
|
if (end > k_CompressedSize_MAX)
|
||||||
end = (end + clusterSize - 1) >> _clusterBits << _clusterBits;
|
return S_FALSE;
|
||||||
|
// we need to use align end for empty qcow files
|
||||||
|
// some files has no cluster alignment padding at the end
|
||||||
|
// but has sector alignment
|
||||||
|
// end = (end + clusterSize - 1) >> _clusterBits << _clusterBits;
|
||||||
if (_phySize < end)
|
if (_phySize < end)
|
||||||
_phySize = end;
|
_phySize = end;
|
||||||
|
if (end > fileSize)
|
||||||
|
return S_FALSE;
|
||||||
|
if (_phySize < fileSize)
|
||||||
|
{
|
||||||
|
const UInt64 end2 = (end + 511) & ~(UInt64)511;
|
||||||
|
if (end2 == fileSize)
|
||||||
|
_phySize = end2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CObjArray<UInt64> table64(l1Size);
|
||||||
|
{
|
||||||
|
// if ((t1SizeBytes >> 3) != l1Size) return S_FALSE;
|
||||||
|
RINOK(InStream_SeekSet(stream, l1Offset))
|
||||||
|
RINOK(ReadStream_FALSE(stream, table64, t1SizeBytes))
|
||||||
|
}
|
||||||
|
|
||||||
_compressedFlag = (_version <= 1) ? ((UInt64)1 << 63) : ((UInt64)1 << 62);
|
_compressedFlag = (_version <= 1) ? ((UInt64)1 << 63) : ((UInt64)1 << 62);
|
||||||
const UInt64 offsetMask = _compressedFlag - 1;
|
const UInt64 offsetMask = _compressedFlag - 1;
|
||||||
|
const size_t midSize = (size_t)1 << (_numMidBits + 3);
|
||||||
UInt32 numTables = 0;
|
size_t numTables = 0;
|
||||||
UInt32 i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < l1Size; i++)
|
for (i = 0; i < l1Size; i++)
|
||||||
{
|
{
|
||||||
const UInt64 v = Get64((const Byte *)table + (size_t)i * 8) & offsetMask;
|
const UInt64 v = Get64(table64 + (size_t)i) & offsetMask;
|
||||||
if (v != 0)
|
if (!v)
|
||||||
|
continue;
|
||||||
numTables++;
|
numTables++;
|
||||||
|
const UInt64 end = v + midSize;
|
||||||
|
if (end > k_CompressedSize_MAX)
|
||||||
|
return S_FALSE;
|
||||||
|
if (_phySize < end)
|
||||||
|
_phySize = end;
|
||||||
|
if (end > fileSize)
|
||||||
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numTables != 0)
|
if (numTables)
|
||||||
{
|
{
|
||||||
const size_t size = (size_t)numTables << (_numMidBits + 3);
|
const size_t size = (size_t)numTables << (_numMidBits + 3);
|
||||||
if (size >> (_numMidBits + 3) != numTables)
|
if (size >> (_numMidBits + 3) != numTables)
|
||||||
|
|
@ -485,48 +553,38 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
|
||||||
_table.Alloc(size);
|
_table.Alloc(size);
|
||||||
if (!_table.IsAllocated())
|
if (!_table.IsAllocated())
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
_dir.SetSize(l1Size);
|
|
||||||
|
|
||||||
UInt32 curTable = 0;
|
|
||||||
|
|
||||||
if (openCallback)
|
if (openCallback)
|
||||||
{
|
{
|
||||||
const UInt64 totalBytes = (UInt64)numTables << (_numMidBits + 3);
|
const UInt64 totalBytes = size;
|
||||||
RINOK(openCallback->SetTotal(NULL, &totalBytes))
|
RINOK(openCallback->SetTotal(NULL, &totalBytes))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_dir.SetSize((unsigned)l1Size);
|
||||||
|
|
||||||
|
UInt32 curTable = 0;
|
||||||
|
|
||||||
for (i = 0; i < l1Size; i++)
|
for (i = 0; i < l1Size; i++)
|
||||||
{
|
{
|
||||||
Byte *buf2;
|
Byte *buf2;
|
||||||
const size_t midSize = (size_t)1 << (_numMidBits + 3);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const UInt64 v = Get64((const Byte *)table + (size_t)i * 8) & offsetMask;
|
const UInt64 v = Get64(table64 + (size_t)i) & offsetMask;
|
||||||
if (v == 0)
|
if (v == 0)
|
||||||
{
|
{
|
||||||
_dir[i] = kEmptyDirItem;
|
_dir[i] = kEmptyDirItem;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dir[i] = curTable;
|
_dir[i] = curTable;
|
||||||
const size_t tableOffset = ((size_t)curTable << (_numMidBits + 3));
|
const size_t tableOffset = (size_t)curTable << (_numMidBits + 3);
|
||||||
buf2 = (Byte *)_table + tableOffset;
|
buf2 = (Byte *)_table + tableOffset;
|
||||||
curTable++;
|
curTable++;
|
||||||
|
|
||||||
if (openCallback && (tableOffset & 0xFFFFF) == 0)
|
if (openCallback && (tableOffset & 0xFFFFF) == 0)
|
||||||
{
|
{
|
||||||
const UInt64 numBytes = tableOffset;
|
const UInt64 numBytes = tableOffset;
|
||||||
RINOK(openCallback->SetCompleted(NULL, &numBytes))
|
RINOK(openCallback->SetCompleted(NULL, &numBytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(InStream_SeekSet(stream, v))
|
RINOK(InStream_SeekSet(stream, v))
|
||||||
RINOK(ReadStream_FALSE(stream, buf2, midSize))
|
RINOK(ReadStream_FALSE(stream, buf2, midSize))
|
||||||
|
|
||||||
const UInt64 end = v + midSize;
|
|
||||||
if (_phySize < end)
|
|
||||||
_phySize = end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t k = 0; k < midSize; k += 8)
|
for (size_t k = 0; k < midSize; k += 8)
|
||||||
|
|
@ -537,33 +595,30 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
|
||||||
UInt64 offset = v & offsetMask;
|
UInt64 offset = v & offsetMask;
|
||||||
size_t dataSize = clusterSize;
|
size_t dataSize = clusterSize;
|
||||||
|
|
||||||
if ((v & _compressedFlag) != 0)
|
if (v & _compressedFlag)
|
||||||
{
|
{
|
||||||
if (_version <= 1)
|
if (_version <= 1)
|
||||||
{
|
{
|
||||||
unsigned numOffsetBits = (63 - _clusterBits);
|
const unsigned numOffsetBits = 63 - _clusterBits;
|
||||||
dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9;
|
dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9;
|
||||||
offset &= ((UInt64)1 << numOffsetBits) - 1;
|
offset &= ((UInt64)1 << numOffsetBits) - 1;
|
||||||
dataSize = 0;
|
dataSize = 0; // why ?
|
||||||
// offset >>= 9;
|
// offset &= ~(((UInt64)1 << 9) - 1);
|
||||||
// offset <<= 9;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned numOffsetBits = (62 - (_clusterBits - 8));
|
const unsigned numOffsetBits = 62 - (_clusterBits - 8);
|
||||||
dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9;
|
dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9;
|
||||||
offset &= ((UInt64)1 << numOffsetBits) - 1;
|
offset &= ((UInt64)1 << numOffsetBits) - (1 << 9);
|
||||||
offset >>= 9;
|
|
||||||
offset <<= 9;
|
|
||||||
}
|
}
|
||||||
_needDeflate = true;
|
_needCompression = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 low = (UInt32)v & 511;
|
const UInt32 low = (UInt32)v & 511;
|
||||||
if (low != 0)
|
if (low)
|
||||||
{
|
{
|
||||||
// version 3 support zero clusters
|
// version_3 supports zero clusters
|
||||||
if (_version < 3 || low != 1)
|
if (_version < 3 || low != 1)
|
||||||
{
|
{
|
||||||
_unsupported = true;
|
_unsupported = true;
|
||||||
|
|
@ -581,10 +636,11 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
|
||||||
if (curTable != numTables)
|
if (curTable != numTables)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
if (_cryptMethod != 0)
|
if (_cryptMethod)
|
||||||
_unsupported = true;
|
_unsupported = true;
|
||||||
|
if (_needCompression && _version <= 1) // that case was not implemented
|
||||||
if (_needDeflate && _version <= 1) // that case was not implemented
|
_unsupported = true;
|
||||||
|
if (_compressionType)
|
||||||
_unsupported = true;
|
_unsupported = true;
|
||||||
|
|
||||||
Stream = stream;
|
Stream = stream;
|
||||||
|
|
@ -596,16 +652,21 @@ Z7_COM7F_IMF(CHandler::Close())
|
||||||
{
|
{
|
||||||
_table.Free();
|
_table.Free();
|
||||||
_dir.Free();
|
_dir.Free();
|
||||||
|
// _cache.Free();
|
||||||
|
// _cacheCompressed.Free();
|
||||||
_phySize = 0;
|
_phySize = 0;
|
||||||
|
|
||||||
_cacheCluster = (UInt64)(Int64)-1;
|
_cacheCluster = (UInt64)(Int64)-1;
|
||||||
_comprPos = 0;
|
_comprPos = 0;
|
||||||
_comprSize = 0;
|
_comprSize = 0;
|
||||||
_needDeflate = false;
|
|
||||||
|
|
||||||
|
_needCompression = false;
|
||||||
_isArc = false;
|
_isArc = false;
|
||||||
_unsupported = false;
|
_unsupported = false;
|
||||||
|
|
||||||
|
_compressionType = 0;
|
||||||
|
_incompatFlags = 0;
|
||||||
|
|
||||||
// CHandlerImg:
|
// CHandlerImg:
|
||||||
Clear_HandlerImg_Vars();
|
Clear_HandlerImg_Vars();
|
||||||
Stream.Release();
|
Stream.Release();
|
||||||
|
|
@ -617,39 +678,20 @@ Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **strea
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
*stream = NULL;
|
*stream = NULL;
|
||||||
|
if (_unsupported || !Stream)
|
||||||
if (_unsupported)
|
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
if (_needCompression)
|
||||||
if (_needDeflate)
|
|
||||||
{
|
{
|
||||||
if (_version <= 1)
|
if (_version <= 1 || _compressionType)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
_bufInStream.Create_if_Empty();
|
||||||
if (!_bufInStream)
|
_bufOutStream.Create_if_Empty();
|
||||||
{
|
_deflateDecoder.Create_if_Empty();
|
||||||
_bufInStreamSpec = new CBufInStream;
|
_deflateDecoder->Set_NeedFinishInput(true);
|
||||||
_bufInStream = _bufInStreamSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_bufOutStream)
|
|
||||||
{
|
|
||||||
_bufOutStreamSpec = new CBufPtrSeqOutStream();
|
|
||||||
_bufOutStream = _bufOutStreamSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_deflateDecoder)
|
|
||||||
{
|
|
||||||
_deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder();
|
|
||||||
_deflateDecoder = _deflateDecoderSpec;
|
|
||||||
_deflateDecoderSpec->Set_NeedFinishInput(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t clusterSize = (size_t)1 << _clusterBits;
|
const size_t clusterSize = (size_t)1 << _clusterBits;
|
||||||
_cache.AllocAtLeast(clusterSize);
|
_cache.AllocAtLeast(clusterSize);
|
||||||
_cacheCompressed.AllocAtLeast(clusterSize * 2);
|
_cacheCompressed.AllocAtLeast(clusterSize * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMyComPtr<ISequentialInStream> streamTemp = this;
|
CMyComPtr<ISequentialInStream> streamTemp = this;
|
||||||
RINOK(InitAndSeek())
|
RINOK(InitAndSeek())
|
||||||
*stream = streamTemp.Detach();
|
*stream = streamTemp.Detach();
|
||||||
|
|
|
||||||
|
|
@ -658,6 +658,9 @@ HRESULT CInArchive::ReadBlockHeader(CHeader &h)
|
||||||
RINOK(ReadStream_Check(_buf, AES_BLOCK_SIZE * 2))
|
RINOK(ReadStream_Check(_buf, AES_BLOCK_SIZE * 2))
|
||||||
memcpy(m_CryptoDecoder->_iv, _buf, AES_BLOCK_SIZE);
|
memcpy(m_CryptoDecoder->_iv, _buf, AES_BLOCK_SIZE);
|
||||||
RINOK(m_CryptoDecoder->Init())
|
RINOK(m_CryptoDecoder->Init())
|
||||||
|
// we call RAR5_AES_Filter with:
|
||||||
|
// data_ptr == aligned_ptr + 16
|
||||||
|
// data_size == 16
|
||||||
if (m_CryptoDecoder->Filter(_buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE) != AES_BLOCK_SIZE)
|
if (m_CryptoDecoder->Filter(_buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE) != AES_BLOCK_SIZE)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
memcpy(buf, _buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
memcpy(buf, _buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||||
|
|
@ -689,10 +692,14 @@ HRESULT CInArchive::ReadBlockHeader(CHeader &h)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
memcpy(_buf, buf, filled);
|
memcpy(_buf, buf, filled);
|
||||||
const size_t rem = size - filled;
|
const size_t rem = size - filled;
|
||||||
|
// if (m_CryptoMode), we add AES_BLOCK_SIZE here, because _iv is not included to size.
|
||||||
AddToSeekValue(size + (m_CryptoMode ? AES_BLOCK_SIZE : 0));
|
AddToSeekValue(size + (m_CryptoMode ? AES_BLOCK_SIZE : 0));
|
||||||
RINOK(ReadStream_Check(_buf + filled, rem))
|
RINOK(ReadStream_Check(_buf + filled, rem))
|
||||||
if (m_CryptoMode)
|
if (m_CryptoMode)
|
||||||
{
|
{
|
||||||
|
// we call RAR5_AES_Filter with:
|
||||||
|
// data_ptr == aligned_ptr + 16
|
||||||
|
// (rem) can be big
|
||||||
if (m_CryptoDecoder->Filter(_buf + filled, (UInt32)rem) != rem)
|
if (m_CryptoDecoder->Filter(_buf + filled, (UInt32)rem) != rem)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
#if 1
|
#if 1
|
||||||
|
|
@ -1065,7 +1072,8 @@ HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
|
|
||||||
CMyComPtr<ICompressSetDecoderProperties2> csdp;
|
CMyComPtr<ICompressSetDecoderProperties2> csdp;
|
||||||
RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp))
|
RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp))
|
||||||
|
if (!csdp)
|
||||||
|
return E_NOTIMPL;
|
||||||
const unsigned ver = item.Get_AlgoVersion_HuffRev();
|
const unsigned ver = item.Get_AlgoVersion_HuffRev();
|
||||||
if (ver > 1)
|
if (ver > 1)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
|
@ -1456,7 +1464,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||||
}
|
}
|
||||||
if (arcInfo->Locator.Is_Recovery())
|
if (arcInfo->Locator.Is_Recovery())
|
||||||
{
|
{
|
||||||
s += "Recovery:";
|
s.Add_OptSpaced("Recovery:");
|
||||||
s.Add_UInt64(arcInfo->Locator.Recovery);
|
s.Add_UInt64(arcInfo->Locator.Recovery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3343,9 +3351,9 @@ Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
|
||||||
}
|
}
|
||||||
else if (name.IsPrefixedBy_Ascii_NoCase("memx"))
|
else if (name.IsPrefixedBy_Ascii_NoCase("memx"))
|
||||||
{
|
{
|
||||||
UInt64 memAvail;
|
size_t memAvail;
|
||||||
if (!NWindows::NSystem::GetRamSize(memAvail))
|
if (!NWindows::NSystem::GetRamSize(memAvail))
|
||||||
memAvail = (UInt64)(sizeof(size_t)) << 28;
|
memAvail = (size_t)sizeof(size_t) << 28;
|
||||||
UInt64 v;
|
UInt64 v;
|
||||||
if (!ParseSizeString(name.Ptr(4), prop, memAvail, v))
|
if (!ParseSizeString(name.Ptr(4), prop, memAvail, v))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
|
||||||
|
|
@ -1579,6 +1579,8 @@ HRESULT CHandler::OpenCapsule(IInStream *stream)
|
||||||
|| _h.CapsuleImageSize < _h.HeaderSize
|
|| _h.CapsuleImageSize < _h.HeaderSize
|
||||||
|| _h.OffsetToCapsuleBody < _h.HeaderSize
|
|| _h.OffsetToCapsuleBody < _h.HeaderSize
|
||||||
|| _h.OffsetToCapsuleBody > _h.CapsuleImageSize
|
|| _h.OffsetToCapsuleBody > _h.CapsuleImageSize
|
||||||
|
|| _h.CapsuleImageSize > (1u << 30) // to reduce false detection
|
||||||
|
|| _h.HeaderSize > (1u << 28) // to reduce false detection
|
||||||
)
|
)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
_phySize = _h.CapsuleImageSize;
|
_phySize = _h.CapsuleImageSize;
|
||||||
|
|
@ -1587,7 +1589,7 @@ HRESULT CHandler::OpenCapsule(IInStream *stream)
|
||||||
_h.OffsetToSplitInformation != 0 )
|
_h.OffsetToSplitInformation != 0 )
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
|
||||||
unsigned bufIndex = AddBuf(_h.CapsuleImageSize);
|
const unsigned bufIndex = AddBuf(_h.CapsuleImageSize);
|
||||||
CByteBuffer &buf0 = _bufs[bufIndex];
|
CByteBuffer &buf0 = _bufs[bufIndex];
|
||||||
memcpy(buf0, buf, kHeaderSize);
|
memcpy(buf0, buf, kHeaderSize);
|
||||||
ReadStream_FALSE(stream, buf0 + kHeaderSize, _h.CapsuleImageSize - kHeaderSize);
|
ReadStream_FALSE(stream, buf0 + kHeaderSize, _h.CapsuleImageSize - kHeaderSize);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "../../../C/Sha256.h"
|
#include "../../../C/Sha256.h"
|
||||||
|
#include "../../../C/Sha512.h"
|
||||||
#include "../../../C/CpuArch.h"
|
#include "../../../C/CpuArch.h"
|
||||||
|
|
||||||
#include "../../Common/ComTry.h"
|
#include "../../Common/ComTry.h"
|
||||||
|
|
@ -41,22 +42,33 @@ Z7_CLASS_IMP_NOQIB_1(
|
||||||
CInStreamWithSha256
|
CInStreamWithSha256
|
||||||
, ISequentialInStream
|
, ISequentialInStream
|
||||||
)
|
)
|
||||||
|
bool _sha512Mode;
|
||||||
CMyComPtr<ISequentialInStream> _stream;
|
CMyComPtr<ISequentialInStream> _stream;
|
||||||
CAlignedBuffer1 _sha;
|
CAlignedBuffer1 _sha256;
|
||||||
|
CAlignedBuffer1 _sha512;
|
||||||
UInt64 _size;
|
UInt64 _size;
|
||||||
|
|
||||||
CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_sha; }
|
CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; }
|
||||||
|
CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; }
|
||||||
public:
|
public:
|
||||||
CInStreamWithSha256(): _sha(sizeof(CSha256)) {}
|
CInStreamWithSha256():
|
||||||
|
_sha256(sizeof(CSha256)),
|
||||||
|
_sha512(sizeof(CSha512))
|
||||||
|
{}
|
||||||
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
||||||
void Init()
|
void Init(bool sha512Mode)
|
||||||
{
|
{
|
||||||
|
_sha512Mode = sha512Mode;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
Sha256_Init(Sha());
|
if (sha512Mode)
|
||||||
|
Sha512_Init(Sha512(), SHA512_DIGEST_SIZE);
|
||||||
|
else
|
||||||
|
Sha256_Init(Sha256());
|
||||||
}
|
}
|
||||||
void ReleaseStream() { _stream.Release(); }
|
void ReleaseStream() { _stream.Release(); }
|
||||||
UInt64 GetSize() const { return _size; }
|
UInt64 GetSize() const { return _size; }
|
||||||
void Final(Byte *digest) { Sha256_Final(Sha(), digest); }
|
void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); }
|
||||||
|
void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); }
|
||||||
};
|
};
|
||||||
|
|
||||||
Z7_COM7F_IMF(CInStreamWithSha256::Read(void *data, UInt32 size, UInt32 *processedSize))
|
Z7_COM7F_IMF(CInStreamWithSha256::Read(void *data, UInt32 size, UInt32 *processedSize))
|
||||||
|
|
@ -64,7 +76,10 @@ Z7_COM7F_IMF(CInStreamWithSha256::Read(void *data, UInt32 size, UInt32 *processe
|
||||||
UInt32 realProcessedSize;
|
UInt32 realProcessedSize;
|
||||||
const HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
const HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||||
_size += realProcessedSize;
|
_size += realProcessedSize;
|
||||||
Sha256_Update(Sha(), (const Byte *)data, realProcessedSize);
|
if (_sha512Mode)
|
||||||
|
Sha512_Update(Sha512(), (const Byte *)data, realProcessedSize);
|
||||||
|
else
|
||||||
|
Sha256_Update(Sha256(), (const Byte *)data, realProcessedSize);
|
||||||
if (processedSize)
|
if (processedSize)
|
||||||
*processedSize = realProcessedSize;
|
*processedSize = realProcessedSize;
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -75,25 +90,33 @@ Z7_CLASS_IMP_NOQIB_1(
|
||||||
COutStreamWithSha256
|
COutStreamWithSha256
|
||||||
, ISequentialOutStream
|
, ISequentialOutStream
|
||||||
)
|
)
|
||||||
// bool _calculate;
|
bool _sha512Mode;
|
||||||
CMyComPtr<ISequentialOutStream> _stream;
|
CMyComPtr<ISequentialOutStream> _stream;
|
||||||
CAlignedBuffer1 _sha;
|
CAlignedBuffer1 _sha256;
|
||||||
|
CAlignedBuffer1 _sha512;
|
||||||
UInt64 _size;
|
UInt64 _size;
|
||||||
|
|
||||||
CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_sha; }
|
CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; }
|
||||||
|
CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; }
|
||||||
public:
|
public:
|
||||||
COutStreamWithSha256(): _sha(sizeof(CSha256)) {}
|
COutStreamWithSha256():
|
||||||
|
_sha256(sizeof(CSha256)),
|
||||||
|
_sha512(sizeof(CSha512))
|
||||||
|
{}
|
||||||
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
|
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
|
||||||
void ReleaseStream() { _stream.Release(); }
|
void ReleaseStream() { _stream.Release(); }
|
||||||
void Init(/* bool calculate = true */ )
|
void Init(bool sha512Mode)
|
||||||
{
|
{
|
||||||
// _calculate = calculate;
|
_sha512Mode = sha512Mode;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
Sha256_Init(Sha());
|
if (sha512Mode)
|
||||||
|
Sha512_Init(Sha512(), SHA512_DIGEST_SIZE);
|
||||||
|
else
|
||||||
|
Sha256_Init(Sha256());
|
||||||
}
|
}
|
||||||
void InitSha256() { Sha256_Init(Sha()); }
|
|
||||||
UInt64 GetSize() const { return _size; }
|
UInt64 GetSize() const { return _size; }
|
||||||
void Final(Byte *digest) { Sha256_Final(Sha(), digest); }
|
void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); }
|
||||||
|
void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); }
|
||||||
};
|
};
|
||||||
|
|
||||||
Z7_COM7F_IMF(COutStreamWithSha256::Write(const void *data, UInt32 size, UInt32 *processedSize))
|
Z7_COM7F_IMF(COutStreamWithSha256::Write(const void *data, UInt32 size, UInt32 *processedSize))
|
||||||
|
|
@ -102,7 +125,10 @@ Z7_COM7F_IMF(COutStreamWithSha256::Write(const void *data, UInt32 size, UInt32 *
|
||||||
if (_stream)
|
if (_stream)
|
||||||
result = _stream->Write(data, size, &size);
|
result = _stream->Write(data, size, &size);
|
||||||
// if (_calculate)
|
// if (_calculate)
|
||||||
Sha256_Update(Sha(), (const Byte *)data, size);
|
if (_sha512Mode)
|
||||||
|
Sha512_Update(Sha512(), (const Byte *)data, size);
|
||||||
|
else
|
||||||
|
Sha256_Update(Sha256(), (const Byte *)data, size);
|
||||||
_size += size;
|
_size += size;
|
||||||
if (processedSize)
|
if (processedSize)
|
||||||
*processedSize = size;
|
*processedSize = size;
|
||||||
|
|
@ -521,10 +547,11 @@ void CInStreamWithHash::SetStreamAndInit(ISequentialInStream *stream, int algo)
|
||||||
inStreamSha1->Init();
|
inStreamSha1->Init();
|
||||||
stream = inStreamSha1;
|
stream = inStreamSha1;
|
||||||
}
|
}
|
||||||
else if (algo == XAR_CKSUM_SHA256)
|
else if (algo == XAR_CKSUM_SHA256
|
||||||
|
|| algo == XAR_CKSUM_SHA512)
|
||||||
{
|
{
|
||||||
inStreamSha256->SetStream(stream);
|
inStreamSha256->SetStream(stream);
|
||||||
inStreamSha256->Init();
|
inStreamSha256->Init(algo == XAR_CKSUM_SHA512);
|
||||||
stream = inStreamSha256;
|
stream = inStreamSha256;
|
||||||
}
|
}
|
||||||
inStreamLim->SetStream(stream);
|
inStreamLim->SetStream(stream);
|
||||||
|
|
@ -542,7 +569,14 @@ bool CInStreamWithHash::CheckHash(int algo, const Byte *digest_from_arc) const
|
||||||
else if (algo == XAR_CKSUM_SHA256)
|
else if (algo == XAR_CKSUM_SHA256)
|
||||||
{
|
{
|
||||||
Byte digest[SHA256_DIGEST_SIZE];
|
Byte digest[SHA256_DIGEST_SIZE];
|
||||||
inStreamSha256->Final(digest);
|
inStreamSha256->Final256(digest);
|
||||||
|
if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (algo == XAR_CKSUM_SHA512)
|
||||||
|
{
|
||||||
|
Byte digest[SHA512_DIGEST_SIZE];
|
||||||
|
inStreamSha256->Final512(digest);
|
||||||
if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0)
|
if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1151,11 +1185,12 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
outStreamSha1->SetStream(realOutStream);
|
outStreamSha1->SetStream(realOutStream);
|
||||||
outStreamSha1->Init();
|
outStreamSha1->Init();
|
||||||
}
|
}
|
||||||
else if (checksum_method == XAR_CKSUM_SHA256)
|
else if (checksum_method == XAR_CKSUM_SHA256
|
||||||
|
|| checksum_method == XAR_CKSUM_SHA512)
|
||||||
{
|
{
|
||||||
outStreamLim->SetStream(outStreamSha256);
|
outStreamLim->SetStream(outStreamSha256);
|
||||||
outStreamSha256->SetStream(realOutStream);
|
outStreamSha256->SetStream(realOutStream);
|
||||||
outStreamSha256->Init();
|
outStreamSha256->Init(checksum_method == XAR_CKSUM_SHA512);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
outStreamLim->SetStream(realOutStream);
|
outStreamLim->SetStream(realOutStream);
|
||||||
|
|
@ -1209,8 +1244,15 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
else if (checksum_method == XAR_CKSUM_SHA256)
|
else if (checksum_method == XAR_CKSUM_SHA256)
|
||||||
{
|
{
|
||||||
Byte digest[SHA256_DIGEST_SIZE];
|
Byte digest[SHA256_DIGEST_SIZE];
|
||||||
outStreamSha256->Final(digest);
|
outStreamSha256->Final256(digest);
|
||||||
if (memcmp(digest, item.extracted_checksum.Data, SHA256_DIGEST_SIZE) != 0)
|
if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0)
|
||||||
|
opRes = NExtract::NOperationResult::kCRCError;
|
||||||
|
}
|
||||||
|
else if (checksum_method == XAR_CKSUM_SHA512)
|
||||||
|
{
|
||||||
|
Byte digest[SHA512_DIGEST_SIZE];
|
||||||
|
outStreamSha256->Final512(digest);
|
||||||
|
if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0)
|
||||||
opRes = NExtract::NOperationResult::kCRCError;
|
opRes = NExtract::NOperationResult::kCRCError;
|
||||||
}
|
}
|
||||||
if (opRes == NExtract::NOperationResult::kOK)
|
if (opRes == NExtract::NOperationResult::kOK)
|
||||||
|
|
|
||||||
|
|
@ -967,9 +967,9 @@ Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream))
|
||||||
|| _maxBlocksSize != (size_t)_maxBlocksSize)
|
|| _maxBlocksSize != (size_t)_maxBlocksSize)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
UInt64 memSize;
|
size_t memSize;
|
||||||
if (!NSystem::GetRamSize(memSize))
|
if (!NSystem::GetRamSize(memSize))
|
||||||
memSize = (UInt64)(sizeof(size_t)) << 28;
|
memSize = (size_t)sizeof(size_t) << 28;
|
||||||
{
|
{
|
||||||
if (_maxBlocksSize > memSize / 4)
|
if (_maxBlocksSize > memSize / 4)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
|
||||||
|
|
@ -1755,16 +1755,17 @@ HRESULT CCacheOutStream::FlushFromCache(size_t size)
|
||||||
PRF(printf("\n-- CCacheOutStream::FlushFromCache %u\n", (unsigned)size));
|
PRF(printf("\n-- CCacheOutStream::FlushFromCache %u\n", (unsigned)size));
|
||||||
if (_hres != S_OK)
|
if (_hres != S_OK)
|
||||||
return _hres;
|
return _hres;
|
||||||
if (size == 0 || _cachedSize == 0)
|
if (size > _cachedSize)
|
||||||
|
size = _cachedSize;
|
||||||
|
// (size <= _cachedSize)
|
||||||
|
if (size == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
RINOK(SeekPhy(_cachedPos))
|
RINOK(SeekPhy(_cachedPos))
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
// (_phyPos == _cachedPos)
|
// (_phyPos == _cachedPos)
|
||||||
const size_t pos = (size_t)_cachedPos & kCacheMask;
|
const size_t pos = (size_t)_cachedPos & kCacheMask;
|
||||||
size_t cur = kCacheSize - pos;
|
const size_t cur = MyMin(kCacheSize - pos, size);
|
||||||
cur = MyMin(cur, _cachedSize);
|
|
||||||
cur = MyMin(cur, size);
|
|
||||||
_hres = SetRestriction_ForWrite(cur);
|
_hres = SetRestriction_ForWrite(cur);
|
||||||
RINOK(_hres)
|
RINOK(_hres)
|
||||||
PRF(printf("\n-- CCacheOutStream::WriteFromCache _phyPos = 0x%x, size = %d\n", (unsigned)_phyPos, (unsigned)cur));
|
PRF(printf("\n-- CCacheOutStream::WriteFromCache _phyPos = 0x%x, size = %d\n", (unsigned)_phyPos, (unsigned)cur));
|
||||||
|
|
@ -1776,7 +1777,7 @@ HRESULT CCacheOutStream::FlushFromCache(size_t size)
|
||||||
_cachedPos += cur;
|
_cachedPos += cur;
|
||||||
_cachedSize -= cur;
|
_cachedSize -= cur;
|
||||||
size -= cur;
|
size -= cur;
|
||||||
if (size == 0 || _cachedSize == 0)
|
if (size == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1964,7 +1965,11 @@ Z7_COM7F_IMF(CCacheOutStream::SetSize(UInt64 newSize))
|
||||||
// so we reduce cache
|
// so we reduce cache
|
||||||
_cachedSize = (size_t)offset;
|
_cachedSize = (size_t)offset;
|
||||||
if (_phySize <= newSize)
|
if (_phySize <= newSize)
|
||||||
return S_OK; // _phySize will be restored later after cache flush
|
{
|
||||||
|
// _phySize will be restored later after cache flush
|
||||||
|
_virtSize = newSize;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
// (_phySize > newSize)
|
// (_phySize > newSize)
|
||||||
// so we must reduce phyStream size to (newSize) or to (_cachedPos)
|
// so we must reduce phyStream size to (newSize) or to (_cachedPos)
|
||||||
// newPhySize = _cachedPos; // optional reduce to _cachedPos
|
// newPhySize = _cachedPos; // optional reduce to _cachedPos
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ COMMON_OBJS = \
|
||||||
$O\DynLimBuf.obj \
|
$O\DynLimBuf.obj \
|
||||||
$O\IntToString.obj \
|
$O\IntToString.obj \
|
||||||
$O\LzFindPrepare.obj \
|
$O\LzFindPrepare.obj \
|
||||||
|
$O\Md5Reg.obj \
|
||||||
$O\MyMap.obj \
|
$O\MyMap.obj \
|
||||||
$O\MyString.obj \
|
$O\MyString.obj \
|
||||||
$O\MyVector.obj \
|
$O\MyVector.obj \
|
||||||
|
|
@ -11,6 +12,9 @@ COMMON_OBJS = \
|
||||||
$O\NewHandler.obj \
|
$O\NewHandler.obj \
|
||||||
$O\Sha1Reg.obj \
|
$O\Sha1Reg.obj \
|
||||||
$O\Sha256Reg.obj \
|
$O\Sha256Reg.obj \
|
||||||
|
$O\Sha3Reg.obj \
|
||||||
|
$O\Sha512Reg.obj \
|
||||||
|
$O\Sha512Prepare.obj \
|
||||||
$O\StringConvert.obj \
|
$O\StringConvert.obj \
|
||||||
$O\StringToInt.obj \
|
$O\StringToInt.obj \
|
||||||
$O\UTFConvert.obj \
|
$O\UTFConvert.obj \
|
||||||
|
|
@ -274,6 +278,7 @@ C_OBJS = \
|
||||||
$O\Lzma2Enc.obj \
|
$O\Lzma2Enc.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
$O\LzmaEnc.obj \
|
$O\LzmaEnc.obj \
|
||||||
|
$O\Md5.obj \
|
||||||
$O\MtCoder.obj \
|
$O\MtCoder.obj \
|
||||||
$O\MtDec.obj \
|
$O\MtDec.obj \
|
||||||
$O\Ppmd7.obj \
|
$O\Ppmd7.obj \
|
||||||
|
|
@ -283,6 +288,9 @@ C_OBJS = \
|
||||||
$O\Ppmd8.obj \
|
$O\Ppmd8.obj \
|
||||||
$O\Ppmd8Dec.obj \
|
$O\Ppmd8Dec.obj \
|
||||||
$O\Ppmd8Enc.obj \
|
$O\Ppmd8Enc.obj \
|
||||||
|
$O\Sha3.obj \
|
||||||
|
$O\Sha512.obj \
|
||||||
|
$O\Sha512Opt.obj \
|
||||||
$O\Sort.obj \
|
$O\Sort.obj \
|
||||||
$O\SwapBytes.obj \
|
$O\SwapBytes.obj \
|
||||||
$O\Threads.obj \
|
$O\Threads.obj \
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ COMMON_OBJS = \
|
||||||
$O/DynLimBuf.o \
|
$O/DynLimBuf.o \
|
||||||
$O/IntToString.o \
|
$O/IntToString.o \
|
||||||
$O/LzFindPrepare.o \
|
$O/LzFindPrepare.o \
|
||||||
|
$O/Md5Reg.o \
|
||||||
$O/MyMap.o \
|
$O/MyMap.o \
|
||||||
$O/MyString.o \
|
$O/MyString.o \
|
||||||
$O/MyVector.o \
|
$O/MyVector.o \
|
||||||
|
|
@ -54,6 +55,9 @@ COMMON_OBJS = \
|
||||||
$O/Sha1Reg.o \
|
$O/Sha1Reg.o \
|
||||||
$O/Sha256Prepare.o \
|
$O/Sha256Prepare.o \
|
||||||
$O/Sha256Reg.o \
|
$O/Sha256Reg.o \
|
||||||
|
$O/Sha3Reg.o \
|
||||||
|
$O/Sha512Prepare.o \
|
||||||
|
$O/Sha512Reg.o \
|
||||||
$O/StringConvert.o \
|
$O/StringConvert.o \
|
||||||
$O/StringToInt.o \
|
$O/StringToInt.o \
|
||||||
$O/UTFConvert.o \
|
$O/UTFConvert.o \
|
||||||
|
|
@ -337,6 +341,7 @@ C_OBJS = \
|
||||||
$O/Lzma2Enc.o \
|
$O/Lzma2Enc.o \
|
||||||
$O/LzmaDec.o \
|
$O/LzmaDec.o \
|
||||||
$O/LzmaEnc.o \
|
$O/LzmaEnc.o \
|
||||||
|
$O/Md5.o \
|
||||||
$O/MtCoder.o \
|
$O/MtCoder.o \
|
||||||
$O/MtDec.o \
|
$O/MtDec.o \
|
||||||
$O/Ppmd7.o \
|
$O/Ppmd7.o \
|
||||||
|
|
@ -350,6 +355,9 @@ C_OBJS = \
|
||||||
$O/Sha1Opt.o \
|
$O/Sha1Opt.o \
|
||||||
$O/Sha256.o \
|
$O/Sha256.o \
|
||||||
$O/Sha256Opt.o \
|
$O/Sha256Opt.o \
|
||||||
|
$O/Sha3.o \
|
||||||
|
$O/Sha512.o \
|
||||||
|
$O/Sha512Opt.o \
|
||||||
$O/Sort.o \
|
$O/Sort.o \
|
||||||
$O/SwapBytes.o \
|
$O/SwapBytes.o \
|
||||||
$O/Xxh64.o \
|
$O/Xxh64.o \
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,10 @@ SOURCE=..\..\..\Common\LzFindPrepare.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Md5Reg.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\MyBuffer.h
|
SOURCE=..\..\..\Common\MyBuffer.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
@ -383,6 +387,18 @@ SOURCE=..\..\..\Common\Sha256Reg.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Sha3Reg.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Sha512Prepare.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Sha512Reg.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
@ -2029,6 +2045,26 @@ SOURCE=..\..\..\..\C\LzmaEnc.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Md5.c
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "7z - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
|
||||||
|
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Md5.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\..\..\C\MtCoder.c
|
SOURCE=..\..\..\..\C\MtCoder.c
|
||||||
# SUBTRACT CPP /YX /Yc /Yu
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
# End Source File
|
# End Source File
|
||||||
|
|
@ -2230,6 +2266,62 @@ SOURCE=..\..\..\..\C\Sha256.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Sha3.c
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "7z - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
|
||||||
|
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Sha3.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Sha512.c
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "7z - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
|
||||||
|
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Sha512.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Sha512Opt.c
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "7z - Win32 Release"
|
||||||
|
|
||||||
|
# ADD CPP /O2
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
|
||||||
|
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\..\..\C\Sort.c
|
SOURCE=..\..\..\..\C\Sort.c
|
||||||
|
|
||||||
!IF "$(CFG)" == "7z - Win32 Release"
|
!IF "$(CFG)" == "7z - Win32 Release"
|
||||||
|
|
|
||||||
|
|
@ -59,13 +59,13 @@ static const char * const kHelpString =
|
||||||
" b : Benchmark\n"
|
" b : Benchmark\n"
|
||||||
"<switches>\n"
|
"<switches>\n"
|
||||||
" -a{N} : set compression mode : [0, 1] : default = 1 (max)\n"
|
" -a{N} : set compression mode : [0, 1] : default = 1 (max)\n"
|
||||||
" -d{N} : set dictionary size : [12, 30] : default = 24 (16 MiB)\n"
|
" -d{N} : set dictionary size : [12, 31] : default = 24 (16 MiB)\n"
|
||||||
" -fb{N} : set number of fast bytes : [5, 273] : default = 128\n"
|
" -fb{N} : set number of fast bytes : [5, 273] : default = 128\n"
|
||||||
" -mc{N} : set number of cycles for match finder\n"
|
" -mc{N} : set number of cycles for match finder\n"
|
||||||
" -lc{N} : set number of literal context bits : [0, 8] : default = 3\n"
|
" -lc{N} : set number of literal context bits : [0, 8] : default = 3\n"
|
||||||
" -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n"
|
" -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n"
|
||||||
" -pb{N} : set number of pos bits : [0, 4] : default = 2\n"
|
" -pb{N} : set number of pos bits : [0, 4] : default = 2\n"
|
||||||
" -mf{M} : set match finder: [hc4, bt2, bt3, bt4] : default = bt4\n"
|
" -mf{M} : set match finder: [hc4, hc5, bt2, bt3, bt4, bt5] : default = bt4\n"
|
||||||
" -mt{N} : set number of CPU threads\n"
|
" -mt{N} : set number of CPU threads\n"
|
||||||
" -eos : write end of stream marker\n"
|
" -eos : write end of stream marker\n"
|
||||||
" -si : read data from stdin\n"
|
" -si : read data from stdin\n"
|
||||||
|
|
@ -372,8 +372,8 @@ static int main2(int numArgs, const char *args[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stdInMode = parser[NKey::kStdIn].ThereIs;
|
const bool stdInMode = parser[NKey::kStdIn].ThereIs;
|
||||||
bool stdOutMode = parser[NKey::kStdOut].ThereIs;
|
const bool stdOutMode = parser[NKey::kStdOut].ThereIs;
|
||||||
|
|
||||||
if (!stdOutMode)
|
if (!stdOutMode)
|
||||||
PrintTitle();
|
PrintTitle();
|
||||||
|
|
@ -394,7 +394,16 @@ static int main2(int numArgs, const char *args[])
|
||||||
UInt32 dictLog;
|
UInt32 dictLog;
|
||||||
const UString &s = parser[NKey::kDict].PostStrings[0];
|
const UString &s = parser[NKey::kDict].PostStrings[0];
|
||||||
dictLog = GetNumber(s);
|
dictLog = GetNumber(s);
|
||||||
dict = 1 << dictLog;
|
if (dictLog >= 32)
|
||||||
|
throw "unsupported dictionary size";
|
||||||
|
// we only want to use dictionary sizes that are powers of 2,
|
||||||
|
// because 7-zip only recognizes such dictionary sizes in the lzma header.#if 0
|
||||||
|
#if 0
|
||||||
|
if (dictLog == 32)
|
||||||
|
dict = (UInt32)3840 << 20;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
dict = (UInt32)1 << dictLog;
|
||||||
dictDefined = true;
|
dictDefined = true;
|
||||||
AddProp(props2, "d", s);
|
AddProp(props2, "d", s);
|
||||||
}
|
}
|
||||||
|
|
@ -522,7 +531,7 @@ static int main2(int numArgs, const char *args[])
|
||||||
|
|
||||||
if (encodeMode && !dictDefined)
|
if (encodeMode && !dictDefined)
|
||||||
{
|
{
|
||||||
dict = 1 << kDictSizeLog;
|
dict = (UInt32)1 << kDictSizeLog;
|
||||||
if (fileSizeDefined)
|
if (fileSizeDefined)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
|
||||||
|
|
@ -422,7 +422,7 @@ int Main2(
|
||||||
{
|
{
|
||||||
CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
|
CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
|
||||||
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
|
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
|
||||||
ecs->Init(g_StdStream, &g_StdErr, g_StdStream);
|
ecs->Init(g_StdStream, &g_StdErr, g_StdStream, false);
|
||||||
|
|
||||||
#ifndef Z7_NO_CRYPTO
|
#ifndef Z7_NO_CRYPTO
|
||||||
ecs->PasswordIsDefined = passwordEnabled;
|
ecs->PasswordIsDefined = passwordEnabled;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw()
|
||||||
g_Codecs[g_NumCodecs++] = codecInfo;
|
g_Codecs[g_NumCodecs++] = codecInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const unsigned kNumHashersMax = 16;
|
static const unsigned kNumHashersMax = 32;
|
||||||
extern
|
extern
|
||||||
unsigned g_NumHashers;
|
unsigned g_NumHashers;
|
||||||
unsigned g_NumHashers = 0;
|
unsigned g_NumHashers = 0;
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ public:
|
||||||
|
|
||||||
UInt32 Get_Lzma_Algo() const
|
UInt32 Get_Lzma_Algo() const
|
||||||
{
|
{
|
||||||
int i = FindProp(NCoderPropID::kAlgorithm);
|
const int i = FindProp(NCoderPropID::kAlgorithm);
|
||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
{
|
{
|
||||||
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
||||||
|
|
@ -141,11 +141,11 @@ public:
|
||||||
if (Get_DicSize(v))
|
if (Get_DicSize(v))
|
||||||
return v;
|
return v;
|
||||||
const unsigned level = GetLevel();
|
const unsigned level = GetLevel();
|
||||||
const UInt32 dictSize =
|
const UInt32 dictSize = level <= 4 ?
|
||||||
( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) :
|
(UInt32)1 << (level * 2 + 16) :
|
||||||
( level <= 6 ? ((UInt32)1 << (level + 19)) :
|
level <= sizeof(size_t) / 2 + 4 ?
|
||||||
( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26)
|
(UInt32)1 << (level + 20) :
|
||||||
)));
|
(UInt32)1 << (sizeof(size_t) / 2 + 24);
|
||||||
return dictSize;
|
return dictSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,29 +196,17 @@ static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
|
||||||
|
|
||||||
const Byte b = p[0];
|
const Byte b = p[0];
|
||||||
|
|
||||||
if (b == 0x48)
|
if ((b & 0x80) == 0) // REX (0x48 or 0x4c)
|
||||||
{
|
{
|
||||||
if (p[1] == 0x8B)
|
const unsigned b2 = p[2] - 0x5; // [RIP + disp32]
|
||||||
|
if (b2 & 0x7)
|
||||||
|
continue;
|
||||||
|
if (p[1] != 0x8d) // LEA
|
||||||
{
|
{
|
||||||
if ((p[2] & 0xF7) != 0x5)
|
if (p[1] != 0x8b || b != 0x48 || (b2 & 0xf7))
|
||||||
continue;
|
continue;
|
||||||
// MOV RAX / RCX, [RIP + disp32]
|
// MOV RAX / RCX, [RIP + disp32]
|
||||||
}
|
}
|
||||||
else if (p[1] == 0x8D) // LEA
|
|
||||||
{
|
|
||||||
if ((p[2] & 0x7) != 0x5)
|
|
||||||
continue;
|
|
||||||
// LEA R**, []
|
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
codeLen = 3;
|
|
||||||
}
|
|
||||||
else if (b == 0x4C)
|
|
||||||
{
|
|
||||||
if (p[1] != 0x8D || (p[2] & 0x7) != 0x5)
|
|
||||||
continue;
|
|
||||||
// LEA R*, []
|
|
||||||
codeLen = 3;
|
codeLen = 3;
|
||||||
}
|
}
|
||||||
else if (b == 0xE8)
|
else if (b == 0xE8)
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,17 @@
|
||||||
#include "../../Windows/Synchronization.h"
|
#include "../../Windows/Synchronization.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Rar5Aes.h"
|
|
||||||
#include "HmacSha256.h"
|
#include "HmacSha256.h"
|
||||||
|
#include "Rar5Aes.h"
|
||||||
|
|
||||||
|
#define MY_ALIGN_FOR_SHA256 MY_ALIGN(16)
|
||||||
|
|
||||||
namespace NCrypto {
|
namespace NCrypto {
|
||||||
namespace NRar5 {
|
namespace NRar5 {
|
||||||
|
|
||||||
static const unsigned kNumIterationsLog_Max = 24;
|
static const unsigned kNumIterationsLog_Max = 24;
|
||||||
|
static const unsigned kPswCheckCsumSize32 = 1;
|
||||||
static const unsigned kPswCheckCsumSize = 4;
|
static const unsigned kCheckSize32 = kPswCheckSize32 + kPswCheckCsumSize32;
|
||||||
static const unsigned kCheckSize = kPswCheckSize + kPswCheckCsumSize;
|
|
||||||
|
|
||||||
CKey::CKey():
|
CKey::CKey():
|
||||||
_needCalc(true),
|
_needCalc(true),
|
||||||
|
|
@ -27,15 +28,29 @@ CKey::CKey():
|
||||||
_salt[i] = 0;
|
_salt[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CKey::~CKey()
|
||||||
|
{
|
||||||
|
Wipe();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKey::Wipe()
|
||||||
|
{
|
||||||
|
_password.Wipe();
|
||||||
|
Z7_memset_0_ARRAY(_salt);
|
||||||
|
// Z7_memset_0_ARRAY(_key32);
|
||||||
|
// Z7_memset_0_ARRAY(_check_Calced32);
|
||||||
|
// Z7_memset_0_ARRAY(_hashKey32);
|
||||||
|
CKeyBase::Wipe();
|
||||||
|
}
|
||||||
|
|
||||||
CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {}
|
CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {}
|
||||||
|
|
||||||
static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val)
|
static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val)
|
||||||
{
|
{
|
||||||
*val = 0;
|
*val = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < maxSize && i < 10;)
|
for (unsigned i = 0; i < maxSize && i < 10;)
|
||||||
{
|
{
|
||||||
Byte b = p[i];
|
const Byte b = p[i];
|
||||||
*val |= (UInt64)(b & 0x7F) << (7 * i);
|
*val |= (UInt64)(b & 0x7F) << (7 * i);
|
||||||
i++;
|
i++;
|
||||||
if ((b & 0x80) == 0)
|
if ((b & 0x80) == 0)
|
||||||
|
|
@ -64,7 +79,7 @@ HRESULT CDecoder::SetDecoderProps(const Byte *p, unsigned size, bool includeIV,
|
||||||
size -= num;
|
size -= num;
|
||||||
|
|
||||||
bool isCheck = IsThereCheck();
|
bool isCheck = IsThereCheck();
|
||||||
if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize : 0))
|
if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize32 * 4 : 0))
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
|
||||||
if (_numIterationsLog != p[0])
|
if (_numIterationsLog != p[0])
|
||||||
|
|
@ -93,19 +108,21 @@ HRESULT CDecoder::SetDecoderProps(const Byte *p, unsigned size, bool includeIV,
|
||||||
|
|
||||||
if (isCheck)
|
if (isCheck)
|
||||||
{
|
{
|
||||||
memcpy(_check, p, kPswCheckSize);
|
memcpy(_check32, p, sizeof(_check32));
|
||||||
|
MY_ALIGN_FOR_SHA256
|
||||||
CSha256 sha;
|
CSha256 sha;
|
||||||
|
MY_ALIGN_FOR_SHA256
|
||||||
Byte digest[SHA256_DIGEST_SIZE];
|
Byte digest[SHA256_DIGEST_SIZE];
|
||||||
Sha256_Init(&sha);
|
Sha256_Init(&sha);
|
||||||
Sha256_Update(&sha, _check, kPswCheckSize);
|
Sha256_Update(&sha, (const Byte *)_check32, sizeof(_check32));
|
||||||
Sha256_Final(&sha, digest);
|
Sha256_Final(&sha, digest);
|
||||||
_canCheck = (memcmp(digest, p + kPswCheckSize, kPswCheckCsumSize) == 0);
|
_canCheck = (memcmp(digest, p + sizeof(_check32), kPswCheckCsumSize32 * 4) == 0);
|
||||||
if (_canCheck && isService)
|
if (_canCheck && isService)
|
||||||
{
|
{
|
||||||
// There was bug in RAR 5.21- : PswCheck field in service records ("QO") contained zeros.
|
// There was bug in RAR 5.21- : PswCheck field in service records ("QO") contained zeros.
|
||||||
// so we disable password checking for such bad records.
|
// so we disable password checking for such bad records.
|
||||||
_canCheck = false;
|
_canCheck = false;
|
||||||
for (unsigned i = 0; i < kPswCheckSize; i++)
|
for (unsigned i = 0; i < kPswCheckSize32 * 4; i++)
|
||||||
if (p[i] != 0)
|
if (p[i] != 0)
|
||||||
{
|
{
|
||||||
_canCheck = true;
|
_canCheck = true;
|
||||||
|
|
@ -132,7 +149,7 @@ void CDecoder::SetPassword(const Byte *data, size_t size)
|
||||||
Z7_COM7F_IMF(CDecoder::Init())
|
Z7_COM7F_IMF(CDecoder::Init())
|
||||||
{
|
{
|
||||||
CalcKey_and_CheckPassword();
|
CalcKey_and_CheckPassword();
|
||||||
RINOK(SetKey(_key, kAesKeySize))
|
RINOK(SetKey((const Byte *)_key32, kAesKeySize))
|
||||||
RINOK(SetInitVector(_iv, AES_BLOCK_SIZE))
|
RINOK(SetInitVector(_iv, AES_BLOCK_SIZE))
|
||||||
return CAesCoder::Init();
|
return CAesCoder::Init();
|
||||||
}
|
}
|
||||||
|
|
@ -140,27 +157,27 @@ Z7_COM7F_IMF(CDecoder::Init())
|
||||||
|
|
||||||
UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const
|
UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const
|
||||||
{
|
{
|
||||||
MY_ALIGN (16)
|
MY_ALIGN_FOR_SHA256
|
||||||
NSha256::CHmac ctx;
|
NSha256::CHmac ctx;
|
||||||
ctx.SetKey(_hashKey, NSha256::kDigestSize);
|
ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize);
|
||||||
UInt32 v;
|
UInt32 v;
|
||||||
SetUi32(&v, crc)
|
SetUi32a(&v, crc)
|
||||||
ctx.Update((const Byte *)&v, 4);
|
ctx.Update((const Byte *)&v, 4);
|
||||||
MY_ALIGN (16)
|
MY_ALIGN_FOR_SHA256
|
||||||
UInt32 h[SHA256_NUM_DIGEST_WORDS];
|
UInt32 h[SHA256_NUM_DIGEST_WORDS];
|
||||||
ctx.Final((Byte *)h);
|
ctx.Final((Byte *)h);
|
||||||
crc = 0;
|
crc = 0;
|
||||||
for (unsigned i = 0; i < SHA256_NUM_DIGEST_WORDS; i++)
|
for (unsigned i = 0; i < SHA256_NUM_DIGEST_WORDS; i++)
|
||||||
crc ^= (UInt32)GetUi32(h + i);
|
crc ^= (UInt32)GetUi32a(h + i);
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CDecoder::Hmac_Convert_32Bytes(Byte *data) const
|
void CDecoder::Hmac_Convert_32Bytes(Byte *data) const
|
||||||
{
|
{
|
||||||
MY_ALIGN (16)
|
MY_ALIGN_FOR_SHA256
|
||||||
NSha256::CHmac ctx;
|
NSha256::CHmac ctx;
|
||||||
ctx.SetKey(_hashKey, NSha256::kDigestSize);
|
ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize);
|
||||||
ctx.Update(data, NSha256::kDigestSize);
|
ctx.Update(data, NSha256::kDigestSize);
|
||||||
ctx.Final(data);
|
ctx.Final(data);
|
||||||
}
|
}
|
||||||
|
|
@ -190,30 +207,31 @@ bool CDecoder::CalcKey_and_CheckPassword()
|
||||||
|
|
||||||
if (_needCalc)
|
if (_needCalc)
|
||||||
{
|
{
|
||||||
Byte pswCheck[SHA256_DIGEST_SIZE];
|
MY_ALIGN_FOR_SHA256
|
||||||
|
UInt32 pswCheck[SHA256_NUM_DIGEST_WORDS];
|
||||||
{
|
{
|
||||||
// Pbkdf HMAC-SHA-256
|
// Pbkdf HMAC-SHA-256
|
||||||
|
MY_ALIGN_FOR_SHA256
|
||||||
MY_ALIGN (16)
|
|
||||||
NSha256::CHmac baseCtx;
|
NSha256::CHmac baseCtx;
|
||||||
baseCtx.SetKey(_password, _password.Size());
|
baseCtx.SetKey(_password, _password.Size());
|
||||||
|
MY_ALIGN_FOR_SHA256
|
||||||
NSha256::CHmac ctx = baseCtx;
|
NSha256::CHmac ctx;
|
||||||
|
ctx = baseCtx;
|
||||||
ctx.Update(_salt, sizeof(_salt));
|
ctx.Update(_salt, sizeof(_salt));
|
||||||
|
|
||||||
MY_ALIGN (16)
|
MY_ALIGN_FOR_SHA256
|
||||||
Byte u[NSha256::kDigestSize];
|
UInt32 u[SHA256_NUM_DIGEST_WORDS];
|
||||||
MY_ALIGN (16)
|
MY_ALIGN_FOR_SHA256
|
||||||
Byte key[NSha256::kDigestSize];
|
UInt32 key[SHA256_NUM_DIGEST_WORDS];
|
||||||
|
|
||||||
u[0] = 0;
|
// u[0] = 0;
|
||||||
u[1] = 0;
|
// u[1] = 0;
|
||||||
u[2] = 0;
|
// u[2] = 0;
|
||||||
u[3] = 1;
|
// u[3] = 1;
|
||||||
|
SetUi32a(u, 0x1000000)
|
||||||
|
|
||||||
ctx.Update(u, 4);
|
ctx.Update((const Byte *)(const void *)u, 4);
|
||||||
ctx.Final(u);
|
ctx.Final((Byte *)(void *)u);
|
||||||
|
|
||||||
memcpy(key, u, NSha256::kDigestSize);
|
memcpy(key, u, NSha256::kDigestSize);
|
||||||
|
|
||||||
|
|
@ -221,35 +239,24 @@ bool CDecoder::CalcKey_and_CheckPassword()
|
||||||
|
|
||||||
for (unsigned i = 0; i < 3; i++)
|
for (unsigned i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
UInt32 j = numIterations;
|
for (; numIterations != 0; numIterations--)
|
||||||
|
|
||||||
for (; j != 0; j--)
|
|
||||||
{
|
{
|
||||||
ctx = baseCtx;
|
ctx = baseCtx;
|
||||||
ctx.Update(u, NSha256::kDigestSize);
|
ctx.Update((const Byte *)(const void *)u, NSha256::kDigestSize);
|
||||||
ctx.Final(u);
|
ctx.Final((Byte *)(void *)u);
|
||||||
for (unsigned s = 0; s < NSha256::kDigestSize; s++)
|
for (unsigned s = 0; s < Z7_ARRAY_SIZE(u); s++)
|
||||||
key[s] ^= u[s];
|
key[s] ^= u[s];
|
||||||
}
|
}
|
||||||
|
|
||||||
// RAR uses additional iterations for additional keys
|
// RAR uses additional iterations for additional keys
|
||||||
memcpy((i == 0 ? _key : (i == 1 ? _hashKey : pswCheck)), key, NSha256::kDigestSize);
|
memcpy(i == 0 ? _key32 : i == 1 ? _hashKey32 : pswCheck,
|
||||||
|
key, NSha256::kDigestSize);
|
||||||
numIterations = 16;
|
numIterations = 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_check_Calced32[0] = pswCheck[0] ^ pswCheck[2] ^ pswCheck[4] ^ pswCheck[6];
|
||||||
{
|
_check_Calced32[1] = pswCheck[1] ^ pswCheck[3] ^ pswCheck[5] ^ pswCheck[7];
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < kPswCheckSize; i++)
|
|
||||||
_check_Calced[i] = pswCheck[i];
|
|
||||||
|
|
||||||
for (i = kPswCheckSize; i < SHA256_DIGEST_SIZE; i++)
|
|
||||||
_check_Calced[i & (kPswCheckSize - 1)] ^= pswCheck[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
_needCalc = false;
|
_needCalc = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
MT_LOCK
|
MT_LOCK
|
||||||
g_Key = *this;
|
g_Key = *this;
|
||||||
|
|
@ -258,7 +265,7 @@ bool CDecoder::CalcKey_and_CheckPassword()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsThereCheck() && _canCheck)
|
if (IsThereCheck() && _canCheck)
|
||||||
return (memcmp(_check_Calced, _check, kPswCheckSize) == 0);
|
return memcmp(_check_Calced32, _check32, sizeof(_check32)) == 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace NCrypto {
|
||||||
namespace NRar5 {
|
namespace NRar5 {
|
||||||
|
|
||||||
const unsigned kSaltSize = 16;
|
const unsigned kSaltSize = 16;
|
||||||
const unsigned kPswCheckSize = 8;
|
const unsigned kPswCheckSize32 = 2;
|
||||||
const unsigned kAesKeySize = 32;
|
const unsigned kAesKeySize = 32;
|
||||||
|
|
||||||
namespace NCryptoFlags
|
namespace NCryptoFlags
|
||||||
|
|
@ -22,48 +22,47 @@ namespace NCryptoFlags
|
||||||
const unsigned kUseMAC = 1 << 1;
|
const unsigned kUseMAC = 1 << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CKey
|
struct CKeyBase
|
||||||
{
|
{
|
||||||
bool _needCalc;
|
protected:
|
||||||
|
UInt32 _key32[kAesKeySize / 4];
|
||||||
unsigned _numIterationsLog;
|
UInt32 _hashKey32[SHA256_NUM_DIGEST_WORDS];
|
||||||
Byte _salt[kSaltSize];
|
UInt32 _check_Calced32[kPswCheckSize32];
|
||||||
CByteBuffer _password;
|
|
||||||
|
|
||||||
Byte _key[kAesKeySize];
|
|
||||||
Byte _check_Calced[kPswCheckSize];
|
|
||||||
Byte _hashKey[SHA256_DIGEST_SIZE];
|
|
||||||
|
|
||||||
void CopyCalcedKeysFrom(const CKey &k)
|
|
||||||
{
|
|
||||||
memcpy(_key, k._key, sizeof(_key));
|
|
||||||
memcpy(_check_Calced, k._check_Calced, sizeof(_check_Calced));
|
|
||||||
memcpy(_hashKey, k._hashKey, sizeof(_hashKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsKeyEqualTo(const CKey &key)
|
|
||||||
{
|
|
||||||
return (_numIterationsLog == key._numIterationsLog
|
|
||||||
&& memcmp(_salt, key._salt, sizeof(_salt)) == 0
|
|
||||||
&& _password == key._password);
|
|
||||||
}
|
|
||||||
|
|
||||||
CKey();
|
|
||||||
|
|
||||||
void Wipe()
|
void Wipe()
|
||||||
{
|
{
|
||||||
_password.Wipe();
|
memset(this, 0, sizeof(*this));
|
||||||
Z7_memset_0_ARRAY(_salt);
|
|
||||||
Z7_memset_0_ARRAY(_key);
|
|
||||||
Z7_memset_0_ARRAY(_check_Calced);
|
|
||||||
Z7_memset_0_ARRAY(_hashKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CopyCalcedKeysFrom(const CKeyBase &k)
|
||||||
|
{
|
||||||
|
*this = k;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CKey: public CKeyBase
|
||||||
|
{
|
||||||
|
CByteBuffer _password;
|
||||||
|
bool _needCalc;
|
||||||
|
unsigned _numIterationsLog;
|
||||||
|
Byte _salt[kSaltSize];
|
||||||
|
|
||||||
|
bool IsKeyEqualTo(const CKey &key)
|
||||||
|
{
|
||||||
|
return _numIterationsLog == key._numIterationsLog
|
||||||
|
&& memcmp(_salt, key._salt, sizeof(_salt)) == 0
|
||||||
|
&& _password == key._password;
|
||||||
|
}
|
||||||
|
|
||||||
|
CKey();
|
||||||
|
~CKey();
|
||||||
|
|
||||||
|
void Wipe();
|
||||||
|
|
||||||
#ifdef Z7_CPP_IS_SUPPORTED_default
|
#ifdef Z7_CPP_IS_SUPPORTED_default
|
||||||
// CKey(const CKey &) = default;
|
// CKey(const CKey &) = default;
|
||||||
CKey& operator =(const CKey &) = default;
|
CKey& operator =(const CKey &) = default;
|
||||||
#endif
|
#endif
|
||||||
~CKey() { Wipe(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -71,11 +70,11 @@ class CDecoder Z7_final:
|
||||||
public CAesCbcDecoder,
|
public CAesCbcDecoder,
|
||||||
public CKey
|
public CKey
|
||||||
{
|
{
|
||||||
Byte _check[kPswCheckSize];
|
UInt32 _check32[kPswCheckSize32];
|
||||||
bool _canCheck;
|
bool _canCheck;
|
||||||
UInt64 Flags;
|
UInt64 Flags;
|
||||||
|
|
||||||
bool IsThereCheck() const { return ((Flags & NCryptoFlags::kPswCheck) != 0); }
|
bool IsThereCheck() const { return (Flags & NCryptoFlags::kPswCheck) != 0; }
|
||||||
public:
|
public:
|
||||||
Byte _iv[AES_BLOCK_SIZE];
|
Byte _iv[AES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@ static void UpdatePswDataSha1(Byte *data)
|
||||||
|
|
||||||
for (i = 16; i < 80; i++)
|
for (i = 16; i < 80; i++)
|
||||||
{
|
{
|
||||||
WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1);
|
const UInt32 t = WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16);
|
||||||
|
WW(i) = rotlFixed(t, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
|
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
|
||||||
|
|
@ -128,6 +129,7 @@ void CDecoder::CalcKey()
|
||||||
|
|
||||||
const unsigned kSaltSize = 8;
|
const unsigned kSaltSize = 8;
|
||||||
|
|
||||||
|
MY_ALIGN (16)
|
||||||
Byte buf[kPasswordLen_Bytes_MAX + kSaltSize];
|
Byte buf[kPasswordLen_Bytes_MAX + kSaltSize];
|
||||||
|
|
||||||
if (_password.Size() != 0)
|
if (_password.Size() != 0)
|
||||||
|
|
@ -148,7 +150,7 @@ void CDecoder::CalcKey()
|
||||||
MY_ALIGN (16)
|
MY_ALIGN (16)
|
||||||
Byte digest[NSha1::kDigestSize];
|
Byte digest[NSha1::kDigestSize];
|
||||||
// rar reverts hash for sha.
|
// rar reverts hash for sha.
|
||||||
const UInt32 kNumRounds = ((UInt32)1 << 18);
|
const UInt32 kNumRounds = (UInt32)1 << 18;
|
||||||
UInt32 pos = 0;
|
UInt32 pos = 0;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < kNumRounds; i++)
|
for (i = 0; i < kNumRounds; i++)
|
||||||
|
|
@ -171,8 +173,14 @@ void CDecoder::CalcKey()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pos += (UInt32)rawSize;
|
pos += (UInt32)rawSize;
|
||||||
|
#if 1
|
||||||
|
UInt32 pswNum;
|
||||||
|
SetUi32a(&pswNum, i)
|
||||||
|
sha.Update((const Byte *)&pswNum, 3);
|
||||||
|
#else
|
||||||
Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) };
|
Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) };
|
||||||
sha.Update(pswNum, 3);
|
sha.Update(pswNum, 3);
|
||||||
|
#endif
|
||||||
pos += 3;
|
pos += 3;
|
||||||
if (i % (kNumRounds / 16) == 0)
|
if (i % (kNumRounds / 16) == 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,30 +24,31 @@ static const UInt16 kAES128 = 0x660E;
|
||||||
if (method != AES && method != 3DES), probably we need another code.
|
if (method != AES && method != 3DES), probably we need another code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void DeriveKey2(const Byte *digest, Byte c, Byte *dest)
|
static void DeriveKey2(const UInt32 *digest32, Byte c, UInt32 *dest32)
|
||||||
{
|
{
|
||||||
|
const unsigned kBufSize = 64;
|
||||||
MY_ALIGN (16)
|
MY_ALIGN (16)
|
||||||
Byte buf[64];
|
UInt32 buf32[kBufSize / 4];
|
||||||
memset(buf, c, 64);
|
memset(buf32, c, kBufSize);
|
||||||
for (unsigned i = 0; i < NSha1::kDigestSize; i++)
|
for (unsigned i = 0; i < NSha1::kNumDigestWords; i++)
|
||||||
buf[i] ^= digest[i];
|
buf32[i] ^= digest32[i];
|
||||||
MY_ALIGN (16)
|
MY_ALIGN (16)
|
||||||
NSha1::CContext sha;
|
NSha1::CContext sha;
|
||||||
sha.Init();
|
sha.Init();
|
||||||
sha.Update(buf, 64);
|
sha.Update((const Byte *)buf32, kBufSize);
|
||||||
sha.Final(dest);
|
sha.Final((Byte *)dest32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeriveKey(NSha1::CContext &sha, Byte *key)
|
static void DeriveKey(NSha1::CContext &sha, Byte *key)
|
||||||
{
|
{
|
||||||
MY_ALIGN (16)
|
MY_ALIGN (16)
|
||||||
Byte digest[NSha1::kDigestSize];
|
UInt32 digest32[NSha1::kNumDigestWords];
|
||||||
sha.Final(digest);
|
sha.Final((Byte *)digest32);
|
||||||
MY_ALIGN (16)
|
MY_ALIGN (16)
|
||||||
Byte temp[NSha1::kDigestSize * 2];
|
UInt32 temp32[NSha1::kNumDigestWords * 2];
|
||||||
DeriveKey2(digest, 0x36, temp);
|
DeriveKey2(digest32, 0x36, temp32);
|
||||||
DeriveKey2(digest, 0x5C, temp + NSha1::kDigestSize);
|
DeriveKey2(digest32, 0x5C, temp32 + NSha1::kNumDigestWords);
|
||||||
memcpy(key, temp, 32);
|
memcpy(key, temp32, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeyInfo::SetPassword(const Byte *data, UInt32 size)
|
void CKeyInfo::SetPassword(const Byte *data, UInt32 size)
|
||||||
|
|
@ -122,24 +123,24 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
|
||||||
passwOK = false;
|
passwOK = false;
|
||||||
if (_remSize < 16)
|
if (_remSize < 16)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
Byte *p = _bufAligned;
|
Byte * const p = _bufAligned;
|
||||||
const unsigned format = GetUi16(p);
|
const unsigned format = GetUi16a(p);
|
||||||
if (format != 3)
|
if (format != 3)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
unsigned algId = GetUi16(p + 2);
|
unsigned algId = GetUi16a(p + 2);
|
||||||
if (algId < kAES128)
|
if (algId < kAES128)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
algId -= kAES128;
|
algId -= kAES128;
|
||||||
if (algId > 2)
|
if (algId > 2)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
const unsigned bitLen = GetUi16(p + 4);
|
const unsigned bitLen = GetUi16a(p + 4);
|
||||||
const unsigned flags = GetUi16(p + 6);
|
const unsigned flags = GetUi16a(p + 6);
|
||||||
if (algId * 64 + 128 != bitLen)
|
if (algId * 64 + 128 != bitLen)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
_key.KeySize = 16 + algId * 8;
|
_key.KeySize = 16 + algId * 8;
|
||||||
const bool cert = ((flags & 2) != 0);
|
const bool cert = ((flags & 2) != 0);
|
||||||
|
|
||||||
if ((flags & 0x4000) != 0)
|
if (flags & 0x4000)
|
||||||
{
|
{
|
||||||
// Use 3DES for rd data
|
// Use 3DES for rd data
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
|
@ -155,7 +156,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 rdSize = GetUi16(p + 8);
|
UInt32 rdSize = GetUi16a(p + 8);
|
||||||
|
|
||||||
if (rdSize + 16 > _remSize)
|
if (rdSize + 16 > _remSize)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
|
@ -174,7 +175,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
|
||||||
// PKCS7 padding
|
// PKCS7 padding
|
||||||
if (rdSize < kPadSize)
|
if (rdSize < kPadSize)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
if ((rdSize & (kPadSize - 1)) != 0)
|
if (rdSize & (kPadSize - 1))
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,5 +115,5 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
_x + _xSize, _y, 8, 12 // these values are unused
|
_x + _xSize, _y, 8, 12 // these values are unused
|
||||||
|
|
||||||
|
|
||||||
#define OPTIONS_PAGE_XC_SIZE 280
|
#define OPTIONS_PAGE_XC_SIZE 300
|
||||||
#define OPTIONS_PAGE_YC_SIZE 280
|
#define OPTIONS_PAGE_YC_SIZE 280
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
10 IFolderArchiveUpdateCallback2
|
10 IFolderArchiveUpdateCallback2
|
||||||
11 IFolderScanProgress
|
11 IFolderScanProgress
|
||||||
12 IFolderSetZoneIdMode
|
12 IFolderSetZoneIdMode
|
||||||
|
13 IFolderSetZoneIdFile
|
||||||
|
14 IFolderArchiveUpdateCallback_MoveArc
|
||||||
|
|
||||||
20 IFileExtractCallback.h::IGetProp
|
20 IFileExtractCallback.h::IGetProp
|
||||||
30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old)
|
30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old)
|
||||||
|
|
|
||||||
|
|
@ -1516,6 +1516,8 @@ Z7_COM7F_IMF(CAgentFolder::Extract(const UInt32 *indices,
|
||||||
if (_zoneMode != NExtract::NZoneIdMode::kNone)
|
if (_zoneMode != NExtract::NZoneIdMode::kNone)
|
||||||
{
|
{
|
||||||
ReadZoneFile_Of_BaseFile(us2fs(_agentSpec->_archiveFilePath), extractCallbackSpec->ZoneBuf);
|
ReadZoneFile_Of_BaseFile(us2fs(_agentSpec->_archiveFilePath), extractCallbackSpec->ZoneBuf);
|
||||||
|
if (_zoneBuf.Size() != 0)
|
||||||
|
extractCallbackSpec->ZoneBuf = _zoneBuf;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ class CAgentFolder Z7_final:
|
||||||
public IArchiveFolderInternal,
|
public IArchiveFolderInternal,
|
||||||
public IInArchiveGetStream,
|
public IInArchiveGetStream,
|
||||||
public IFolderSetZoneIdMode,
|
public IFolderSetZoneIdMode,
|
||||||
|
public IFolderSetZoneIdFile,
|
||||||
public IFolderOperations,
|
public IFolderOperations,
|
||||||
public IFolderSetFlatMode,
|
public IFolderSetFlatMode,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
|
|
@ -75,6 +76,7 @@ class CAgentFolder Z7_final:
|
||||||
Z7_COM_QI_ENTRY(IArchiveFolderInternal)
|
Z7_COM_QI_ENTRY(IArchiveFolderInternal)
|
||||||
Z7_COM_QI_ENTRY(IInArchiveGetStream)
|
Z7_COM_QI_ENTRY(IInArchiveGetStream)
|
||||||
Z7_COM_QI_ENTRY(IFolderSetZoneIdMode)
|
Z7_COM_QI_ENTRY(IFolderSetZoneIdMode)
|
||||||
|
Z7_COM_QI_ENTRY(IFolderSetZoneIdFile)
|
||||||
Z7_COM_QI_ENTRY(IFolderOperations)
|
Z7_COM_QI_ENTRY(IFolderOperations)
|
||||||
Z7_COM_QI_ENTRY(IFolderSetFlatMode)
|
Z7_COM_QI_ENTRY(IFolderSetFlatMode)
|
||||||
Z7_COM_QI_END
|
Z7_COM_QI_END
|
||||||
|
|
@ -91,6 +93,7 @@ class CAgentFolder Z7_final:
|
||||||
Z7_IFACE_COM7_IMP(IArchiveFolderInternal)
|
Z7_IFACE_COM7_IMP(IArchiveFolderInternal)
|
||||||
Z7_IFACE_COM7_IMP(IInArchiveGetStream)
|
Z7_IFACE_COM7_IMP(IInArchiveGetStream)
|
||||||
Z7_IFACE_COM7_IMP(IFolderSetZoneIdMode)
|
Z7_IFACE_COM7_IMP(IFolderSetZoneIdMode)
|
||||||
|
Z7_IFACE_COM7_IMP(IFolderSetZoneIdFile)
|
||||||
Z7_IFACE_COM7_IMP(IFolderOperations)
|
Z7_IFACE_COM7_IMP(IFolderOperations)
|
||||||
Z7_IFACE_COM7_IMP(IFolderSetFlatMode)
|
Z7_IFACE_COM7_IMP(IFolderSetFlatMode)
|
||||||
|
|
||||||
|
|
@ -106,11 +109,11 @@ public:
|
||||||
int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
|
int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
|
||||||
|
|
||||||
CAgentFolder():
|
CAgentFolder():
|
||||||
_proxyDirIndex(0),
|
|
||||||
_isAltStreamFolder(false),
|
_isAltStreamFolder(false),
|
||||||
_flatMode(false),
|
_flatMode(false),
|
||||||
_loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now
|
_loadAltStreams(false), // _loadAltStreams alt streams works in flat mode, but we don't use it now
|
||||||
, _zoneMode(NExtract::NZoneIdMode::kNone)
|
_proxyDirIndex(0),
|
||||||
|
_zoneMode(NExtract::NZoneIdMode::kNone)
|
||||||
/* , _replaceAltStreamCharsMode(0) */
|
/* , _replaceAltStreamCharsMode(0) */
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -145,21 +148,23 @@ public:
|
||||||
UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive
|
UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool _isAltStreamFolder;
|
||||||
|
bool _flatMode;
|
||||||
|
bool _loadAltStreams; // in Flat mode
|
||||||
const CProxyArc *_proxy;
|
const CProxyArc *_proxy;
|
||||||
const CProxyArc2 *_proxy2;
|
const CProxyArc2 *_proxy2;
|
||||||
unsigned _proxyDirIndex;
|
unsigned _proxyDirIndex;
|
||||||
bool _isAltStreamFolder;
|
NExtract::NZoneIdMode::EEnum _zoneMode;
|
||||||
|
CByteBuffer _zoneBuf;
|
||||||
|
// Int32 _replaceAltStreamCharsMode;
|
||||||
// CMyComPtr<IFolderFolder> _parentFolder;
|
// CMyComPtr<IFolderFolder> _parentFolder;
|
||||||
CMyComPtr<IInFolderArchive> _agent;
|
CMyComPtr<IInFolderArchive> _agent;
|
||||||
CAgent *_agentSpec;
|
CAgent *_agentSpec;
|
||||||
|
|
||||||
CRecordVector<CProxyItem> _items;
|
CRecordVector<CProxyItem> _items;
|
||||||
bool _flatMode;
|
|
||||||
bool _loadAltStreams; // in Flat mode
|
|
||||||
// Int32 _replaceAltStreamCharsMode;
|
|
||||||
NExtract::NZoneIdMode::EEnum _zoneMode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CAgent Z7_final:
|
class CAgent Z7_final:
|
||||||
public IInFolderArchive,
|
public IInFolderArchive,
|
||||||
public IFolderArcProps,
|
public IFolderArcProps,
|
||||||
|
|
@ -213,22 +218,22 @@ public:
|
||||||
CProxyArc2 *_proxy2;
|
CProxyArc2 *_proxy2;
|
||||||
CArchiveLink _archiveLink;
|
CArchiveLink _archiveLink;
|
||||||
|
|
||||||
bool ThereIsPathProp;
|
|
||||||
// bool ThereIsAltStreamProp;
|
|
||||||
|
|
||||||
UString ArchiveType;
|
UString ArchiveType;
|
||||||
|
|
||||||
FStringVector _names;
|
FStringVector _names;
|
||||||
FString _folderPrefix; // for new files from disk
|
FString _folderPrefix; // for new files from disk
|
||||||
|
|
||||||
bool _updatePathPrefix_is_AltFolder;
|
|
||||||
UString _updatePathPrefix;
|
UString _updatePathPrefix;
|
||||||
CAgentFolder *_agentFolder;
|
CAgentFolder *_agentFolder;
|
||||||
|
|
||||||
UString _archiveFilePath;
|
UString _archiveFilePath; // it can be path of non-existing file if file is virtual
|
||||||
|
|
||||||
DWORD _attrib;
|
DWORD _attrib;
|
||||||
|
bool _updatePathPrefix_is_AltFolder;
|
||||||
|
bool ThereIsPathProp;
|
||||||
bool _isDeviceFile;
|
bool _isDeviceFile;
|
||||||
bool _isHashHandler;
|
bool _isHashHandler;
|
||||||
|
|
||||||
FString _hashBaseFolderPrefix;
|
FString _hashBaseFolderPrefix;
|
||||||
|
|
||||||
#ifndef Z7_EXTRACT_ONLY
|
#ifndef Z7_EXTRACT_ONLY
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,12 @@ Z7_COM7F_IMF(CAgentFolder::SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode))
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Z7_COM7F_IMF(CAgentFolder::SetZoneIdFile(const Byte *data, UInt32 size))
|
||||||
|
{
|
||||||
|
_zoneBuf.CopyFrom(data, size);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Z7_COM7F_IMF(CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
|
Z7_COM7F_IMF(CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 includeAltStreams, Int32 replaceAltStreamCharsMode,
|
Int32 includeAltStreams, Int32 replaceAltStreamCharsMode,
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,33 @@ static bool Delete_EmptyFolder_And_EmptySubFolders(const FString &path)
|
||||||
return RemoveDir(path);
|
return RemoveDir(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct C_CopyFileProgress_to_FolderCallback_MoveArc Z7_final:
|
||||||
|
public ICopyFileProgress
|
||||||
|
{
|
||||||
|
IFolderArchiveUpdateCallback_MoveArc *Callback;
|
||||||
|
HRESULT CallbackResult;
|
||||||
|
|
||||||
|
virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override
|
||||||
|
{
|
||||||
|
HRESULT res = Callback->MoveArc_Progress(total, current);
|
||||||
|
CallbackResult = res;
|
||||||
|
// we can ignore E_ABORT here, because we update archive,
|
||||||
|
// and we want to get correct archive after updating
|
||||||
|
if (res == E_ABORT)
|
||||||
|
res = S_OK;
|
||||||
|
return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_CopyFileProgress_to_FolderCallback_MoveArc(
|
||||||
|
IFolderArchiveUpdateCallback_MoveArc *callback) :
|
||||||
|
Callback(callback),
|
||||||
|
CallbackResult(S_OK)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
HRESULT CAgentFolder::CommonUpdateOperation(
|
HRESULT CAgentFolder::CommonUpdateOperation(
|
||||||
AGENT_OP operation,
|
AGENT_OP operation,
|
||||||
bool moveMode,
|
bool moveMode,
|
||||||
|
|
@ -159,8 +186,51 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||||
// now: we reopen archive after close
|
// now: we reopen archive after close
|
||||||
|
|
||||||
// m_FolderItem = NULL;
|
// m_FolderItem = NULL;
|
||||||
|
_items.Clear();
|
||||||
|
_proxyDirIndex = k_Proxy_RootDirIndex;
|
||||||
|
|
||||||
const HRESULT res = tempFile.MoveToOriginal(true);
|
CMyComPtr<IFolderArchiveUpdateCallback_MoveArc> updateCallback_MoveArc;
|
||||||
|
if (progress)
|
||||||
|
progress->QueryInterface(IID_IFolderArchiveUpdateCallback_MoveArc, (void **)&updateCallback_MoveArc);
|
||||||
|
|
||||||
|
HRESULT res;
|
||||||
|
if (updateCallback_MoveArc)
|
||||||
|
{
|
||||||
|
const FString &tempFilePath = tempFile.Get_TempFilePath();
|
||||||
|
UInt64 totalSize = 0;
|
||||||
|
{
|
||||||
|
NFind::CFileInfo fi;
|
||||||
|
if (fi.Find(tempFilePath))
|
||||||
|
totalSize = fi.Size;
|
||||||
|
}
|
||||||
|
RINOK(updateCallback_MoveArc->MoveArc_Start(
|
||||||
|
fs2us(tempFilePath),
|
||||||
|
fs2us(tempFile.Get_OriginalFilePath()),
|
||||||
|
totalSize,
|
||||||
|
1)) // updateMode
|
||||||
|
|
||||||
|
C_CopyFileProgress_to_FolderCallback_MoveArc prox(updateCallback_MoveArc);
|
||||||
|
res = tempFile.MoveToOriginal(
|
||||||
|
true, // deleteOriginal
|
||||||
|
&prox);
|
||||||
|
if (res == S_OK)
|
||||||
|
{
|
||||||
|
res = updateCallback_MoveArc->MoveArc_Finish();
|
||||||
|
// we don't return after E_ABORT here, because
|
||||||
|
// we want to reopen new archive still.
|
||||||
|
}
|
||||||
|
else if (prox.CallbackResult != S_OK)
|
||||||
|
res = prox.CallbackResult;
|
||||||
|
|
||||||
|
// if updating callback returned E_ABORT,
|
||||||
|
// then openCallback still can return E_ABORT also.
|
||||||
|
// So ReOpen() will return with E_ABORT.
|
||||||
|
// But we want to open archive still.
|
||||||
|
// And Before_ArcReopen() call will clear user break status in that case.
|
||||||
|
RINOK(updateCallback_MoveArc->Before_ArcReopen())
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = tempFile.MoveToOriginal(true); // deleteOriginal
|
||||||
|
|
||||||
// RINOK(res);
|
// RINOK(res);
|
||||||
if (res == S_OK)
|
if (res == S_OK)
|
||||||
|
|
@ -189,10 +259,10 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||||
}
|
}
|
||||||
|
|
||||||
// CAgent::ReOpen() deletes _proxy and _proxy2
|
// CAgent::ReOpen() deletes _proxy and _proxy2
|
||||||
_items.Clear();
|
// _items.Clear();
|
||||||
_proxy = NULL;
|
_proxy = NULL;
|
||||||
_proxy2 = NULL;
|
_proxy2 = NULL;
|
||||||
_proxyDirIndex = k_Proxy_RootDirIndex;
|
// _proxyDirIndex = k_Proxy_RootDirIndex;
|
||||||
_isAltStreamFolder = false;
|
_isAltStreamFolder = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,5 +103,21 @@ Z7_IFACE_CONSTR_FOLDERARC(IFolderScanProgress, 0x11)
|
||||||
|
|
||||||
Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdMode, 0x12)
|
Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdMode, 0x12)
|
||||||
|
|
||||||
|
#define Z7_IFACEM_IFolderSetZoneIdFile(x) \
|
||||||
|
x(SetZoneIdFile(const Byte *data, UInt32 size)) \
|
||||||
|
|
||||||
|
Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdFile, 0x13)
|
||||||
|
|
||||||
|
|
||||||
|
// if the caller calls Before_ArcReopen(), the callee must
|
||||||
|
// clear user break status, because the caller want to open archive still.
|
||||||
|
#define Z7_IFACEM_IFolderArchiveUpdateCallback_MoveArc(x) \
|
||||||
|
x(MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode)) \
|
||||||
|
x(MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) \
|
||||||
|
x(MoveArc_Finish()) \
|
||||||
|
x(Before_ArcReopen()) \
|
||||||
|
|
||||||
|
Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveUpdateCallback_MoveArc, 0x14)
|
||||||
|
|
||||||
Z7_PURE_INTERFACES_END
|
Z7_PURE_INTERFACES_END
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,11 @@ WIN_OBJS = \
|
||||||
7ZIP_COMMON_OBJS = \
|
7ZIP_COMMON_OBJS = \
|
||||||
$O/FileStreams.o \
|
$O/FileStreams.o \
|
||||||
|
|
||||||
|
C_OBJS = \
|
||||||
|
$O/Alloc.o \
|
||||||
|
|
||||||
OBJS = \
|
OBJS = \
|
||||||
|
$(C_OBJS) \
|
||||||
$(COMMON_OBJS) \
|
$(COMMON_OBJS) \
|
||||||
$(WIN_OBJS) \
|
$(WIN_OBJS) \
|
||||||
$(SYS_OBJS) \
|
$(SYS_OBJS) \
|
||||||
|
|
|
||||||
|
|
@ -1039,6 +1039,9 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
|
||||||
options.TechMode = parser[NKey::kTechMode].ThereIs;
|
options.TechMode = parser[NKey::kTechMode].ThereIs;
|
||||||
options.ShowTime = parser[NKey::kShowTime].ThereIs;
|
options.ShowTime = parser[NKey::kShowTime].ThereIs;
|
||||||
|
|
||||||
|
if (parser[NKey::kDisablePercents].ThereIs)
|
||||||
|
options.DisablePercents = true;
|
||||||
|
|
||||||
if (parser[NKey::kDisablePercents].ThereIs
|
if (parser[NKey::kDisablePercents].ThereIs
|
||||||
|| options.StdOutMode
|
|| options.StdOutMode
|
||||||
|| !options.IsStdOutTerminal)
|
|| !options.IsStdOutTerminal)
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ struct CArcCmdLineOptions
|
||||||
bool StdInMode;
|
bool StdInMode;
|
||||||
bool StdOutMode;
|
bool StdOutMode;
|
||||||
bool EnableHeaders;
|
bool EnableHeaders;
|
||||||
|
bool DisablePercents;
|
||||||
|
|
||||||
|
|
||||||
bool YesToAll;
|
bool YesToAll;
|
||||||
bool ShowDialog;
|
bool ShowDialog;
|
||||||
|
|
@ -132,6 +134,7 @@ struct CArcCmdLineOptions
|
||||||
StdOutMode(false),
|
StdOutMode(false),
|
||||||
|
|
||||||
EnableHeaders(false),
|
EnableHeaders(false),
|
||||||
|
DisablePercents(false),
|
||||||
|
|
||||||
YesToAll(false),
|
YesToAll(false),
|
||||||
ShowDialog(false),
|
ShowDialog(false),
|
||||||
|
|
|
||||||
|
|
@ -140,21 +140,25 @@ static bool FindExt2(const char *p, const UString &name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
|
static const char * const k_ZoneId_StreamName_With_Colon_Prefix = ":Zone.Identifier";
|
||||||
|
|
||||||
void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf)
|
bool Is_ZoneId_StreamName(const wchar_t *s)
|
||||||
{
|
{
|
||||||
FString fileName (fileName2);
|
return StringsAreEqualNoCase_Ascii(s, k_ZoneId_StreamName_With_Colon_Prefix + 1);
|
||||||
fileName += k_ZoneId_StreamName;
|
}
|
||||||
|
|
||||||
|
void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf)
|
||||||
|
{
|
||||||
buf.Free();
|
buf.Free();
|
||||||
|
FString path (fileName);
|
||||||
|
path += k_ZoneId_StreamName_With_Colon_Prefix;
|
||||||
NIO::CInFile file;
|
NIO::CInFile file;
|
||||||
if (!file.Open(fileName))
|
if (!file.Open(path))
|
||||||
return;
|
return;
|
||||||
UInt64 fileSize;
|
UInt64 fileSize;
|
||||||
if (!file.GetLength(fileSize))
|
if (!file.GetLength(fileSize))
|
||||||
return;
|
return;
|
||||||
if (fileSize == 0 || fileSize >= ((UInt32)1 << 16))
|
if (fileSize == 0 || fileSize >= (1u << 15))
|
||||||
return;
|
return;
|
||||||
buf.Alloc((size_t)fileSize);
|
buf.Alloc((size_t)fileSize);
|
||||||
size_t processed;
|
size_t processed;
|
||||||
|
|
@ -166,7 +170,7 @@ void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf)
|
||||||
bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf)
|
bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf)
|
||||||
{
|
{
|
||||||
FString path (fileName);
|
FString path (fileName);
|
||||||
path += k_ZoneId_StreamName;
|
path += k_ZoneId_StreamName_With_Colon_Prefix;
|
||||||
NIO::COutFile file;
|
NIO::COutFile file;
|
||||||
if (!file.Create_ALWAYS(path))
|
if (!file.Create_ALWAYS(path))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -275,16 +279,13 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r
|
||||||
|
|
||||||
|
|
||||||
CArchiveExtractCallback::CArchiveExtractCallback():
|
CArchiveExtractCallback::CArchiveExtractCallback():
|
||||||
_arc(NULL),
|
// Write_CTime(true),
|
||||||
Write_CTime(true),
|
// Write_ATime(true),
|
||||||
Write_ATime(true),
|
// Write_MTime(true),
|
||||||
Write_MTime(true),
|
|
||||||
Is_elimPrefix_Mode(false),
|
Is_elimPrefix_Mode(false),
|
||||||
|
_arc(NULL),
|
||||||
_multiArchives(false)
|
_multiArchives(false)
|
||||||
{
|
{
|
||||||
LocalProgressSpec = new CLocalProgress();
|
|
||||||
_localProgress = LocalProgressSpec;
|
|
||||||
|
|
||||||
#ifdef Z7_USE_SECURITY_CODE
|
#ifdef Z7_USE_SECURITY_CODE
|
||||||
_saclEnabled = InitLocalPrivileges();
|
_saclEnabled = InitLocalPrivileges();
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -293,7 +294,7 @@ CArchiveExtractCallback::CArchiveExtractCallback():
|
||||||
|
|
||||||
void CArchiveExtractCallback::InitBeforeNewArchive()
|
void CArchiveExtractCallback::InitBeforeNewArchive()
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
|
||||||
ZoneBuf.Free();
|
ZoneBuf.Free();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -322,27 +323,20 @@ void CArchiveExtractCallback::Init(
|
||||||
|
|
||||||
_ntOptions = ntOptions;
|
_ntOptions = ntOptions;
|
||||||
_wildcardCensor = wildcardCensor;
|
_wildcardCensor = wildcardCensor;
|
||||||
|
|
||||||
_stdOutMode = stdOutMode;
|
_stdOutMode = stdOutMode;
|
||||||
_testMode = testMode;
|
_testMode = testMode;
|
||||||
|
|
||||||
// _progressTotal = 0;
|
|
||||||
// _progressTotal_Defined = false;
|
|
||||||
|
|
||||||
_packTotal = packSize;
|
_packTotal = packSize;
|
||||||
_progressTotal = packSize;
|
_progressTotal = packSize;
|
||||||
_progressTotal_Defined = true;
|
// _progressTotal = 0;
|
||||||
|
// _progressTotal_Defined = false;
|
||||||
|
// _progressTotal_Defined = true;
|
||||||
_extractCallback2 = extractCallback2;
|
_extractCallback2 = extractCallback2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
_compressProgress.Release();
|
_compressProgress.Release();
|
||||||
_extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
|
_extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
|
||||||
|
|
||||||
_callbackMessage.Release();
|
_callbackMessage.Release();
|
||||||
_extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage);
|
_extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_folderArchiveExtractCallback2.Release();
|
_folderArchiveExtractCallback2.Release();
|
||||||
_extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2);
|
_extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2);
|
||||||
|
|
||||||
|
|
@ -390,7 +384,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 size))
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
_progressTotal = size;
|
_progressTotal = size;
|
||||||
_progressTotal_Defined = true;
|
// _progressTotal_Defined = true;
|
||||||
if (!_multiArchives && _extractCallback2)
|
if (!_multiArchives && _extractCallback2)
|
||||||
return _extractCallback2->SetTotal(size);
|
return _extractCallback2->SetTotal(size);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
@ -430,7 +424,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue))
|
||||||
if (_multiArchives)
|
if (_multiArchives)
|
||||||
{
|
{
|
||||||
packCur = LocalProgressSpec->InSize;
|
packCur = LocalProgressSpec->InSize;
|
||||||
if (completeValue && _progressTotal_Defined)
|
if (completeValue /* && _progressTotal_Defined */)
|
||||||
packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal);
|
packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal);
|
||||||
completeValue = &packCur;
|
completeValue = &packCur;
|
||||||
}
|
}
|
||||||
|
|
@ -443,7 +437,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue))
|
||||||
Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
|
Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
return _localProgress->SetRatioInfo(inSize, outSize);
|
return LocalProgressSpec.Interface()->SetRatioInfo(inSize, outSize);
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -582,13 +576,23 @@ HRESULT CArchiveExtractCallback::SendMessageError2(HRESULT errorCode, const char
|
||||||
|
|
||||||
#ifndef Z7_SFX
|
#ifndef Z7_SFX
|
||||||
|
|
||||||
|
Z7_CLASS_IMP_COM_1(
|
||||||
|
CGetProp
|
||||||
|
, IGetProp
|
||||||
|
)
|
||||||
|
public:
|
||||||
|
UInt32 IndexInArc;
|
||||||
|
const CArc *Arc;
|
||||||
|
// UString BaseName; // relative path
|
||||||
|
};
|
||||||
|
|
||||||
Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value))
|
Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
if (propID == kpidName)
|
if (propID == kpidBaseName)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
NCOM::CPropVariant prop = Name;
|
NCOM::CPropVariant prop = BaseName;
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
|
|
@ -1087,7 +1091,7 @@ void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt)
|
||||||
pt.ATime_Defined = false;
|
pt.ATime_Defined = false;
|
||||||
pt.MTime_Defined = false;
|
pt.MTime_Defined = false;
|
||||||
|
|
||||||
if (Write_MTime)
|
// if (Write_MTime)
|
||||||
{
|
{
|
||||||
if (_fi.MTime.Def)
|
if (_fi.MTime.Def)
|
||||||
{
|
{
|
||||||
|
|
@ -1101,13 +1105,13 @@ void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Write_CTime && _fi.CTime.Def)
|
if (/* Write_CTime && */ _fi.CTime.Def)
|
||||||
{
|
{
|
||||||
_fi.CTime.Write_To_FiTime(pt.CTime);
|
_fi.CTime.Write_To_FiTime(pt.CTime);
|
||||||
pt.CTime_Defined = true;
|
pt.CTime_Defined = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Write_ATime && _fi.ATime.Def)
|
if (/* Write_ATime && */ _fi.ATime.Def)
|
||||||
{
|
{
|
||||||
_fi.ATime.Write_To_FiTime(pt.ATime);
|
_fi.ATime.Write_To_FiTime(pt.ATime);
|
||||||
pt.ATime_Defined = true;
|
pt.ATime_Defined = true;
|
||||||
|
|
@ -1302,7 +1306,7 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||||
// we need to clear READ-ONLY of parent before creating alt stream
|
// we need to clear READ-ONLY of parent before creating alt stream
|
||||||
int colonPos = NName::FindAltStreamColon(fullProcessedPath);
|
const int colonPos = NName::FindAltStreamColon(fullProcessedPath);
|
||||||
if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0)
|
if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0)
|
||||||
{
|
{
|
||||||
FString parentFsPath (fullProcessedPath);
|
FString parentFsPath (fullProcessedPath);
|
||||||
|
|
@ -1311,9 +1315,13 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool
|
||||||
if (parentFi.Find(parentFsPath))
|
if (parentFi.Find(parentFsPath))
|
||||||
{
|
{
|
||||||
if (parentFi.IsReadOnly())
|
if (parentFi.IsReadOnly())
|
||||||
|
{
|
||||||
|
_altStream_NeedRestore_Attrib_for_parentFsPath = parentFsPath;
|
||||||
|
_altStream_NeedRestore_AttribVal = parentFi.Attrib;
|
||||||
SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY);
|
SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif // defined(_WIN32) && !defined(UNDER_CE)
|
#endif // defined(_WIN32) && !defined(UNDER_CE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1607,37 +1615,37 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||||
_bufPtrSeqOutStream.Release();
|
_bufPtrSeqOutStream.Release();
|
||||||
|
|
||||||
_encrypted = false;
|
_encrypted = false;
|
||||||
_position = 0;
|
|
||||||
_isSplit = false;
|
_isSplit = false;
|
||||||
|
|
||||||
_curSize = 0;
|
|
||||||
_curSize_Defined = false;
|
_curSize_Defined = false;
|
||||||
_fileLength_WasSet = false;
|
_fileLength_WasSet = false;
|
||||||
_fileLength_that_WasSet = 0;
|
|
||||||
_index = index;
|
|
||||||
|
|
||||||
_diskFilePath.Empty();
|
|
||||||
|
|
||||||
_isRenamed = false;
|
_isRenamed = false;
|
||||||
|
|
||||||
// _fi.Clear();
|
// _fi.Clear();
|
||||||
|
_extractMode = false;
|
||||||
// _is_SymLink_in_Data = false;
|
// _is_SymLink_in_Data = false;
|
||||||
_is_SymLink_in_Data_Linux = false;
|
_is_SymLink_in_Data_Linux = false;
|
||||||
|
|
||||||
_needSetAttrib = false;
|
_needSetAttrib = false;
|
||||||
_isSymLinkCreated = false;
|
_isSymLinkCreated = false;
|
||||||
_itemFailure = false;
|
_itemFailure = false;
|
||||||
|
|
||||||
_some_pathParts_wereRemoved = false;
|
_some_pathParts_wereRemoved = false;
|
||||||
// _op_WasReported = false;
|
// _op_WasReported = false;
|
||||||
|
|
||||||
|
_position = 0;
|
||||||
|
_curSize = 0;
|
||||||
|
_fileLength_that_WasSet = 0;
|
||||||
|
_index = index;
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||||
|
_altStream_NeedRestore_AttribVal = 0;
|
||||||
|
_altStream_NeedRestore_Attrib_for_parentFsPath.Empty();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_diskFilePath.Empty();
|
||||||
|
|
||||||
#ifdef SUPPORT_LINKS
|
#ifdef SUPPORT_LINKS
|
||||||
// _copyFile_Path.Empty();
|
// _copyFile_Path.Empty();
|
||||||
_link.Clear();
|
_link.Clear();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_extractMode = false;
|
|
||||||
|
|
||||||
switch (askExtractMode)
|
switch (askExtractMode)
|
||||||
{
|
{
|
||||||
|
|
@ -1692,6 +1700,19 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
|
||||||
|
if (askExtractMode == NArchive::NExtract::NAskMode::kExtract
|
||||||
|
&& !_testMode
|
||||||
|
&& _item.IsAltStream
|
||||||
|
&& ZoneBuf.Size() != 0
|
||||||
|
&& Is_ZoneId_StreamName(_item.AltStreamName))
|
||||||
|
if (ZoneMode != NExtract::NZoneIdMode::kOffice
|
||||||
|
|| _item.PathParts.IsEmpty()
|
||||||
|
|| FindExt2(kOfficeExtensions, _item.PathParts.Back()))
|
||||||
|
return S_OK;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef Z7_SFX
|
#ifndef Z7_SFX
|
||||||
if (_use_baseParentFolder_mode)
|
if (_use_baseParentFolder_mode)
|
||||||
{
|
{
|
||||||
|
|
@ -1810,15 +1831,11 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||||
|
|
||||||
if (ExtractToStreamCallback)
|
if (ExtractToStreamCallback)
|
||||||
{
|
{
|
||||||
if (!GetProp)
|
CMyComPtr2_Create<IGetProp, CGetProp> GetProp;
|
||||||
{
|
GetProp->Arc = _arc;
|
||||||
GetProp_Spec = new CGetProp;
|
GetProp->IndexInArc = index;
|
||||||
GetProp = GetProp_Spec;
|
|
||||||
}
|
|
||||||
GetProp_Spec->Arc = _arc;
|
|
||||||
GetProp_Spec->IndexInArc = index;
|
|
||||||
UString name (MakePathFromParts(pathParts));
|
UString name (MakePathFromParts(pathParts));
|
||||||
|
// GetProp->BaseName = name;
|
||||||
#ifdef SUPPORT_ALT_STREAMS
|
#ifdef SUPPORT_ALT_STREAMS
|
||||||
if (_item.IsAltStream)
|
if (_item.IsAltStream)
|
||||||
{
|
{
|
||||||
|
|
@ -1984,6 +2001,15 @@ HRESULT CArchiveExtractCallback::CloseFile()
|
||||||
|
|
||||||
RINOK(_outFileStreamSpec->Close())
|
RINOK(_outFileStreamSpec->Close())
|
||||||
_outFileStream.Release();
|
_outFileStream.Release();
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||||
|
if (!_altStream_NeedRestore_Attrib_for_parentFsPath.IsEmpty())
|
||||||
|
{
|
||||||
|
SetFileAttrib(_altStream_NeedRestore_Attrib_for_parentFsPath, _altStream_NeedRestore_AttribVal);
|
||||||
|
_altStream_NeedRestore_Attrib_for_parentFsPath.Empty();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,25 +90,10 @@ struct CExtractNtOptions
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef Z7_SFX
|
|
||||||
|
|
||||||
Z7_CLASS_IMP_COM_1(
|
|
||||||
CGetProp
|
|
||||||
, IGetProp
|
|
||||||
)
|
|
||||||
public:
|
|
||||||
UInt32 IndexInArc;
|
|
||||||
const CArc *Arc;
|
|
||||||
// UString Name; // relative path
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Z7_SFX
|
#ifndef Z7_SFX
|
||||||
#ifndef UNDER_CE
|
#ifndef UNDER_CE
|
||||||
|
|
||||||
#define SUPPORT_LINKS
|
#define SUPPORT_LINKS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -282,46 +267,44 @@ class CArchiveExtractCallback Z7_final:
|
||||||
Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback)
|
Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// bool Write_CTime;
|
||||||
|
// bool Write_ATime;
|
||||||
|
// bool Write_MTime;
|
||||||
|
bool _stdOutMode;
|
||||||
|
bool _testMode;
|
||||||
|
bool _removePartsForAltStreams;
|
||||||
|
public:
|
||||||
|
bool Is_elimPrefix_Mode;
|
||||||
|
private:
|
||||||
|
|
||||||
const CArc *_arc;
|
const CArc *_arc;
|
||||||
CExtractNtOptions _ntOptions;
|
CExtractNtOptions _ntOptions;
|
||||||
|
|
||||||
bool _isSplit;
|
|
||||||
|
|
||||||
bool _extractMode;
|
|
||||||
|
|
||||||
bool Write_CTime;
|
|
||||||
bool Write_ATime;
|
|
||||||
bool Write_MTime;
|
|
||||||
bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_";
|
|
||||||
|
|
||||||
bool _encrypted;
|
bool _encrypted;
|
||||||
|
bool _isSplit;
|
||||||
// bool _is_SymLink_in_Data;
|
|
||||||
bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX
|
|
||||||
|
|
||||||
bool _needSetAttrib;
|
|
||||||
bool _isSymLinkCreated;
|
|
||||||
bool _itemFailure;
|
|
||||||
|
|
||||||
bool _some_pathParts_wereRemoved;
|
|
||||||
public:
|
|
||||||
bool Is_elimPrefix_Mode;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _curSize_Defined;
|
bool _curSize_Defined;
|
||||||
bool _fileLength_WasSet;
|
bool _fileLength_WasSet;
|
||||||
|
|
||||||
bool _removePartsForAltStreams;
|
bool _isRenamed;
|
||||||
|
bool _extractMode;
|
||||||
|
// bool _is_SymLink_in_Data;
|
||||||
|
bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX
|
||||||
|
bool _needSetAttrib;
|
||||||
|
bool _isSymLinkCreated;
|
||||||
|
bool _itemFailure;
|
||||||
|
bool _some_pathParts_wereRemoved;
|
||||||
|
|
||||||
bool _stdOutMode;
|
|
||||||
bool _testMode;
|
|
||||||
bool _multiArchives;
|
bool _multiArchives;
|
||||||
|
bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_";
|
||||||
|
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
|
||||||
|
bool _saclEnabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
NExtract::NPathMode::EEnum _pathMode;
|
NExtract::NPathMode::EEnum _pathMode;
|
||||||
NExtract::NOverwriteMode::EEnum _overwriteMode;
|
NExtract::NOverwriteMode::EEnum _overwriteMode;
|
||||||
|
|
||||||
const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
|
|
||||||
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
|
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
|
||||||
|
const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
|
||||||
// CMyComPtr<ICompressProgressInfo> _compressProgress;
|
// CMyComPtr<ICompressProgressInfo> _compressProgress;
|
||||||
// CMyComPtr<IArchiveExtractCallbackMessage2> _callbackMessage;
|
// CMyComPtr<IArchiveExtractCallbackMessage2> _callbackMessage;
|
||||||
CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2;
|
CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2;
|
||||||
|
|
@ -333,15 +316,12 @@ private:
|
||||||
#ifndef Z7_SFX
|
#ifndef Z7_SFX
|
||||||
|
|
||||||
CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
|
CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
|
||||||
CGetProp *GetProp_Spec;
|
|
||||||
CMyComPtr<IGetProp> GetProp;
|
|
||||||
CMyComPtr<IArchiveRequestMemoryUseCallback> _requestMemoryUseCallback;
|
CMyComPtr<IArchiveRequestMemoryUseCallback> _requestMemoryUseCallback;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CReadArcItem _item;
|
CReadArcItem _item;
|
||||||
FString _diskFilePath;
|
FString _diskFilePath;
|
||||||
UInt64 _position;
|
|
||||||
|
|
||||||
struct CProcessedFileInfo
|
struct CProcessedFileInfo
|
||||||
{
|
{
|
||||||
|
|
@ -387,9 +367,17 @@ private:
|
||||||
}
|
}
|
||||||
} _fi;
|
} _fi;
|
||||||
|
|
||||||
UInt32 _index;
|
UInt64 _position;
|
||||||
UInt64 _curSize;
|
UInt64 _curSize;
|
||||||
UInt64 _fileLength_that_WasSet;
|
UInt64 _fileLength_that_WasSet;
|
||||||
|
UInt32 _index;
|
||||||
|
|
||||||
|
// #ifdef SUPPORT_ALT_STREAMS
|
||||||
|
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||||
|
DWORD _altStream_NeedRestore_AttribVal;
|
||||||
|
FString _altStream_NeedRestore_Attrib_for_parentFsPath;
|
||||||
|
#endif
|
||||||
|
// #endif
|
||||||
|
|
||||||
COutFileStream *_outFileStreamSpec;
|
COutFileStream *_outFileStreamSpec;
|
||||||
CMyComPtr<ISequentialOutStream> _outFileStream;
|
CMyComPtr<ISequentialOutStream> _outFileStream;
|
||||||
|
|
@ -398,9 +386,7 @@ private:
|
||||||
CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec;
|
CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec;
|
||||||
CMyComPtr<ISequentialOutStream> _bufPtrSeqOutStream;
|
CMyComPtr<ISequentialOutStream> _bufPtrSeqOutStream;
|
||||||
|
|
||||||
|
|
||||||
#ifndef Z7_SFX
|
#ifndef Z7_SFX
|
||||||
|
|
||||||
COutStreamWithHash *_hashStreamSpec;
|
COutStreamWithHash *_hashStreamSpec;
|
||||||
CMyComPtr<ISequentialOutStream> _hashStream;
|
CMyComPtr<ISequentialOutStream> _hashStream;
|
||||||
bool _hashStreamWasUsed;
|
bool _hashStreamWasUsed;
|
||||||
|
|
@ -411,11 +397,9 @@ private:
|
||||||
|
|
||||||
UStringVector _removePathParts;
|
UStringVector _removePathParts;
|
||||||
|
|
||||||
CMyComPtr<ICompressProgressInfo> _localProgress;
|
|
||||||
UInt64 _packTotal;
|
UInt64 _packTotal;
|
||||||
|
|
||||||
UInt64 _progressTotal;
|
UInt64 _progressTotal;
|
||||||
bool _progressTotal_Defined;
|
// bool _progressTotal_Defined;
|
||||||
|
|
||||||
CObjectVector<CDirPathTime> _extractedFolders;
|
CObjectVector<CDirPathTime> _extractedFolders;
|
||||||
|
|
||||||
|
|
@ -423,10 +407,6 @@ private:
|
||||||
// CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks;
|
// CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
|
|
||||||
bool _saclEnabled;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
|
void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
|
||||||
HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft);
|
HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft);
|
||||||
HRESULT GetUnpackSize();
|
HRESULT GetUnpackSize();
|
||||||
|
|
@ -441,13 +421,12 @@ public:
|
||||||
HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
|
HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
|
||||||
HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2);
|
HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2);
|
||||||
|
|
||||||
public:
|
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
|
||||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
|
||||||
NExtract::NZoneIdMode::EEnum ZoneMode;
|
NExtract::NZoneIdMode::EEnum ZoneMode;
|
||||||
CByteBuffer ZoneBuf;
|
CByteBuffer ZoneBuf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CLocalProgress *LocalProgressSpec;
|
CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> LocalProgressSpec;
|
||||||
|
|
||||||
UInt64 NumFolders;
|
UInt64 NumFolders;
|
||||||
UInt64 NumFiles;
|
UInt64 NumFiles;
|
||||||
|
|
@ -468,7 +447,7 @@ public:
|
||||||
_multiArchives = multiArchives;
|
_multiArchives = multiArchives;
|
||||||
_pathMode = pathMode;
|
_pathMode = pathMode;
|
||||||
_overwriteMode = overwriteMode;
|
_overwriteMode = overwriteMode;
|
||||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
|
||||||
ZoneMode = zoneMode;
|
ZoneMode = zoneMode;
|
||||||
#else
|
#else
|
||||||
UNUSED_VAR(zoneMode)
|
UNUSED_VAR(zoneMode)
|
||||||
|
|
@ -551,7 +530,6 @@ private:
|
||||||
void GetFiTimesCAM(CFiTimesCAM &pt);
|
void GetFiTimesCAM(CFiTimesCAM &pt);
|
||||||
void CreateFolders();
|
void CreateFolders();
|
||||||
|
|
||||||
bool _isRenamed;
|
|
||||||
HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit);
|
HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit);
|
||||||
HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit);
|
HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit);
|
||||||
HRESULT GetItem(UInt32 index);
|
HRESULT GetItem(UInt32 index);
|
||||||
|
|
@ -599,7 +577,8 @@ struct CArchiveExtractCallback_Closer
|
||||||
|
|
||||||
bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
|
bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
|
||||||
|
|
||||||
void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf);
|
bool Is_ZoneId_StreamName(const wchar_t *s);
|
||||||
|
void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf);
|
||||||
bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf);
|
bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2298,6 +2298,28 @@ HRESULT CCrcInfo_Base::Generate(const Byte *data, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#define HashUpdate(hf, data, size) hf->Update(data, size)
|
||||||
|
#else
|
||||||
|
// for debug:
|
||||||
|
static void HashUpdate(IHasher *hf, const void *data, UInt32 size)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
UInt32 size2 = (size * 0x85EBCA87) % size / 8;
|
||||||
|
// UInt32 size2 = size / 2;
|
||||||
|
if (size2 == 0)
|
||||||
|
size2 = 1;
|
||||||
|
hf->Update(data, size2);
|
||||||
|
data = (const void *)((const Byte *)data + size2);
|
||||||
|
size -= size2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations,
|
HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations,
|
||||||
const UInt32 *checkSum, IHasher *hf,
|
const UInt32 *checkSum, IHasher *hf,
|
||||||
IBenchPrintCallback *callback)
|
IBenchPrintCallback *callback)
|
||||||
|
|
@ -2328,7 +2350,7 @@ HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations,
|
||||||
const size_t rem = size - pos;
|
const size_t rem = size - pos;
|
||||||
const UInt32 kStep = ((UInt32)1 << 31);
|
const UInt32 kStep = ((UInt32)1 << 31);
|
||||||
const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep;
|
const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep;
|
||||||
hf->Update(buf + pos, curSize);
|
HashUpdate(hf, buf + pos, curSize);
|
||||||
pos += curSize;
|
pos += curSize;
|
||||||
}
|
}
|
||||||
while (pos != size);
|
while (pos != size);
|
||||||
|
|
@ -2742,14 +2764,20 @@ static const CBenchHash g_Hash[] =
|
||||||
{ 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" },
|
{ 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" },
|
||||||
{ 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" },
|
{ 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" },
|
||||||
{ 10, 256, 0x41b901d1, "CRC64" },
|
{ 10, 256, 0x41b901d1, "CRC64" },
|
||||||
{ 10, 64, 0x43eac94f, "XXH64" },
|
{ 5, 64, 0x43eac94f, "XXH64" },
|
||||||
|
{ 2, 2340, 0x3398a904, "MD5" },
|
||||||
{ 10, 5100, 0x7913ba03, "SHA256:1" },
|
|
||||||
{ 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" },
|
|
||||||
|
|
||||||
{ 10, 2340, 0xff769021, "SHA1:1" },
|
{ 10, 2340, 0xff769021, "SHA1:1" },
|
||||||
{ 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" },
|
{ 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" },
|
||||||
|
{ 10, 5100, 0x7913ba03, "SHA256:1" },
|
||||||
|
{ 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" },
|
||||||
|
{ 5, 3200, 0xe7aeb394, "SHA512:1" },
|
||||||
|
{ 2, CMPLX((40 * 4 + 1) * 4 + 4), 0xe7aeb394, "SHA512:2" },
|
||||||
|
// { 10, 3428, 0x1cc99b18, "SHAKE128" },
|
||||||
|
// { 10, 4235, 0x74eaddc3, "SHAKE256" },
|
||||||
|
// { 10, 4000, 0xdf3e6863, "SHA3-224" },
|
||||||
|
{ 5, 4200, 0xcecac10d, "SHA3-256" },
|
||||||
|
// { 10, 5538, 0x4e5d9163, "SHA3-384" },
|
||||||
|
// { 10, 8000, 0x96a58289, "SHA3-512" },
|
||||||
{ 2, 4096, 0x85189d02, "BLAKE2sp:1" },
|
{ 2, 4096, 0x85189d02, "BLAKE2sp:1" },
|
||||||
{ 2, 1024, 0x85189d02, "BLAKE2sp:2" }, // sse2-way4-fast
|
{ 2, 1024, 0x85189d02, "BLAKE2sp:2" }, // sse2-way4-fast
|
||||||
{ 2, 512, 0x85189d02, "BLAKE2sp:3" } // avx2-way8-fast
|
{ 2, 512, 0x85189d02, "BLAKE2sp:3" } // avx2-way8-fast
|
||||||
|
|
@ -3687,7 +3715,7 @@ HRESULT Bench(
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
UInt32 numCPUs = 1;
|
UInt32 numCPUs = 1;
|
||||||
UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
|
size_t ramSize = (size_t)sizeof(size_t) << 29;
|
||||||
|
|
||||||
NSystem::CProcessAffinity threadsInfo;
|
NSystem::CProcessAffinity threadsInfo;
|
||||||
threadsInfo.InitST();
|
threadsInfo.InitST();
|
||||||
|
|
@ -3713,7 +3741,7 @@ HRESULT Bench(
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool ramSize_Defined = NSystem::GetRamSize(ramSize);
|
const bool ramSize_Defined = NSystem::GetRamSize(ramSize);
|
||||||
|
|
||||||
UInt32 numThreadsSpecified = numCPUs;
|
UInt32 numThreadsSpecified = numCPUs;
|
||||||
bool needSetComplexity = false;
|
bool needSetComplexity = false;
|
||||||
|
|
@ -4002,16 +4030,29 @@ HRESULT Bench(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numThreadsSpecified >= 2)
|
|
||||||
if (printCallback || freqCallback)
|
if (printCallback || freqCallback)
|
||||||
|
for (unsigned test = 0; test < 3; test++)
|
||||||
{
|
{
|
||||||
|
if (numThreadsSpecified < 2)
|
||||||
|
{
|
||||||
|
// if (test == 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (test == 2 && numThreadsSpecified <= numCPUs)
|
||||||
|
break;
|
||||||
if (printCallback)
|
if (printCallback)
|
||||||
printCallback->NewLine();
|
printCallback->NewLine();
|
||||||
|
|
||||||
/* it can show incorrect frequency for HT threads.
|
/* it can show incorrect frequency for HT threads. */
|
||||||
so we reduce freq test to (numCPUs / 2) */
|
|
||||||
|
|
||||||
UInt32 numThreads = (numThreadsSpecified >= numCPUs / 2 ? numCPUs / 2 : numThreadsSpecified);
|
UInt32 numThreads = numThreadsSpecified;
|
||||||
|
if (test < 2)
|
||||||
|
{
|
||||||
|
if (numThreads >= numCPUs)
|
||||||
|
numThreads = numCPUs;
|
||||||
|
if (test == 0)
|
||||||
|
numThreads /= 2;
|
||||||
|
}
|
||||||
if (numThreads < 1)
|
if (numThreads < 1)
|
||||||
numThreads = 1;
|
numThreads = 1;
|
||||||
|
|
||||||
|
|
@ -4567,6 +4608,8 @@ HRESULT Bench(
|
||||||
|
|
||||||
if (!dictIsDefined && !onlyHashBench)
|
if (!dictIsDefined && !onlyHashBench)
|
||||||
{
|
{
|
||||||
|
// we use dicSizeLog and dicSizeLog_Main for data size.
|
||||||
|
// also we use it to reduce dictionary size of LZMA encoder via NCoderPropID::kReduceSize.
|
||||||
const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25);
|
const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25);
|
||||||
unsigned dicSizeLog = dicSizeLog_Main;
|
unsigned dicSizeLog = dicSizeLog_Main;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -671,7 +671,7 @@ static HRESULT EnumerateForItem(
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (needAltStreams && dirItems.ScanAltStreams)
|
if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream)
|
||||||
{
|
{
|
||||||
RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
|
RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
|
||||||
phyPrefix + fi.Name, // with (fi.Name)
|
phyPrefix + fi.Name, // with (fi.Name)
|
||||||
|
|
@ -929,7 +929,7 @@ static HRESULT EnumerateDirItems(
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (needAltStreams && dirItems.ScanAltStreams)
|
if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream)
|
||||||
{
|
{
|
||||||
UStringVector pathParts;
|
UStringVector pathParts;
|
||||||
pathParts.Add(fs2us(fi.Name));
|
pathParts.Add(fs2us(fi.Name));
|
||||||
|
|
|
||||||
|
|
@ -773,13 +773,21 @@ static const char * const k_CsumMethodNames[] =
|
||||||
{
|
{
|
||||||
"sha256"
|
"sha256"
|
||||||
, "sha224"
|
, "sha224"
|
||||||
// , "sha512/224"
|
// , "sha512-224"
|
||||||
// , "sha512/256"
|
// , "sha512-256"
|
||||||
, "sha512"
|
|
||||||
, "sha384"
|
, "sha384"
|
||||||
|
, "sha512"
|
||||||
|
// , "sha3-224"
|
||||||
|
, "sha3-256"
|
||||||
|
// , "sha3-384"
|
||||||
|
// , "sha3-512"
|
||||||
|
// , "shake128"
|
||||||
|
// , "shake256"
|
||||||
, "sha1"
|
, "sha1"
|
||||||
, "md5"
|
, "md5"
|
||||||
|
, "blake2sp"
|
||||||
, "blake2b"
|
, "blake2b"
|
||||||
|
, "xxh64"
|
||||||
, "crc64"
|
, "crc64"
|
||||||
, "crc32"
|
, "crc32"
|
||||||
, "cksum"
|
, "cksum"
|
||||||
|
|
@ -2076,11 +2084,27 @@ void Codecs_AddHashArcHandler(CCodecs *codecs)
|
||||||
|
|
||||||
// ubuntu uses "SHA256SUMS" file
|
// ubuntu uses "SHA256SUMS" file
|
||||||
item.AddExts(UString (
|
item.AddExts(UString (
|
||||||
"sha256 sha512 sha224 sha384 sha1 sha md5"
|
"sha256"
|
||||||
// "b2sum"
|
" sha512"
|
||||||
|
" sha384"
|
||||||
|
" sha224"
|
||||||
|
// " sha512-224"
|
||||||
|
// " sha512-256"
|
||||||
|
// " sha3-224"
|
||||||
|
" sha3-256"
|
||||||
|
// " sha3-384"
|
||||||
|
// " sha3-512"
|
||||||
|
// " shake128"
|
||||||
|
// " shake256"
|
||||||
|
" sha1"
|
||||||
|
" sha"
|
||||||
|
" md5"
|
||||||
|
" blake2sp"
|
||||||
|
" xxh64"
|
||||||
" crc32 crc64"
|
" crc32 crc64"
|
||||||
" asc"
|
" asc"
|
||||||
" cksum"
|
" cksum"
|
||||||
|
// " b2sum"
|
||||||
),
|
),
|
||||||
UString());
|
UString());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
static const unsigned kNumWinAtrribFlags = 21;
|
static const unsigned kNumWinAtrribFlags = 30;
|
||||||
static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEV.X.PU";
|
static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEVvX.PU.M......B";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FILE_ATTRIBUTE_
|
FILE_ATTRIBUTE_
|
||||||
|
|
@ -48,8 +48,9 @@ FILE_ATTRIBUTE_
|
||||||
18 RECALL_ON_OPEN or EA
|
18 RECALL_ON_OPEN or EA
|
||||||
19 PINNED
|
19 PINNED
|
||||||
20 UNPINNED
|
20 UNPINNED
|
||||||
21 STRICTLY_SEQUENTIAL
|
21 STRICTLY_SEQUENTIAL (10.0.16267)
|
||||||
22 RECALL_ON_DATA_ACCESS
|
22 RECALL_ON_DATA_ACCESS
|
||||||
|
29 STRICTLY_SEQUENTIAL (10.0.17134+) (SMR Blob)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -107,10 +108,10 @@ void ConvertWinAttribToString(char *s, UInt32 wa) throw()
|
||||||
|
|
||||||
for (unsigned i = 0; i < kNumWinAtrribFlags; i++)
|
for (unsigned i = 0; i < kNumWinAtrribFlags; i++)
|
||||||
{
|
{
|
||||||
UInt32 flag = (1 << i);
|
const UInt32 flag = (UInt32)1 << i;
|
||||||
if ((wa & flag) != 0)
|
if (wa & flag)
|
||||||
{
|
{
|
||||||
char c = g_WinAttribChars[i];
|
const char c = g_WinAttribChars[i];
|
||||||
if (c != '.')
|
if (c != '.')
|
||||||
{
|
{
|
||||||
wa &= ~flag;
|
wa &= ~flag;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ void CTempFiles::Clear()
|
||||||
{
|
{
|
||||||
while (!Paths.IsEmpty())
|
while (!Paths.IsEmpty())
|
||||||
{
|
{
|
||||||
|
if (NeedDeleteFiles)
|
||||||
NDir::DeleteFileAlways(Paths.Back());
|
NDir::DeleteFileAlways(Paths.Back());
|
||||||
Paths.DeleteBack();
|
Paths.DeleteBack();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ class CTempFiles
|
||||||
void Clear();
|
void Clear();
|
||||||
public:
|
public:
|
||||||
FStringVector Paths;
|
FStringVector Paths;
|
||||||
|
bool NeedDeleteFiles;
|
||||||
|
|
||||||
|
CTempFiles(): NeedDeleteFiles(true) {}
|
||||||
~CTempFiles() { Clear(); }
|
~CTempFiles() { Clear(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1096,6 +1096,30 @@ typedef Z7_WIN_MAPISENDMAILW FAR *Z7_WIN_LPMAPISENDMAILW;
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|
||||||
|
struct C_CopyFileProgress_to_IUpdateCallbackUI2 Z7_final:
|
||||||
|
public ICopyFileProgress
|
||||||
|
{
|
||||||
|
IUpdateCallbackUI2 *Callback;
|
||||||
|
HRESULT CallbackResult;
|
||||||
|
// bool Disable_Break;
|
||||||
|
|
||||||
|
virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override
|
||||||
|
{
|
||||||
|
const HRESULT res = Callback->MoveArc_Progress(total, current);
|
||||||
|
CallbackResult = res;
|
||||||
|
// if (Disable_Break && res == E_ABORT) res = S_OK;
|
||||||
|
return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_CopyFileProgress_to_IUpdateCallbackUI2(
|
||||||
|
IUpdateCallbackUI2 *callback) :
|
||||||
|
Callback(callback),
|
||||||
|
CallbackResult(S_OK)
|
||||||
|
// , Disable_Break(false)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
HRESULT UpdateArchive(
|
HRESULT UpdateArchive(
|
||||||
CCodecs *codecs,
|
CCodecs *codecs,
|
||||||
const CObjectVector<COpenType> &types,
|
const CObjectVector<COpenType> &types,
|
||||||
|
|
@ -1311,7 +1335,7 @@ HRESULT UpdateArchive(
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool thereIsInArchive = arcLink.IsOpen;
|
const bool thereIsInArchive = arcLink.IsOpen;
|
||||||
if (!thereIsInArchive && renameMode)
|
if (!thereIsInArchive && renameMode)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
|
|
@ -1588,7 +1612,14 @@ HRESULT UpdateArchive(
|
||||||
multiStreams.DisableDeletion();
|
multiStreams.DisableDeletion();
|
||||||
RINOK(multiStreams.Destruct())
|
RINOK(multiStreams.Destruct())
|
||||||
|
|
||||||
tempFiles.Paths.Clear();
|
// here we disable deleting of temp archives.
|
||||||
|
// note: archive moving can fail, or it can be interrupted,
|
||||||
|
// if we move new temp update from another volume.
|
||||||
|
// And we still want to keep temp archive in that case,
|
||||||
|
// because we will have deleted original archive.
|
||||||
|
tempFiles.NeedDeleteFiles = false;
|
||||||
|
// tempFiles.Paths.Clear();
|
||||||
|
|
||||||
if (createTempFile)
|
if (createTempFile)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -1604,13 +1635,52 @@ HRESULT UpdateArchive(
|
||||||
return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath));
|
return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MyMoveFile(tempPath, us2fs(arcPath)))
|
UInt64 totalArcSize = 0;
|
||||||
{
|
{
|
||||||
errorInfo.SetFromLastError("cannot move the file", tempPath);
|
NFind::CFileInfo fi;
|
||||||
|
if (fi.Find(tempPath))
|
||||||
|
totalArcSize = fi.Size;
|
||||||
|
}
|
||||||
|
RINOK(callback->MoveArc_Start(fs2us(tempPath), arcPath,
|
||||||
|
totalArcSize, BoolToInt(thereIsInArchive)))
|
||||||
|
|
||||||
|
C_CopyFileProgress_to_IUpdateCallbackUI2 prox(callback);
|
||||||
|
// if we update archive, we have removed original archive.
|
||||||
|
// So if we break archive moving, we will have only temporary archive.
|
||||||
|
// We can disable breaking here:
|
||||||
|
// prox.Disable_Break = thereIsInArchive;
|
||||||
|
|
||||||
|
if (!MyMoveFile_with_Progress(tempPath, us2fs(arcPath), &prox))
|
||||||
|
{
|
||||||
|
errorInfo.SystemError = ::GetLastError();
|
||||||
|
errorInfo.Message = "cannot move the file";
|
||||||
|
if (errorInfo.SystemError == ERROR_INVALID_PARAMETER)
|
||||||
|
{
|
||||||
|
if (totalArcSize > (UInt32)(Int32)-1)
|
||||||
|
{
|
||||||
|
// bool isFsDetected = false;
|
||||||
|
// if (NSystem::Is_File_LimitedBy_4GB(us2fs(arcPath), isFsDetected) || !isFsDetected)
|
||||||
|
{
|
||||||
|
errorInfo.Message.Add_LF();
|
||||||
|
errorInfo.Message += "Archive file size exceeds 4 GB";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if there was no input archive, and we have operation breaking.
|
||||||
|
// then we can remove temporary archive, because we still have original uncompressed files.
|
||||||
|
if (!thereIsInArchive
|
||||||
|
&& prox.CallbackResult == E_ABORT)
|
||||||
|
tempFiles.NeedDeleteFiles = true;
|
||||||
|
errorInfo.FileNames.Add(tempPath);
|
||||||
errorInfo.FileNames.Add(us2fs(arcPath));
|
errorInfo.FileNames.Add(us2fs(arcPath));
|
||||||
|
RINOK(prox.CallbackResult)
|
||||||
return errorInfo.Get_HRESULT_Error();
|
return errorInfo.Get_HRESULT_Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoveArc_Finish() can return delayed user break (E_ABORT) status,
|
||||||
|
// if callback callee ignored interruption to finish archive creation operation.
|
||||||
|
RINOK(callback->MoveArc_Finish())
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY))
|
if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@
|
||||||
#include "UpdateAction.h"
|
#include "UpdateAction.h"
|
||||||
#include "UpdateCallback.h"
|
#include "UpdateCallback.h"
|
||||||
|
|
||||||
#include "DirItem.h"
|
|
||||||
|
|
||||||
enum EArcNameMode
|
enum EArcNameMode
|
||||||
{
|
{
|
||||||
k_ArcNameMode_Smart,
|
k_ArcNameMode_Smart,
|
||||||
|
|
@ -195,6 +193,9 @@ Z7_PURE_INTERFACES_BEGIN
|
||||||
virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x \
|
virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x \
|
||||||
virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x \
|
virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x \
|
||||||
virtual HRESULT FinishDeletingAfterArchiving() x \
|
virtual HRESULT FinishDeletingAfterArchiving() x \
|
||||||
|
virtual HRESULT MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode) x \
|
||||||
|
virtual HRESULT MoveArc_Progress(UInt64 total, UInt64 current) x \
|
||||||
|
virtual HRESULT MoveArc_Finish() x \
|
||||||
|
|
||||||
DECLARE_INTERFACE(IUpdateCallbackUI2):
|
DECLARE_INTERFACE(IUpdateCallbackUI2):
|
||||||
public IUpdateCallbackUI,
|
public IUpdateCallbackUI,
|
||||||
|
|
|
||||||
|
|
@ -63,24 +63,22 @@ HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath)
|
||||||
NWorkDir::CInfo workDirInfo;
|
NWorkDir::CInfo workDirInfo;
|
||||||
workDirInfo.Load();
|
workDirInfo.Load();
|
||||||
FString namePart;
|
FString namePart;
|
||||||
const FString workDir = GetWorkDir(workDirInfo, originalPath, namePart);
|
FString path = GetWorkDir(workDirInfo, originalPath, namePart);
|
||||||
CreateComplexDir(workDir);
|
CreateComplexDir(path);
|
||||||
|
path += namePart;
|
||||||
_outStreamSpec = new COutFileStream;
|
_outStreamSpec = new COutFileStream;
|
||||||
OutStream = _outStreamSpec;
|
OutStream = _outStreamSpec;
|
||||||
if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File))
|
if (!_tempFile.Create(path, &_outStreamSpec->File))
|
||||||
{
|
|
||||||
return GetLastError_noZero_HRESULT();
|
return GetLastError_noZero_HRESULT();
|
||||||
}
|
|
||||||
_originalPath = originalPath;
|
_originalPath = originalPath;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal)
|
HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal,
|
||||||
|
NWindows::NFile::NDir::ICopyFileProgress *progress)
|
||||||
{
|
{
|
||||||
OutStream.Release();
|
OutStream.Release();
|
||||||
if (!_tempFile.MoveTo(_originalPath, deleteOriginal))
|
if (!_tempFile.MoveTo(_originalPath, deleteOriginal, progress))
|
||||||
{
|
|
||||||
return GetLastError_noZero_HRESULT();
|
return GetLastError_noZero_HRESULT();
|
||||||
}
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName);
|
FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName);
|
||||||
|
|
||||||
class CWorkDirTempFile
|
class CWorkDirTempFile MY_UNCOPYABLE
|
||||||
{
|
{
|
||||||
FString _originalPath;
|
FString _originalPath;
|
||||||
NWindows::NFile::NDir::CTempFile _tempFile;
|
NWindows::NFile::NDir::CTempFile _tempFile;
|
||||||
|
|
@ -19,8 +19,12 @@ class CWorkDirTempFile
|
||||||
public:
|
public:
|
||||||
CMyComPtr<IOutStream> OutStream;
|
CMyComPtr<IOutStream> OutStream;
|
||||||
|
|
||||||
|
const FString &Get_OriginalFilePath() const { return _originalPath; }
|
||||||
|
const FString &Get_TempFilePath() const { return _tempFile.GetPath(); }
|
||||||
|
|
||||||
HRESULT CreateTempFile(const FString &originalPath);
|
HRESULT CreateTempFile(const FString &originalPath);
|
||||||
HRESULT MoveToOriginal(bool deleteOriginal);
|
HRESULT MoveToOriginal(bool deleteOriginal,
|
||||||
|
NWindows::NFile::NDir::ICopyFileProgress *progress = NULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ static void Key_Set_UInt32(CKey &key, LPCTSTR name, UInt32 value)
|
||||||
|
|
||||||
static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value)
|
static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value)
|
||||||
{
|
{
|
||||||
if (key.QueryValue(name, value) != ERROR_SUCCESS)
|
|
||||||
value = (UInt32)(Int32)-1;
|
value = (UInt32)(Int32)-1;
|
||||||
|
key.GetValue_UInt32_IfOk(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -59,7 +59,7 @@ static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b)
|
||||||
static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val)
|
static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val)
|
||||||
{
|
{
|
||||||
bool oldVal = false;
|
bool oldVal = false;
|
||||||
if (key.GetValue_IfOk(name, oldVal) == ERROR_SUCCESS)
|
if (key.GetValue_bool_IfOk(name, oldVal) == ERROR_SUCCESS)
|
||||||
if (val == oldVal)
|
if (val == oldVal)
|
||||||
return;
|
return;
|
||||||
key.SetValue(name, val);
|
key.SetValue(name, val);
|
||||||
|
|
@ -76,13 +76,13 @@ static void Key_Set_BoolPair_Delete_IfNotDef(CKey &key, LPCTSTR name, const CBoo
|
||||||
static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
|
static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
|
||||||
{
|
{
|
||||||
b.Val = false;
|
b.Val = false;
|
||||||
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
|
b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
|
static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
|
||||||
{
|
{
|
||||||
b.Val = true;
|
b.Val = true;
|
||||||
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
|
b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NExtract
|
namespace NExtract
|
||||||
|
|
@ -155,12 +155,12 @@ void CInfo::Load()
|
||||||
|
|
||||||
key.GetValue_Strings(kPathHistory, Paths);
|
key.GetValue_Strings(kPathHistory, Paths);
|
||||||
UInt32 v;
|
UInt32 v;
|
||||||
if (key.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths)
|
if (key.GetValue_UInt32_IfOk(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths)
|
||||||
{
|
{
|
||||||
PathMode = (NPathMode::EEnum)v;
|
PathMode = (NPathMode::EEnum)v;
|
||||||
PathMode_Force = true;
|
PathMode_Force = true;
|
||||||
}
|
}
|
||||||
if (key.QueryValue(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting)
|
if (key.GetValue_UInt32_IfOk(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting)
|
||||||
{
|
{
|
||||||
OverwriteMode = (NOverwriteMode::EEnum)v;
|
OverwriteMode = (NOverwriteMode::EEnum)v;
|
||||||
OverwriteMode_Force = true;
|
OverwriteMode_Force = true;
|
||||||
|
|
@ -181,7 +181,7 @@ bool Read_ShowPassword()
|
||||||
bool showPassword = false;
|
bool showPassword = false;
|
||||||
if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
|
if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
|
||||||
return showPassword;
|
return showPassword;
|
||||||
key.GetValue_IfOk(kShowPassword, showPassword);
|
key.GetValue_bool_IfOk(kShowPassword, showPassword);
|
||||||
return showPassword;
|
return showPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,14 +189,11 @@ UInt32 Read_LimitGB()
|
||||||
{
|
{
|
||||||
CS_LOCK
|
CS_LOCK
|
||||||
CKey key;
|
CKey key;
|
||||||
|
UInt32 v = (UInt32)(Int32)-1;
|
||||||
if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS)
|
if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS)
|
||||||
{
|
key.GetValue_UInt32_IfOk(kMemLimit, v);
|
||||||
UInt32 v;
|
|
||||||
if (key.QueryValue(kMemLimit, v) == ERROR_SUCCESS)
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
return (UInt32)(Int32)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -371,9 +368,9 @@ void CInfo::Load()
|
||||||
UString a;
|
UString a;
|
||||||
if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS)
|
if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS)
|
||||||
ArcType = a;
|
ArcType = a;
|
||||||
key.GetValue_IfOk(kLevel, Level);
|
key.GetValue_UInt32_IfOk(kLevel, Level);
|
||||||
key.GetValue_IfOk(kShowPassword, ShowPassword);
|
key.GetValue_bool_IfOk(kShowPassword, ShowPassword);
|
||||||
key.GetValue_IfOk(kEncryptHeaders, EncryptHeaders);
|
key.GetValue_bool_IfOk(kEncryptHeaders, EncryptHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -517,7 +514,7 @@ void CInfo::Load()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UInt32 dirType;
|
UInt32 dirType;
|
||||||
if (key.QueryValue(kWorkDirType, dirType) != ERROR_SUCCESS)
|
if (key.GetValue_UInt32_IfOk(kWorkDirType, dirType) != ERROR_SUCCESS)
|
||||||
return;
|
return;
|
||||||
switch (dirType)
|
switch (dirType)
|
||||||
{
|
{
|
||||||
|
|
@ -535,7 +532,7 @@ void CInfo::Load()
|
||||||
if (Mode == NMode::kSpecified)
|
if (Mode == NMode::kSpecified)
|
||||||
Mode = NMode::kSystem;
|
Mode = NMode::kSystem;
|
||||||
}
|
}
|
||||||
key.GetValue_IfOk(kTempRemovableOnly, ForRemovableOnly);
|
key.GetValue_bool_IfOk(kTempRemovableOnly, ForRemovableOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -598,5 +595,5 @@ void CContextMenuInfo::Load()
|
||||||
|
|
||||||
Key_Get_UInt32(key, kWriteZoneId, WriteZone);
|
Key_Get_UInt32(key, kWriteZoneId, WriteZone);
|
||||||
|
|
||||||
Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
|
Flags_Def = (key.GetValue_UInt32_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
namespace NConsoleClose {
|
namespace NConsoleClose {
|
||||||
|
|
||||||
unsigned g_BreakCounter = 0;
|
unsigned g_BreakCounter = 0;
|
||||||
static const unsigned kBreakAbortThreshold = 2;
|
static const unsigned kBreakAbortThreshold = 3;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
|
@ -28,8 +28,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_BreakCounter++;
|
if (++g_BreakCounter < kBreakAbortThreshold)
|
||||||
if (g_BreakCounter < kBreakAbortThreshold)
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
/*
|
/*
|
||||||
|
|
@ -47,7 +46,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
|
||||||
CCtrlHandlerSetter::CCtrlHandlerSetter()
|
CCtrlHandlerSetter::CCtrlHandlerSetter()
|
||||||
{
|
{
|
||||||
if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
|
if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
|
||||||
throw "SetConsoleCtrlHandler fails";
|
throw 1019; // "SetConsoleCtrlHandler fails";
|
||||||
}
|
}
|
||||||
|
|
||||||
CCtrlHandlerSetter::~CCtrlHandlerSetter()
|
CCtrlHandlerSetter::~CCtrlHandlerSetter()
|
||||||
|
|
@ -63,8 +62,7 @@ CCtrlHandlerSetter::~CCtrlHandlerSetter()
|
||||||
|
|
||||||
static void HandlerRoutine(int)
|
static void HandlerRoutine(int)
|
||||||
{
|
{
|
||||||
g_BreakCounter++;
|
if (++g_BreakCounter < kBreakAbortThreshold)
|
||||||
if (g_BreakCounter < kBreakAbortThreshold)
|
|
||||||
return;
|
return;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
namespace NConsoleClose {
|
namespace NConsoleClose {
|
||||||
|
|
||||||
class CCtrlBreakException {};
|
// class CCtrlBreakException {};
|
||||||
|
|
||||||
#ifdef UNDER_CE
|
#ifdef UNDER_CE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -343,7 +343,7 @@ Z7_COM7F_IMF(CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
|
||||||
default: s = "???"; requiredLevel = 2;
|
default: s = "???"; requiredLevel = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool show2 = (LogLevel >= requiredLevel && _so);
|
const bool show2 = (LogLevel >= requiredLevel && _so);
|
||||||
|
|
||||||
if (show2)
|
if (show2)
|
||||||
{
|
{
|
||||||
|
|
@ -373,6 +373,7 @@ Z7_COM7F_IMF(CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
|
||||||
|
|
||||||
if (NeedFlush)
|
if (NeedFlush)
|
||||||
_so->Flush();
|
_so->Flush();
|
||||||
|
// _so->Flush(); // for debug only
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NeedPercents())
|
if (NeedPercents())
|
||||||
|
|
@ -923,11 +924,11 @@ HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NumArcsWithError++;
|
// we don't update NumArcsWithError, if error is not related to archive data.
|
||||||
if (result == E_ABORT
|
if (result == E_ABORT
|
||||||
|| result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)
|
|| result == HRESULT_FROM_WIN32(ERROR_DISK_FULL))
|
||||||
)
|
|
||||||
return result;
|
return result;
|
||||||
|
NumArcsWithError++;
|
||||||
|
|
||||||
if (_se)
|
if (_se)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ class CExtractScanConsole Z7_final: public IDirItemsCallback
|
||||||
|
|
||||||
// CErrorPathCodes2 ScanErrors;
|
// CErrorPathCodes2 ScanErrors;
|
||||||
|
|
||||||
bool NeedPercents() const { return _percent._so != NULL; }
|
bool NeedPercents() const { return _percent._so && !_percent.DisablePrint; }
|
||||||
|
|
||||||
void ClosePercentsAndFlush()
|
void ClosePercentsAndFlush()
|
||||||
{
|
{
|
||||||
|
|
@ -56,11 +56,16 @@ class CExtractScanConsole Z7_final: public IDirItemsCallback
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
|
void Init(
|
||||||
|
CStdOutStream *outStream,
|
||||||
|
CStdOutStream *errorStream,
|
||||||
|
CStdOutStream *percentStream,
|
||||||
|
bool disablePercents)
|
||||||
{
|
{
|
||||||
_so = outStream;
|
_so = outStream;
|
||||||
_se = errorStream;
|
_se = errorStream;
|
||||||
_percent._so = percentStream;
|
_percent._so = percentStream;
|
||||||
|
_percent.DisablePrint = disablePercents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
|
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
|
||||||
|
|
@ -177,9 +182,13 @@ public:
|
||||||
|
|
||||||
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
|
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
|
||||||
|
|
||||||
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
|
void Init(
|
||||||
|
CStdOutStream *outStream,
|
||||||
|
CStdOutStream *errorStream,
|
||||||
|
CStdOutStream *percentStream,
|
||||||
|
bool disablePercents)
|
||||||
{
|
{
|
||||||
COpenCallbackConsole::Init(outStream, errorStream, percentStream);
|
COpenCallbackConsole::Init(outStream, errorStream, percentStream, disablePercents);
|
||||||
|
|
||||||
NumTryArcs = 0;
|
NumTryArcs = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1155,7 +1155,7 @@ HRESULT ListArchives(
|
||||||
CArchiveLink arcLink;
|
CArchiveLink arcLink;
|
||||||
|
|
||||||
COpenCallbackConsole openCallback;
|
COpenCallbackConsole openCallback;
|
||||||
openCallback.Init(&g_StdOut, g_ErrStream, NULL);
|
openCallback.Init(&g_StdOut, g_ErrStream, NULL, listOptions.DisablePercents);
|
||||||
|
|
||||||
#ifndef Z7_NO_CRYPTO
|
#ifndef Z7_NO_CRYPTO
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,12 @@ struct CListOptions
|
||||||
{
|
{
|
||||||
bool ExcludeDirItems;
|
bool ExcludeDirItems;
|
||||||
bool ExcludeFileItems;
|
bool ExcludeFileItems;
|
||||||
|
bool DisablePercents;
|
||||||
|
|
||||||
CListOptions():
|
CListOptions():
|
||||||
ExcludeDirItems(false),
|
ExcludeDirItems(false),
|
||||||
ExcludeFileItems(false)
|
ExcludeFileItems(false),
|
||||||
|
DisablePercents(false)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1280,7 +1280,9 @@ int Main2(
|
||||||
{
|
{
|
||||||
CExtractScanConsole scan;
|
CExtractScanConsole scan;
|
||||||
|
|
||||||
scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream);
|
scan.Init(options.EnableHeaders ? g_StdStream : NULL,
|
||||||
|
g_ErrStream, percentsStream,
|
||||||
|
options.DisablePercents);
|
||||||
scan.SetWindowWidth(consoleWidth);
|
scan.SetWindowWidth(consoleWidth);
|
||||||
|
|
||||||
if (g_StdStream && options.EnableHeaders)
|
if (g_StdStream && options.EnableHeaders)
|
||||||
|
|
@ -1330,7 +1332,7 @@ int Main2(
|
||||||
ecs->Password = options.Password;
|
ecs->Password = options.Password;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ecs->Init(g_StdStream, g_ErrStream, percentsStream);
|
ecs->Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
|
||||||
ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1);
|
ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1);
|
||||||
|
|
||||||
ecs->LogLevel = options.LogLevel;
|
ecs->LogLevel = options.LogLevel;
|
||||||
|
|
@ -1494,6 +1496,7 @@ int Main2(
|
||||||
CListOptions lo;
|
CListOptions lo;
|
||||||
lo.ExcludeDirItems = options.Censor.ExcludeDirItems;
|
lo.ExcludeDirItems = options.Censor.ExcludeDirItems;
|
||||||
lo.ExcludeFileItems = options.Censor.ExcludeFileItems;
|
lo.ExcludeFileItems = options.Censor.ExcludeFileItems;
|
||||||
|
lo.DisablePercents = options.DisablePercents;
|
||||||
|
|
||||||
hresultMain = ListArchives(
|
hresultMain = ListArchives(
|
||||||
lo,
|
lo,
|
||||||
|
|
@ -1538,7 +1541,7 @@ int Main2(
|
||||||
uo.SfxModule = kDefaultSfxModule;
|
uo.SfxModule = kDefaultSfxModule;
|
||||||
|
|
||||||
COpenCallbackConsole openCallback;
|
COpenCallbackConsole openCallback;
|
||||||
openCallback.Init(g_StdStream, g_ErrStream, percentsStream);
|
openCallback.Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
|
||||||
|
|
||||||
#ifndef Z7_NO_CRYPTO
|
#ifndef Z7_NO_CRYPTO
|
||||||
bool passwordIsDefined =
|
bool passwordIsDefined =
|
||||||
|
|
@ -1563,7 +1566,7 @@ int Main2(
|
||||||
callback.StdOutMode = uo.StdOutMode;
|
callback.StdOutMode = uo.StdOutMode;
|
||||||
callback.Init(
|
callback.Init(
|
||||||
// NULL,
|
// NULL,
|
||||||
g_StdStream, g_ErrStream, percentsStream);
|
g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
|
||||||
|
|
||||||
CUpdateErrorInfo errorInfo;
|
CUpdateErrorInfo errorInfo;
|
||||||
|
|
||||||
|
|
@ -1598,7 +1601,7 @@ int Main2(
|
||||||
if (percentsStream)
|
if (percentsStream)
|
||||||
callback.SetWindowWidth(consoleWidth);
|
callback.SetWindowWidth(consoleWidth);
|
||||||
|
|
||||||
callback.Init(g_StdStream, g_ErrStream, percentsStream);
|
callback.Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
|
||||||
callback.PrintHeaders = options.EnableHeaders;
|
callback.PrintHeaders = options.EnableHeaders;
|
||||||
callback.PrintFields = options.ListFields;
|
callback.PrintFields = options.ListFields;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,11 +140,13 @@ int Z7_CDECL main
|
||||||
PrintError(kMemoryExceptionMessage);
|
PrintError(kMemoryExceptionMessage);
|
||||||
return (NExitCode::kMemoryError);
|
return (NExitCode::kMemoryError);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
catch(const NConsoleClose::CCtrlBreakException &)
|
catch(const NConsoleClose::CCtrlBreakException &)
|
||||||
{
|
{
|
||||||
PrintError(kUserBreakMessage);
|
PrintError(kUserBreakMessage);
|
||||||
return (NExitCode::kUserBreak);
|
return (NExitCode::kUserBreak);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
catch(const CMessagePathException &e)
|
catch(const CMessagePathException &e)
|
||||||
{
|
{
|
||||||
PrintError(kException_CmdLine_Error_Message);
|
PrintError(kException_CmdLine_Error_Message);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ protected:
|
||||||
bool _totalFilesDefined;
|
bool _totalFilesDefined;
|
||||||
// bool _totalBytesDefined;
|
// bool _totalBytesDefined;
|
||||||
|
|
||||||
bool NeedPercents() const { return _percent._so != NULL; }
|
bool NeedPercents() const { return _percent._so && !_percent.DisablePrint; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -49,11 +49,16 @@ public:
|
||||||
|
|
||||||
virtual ~COpenCallbackConsole() {}
|
virtual ~COpenCallbackConsole() {}
|
||||||
|
|
||||||
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
|
void Init(
|
||||||
|
CStdOutStream *outStream,
|
||||||
|
CStdOutStream *errorStream,
|
||||||
|
CStdOutStream *percentStream,
|
||||||
|
bool disablePercents)
|
||||||
{
|
{
|
||||||
_so = outStream;
|
_so = outStream;
|
||||||
_se = errorStream;
|
_se = errorStream;
|
||||||
_percent._so = percentStream;
|
_percent._so = percentStream;
|
||||||
|
_percent.DisablePrint = disablePercents;
|
||||||
}
|
}
|
||||||
|
|
||||||
Z7_IFACE_IMP(IOpenCallbackUI)
|
Z7_IFACE_IMP(IOpenCallbackUI)
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,8 @@ void CPercentPrinter::GetPercents()
|
||||||
|
|
||||||
void CPercentPrinter::Print()
|
void CPercentPrinter::Print()
|
||||||
{
|
{
|
||||||
|
if (DisablePrint)
|
||||||
|
return;
|
||||||
DWORD tick = 0;
|
DWORD tick = 0;
|
||||||
if (_tickStep != 0)
|
if (_tickStep != 0)
|
||||||
tick = GetTickCount();
|
tick = GetTickCount();
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,13 @@ struct CPercentPrinterState
|
||||||
|
|
||||||
class CPercentPrinter: public CPercentPrinterState
|
class CPercentPrinter: public CPercentPrinterState
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
CStdOutStream *_so;
|
||||||
|
bool DisablePrint;
|
||||||
|
bool NeedFlush;
|
||||||
|
unsigned MaxLen;
|
||||||
|
|
||||||
|
private:
|
||||||
UInt32 _tickStep;
|
UInt32 _tickStep;
|
||||||
DWORD _prevTick;
|
DWORD _prevTick;
|
||||||
|
|
||||||
|
|
@ -41,16 +48,13 @@ class CPercentPrinter: public CPercentPrinterState
|
||||||
void GetPercents();
|
void GetPercents();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CStdOutStream *_so;
|
|
||||||
|
|
||||||
bool NeedFlush;
|
|
||||||
unsigned MaxLen;
|
|
||||||
|
|
||||||
CPercentPrinter(UInt32 tickStep = 200):
|
CPercentPrinter(UInt32 tickStep = 200):
|
||||||
_tickStep(tickStep),
|
DisablePrint(false),
|
||||||
_prevTick(0),
|
|
||||||
NeedFlush(true),
|
NeedFlush(true),
|
||||||
MaxLen(80 - 1)
|
MaxLen(80 - 1),
|
||||||
|
_tickStep(tickStep),
|
||||||
|
_prevTick(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~CPercentPrinter();
|
~CPercentPrinter();
|
||||||
|
|
|
||||||
|
|
@ -361,6 +361,119 @@ HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT CUpdateCallbackConsole::MoveArc_UpdateStatus()
|
||||||
|
{
|
||||||
|
if (NeedPercents())
|
||||||
|
{
|
||||||
|
AString &s = _percent.Command;
|
||||||
|
s = " : ";
|
||||||
|
s.Add_UInt64(_arcMoving_percents);
|
||||||
|
s.Add_Char('%');
|
||||||
|
const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1);
|
||||||
|
if (_arcMoving_current != 0 || totalDefined)
|
||||||
|
{
|
||||||
|
s += " : ";
|
||||||
|
s.Add_UInt64(_arcMoving_current >> 20);
|
||||||
|
s += " MiB";
|
||||||
|
}
|
||||||
|
if (totalDefined)
|
||||||
|
{
|
||||||
|
s += " / ";
|
||||||
|
s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20);
|
||||||
|
s += " MiB";
|
||||||
|
}
|
||||||
|
s += " : temporary archive moving ...";
|
||||||
|
_percent.Print();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we ignore single Ctrl-C, if (_arcMoving_updateMode) mode
|
||||||
|
// because we want to get good final archive instead of temp archive.
|
||||||
|
if (NConsoleClose::g_BreakCounter == 1 && _arcMoving_updateMode)
|
||||||
|
return S_OK;
|
||||||
|
return CheckBreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT CUpdateCallbackConsole::MoveArc_Start(
|
||||||
|
const wchar_t *srcTempPath, const wchar_t *destFinalPath,
|
||||||
|
UInt64 size, Int32 updateMode)
|
||||||
|
{
|
||||||
|
#if 0 // 1 : for debug
|
||||||
|
if (LogLevel > 0 && _so)
|
||||||
|
{
|
||||||
|
ClosePercents_for_so();
|
||||||
|
*_so << "Temporary archive moving:" << endl;
|
||||||
|
_tempU = srcTempPath;
|
||||||
|
_so->Normalize_UString_Path(_tempU);
|
||||||
|
_so->PrintUString(_tempU, _tempA);
|
||||||
|
*_so << endl;
|
||||||
|
_tempU = destFinalPath;
|
||||||
|
_so->Normalize_UString_Path(_tempU);
|
||||||
|
_so->PrintUString(_tempU, _tempA);
|
||||||
|
*_so << endl;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
UNUSED_VAR(srcTempPath)
|
||||||
|
UNUSED_VAR(destFinalPath)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_arcMoving_updateMode = updateMode;
|
||||||
|
_arcMoving_total = size;
|
||||||
|
_arcMoving_current = 0;
|
||||||
|
_arcMoving_percents = 0;
|
||||||
|
return MoveArc_UpdateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT CUpdateCallbackConsole::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)
|
||||||
|
{
|
||||||
|
#if 0 // 1 : for debug
|
||||||
|
if (_so)
|
||||||
|
{
|
||||||
|
ClosePercents_for_so();
|
||||||
|
*_so << totalSize << " : " << currentSize << endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UInt64 percents = 0;
|
||||||
|
if (totalSize != 0)
|
||||||
|
{
|
||||||
|
if (totalSize < ((UInt64)1 << 57))
|
||||||
|
percents = currentSize * 100 / totalSize;
|
||||||
|
else
|
||||||
|
percents = currentSize / (totalSize / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Sleep(300); // for debug
|
||||||
|
#endif
|
||||||
|
// totalSize = (UInt64)(Int64)-1; // for debug
|
||||||
|
|
||||||
|
if (percents == _arcMoving_percents)
|
||||||
|
return CheckBreak();
|
||||||
|
_arcMoving_current = currentSize;
|
||||||
|
_arcMoving_total = totalSize;
|
||||||
|
_arcMoving_percents = percents;
|
||||||
|
return MoveArc_UpdateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT CUpdateCallbackConsole::MoveArc_Finish()
|
||||||
|
{
|
||||||
|
// _arcMoving_percents = 0;
|
||||||
|
if (NeedPercents())
|
||||||
|
{
|
||||||
|
_percent.Command.Empty();
|
||||||
|
_percent.Print();
|
||||||
|
}
|
||||||
|
// it can return delayed user break (E_ABORT) status,
|
||||||
|
// if it ignored single CTRL+C in MoveArc_Progress().
|
||||||
|
return CheckBreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */)
|
HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */)
|
||||||
{
|
{
|
||||||
if (LogLevel > 0 && _so)
|
if (LogLevel > 0 && _so)
|
||||||
|
|
|
||||||
|
|
@ -29,30 +29,31 @@ struct CErrorPathCodes
|
||||||
|
|
||||||
class CCallbackConsoleBase
|
class CCallbackConsoleBase
|
||||||
{
|
{
|
||||||
protected:
|
void CommonError(const FString &path, DWORD systemError, bool isWarning);
|
||||||
CPercentPrinter _percent;
|
|
||||||
|
|
||||||
|
protected:
|
||||||
CStdOutStream *_so;
|
CStdOutStream *_so;
|
||||||
CStdOutStream *_se;
|
CStdOutStream *_se;
|
||||||
|
|
||||||
void CommonError(const FString &path, DWORD systemError, bool isWarning);
|
|
||||||
// void CommonError(const char *message);
|
|
||||||
|
|
||||||
HRESULT ScanError_Base(const FString &path, DWORD systemError);
|
HRESULT ScanError_Base(const FString &path, DWORD systemError);
|
||||||
HRESULT OpenFileError_Base(const FString &name, DWORD systemError);
|
HRESULT OpenFileError_Base(const FString &name, DWORD systemError);
|
||||||
HRESULT ReadingFileError_Base(const FString &name, DWORD systemError);
|
HRESULT ReadingFileError_Base(const FString &name, DWORD systemError);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool NeedPercents() const { return _percent._so != NULL; }
|
|
||||||
|
|
||||||
bool StdOutMode;
|
bool StdOutMode;
|
||||||
|
|
||||||
bool NeedFlush;
|
bool NeedFlush;
|
||||||
unsigned PercentsNameLevel;
|
unsigned PercentsNameLevel;
|
||||||
unsigned LogLevel;
|
unsigned LogLevel;
|
||||||
|
|
||||||
|
protected:
|
||||||
AString _tempA;
|
AString _tempA;
|
||||||
UString _tempU;
|
UString _tempU;
|
||||||
|
CPercentPrinter _percent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CErrorPathCodes FailedFiles;
|
||||||
|
CErrorPathCodes ScanErrors;
|
||||||
|
UInt64 NumNonOpenFiles;
|
||||||
|
|
||||||
CCallbackConsoleBase():
|
CCallbackConsoleBase():
|
||||||
StdOutMode(false),
|
StdOutMode(false),
|
||||||
|
|
@ -62,15 +63,21 @@ public:
|
||||||
NumNonOpenFiles(0)
|
NumNonOpenFiles(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
bool NeedPercents() const { return _percent._so != NULL; }
|
||||||
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
|
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
|
||||||
|
|
||||||
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
|
void Init(
|
||||||
|
CStdOutStream *outStream,
|
||||||
|
CStdOutStream *errorStream,
|
||||||
|
CStdOutStream *percentStream,
|
||||||
|
bool disablePercents)
|
||||||
{
|
{
|
||||||
FailedFiles.Clear();
|
FailedFiles.Clear();
|
||||||
|
|
||||||
_so = outStream;
|
_so = outStream;
|
||||||
_se = errorStream;
|
_se = errorStream;
|
||||||
_percent._so = percentStream;
|
_percent._so = percentStream;
|
||||||
|
_percent.DisablePrint = disablePercents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClosePercents2()
|
void ClosePercents2()
|
||||||
|
|
@ -85,10 +92,6 @@ public:
|
||||||
_percent.ClosePrint(false);
|
_percent.ClosePrint(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CErrorPathCodes FailedFiles;
|
|
||||||
CErrorPathCodes ScanErrors;
|
|
||||||
UInt64 NumNonOpenFiles;
|
|
||||||
|
|
||||||
HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog);
|
HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog);
|
||||||
|
|
||||||
// void PrintInfoLine(const UString &s);
|
// void PrintInfoLine(const UString &s);
|
||||||
|
|
@ -104,6 +107,14 @@ class CUpdateCallbackConsole Z7_final:
|
||||||
Z7_IFACE_IMP(IUpdateCallbackUI)
|
Z7_IFACE_IMP(IUpdateCallbackUI)
|
||||||
Z7_IFACE_IMP(IDirItemsCallback)
|
Z7_IFACE_IMP(IDirItemsCallback)
|
||||||
Z7_IFACE_IMP(IUpdateCallbackUI2)
|
Z7_IFACE_IMP(IUpdateCallbackUI2)
|
||||||
|
|
||||||
|
HRESULT MoveArc_UpdateStatus();
|
||||||
|
|
||||||
|
UInt64 _arcMoving_total;
|
||||||
|
UInt64 _arcMoving_current;
|
||||||
|
UInt64 _arcMoving_percents;
|
||||||
|
Int32 _arcMoving_updateMode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool DeleteMessageWasShown;
|
bool DeleteMessageWasShown;
|
||||||
|
|
||||||
|
|
@ -114,7 +125,11 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CUpdateCallbackConsole():
|
CUpdateCallbackConsole():
|
||||||
DeleteMessageWasShown(false)
|
_arcMoving_total(0)
|
||||||
|
, _arcMoving_current(0)
|
||||||
|
, _arcMoving_percents(0)
|
||||||
|
, _arcMoving_updateMode(0)
|
||||||
|
, DeleteMessageWasShown(false)
|
||||||
#ifndef Z7_NO_CRYPTO
|
#ifndef Z7_NO_CRYPTO
|
||||||
, PasswordIsDefined(false)
|
, PasswordIsDefined(false)
|
||||||
, AskPassword(false)
|
, AskPassword(false)
|
||||||
|
|
|
||||||
|
|
@ -296,8 +296,12 @@ static const CHashCommand g_HashCommands[] =
|
||||||
{ CZipContextMenu::kHash_CRC32, "CRC-32", "CRC32" },
|
{ CZipContextMenu::kHash_CRC32, "CRC-32", "CRC32" },
|
||||||
{ CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" },
|
{ CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" },
|
||||||
{ CZipContextMenu::kHash_XXH64, "XXH64", "XXH64" },
|
{ CZipContextMenu::kHash_XXH64, "XXH64", "XXH64" },
|
||||||
|
{ CZipContextMenu::kHash_MD5, "MD5", "MD5" },
|
||||||
{ CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" },
|
{ CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" },
|
||||||
{ CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" },
|
{ CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" },
|
||||||
|
{ CZipContextMenu::kHash_SHA384, "SHA-384", "SHA384" },
|
||||||
|
{ CZipContextMenu::kHash_SHA512, "SHA-512", "SHA512" },
|
||||||
|
{ CZipContextMenu::kHash_SHA3_256, "SHA3-256", "SHA3-256" },
|
||||||
{ CZipContextMenu::kHash_BLAKE2SP, "BLAKE2sp", "BLAKE2sp" },
|
{ CZipContextMenu::kHash_BLAKE2SP, "BLAKE2sp", "BLAKE2sp" },
|
||||||
{ CZipContextMenu::kHash_All, "*", "*" },
|
{ CZipContextMenu::kHash_All, "*", "*" },
|
||||||
{ CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" },
|
{ CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" },
|
||||||
|
|
@ -534,7 +538,8 @@ bool FindExt(const char *p, const UString &name, CStringFinder &finder);
|
||||||
bool FindExt(const char *p, const UString &name, CStringFinder &finder)
|
bool FindExt(const char *p, const UString &name, CStringFinder &finder)
|
||||||
{
|
{
|
||||||
const int dotPos = name.ReverseFind_Dot();
|
const int dotPos = name.ReverseFind_Dot();
|
||||||
if (dotPos < 0 || dotPos == (int)name.Len() - 1)
|
int len = (int)name.Len() - (dotPos + 1);
|
||||||
|
if (len == 0 || len > 32 || dotPos < 0)
|
||||||
return false;
|
return false;
|
||||||
return finder.FindWord_In_LowCaseAsciiList_NoCase(p, name.Ptr(dotPos + 1));
|
return finder.FindWord_In_LowCaseAsciiList_NoCase(p, name.Ptr(dotPos + 1));
|
||||||
}
|
}
|
||||||
|
|
@ -1337,8 +1342,12 @@ HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi)
|
||||||
case kHash_CRC32:
|
case kHash_CRC32:
|
||||||
case kHash_CRC64:
|
case kHash_CRC64:
|
||||||
case kHash_XXH64:
|
case kHash_XXH64:
|
||||||
|
case kHash_MD5:
|
||||||
case kHash_SHA1:
|
case kHash_SHA1:
|
||||||
case kHash_SHA256:
|
case kHash_SHA256:
|
||||||
|
case kHash_SHA384:
|
||||||
|
case kHash_SHA512:
|
||||||
|
case kHash_SHA3_256:
|
||||||
case kHash_BLAKE2SP:
|
case kHash_BLAKE2SP:
|
||||||
case kHash_All:
|
case kHash_All:
|
||||||
case kHash_Generate_SHA256:
|
case kHash_Generate_SHA256:
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,12 @@ public:
|
||||||
kHash_CRC32,
|
kHash_CRC32,
|
||||||
kHash_CRC64,
|
kHash_CRC64,
|
||||||
kHash_XXH64,
|
kHash_XXH64,
|
||||||
|
kHash_MD5,
|
||||||
kHash_SHA1,
|
kHash_SHA1,
|
||||||
kHash_SHA256,
|
kHash_SHA256,
|
||||||
|
kHash_SHA384,
|
||||||
|
kHash_SHA512,
|
||||||
|
kHash_SHA3_256,
|
||||||
kHash_BLAKE2SP,
|
kHash_BLAKE2SP,
|
||||||
kHash_All,
|
kHash_All,
|
||||||
kHash_Generate_SHA256,
|
kHash_Generate_SHA256,
|
||||||
|
|
|
||||||
|
|
@ -116,15 +116,16 @@ Z7_CLASS_IMP_COM_3(
|
||||||
// DWORD m_StartTickValue;
|
// DWORD m_StartTickValue;
|
||||||
bool m_MessageBoxIsShown;
|
bool m_MessageBoxIsShown;
|
||||||
|
|
||||||
CProgressBox _progressBox;
|
|
||||||
|
|
||||||
bool _numFilesTotalDefined;
|
bool _numFilesTotalDefined;
|
||||||
bool _numBytesTotalDefined;
|
bool _numBytesTotalDefined;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool PasswordIsDefined;
|
bool PasswordIsDefined;
|
||||||
UString Password;
|
UString Password;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CProgressBox _progressBox;
|
||||||
|
public:
|
||||||
|
|
||||||
COpenArchiveCallback()
|
COpenArchiveCallback()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ UInt32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
|
||||||
return valueDefault;
|
return valueDefault;
|
||||||
|
|
||||||
UInt32 value;
|
UInt32 value;
|
||||||
if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS)
|
if (regKey.GetValue_UInt32_IfOk(valueName, value) != ERROR_SUCCESS)
|
||||||
return valueDefault;
|
return valueDefault;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
|
@ -295,7 +295,7 @@ bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
|
||||||
return valueDefault;
|
return valueDefault;
|
||||||
|
|
||||||
bool value;
|
bool value;
|
||||||
if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS)
|
if (regKey.GetValue_bool_IfOk(valueName, value) != ERROR_SUCCESS)
|
||||||
return valueDefault;
|
return valueDefault;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,12 @@ class CProgressBox: public CPercentPrinterState
|
||||||
DWORD _prevElapsedSec;
|
DWORD _prevElapsedSec;
|
||||||
|
|
||||||
bool _wasPrinted;
|
bool _wasPrinted;
|
||||||
|
public:
|
||||||
|
bool UseBytesForPercents;
|
||||||
|
DWORD StartTick;
|
||||||
|
unsigned MaxLen;
|
||||||
|
|
||||||
|
private:
|
||||||
UString _tempU;
|
UString _tempU;
|
||||||
UString _name1U;
|
UString _name1U;
|
||||||
UString _name2U;
|
UString _name2U;
|
||||||
|
|
@ -64,15 +69,12 @@ class CProgressBox: public CPercentPrinterState
|
||||||
void ReduceString(const UString &src, AString &dest);
|
void ReduceString(const UString &src, AString &dest);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DWORD StartTick;
|
|
||||||
bool UseBytesForPercents;
|
|
||||||
unsigned MaxLen;
|
|
||||||
|
|
||||||
CProgressBox(UInt32 tickStep = 200):
|
CProgressBox(UInt32 tickStep = 200):
|
||||||
_tickStep(tickStep),
|
_tickStep(tickStep),
|
||||||
_prevTick(0),
|
_prevTick(0),
|
||||||
StartTick(0),
|
|
||||||
UseBytesForPercents(true),
|
UseBytesForPercents(true),
|
||||||
|
StartTick(0),
|
||||||
MaxLen(60)
|
MaxLen(60)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,96 @@ Z7_COM7F_IMF(CUpdateCallback100Imp::ReportUpdateOperation(UInt32 op, const wchar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT CUpdateCallback100Imp::MoveArc_UpdateStatus()
|
||||||
|
{
|
||||||
|
MT_LOCK
|
||||||
|
|
||||||
|
if (_percent)
|
||||||
|
{
|
||||||
|
AString s;
|
||||||
|
s.Add_UInt64(_arcMoving_percents);
|
||||||
|
// status.Add_Space();
|
||||||
|
s.Add_Char('%');
|
||||||
|
const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1);
|
||||||
|
if (_arcMoving_current != 0 || totalDefined)
|
||||||
|
{
|
||||||
|
s += " : ";
|
||||||
|
s.Add_UInt64(_arcMoving_current >> 20);
|
||||||
|
s += " MiB";
|
||||||
|
}
|
||||||
|
if (totalDefined)
|
||||||
|
{
|
||||||
|
s += " / ";
|
||||||
|
s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20);
|
||||||
|
s += " MiB";
|
||||||
|
}
|
||||||
|
s += " : temporary archive moving ...";
|
||||||
|
_percent->Command = s;
|
||||||
|
_percent->Print();
|
||||||
|
}
|
||||||
|
|
||||||
|
return CheckBreak2();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t * /* destFinalPath */ , UInt64 size, Int32 /* updateMode */))
|
||||||
|
{
|
||||||
|
MT_LOCK
|
||||||
|
|
||||||
|
_arcMoving_total = size;
|
||||||
|
_arcMoving_current = 0;
|
||||||
|
_arcMoving_percents = 0;
|
||||||
|
// _arcMoving_updateMode = updateMode;
|
||||||
|
// _name2 = fs2us(destFinalPath);
|
||||||
|
if (_percent)
|
||||||
|
_percent->FileName = srcTempPath;
|
||||||
|
return MoveArc_UpdateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize))
|
||||||
|
{
|
||||||
|
UInt64 percents = 0;
|
||||||
|
if (totalSize != 0)
|
||||||
|
{
|
||||||
|
if (totalSize < ((UInt64)1 << 57))
|
||||||
|
percents = currentSize * 100 / totalSize;
|
||||||
|
else
|
||||||
|
percents = currentSize / (totalSize / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Sleep(300); // for debug
|
||||||
|
#endif
|
||||||
|
if (percents == _arcMoving_percents)
|
||||||
|
return CheckBreak2();
|
||||||
|
_arcMoving_total = totalSize;
|
||||||
|
_arcMoving_current = currentSize;
|
||||||
|
_arcMoving_percents = percents;
|
||||||
|
// if (_arcMoving_percents > 100) return E_FAIL;
|
||||||
|
return MoveArc_UpdateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Finish())
|
||||||
|
{
|
||||||
|
// _arcMoving_percents = 0;
|
||||||
|
if (_percent)
|
||||||
|
{
|
||||||
|
_percent->Command.Empty();
|
||||||
|
_percent->FileName.Empty();
|
||||||
|
_percent->Print();
|
||||||
|
}
|
||||||
|
return CheckBreak2();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Z7_COM7F_IMF(CUpdateCallback100Imp::Before_ArcReopen())
|
||||||
|
{
|
||||||
|
// fixme: we can use Clear_Stop_Status() here
|
||||||
|
return CheckBreak2();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern HRESULT GetPassword(UString &password);
|
extern HRESULT GetPassword(UString &password);
|
||||||
|
|
||||||
Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password))
|
Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password))
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,11 @@
|
||||||
|
|
||||||
#include "ProgressBox.h"
|
#include "ProgressBox.h"
|
||||||
|
|
||||||
Z7_CLASS_IMP_COM_6(
|
Z7_CLASS_IMP_COM_7(
|
||||||
CUpdateCallback100Imp
|
CUpdateCallback100Imp
|
||||||
, IFolderArchiveUpdateCallback
|
, IFolderArchiveUpdateCallback
|
||||||
, IFolderArchiveUpdateCallback2
|
, IFolderArchiveUpdateCallback2
|
||||||
|
, IFolderArchiveUpdateCallback_MoveArc
|
||||||
, IFolderScanProgress
|
, IFolderScanProgress
|
||||||
, ICryptoGetTextPassword2
|
, ICryptoGetTextPassword2
|
||||||
, ICryptoGetTextPassword
|
, ICryptoGetTextPassword
|
||||||
|
|
@ -25,6 +26,15 @@ Z7_CLASS_IMP_COM_6(
|
||||||
// CMyComPtr<IInFolderArchive> _archiveHandler;
|
// CMyComPtr<IInFolderArchive> _archiveHandler;
|
||||||
CProgressBox *_percent;
|
CProgressBox *_percent;
|
||||||
// UInt64 _total;
|
// UInt64 _total;
|
||||||
|
|
||||||
|
HRESULT MoveArc_UpdateStatus();
|
||||||
|
|
||||||
|
private:
|
||||||
|
UInt64 _arcMoving_total;
|
||||||
|
UInt64 _arcMoving_current;
|
||||||
|
UInt64 _arcMoving_percents;
|
||||||
|
// Int32 _arcMoving_updateMode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool PasswordIsDefined;
|
bool PasswordIsDefined;
|
||||||
UString Password;
|
UString Password;
|
||||||
|
|
@ -38,6 +48,10 @@ public:
|
||||||
_percent = progressBox;
|
_percent = progressBox;
|
||||||
PasswordIsDefined = false;
|
PasswordIsDefined = false;
|
||||||
Password.Empty();
|
Password.Empty();
|
||||||
|
_arcMoving_total = 0;
|
||||||
|
_arcMoving_current = 0;
|
||||||
|
_arcMoving_percents = 0;
|
||||||
|
// _arcMoving_updateMode = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -387,8 +387,8 @@ Z7_COM7F_IMF(CAltStreamsFolder::WasChanged(Int32 *wasChanged))
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
|
const DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
|
||||||
bool wasChangedLoc = (waitResult == WAIT_OBJECT_0);
|
const bool wasChangedLoc = (waitResult == WAIT_OBJECT_0);
|
||||||
if (wasChangedLoc)
|
if (wasChangedLoc)
|
||||||
{
|
{
|
||||||
_findChangeNotification.FindNext();
|
_findChangeNotification.FindNext();
|
||||||
|
|
@ -666,16 +666,10 @@ Z7_COM7F_IMF(CAltStreamsFolder::SetProperty(UInt32 /* index */, PROPID /* propID
|
||||||
Z7_COM7F_IMF(CAltStreamsFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex))
|
Z7_COM7F_IMF(CAltStreamsFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex))
|
||||||
{
|
{
|
||||||
const CAltStream &ss = Streams[index];
|
const CAltStream &ss = Streams[index];
|
||||||
*iconIndex = 0;
|
return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
|
||||||
int iconIndexTemp;
|
_pathPrefix + us2fs(ss.Name),
|
||||||
if (GetRealIconIndex(_pathPrefix + us2fs(ss.Name),
|
FILE_ATTRIBUTE_ARCHIVE,
|
||||||
0 // fi.Attrib
|
iconIndex);
|
||||||
, iconIndexTemp) != 0)
|
|
||||||
{
|
|
||||||
*iconIndex = iconIndexTemp;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return GetLastError_noZero_HRESULT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -402,11 +402,17 @@ void CApp::Save()
|
||||||
// Save_ShowDeleted(ShowDeletedFiles);
|
// Save_ShowDeleted(ShowDeletedFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CApp::Release()
|
void CApp::ReleaseApp()
|
||||||
{
|
{
|
||||||
|
// 24.09: ReleasePanel() will stop panel timer processing.
|
||||||
|
// but we want to stop timer processing for all panels
|
||||||
|
// before ReleasePanel() calling.
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < kNumPanelsMax; i++)
|
||||||
|
Panels[i].Disable_Processing_Timer_Notify_StatusBar();
|
||||||
// It's for unloading COM dll's: don't change it.
|
// It's for unloading COM dll's: don't change it.
|
||||||
for (unsigned i = 0; i < kNumPanelsMax; i++)
|
for (i = 0; i < kNumPanelsMax; i++)
|
||||||
Panels[i].Release();
|
Panels[i].ReleasePanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// reduces path to part that exists on disk (or root prefix of path)
|
// reduces path to part that exists on disk (or root prefix of path)
|
||||||
|
|
@ -644,7 +650,7 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex)
|
||||||
destPath += correctName;
|
destPath += correctName;
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||||
if (destPath.Len() > 0 && destPath[0] == '\\')
|
if (destPath.Len() != 0 && destPath[0] == '\\')
|
||||||
if (destPath.Len() == 1 || destPath[1] != '\\')
|
if (destPath.Len() == 1 || destPath[1] != '\\')
|
||||||
{
|
{
|
||||||
srcPanel.MessageBox_Error_UnsupportOperation();
|
srcPanel.MessageBox_Error_UnsupportOperation();
|
||||||
|
|
@ -782,6 +788,7 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex)
|
||||||
if (useSrcPanel)
|
if (useSrcPanel)
|
||||||
{
|
{
|
||||||
CCopyToOptions options;
|
CCopyToOptions options;
|
||||||
|
// options.src_Is_IO_FS_Folder = useFullItemPaths;
|
||||||
options.folder = useTemp ? fs2us(tempDirPrefix) : destPath;
|
options.folder = useTemp ? fs2us(tempDirPrefix) : destPath;
|
||||||
options.moveMode = move;
|
options.moveMode = move;
|
||||||
options.includeAltStreams = true;
|
options.includeAltStreams = true;
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ public:
|
||||||
HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes);
|
HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes);
|
||||||
void Read();
|
void Read();
|
||||||
void Save();
|
void Save();
|
||||||
void Release();
|
void ReleaseApp();
|
||||||
|
|
||||||
// void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); }
|
// void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); }
|
||||||
void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); }
|
void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); }
|
||||||
|
|
|
||||||
|
|
@ -208,8 +208,8 @@ bool CBrowseDialog::OnInit()
|
||||||
_filterCombo.SetCurSel(FilterIndex);
|
_filterCombo.SetCurSel(FilterIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
_list.SetImageList(GetSysImageList(true), LVSIL_SMALL);
|
_list.SetImageList(Shell_Get_SysImageList_smallIcons(true), LVSIL_SMALL);
|
||||||
_list.SetImageList(GetSysImageList(false), LVSIL_NORMAL);
|
_list.SetImageList(Shell_Get_SysImageList_smallIcons(false), LVSIL_NORMAL);
|
||||||
|
|
||||||
_list.InsertColumn(0, LangString(IDS_PROP_NAME), 100);
|
_list.InsertColumn(0, LangString(IDS_PROP_NAME), 100);
|
||||||
_list.InsertColumn(1, LangString(IDS_PROP_MTIME), 100);
|
_list.InsertColumn(1, LangString(IDS_PROP_MTIME), 100);
|
||||||
|
|
@ -690,8 +690,9 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
|
||||||
#ifndef UNDER_CE
|
#ifndef UNDER_CE
|
||||||
if (isDrive)
|
if (isDrive)
|
||||||
{
|
{
|
||||||
if (GetRealIconIndex(fi.Name + FCHAR_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, item.iImage) == 0)
|
item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path(
|
||||||
item.iImage = 0;
|
fi.Name + FCHAR_PATH_SEPARATOR,
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -702,6 +703,7 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
|
||||||
wchar_t s[64];
|
wchar_t s[64];
|
||||||
{
|
{
|
||||||
s[0] = 0;
|
s[0] = 0;
|
||||||
|
if (!FILETIME_IsZero(fi.MTime))
|
||||||
ConvertUtcFileTimeToString(fi.MTime, s,
|
ConvertUtcFileTimeToString(fi.MTime, s,
|
||||||
#ifndef UNDER_CE
|
#ifndef UNDER_CE
|
||||||
kTimestampPrintLevel_MIN
|
kTimestampPrintLevel_MIN
|
||||||
|
|
|
||||||
|
|
@ -356,8 +356,8 @@ bool CBrowseDialog2::OnInit()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
_list.SetImageList(GetSysImageList(true), LVSIL_SMALL);
|
_list.SetImageList(Shell_Get_SysImageList_smallIcons(true), LVSIL_SMALL);
|
||||||
_list.SetImageList(GetSysImageList(false), LVSIL_NORMAL);
|
_list.SetImageList(Shell_Get_SysImageList_smallIcons(false), LVSIL_NORMAL);
|
||||||
|
|
||||||
unsigned columnIndex = 0;
|
unsigned columnIndex = 0;
|
||||||
_list.InsertColumn(columnIndex++, LangString(IDS_PROP_NAME), 100);
|
_list.InsertColumn(columnIndex++, LangString(IDS_PROP_NAME), 100);
|
||||||
|
|
@ -939,7 +939,8 @@ void CBrowseDialog2::OnDelete(/* bool toRecycleBin */)
|
||||||
s.Add_LF();
|
s.Add_LF();
|
||||||
s += s2;
|
s += s2;
|
||||||
}
|
}
|
||||||
if (::MessageBoxW((HWND)*this, s, LangString(titleID), MB_OKCANCEL | MB_ICONQUESTION) != IDOK)
|
if (::MessageBoxW((HWND)*this, s, LangString(titleID),
|
||||||
|
MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1638,15 +1639,15 @@ HRESULT CBrowseDialog2::Reload(const UString &pathPrefix, const UStringVector &s
|
||||||
#ifndef UNDER_CE
|
#ifndef UNDER_CE
|
||||||
if (isDrive)
|
if (isDrive)
|
||||||
{
|
{
|
||||||
if (GetRealIconIndex(fi.Name + FCHAR_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, item.iImage) == 0)
|
item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path(
|
||||||
item.iImage = 0;
|
fi.Name + FCHAR_PATH_SEPARATOR,
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath);
|
item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath);
|
||||||
if (item.iImage < 0)
|
if (item.iImage < 0)
|
||||||
item.iImage = 0;
|
item.iImage = 0;
|
||||||
|
|
||||||
_list.InsertItem(&item);
|
_list.InsertItem(&item);
|
||||||
wchar_t s[64];
|
wchar_t s[64];
|
||||||
{
|
{
|
||||||
|
|
@ -1661,7 +1662,6 @@ HRESULT CBrowseDialog2::Reload(const UString &pathPrefix, const UStringVector &s
|
||||||
);
|
);
|
||||||
_list.SetSubItem(index, subItem++, s);
|
_list.SetSubItem(index, subItem++, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
s[0] = 0;
|
s[0] = 0;
|
||||||
Browse_ConvertSizeToString(bi, s);
|
Browse_ConvertSizeToString(bi, s);
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue