mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 05:15:00 -06:00
21.04
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
; 7zAsm.asm -- ASM macros
|
||||
; 2021-07-13 : Igor Pavlov : Public domain
|
||||
; 2021-08-29 : Igor Pavlov : Public domain
|
||||
|
||||
ifdef RAX
|
||||
x64 equ 1
|
||||
@@ -27,6 +27,8 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
OPTION PROLOGUE:NONE
|
||||
OPTION EPILOGUE:NONE
|
||||
|
||||
MY_ASM_START macro
|
||||
ifdef x64
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
; LzFindOpt.asm -- ASM version of GetMatchesSpecN_2() function
|
||||
; 2021-07-13: Igor Pavlov : Public domain
|
||||
; 2021-07-21: Igor Pavlov : Public domain
|
||||
;
|
||||
|
||||
ifndef x64
|
||||
@@ -475,7 +475,7 @@ long_loop:
|
||||
je long_footer
|
||||
cmp delta_x, [hash]
|
||||
jne long_footer
|
||||
movzx t0_x, BYTE PTR [diff + cur]
|
||||
movzx t0_x, BYTE PTR [diff + 1 * cur]
|
||||
cmp [cur], t0_L
|
||||
jne long_footer
|
||||
cmp d, d_lim
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#define MY_VER_MAJOR 21
|
||||
#define MY_VER_MINOR 03
|
||||
#define MY_VER_MINOR 04
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION_NUMBERS "21.03 beta"
|
||||
#define MY_VERSION_NUMBERS "21.04 beta"
|
||||
#define MY_VERSION MY_VERSION_NUMBERS
|
||||
|
||||
#ifdef MY_CPU_NAME
|
||||
@@ -10,7 +10,7 @@
|
||||
#define MY_VERSION_CPU MY_VERSION
|
||||
#endif
|
||||
|
||||
#define MY_DATE "2021-07-20"
|
||||
#define MY_DATE "2021-11-02"
|
||||
#undef MY_COPYRIGHT
|
||||
#undef MY_VERSION_COPYRIGHT_DATE
|
||||
#define MY_AUTHOR_NAME "Igor Pavlov"
|
||||
|
||||
@@ -174,6 +174,8 @@ $O/LzFind.o: ../../../C/LzFind.c
|
||||
# ifdef MT_FILES
|
||||
$O/LzFindMt.o: ../../../C/LzFindMt.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
$O/LzFindOpt.o: ../../../C/LzFindOpt.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
||||
$O/Threads.o: ../../../C/Threads.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* LzFind.c -- Match finder for LZ algorithms
|
||||
2021-07-12 : Igor Pavlov : Public domain */
|
||||
2021-09-03 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -1592,7 +1592,7 @@ void LzFindPrepare()
|
||||
{
|
||||
if (CPU_IsSupported_NEON())
|
||||
{
|
||||
#pragma message ("=== LzFind NEON")
|
||||
// #pragma message ("=== LzFind NEON")
|
||||
_PRF(printf("\n=== LzFind NEON\n"));
|
||||
f = LzFind_SaturSub_128;
|
||||
}
|
||||
@@ -1601,14 +1601,14 @@ void LzFindPrepare()
|
||||
#else // MY_CPU_ARM_OR_ARM64
|
||||
if (CPU_IsSupported_SSE41())
|
||||
{
|
||||
#pragma message ("=== LzFind SSE41")
|
||||
// #pragma message ("=== LzFind SSE41")
|
||||
_PRF(printf("\n=== LzFind SSE41\n"));
|
||||
f = LzFind_SaturSub_128;
|
||||
|
||||
#ifdef USE_AVX2
|
||||
if (CPU_IsSupported_AVX2())
|
||||
{
|
||||
#pragma message ("=== LzFind AVX2")
|
||||
// #pragma message ("=== LzFind AVX2")
|
||||
_PRF(printf("\n=== LzFind AVX2\n"));
|
||||
f = LzFind_SaturSub_256;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 7zipInstall.c - 7-Zip Installer
|
||||
2021-02-23 : Igor Pavlov : Public domain */
|
||||
2021-09-02 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -927,6 +927,9 @@ static void WriteShellEx()
|
||||
CatAscii(destPath, "Uninstall.exe\"");
|
||||
MyRegistry_SetString(destKey, L"UninstallString", destPath);
|
||||
|
||||
CatAscii(destPath, " /S");
|
||||
MyRegistry_SetString(destKey, L"QuietUninstallString", destPath);
|
||||
|
||||
MyRegistry_SetDWORD(destKey, L"NoModify", 1);
|
||||
MyRegistry_SetDWORD(destKey, L"NoRepair", 1);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* LzmaUtil.c -- Test application for LZMA compression
|
||||
2021-02-15 : Igor Pavlov : Public domain */
|
||||
2021-11-01 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "../../Precomp.h"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "../../Alloc.h"
|
||||
#include "../../7zFile.h"
|
||||
#include "../../7zVersion.h"
|
||||
#include "../../LzFind.h"
|
||||
#include "../../LzmaDec.h"
|
||||
#include "../../LzmaEnc.h"
|
||||
|
||||
@@ -195,6 +196,8 @@ static int main2(int numArgs, const char *args[], char *rs)
|
||||
int encodeMode;
|
||||
BoolInt useOutFile = False;
|
||||
|
||||
LzFindPrepare();
|
||||
|
||||
FileSeqInStream_CreateVTable(&inStream);
|
||||
File_Construct(&inStream.file);
|
||||
inStream.wres = 0;
|
||||
@@ -276,7 +279,7 @@ static int main2(int numArgs, const char *args[], char *rs)
|
||||
|
||||
int MY_CDECL main(int numArgs, const char *args[])
|
||||
{
|
||||
char rs[800] = { 0 };
|
||||
char rs[1000] = { 0 };
|
||||
int res = main2(numArgs, args, rs);
|
||||
fputs(rs, stdout);
|
||||
return res;
|
||||
|
||||
@@ -134,6 +134,10 @@ SOURCE=..\..\LzFindMt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\LzFindOpt.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\LzHash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -8,8 +8,10 @@ LIB_OBJS = \
|
||||
|
||||
C_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
$O\CpuArch.obj \
|
||||
$O\LzFind.obj \
|
||||
$O\LzFindMt.obj \
|
||||
$O\LzFindOpt.obj \
|
||||
$O\LzmaDec.obj \
|
||||
$O\LzmaEnc.obj \
|
||||
$O\7zFile.obj \
|
||||
|
||||
@@ -8,8 +8,10 @@ OBJS = \
|
||||
$O/7zFile.o \
|
||||
$O/7zStream.o \
|
||||
$O/Alloc.o \
|
||||
$O/CpuArch.o \
|
||||
$O/LzFind.o \
|
||||
$O/LzFindMt.o \
|
||||
$O/LzFindOpt.o \
|
||||
$O/LzmaDec.o \
|
||||
$O/LzmaEnc.o \
|
||||
$O/LzmaUtil.o \
|
||||
|
||||
@@ -11,6 +11,7 @@ LIB_OBJS = \
|
||||
|
||||
C_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
$O\CpuArch.obj \
|
||||
$O\LzFind.obj \
|
||||
$O\LzFindMt.obj \
|
||||
$O\LzFindOpt.obj \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* XzDec.c -- Xz Decode
|
||||
2021-04-01 : Igor Pavlov : Public domain */
|
||||
2021-09-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -773,7 +773,8 @@ static BoolInt Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte
|
||||
|
||||
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \
|
||||
{ unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
|
||||
if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }
|
||||
if (s == 0) return SZ_ERROR_ARCHIVE; \
|
||||
pos += s; }
|
||||
|
||||
|
||||
static BoolInt XzBlock_AreSupportedFilters(const CXzBlock *p)
|
||||
|
||||
5
C/XzIn.c
5
C/XzIn.c
@@ -1,5 +1,5 @@
|
||||
/* XzIn.c - Xz input
|
||||
2021-04-01 : Igor Pavlov : Public domain */
|
||||
2021-09-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -26,7 +26,8 @@ SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)
|
||||
|
||||
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \
|
||||
{ unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
|
||||
if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }
|
||||
if (s == 0) return SZ_ERROR_ARCHIVE; \
|
||||
pos += s; }
|
||||
|
||||
SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, UInt32 *headerSizeRes)
|
||||
{
|
||||
|
||||
@@ -14,8 +14,10 @@ struct CMethodFull: public CMethodProps
|
||||
CMethodId Id;
|
||||
UInt32 NumStreams;
|
||||
int CodecIndex;
|
||||
UInt32 NumThreads;
|
||||
bool Set_NumThreads;
|
||||
|
||||
CMethodFull(): CodecIndex(-1) {}
|
||||
CMethodFull(): CodecIndex(-1), NumThreads(1), Set_NumThreads(false) {}
|
||||
bool IsSimpleCoder() const { return NumStreams == 1; }
|
||||
};
|
||||
|
||||
@@ -53,9 +55,13 @@ struct CCompressionMethodMode
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
UInt32 NumThreads;
|
||||
bool NumThreads_WasForced;
|
||||
bool MultiThreadMixer;
|
||||
#endif
|
||||
|
||||
UInt64 MemoryUsageLimit;
|
||||
bool MemoryUsageLimit_WasSet;
|
||||
|
||||
bool PasswordIsDefined;
|
||||
UString Password; // _Wipe
|
||||
|
||||
@@ -65,8 +71,11 @@ struct CCompressionMethodMode
|
||||
, Filter_was_Inserted(false)
|
||||
#ifndef _7ZIP_ST
|
||||
, NumThreads(1)
|
||||
, NumThreads_WasForced(false)
|
||||
, MultiThreadMixer(true)
|
||||
#endif
|
||||
, MemoryUsageLimit((UInt64)1 << 30)
|
||||
, MemoryUsageLimit_WasSet(false)
|
||||
, PasswordIsDefined(false)
|
||||
{}
|
||||
|
||||
|
||||
@@ -175,12 +175,16 @@ HRESULT CEncoder::CreateMixerCoder(
|
||||
CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2;
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
if (methodFull.Set_NumThreads)
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||
encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||
if (setCoderMt)
|
||||
{
|
||||
RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
|
||||
RINOK(setCoderMt->SetNumberOfThreads(
|
||||
/* _options.NumThreads */
|
||||
methodFull.NumThreads
|
||||
));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -374,7 +374,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
_7Z_DECODER_CRYPRO_VARS
|
||||
#if !defined(_7ZIP_ST)
|
||||
, true, _numThreads, _memUsage
|
||||
, true, _numThreads, _memUsage_Decompress
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
@@ -158,12 +158,7 @@ private:
|
||||
|
||||
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
|
||||
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
|
||||
HRESULT SetMainMethod(CCompressionMethodMode &method
|
||||
#ifndef _7ZIP_ST
|
||||
, UInt32 numThreads
|
||||
#endif
|
||||
);
|
||||
|
||||
HRESULT SetMainMethod(CCompressionMethodMode &method);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -69,15 +69,12 @@ HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
|
||||
return PropsMethod_To_FullMethod(methodFull, m);
|
||||
}
|
||||
|
||||
HRESULT CHandler::SetMainMethod(
|
||||
CCompressionMethodMode &methodMode
|
||||
#ifndef _7ZIP_ST
|
||||
, UInt32 numThreads
|
||||
#endif
|
||||
)
|
||||
|
||||
HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode)
|
||||
{
|
||||
methodMode.Bonds = _bonds;
|
||||
|
||||
// we create local copy of _methods. So we can modify it.
|
||||
CObjectVector<COneMethodInfo> methods = _methods;
|
||||
|
||||
{
|
||||
@@ -120,19 +117,25 @@ HRESULT CHandler::SetMainMethod(
|
||||
COneMethodInfo &oneMethodInfo = methods[i];
|
||||
|
||||
SetGlobalLevelTo(oneMethodInfo);
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
CMultiMethodProps::SetMethodThreadsTo(oneMethodInfo, numThreads);
|
||||
const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0);
|
||||
if (!numThreads_WasSpecifiedInMethod)
|
||||
{
|
||||
// here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already
|
||||
CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, methodMode.NumThreads);
|
||||
}
|
||||
#endif
|
||||
|
||||
CMethodFull &methodFull = methodMode.Methods.AddNew();
|
||||
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
|
||||
|
||||
methodFull.Set_NumThreads = true;
|
||||
methodFull.NumThreads = methodMode.NumThreads;
|
||||
|
||||
if (methodFull.Id != k_Copy)
|
||||
needSolid = true;
|
||||
|
||||
if (_numSolidBytesDefined)
|
||||
continue;
|
||||
|
||||
UInt64 dicSize;
|
||||
switch (methodFull.Id)
|
||||
{
|
||||
@@ -145,9 +148,13 @@ HRESULT CHandler::SetMainMethod(
|
||||
default: continue;
|
||||
}
|
||||
|
||||
UInt64 numSolidBytes;
|
||||
|
||||
if (methodFull.Id == k_LZMA2)
|
||||
{
|
||||
// he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code
|
||||
/* lzma2 code use dictionary upo to fake 4 GiB to calculate ChunkSize.
|
||||
So we do same */
|
||||
UInt64 cs = (UInt64)dicSize << 2;
|
||||
const UInt32 kMinSize = (UInt32)1 << 20;
|
||||
const UInt32 kMaxSize = (UInt32)1 << 28;
|
||||
@@ -157,20 +164,78 @@ HRESULT CHandler::SetMainMethod(
|
||||
cs += (kMinSize - 1);
|
||||
cs &= ~(UInt64)(kMinSize - 1);
|
||||
// we want to use at least 64 chunks (threads) per one solid block.
|
||||
_numSolidBytes = cs << 6;
|
||||
|
||||
// here we don't use chunckSize property
|
||||
numSolidBytes = cs << 6;
|
||||
|
||||
// here we get real chunckSize
|
||||
cs = oneMethodInfo.Get_Xz_BlockSize();
|
||||
if (dicSize > cs)
|
||||
dicSize = cs;
|
||||
|
||||
const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34);
|
||||
if (_numSolidBytes > kSolidBytes_Lzma2_Max)
|
||||
_numSolidBytes = kSolidBytes_Lzma2_Max;
|
||||
if (numSolidBytes > kSolidBytes_Lzma2_Max)
|
||||
numSolidBytes = kSolidBytes_Lzma2_Max;
|
||||
|
||||
methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
if (!numThreads_WasSpecifiedInMethod
|
||||
&& !methodMode.NumThreads_WasForced
|
||||
&& methodMode.MemoryUsageLimit_WasSet
|
||||
)
|
||||
{
|
||||
const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads();
|
||||
const UInt32 numBlockThreads_Original = methodMode.NumThreads / lzmaThreads;
|
||||
|
||||
if (numBlockThreads_Original > 1)
|
||||
{
|
||||
/*
|
||||
const UInt32 kNumThreads_Max = 1024;
|
||||
if (numBlockThreads > kNumMaxThreads)
|
||||
numBlockThreads = kNumMaxThreads;
|
||||
*/
|
||||
|
||||
UInt32 numBlockThreads = numBlockThreads_Original;
|
||||
const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); // solid
|
||||
|
||||
for (; numBlockThreads > 1; numBlockThreads--)
|
||||
{
|
||||
UInt64 size = numBlockThreads * (lzmaMemUsage + cs);
|
||||
UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1;
|
||||
if (cs < ((UInt32)1 << 26)) numPackChunks++;
|
||||
if (cs < ((UInt32)1 << 24)) numPackChunks++;
|
||||
if (cs < ((UInt32)1 << 22)) numPackChunks++;
|
||||
size += numPackChunks * cs;
|
||||
// printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20));
|
||||
if (size <= methodMode.MemoryUsageLimit)
|
||||
break;
|
||||
}
|
||||
|
||||
if (numBlockThreads == 0)
|
||||
numBlockThreads = 1;
|
||||
if (numBlockThreads != numBlockThreads_Original)
|
||||
{
|
||||
const UInt32 numThreads_New = numBlockThreads * lzmaThreads;
|
||||
CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
_numSolidBytes = (UInt64)dicSize << 7;
|
||||
if (_numSolidBytes > kSolidBytes_Max)
|
||||
_numSolidBytes = kSolidBytes_Max;
|
||||
numSolidBytes = (UInt64)dicSize << 7;
|
||||
if (numSolidBytes > kSolidBytes_Max)
|
||||
numSolidBytes = kSolidBytes_Max;
|
||||
}
|
||||
|
||||
if (_numSolidBytes < kSolidBytes_Min)
|
||||
_numSolidBytes = kSolidBytes_Min;
|
||||
if (_numSolidBytesDefined)
|
||||
continue;
|
||||
|
||||
if (numSolidBytes < kSolidBytes_Min)
|
||||
numSolidBytes = kSolidBytes_Min;
|
||||
_numSolidBytes = numSolidBytes;
|
||||
_numSolidBytesDefined = true;
|
||||
}
|
||||
|
||||
@@ -182,9 +247,13 @@ HRESULT CHandler::SetMainMethod(
|
||||
_numSolidBytes = 0;
|
||||
}
|
||||
_numSolidBytesDefined = true;
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined)
|
||||
{
|
||||
// ft = 0;
|
||||
@@ -576,22 +645,28 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
CCompressionMethodMode methodMode, headerMethod;
|
||||
|
||||
HRESULT res = SetMainMethod(methodMode
|
||||
methodMode.MemoryUsageLimit = _memUsage_Compress;
|
||||
methodMode.MemoryUsageLimit_WasSet = _memUsage_WasSet;
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
, _numThreads
|
||||
{
|
||||
UInt32 numThreads = _numThreads;
|
||||
const UInt32 kNumThreads_Max = 1024;
|
||||
if (numThreads > kNumThreads_Max)
|
||||
numThreads = kNumThreads_Max;
|
||||
methodMode.NumThreads = numThreads;
|
||||
methodMode.NumThreads_WasForced = _numThreads_WasForced;
|
||||
methodMode.MultiThreadMixer = _useMultiThreadMixer;
|
||||
// headerMethod.NumThreads = 1;
|
||||
headerMethod.MultiThreadMixer = _useMultiThreadMixer;
|
||||
}
|
||||
#endif
|
||||
);
|
||||
|
||||
HRESULT res = SetMainMethod(methodMode);
|
||||
RINOK(res);
|
||||
|
||||
RINOK(SetHeaderMethod(headerMethod));
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
methodMode.NumThreads = _numThreads;
|
||||
methodMode.MultiThreadMixer = _useMultiThreadMixer;
|
||||
headerMethod.NumThreads = 1;
|
||||
headerMethod.MultiThreadMixer = _useMultiThreadMixer;
|
||||
#endif
|
||||
|
||||
CMyComPtr<ICryptoGetTextPassword2> getPassword2;
|
||||
updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);
|
||||
|
||||
|
||||
@@ -70,15 +70,22 @@ bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIAN
|
||||
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
hres = ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads);
|
||||
_numThreads = _numProcessors;
|
||||
_numThreads_WasForced = false;
|
||||
hres = ParseMtProp2(name.Ptr(2), value, _numThreads, _numThreads_WasForced);
|
||||
// "mt" means "_numThreads_WasForced = false" here
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
|
||||
{
|
||||
if (!ParseSizeString(name.Ptr(6), value, _memAvail, _memUsage))
|
||||
UInt64 v;
|
||||
if (!ParseSizeString(name.Ptr(6), value, _memAvail, v))
|
||||
hres = E_INVALIDARG;
|
||||
_memUsage_Decompress = v;
|
||||
_memUsage_Compress = v;
|
||||
_memUsage_WasSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,12 +95,24 @@ bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIAN
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
|
||||
static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value)
|
||||
{
|
||||
if (m.FindProp(propID) < 0)
|
||||
m.AddProp32(propID, value);
|
||||
}
|
||||
|
||||
static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value)
|
||||
{
|
||||
const int i = m.FindProp(propID);
|
||||
if (i >= 0)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant &val = m.Props[(unsigned)i].Value;
|
||||
val = (UInt32)value;
|
||||
return;
|
||||
}
|
||||
m.AddProp32(propID, value);
|
||||
}
|
||||
|
||||
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
|
||||
{
|
||||
UInt32 level = _level;
|
||||
@@ -102,10 +121,15 @@ void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
|
||||
}
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads)
|
||||
void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads)
|
||||
{
|
||||
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||
}
|
||||
|
||||
void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo, UInt32 numThreads)
|
||||
{
|
||||
SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CMultiMethodProps::InitMulti()
|
||||
|
||||
@@ -18,15 +18,26 @@ protected:
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||
_numThreads_WasForced = false;
|
||||
#endif
|
||||
|
||||
UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28;
|
||||
_memAvail = memAvail;
|
||||
_memUsage = memAvail;
|
||||
if (NWindows::NSystem::GetRamSize(memAvail))
|
||||
_memUsage_Compress = memAvail;
|
||||
_memUsage_Decompress = memAvail;
|
||||
_memUsage_WasSet = NWindows::NSystem::GetRamSize(memAvail);
|
||||
if (_memUsage_WasSet)
|
||||
{
|
||||
_memAvail = memAvail;
|
||||
_memUsage = memAvail / 32 * 17;
|
||||
unsigned bits = sizeof(size_t) * 8;
|
||||
if (bits == 32)
|
||||
{
|
||||
const UInt32 limit2 = (UInt32)7 << 28;
|
||||
if (memAvail > limit2)
|
||||
memAvail = limit2;
|
||||
}
|
||||
_memUsage_Compress = memAvail / 32 * 28;
|
||||
_memUsage_Decompress = memAvail / 32 * 17;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +45,12 @@ public:
|
||||
#ifndef _7ZIP_ST
|
||||
UInt32 _numThreads;
|
||||
UInt32 _numProcessors;
|
||||
bool _numThreads_WasForced;
|
||||
#endif
|
||||
|
||||
UInt64 _memUsage;
|
||||
bool _memUsage_WasSet;
|
||||
UInt64 _memUsage_Compress;
|
||||
UInt64 _memUsage_Decompress;
|
||||
UInt64 _memAvail;
|
||||
|
||||
bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
|
||||
@@ -63,7 +77,8 @@ public:
|
||||
void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const;
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
static void SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads);
|
||||
static void SetMethodThreadsTo_IfNotFinded(CMethodProps &props, UInt32 numThreads);
|
||||
static void SetMethodThreadsTo_Replace(CMethodProps &props, UInt32 numThreads);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1513,6 +1513,9 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
|
||||
*propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
UNUSED_VAR(index);
|
||||
UNUSED_VAR(propID);
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace NArcInfoFlags
|
||||
const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links
|
||||
const UInt32 kHardLinks = 1 << 11; // the handler supports hard links
|
||||
const UInt32 kByExtOnlyOpen = 1 << 12; // call handler only if file extension matches
|
||||
const UInt32 kHashHandler = 1 << 13; // the handler contains the hashes (checksums)
|
||||
}
|
||||
|
||||
namespace NArchive
|
||||
@@ -91,7 +92,8 @@ namespace NArchive
|
||||
{
|
||||
kExtract = 0,
|
||||
kTest,
|
||||
kSkip
|
||||
kSkip,
|
||||
kReadExternal
|
||||
};
|
||||
}
|
||||
|
||||
@@ -458,7 +460,8 @@ namespace NUpdateNotifyOp
|
||||
kRepack,
|
||||
kSkip,
|
||||
kDelete,
|
||||
kHeader
|
||||
kHeader,
|
||||
kHashRead
|
||||
|
||||
// kNumDefined
|
||||
};
|
||||
@@ -481,6 +484,14 @@ ARCHIVE_INTERFACE(IArchiveUpdateCallbackFile, 0x83)
|
||||
};
|
||||
|
||||
|
||||
#define INTERFACE_IArchiveGetDiskProperty(x) \
|
||||
STDMETHOD(GetDiskProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
|
||||
|
||||
ARCHIVE_INTERFACE(IArchiveGetDiskProperty, 0x84)
|
||||
{
|
||||
INTERFACE_IArchiveGetDiskProperty(PURE);
|
||||
};
|
||||
|
||||
/*
|
||||
UpdateItems()
|
||||
-------------
|
||||
|
||||
@@ -763,6 +763,9 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
|
||||
_forceCodePage = true;
|
||||
_curCodePage = _specifiedCodePage = cp;
|
||||
}
|
||||
else if (name.IsPrefixedBy_Ascii_NoCase("mt"))
|
||||
{
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ static UString ParseDString(const Byte *data, unsigned size)
|
||||
}
|
||||
}
|
||||
else
|
||||
return UString("[unknow]");
|
||||
return UString("[unknown]");
|
||||
*p = 0;
|
||||
res.ReleaseBuf_SetLen((unsigned)(p - (const wchar_t *)res));
|
||||
}
|
||||
|
||||
@@ -877,8 +877,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
|
||||
curStream = inStream;
|
||||
else
|
||||
{
|
||||
UString fullName = seqName.GetNextName(i);
|
||||
HRESULT result = openVolumeCallback->GetStream(fullName, &curStream);
|
||||
if (!openVolumeCallback)
|
||||
continue;
|
||||
const UString fullName = seqName.GetNextName(i);
|
||||
const HRESULT result = openVolumeCallback->GetStream(fullName, &curStream);
|
||||
if (result == S_FALSE)
|
||||
continue;
|
||||
if (result != S_OK)
|
||||
|
||||
@@ -151,7 +151,8 @@ IMP_IInArchive_ArcProps
|
||||
|
||||
#define PARSE_NUM(_num_, _dest_) \
|
||||
{ const char *end; _dest_ = ConvertStringToUInt32(p, &end); \
|
||||
if ((unsigned)(end - p) != _num_) return 0; p += _num_ + 1; }
|
||||
if ((unsigned)(end - p) != _num_) return 0; \
|
||||
p += _num_ + 1; }
|
||||
|
||||
static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res)
|
||||
{
|
||||
|
||||
@@ -117,7 +117,7 @@ class CHandler:
|
||||
#ifndef _7ZIP_ST
|
||||
decoder._numThreads = _numThreads;
|
||||
#endif
|
||||
decoder._memUsage = _memUsage;
|
||||
decoder._memUsage = _memUsage_Decompress;
|
||||
|
||||
HRESULT hres = decoder.Decode(seqInStream, outStream,
|
||||
NULL, // *outSizeLimit
|
||||
@@ -1129,14 +1129,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
if (IntToBool(newData))
|
||||
{
|
||||
UInt64 size;
|
||||
UInt64 dataSize;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = prop.uhVal.QuadPart;
|
||||
RINOK(updateCallback->SetTotal(size));
|
||||
dataSize = prop.uhVal.QuadPart;
|
||||
RINOK(updateCallback->SetTotal(dataSize));
|
||||
}
|
||||
|
||||
NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder;
|
||||
@@ -1147,17 +1147,79 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
lzma2Props.lzmaProps.level = GetLevel();
|
||||
|
||||
xzProps.reduceSize = size;
|
||||
xzProps.reduceSize = dataSize;
|
||||
/*
|
||||
{
|
||||
NCOM::CPropVariant prop = (UInt64)size;
|
||||
NCOM::CPropVariant prop = (UInt64)dataSize;
|
||||
RINOK(encoderSpec->SetCoderProp(NCoderPropID::kReduceSize, prop));
|
||||
}
|
||||
*/
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
xzProps.numTotalThreads = (int)_numThreads;
|
||||
#endif
|
||||
|
||||
UInt32 numThreads = _numThreads;
|
||||
|
||||
const UInt32 kNumThreads_Max = 1024;
|
||||
if (numThreads > kNumThreads_Max)
|
||||
numThreads = kNumThreads_Max;
|
||||
|
||||
if (!_numThreads_WasForced
|
||||
&& _numThreads >= 1
|
||||
&& _memUsage_WasSet)
|
||||
{
|
||||
COneMethodInfo oneMethodInfo;
|
||||
if (!_methods.IsEmpty())
|
||||
oneMethodInfo = _methods[0];
|
||||
|
||||
SetGlobalLevelTo(oneMethodInfo);
|
||||
|
||||
const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0);
|
||||
if (!numThreads_WasSpecifiedInMethod)
|
||||
{
|
||||
// here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already
|
||||
CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, numThreads);
|
||||
}
|
||||
|
||||
UInt64 cs = _numSolidBytes;
|
||||
if (cs != XZ_PROPS__BLOCK_SIZE__AUTO)
|
||||
oneMethodInfo.AddProp_BlockSize2(cs);
|
||||
cs = oneMethodInfo.Get_Xz_BlockSize();
|
||||
|
||||
if (cs != XZ_PROPS__BLOCK_SIZE__AUTO &&
|
||||
cs != XZ_PROPS__BLOCK_SIZE__SOLID)
|
||||
{
|
||||
const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads();
|
||||
const UInt32 numBlockThreads_Original = numThreads / lzmaThreads;
|
||||
|
||||
if (numBlockThreads_Original > 1)
|
||||
{
|
||||
UInt32 numBlockThreads = numBlockThreads_Original;
|
||||
{
|
||||
const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false);
|
||||
for (; numBlockThreads > 1; numBlockThreads--)
|
||||
{
|
||||
UInt64 size = numBlockThreads * (lzmaMemUsage + cs);
|
||||
UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1;
|
||||
if (cs < ((UInt32)1 << 26)) numPackChunks++;
|
||||
if (cs < ((UInt32)1 << 24)) numPackChunks++;
|
||||
if (cs < ((UInt32)1 << 22)) numPackChunks++;
|
||||
size += numPackChunks * cs;
|
||||
// printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20));
|
||||
if (size <= _memUsage_Compress)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (numBlockThreads == 0)
|
||||
numBlockThreads = 1;
|
||||
if (numBlockThreads != numBlockThreads_Original)
|
||||
numThreads = numBlockThreads * lzmaThreads;
|
||||
}
|
||||
}
|
||||
}
|
||||
xzProps.numTotalThreads = (int)numThreads;
|
||||
|
||||
#endif // _7ZIP_ST
|
||||
|
||||
|
||||
xzProps.blockSize = _numSolidBytes;
|
||||
if (_numSolidBytes == XZ_PROPS__BLOCK_SIZE__SOLID)
|
||||
|
||||
@@ -1665,7 +1665,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
m_Archive, item, realOutStream, extractCallback,
|
||||
progress,
|
||||
#ifndef _7ZIP_ST
|
||||
_props._numThreads, _props._memUsage,
|
||||
_props._numThreads, _props._memUsage_Decompress,
|
||||
#endif
|
||||
res);
|
||||
|
||||
|
||||
@@ -989,7 +989,8 @@ bool CInArchive::ReadFileName(unsigned size, AString &s)
|
||||
|
||||
|
||||
bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
|
||||
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk)
|
||||
UInt64 &unpackSize, UInt64 &packSize,
|
||||
CItem *cdItem)
|
||||
{
|
||||
extra.Clear();
|
||||
|
||||
@@ -1018,17 +1019,39 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
|
||||
extra.IsZip64 = true;
|
||||
bool isOK = true;
|
||||
|
||||
if (!cdItem
|
||||
&& size == 16
|
||||
&& !ZIP64_IS_32_MAX(unpackSize)
|
||||
&& !ZIP64_IS_32_MAX(packSize))
|
||||
{
|
||||
/* Win10 Explorer's "Send to Zip" for big (3500 MiB) files
|
||||
creates Zip64 Extra in local file header.
|
||||
But if both uncompressed and compressed sizes are smaller than 4 GiB,
|
||||
Win10 doesn't store 0xFFFFFFFF in 32-bit fields as expected by zip specification.
|
||||
21.04: we ignore these minor errors in Win10 zip archives. */
|
||||
if (ReadUInt64() != unpackSize)
|
||||
isOK = false;
|
||||
if (ReadUInt64() != packSize)
|
||||
isOK = false;
|
||||
size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ZIP64_IS_32_MAX(unpackSize))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }}
|
||||
|
||||
if (isOK && ZIP64_IS_32_MAX(packSize))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }}
|
||||
|
||||
if (isOK && ZIP64_IS_32_MAX(localOffset))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; localOffset = ReadUInt64(); }}
|
||||
if (cdItem)
|
||||
{
|
||||
if (isOK && ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; cdItem->LocalHeaderPos = ReadUInt64(); }}
|
||||
|
||||
if (isOK && ZIP64_IS_16_MAX(disk))
|
||||
{ if (size < 4) isOK = false; else { size -= 4; disk = ReadUInt32(); }}
|
||||
if (isOK && ZIP64_IS_16_MAX(cdItem->Disk))
|
||||
{ if (size < 4) isOK = false; else { size -= 4; cdItem->Disk = ReadUInt32(); }}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOK || size != 0)
|
||||
{
|
||||
@@ -1100,9 +1123,7 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
|
||||
|
||||
if (extraSize > 0)
|
||||
{
|
||||
UInt64 localOffset = 0;
|
||||
UInt32 disk = 0;
|
||||
if (!ReadExtra(item, extraSize, item.LocalExtra, item.Size, item.PackSize, localOffset, disk))
|
||||
if (!ReadExtra(item, extraSize, item.LocalExtra, item.Size, item.PackSize, NULL))
|
||||
{
|
||||
/* Most of archives are OK for Extra. But there are some rare cases
|
||||
that have error. And if error in first item, it can't open archive.
|
||||
@@ -1557,7 +1578,7 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
|
||||
ReadFileName(nameSize, item.Name);
|
||||
|
||||
if (extraSize > 0)
|
||||
ReadExtra(item, extraSize, item.CentralExtra, item.Size, item.PackSize, item.LocalHeaderPos, item.Disk);
|
||||
ReadExtra(item, extraSize, item.CentralExtra, item.Size, item.PackSize, &item);
|
||||
|
||||
// May be these strings must be deleted
|
||||
/*
|
||||
|
||||
@@ -312,7 +312,7 @@ class CInArchive
|
||||
bool ReadFileName(unsigned nameSize, AString &dest);
|
||||
|
||||
bool ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
|
||||
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk);
|
||||
UInt64 &unpackSize, UInt64 &packSize, CItem *cdItem);
|
||||
bool ReadLocalItem(CItemEx &item);
|
||||
HRESULT FindDescriptor(CItemEx &item, unsigned numFiles);
|
||||
HRESULT ReadCdItem(CItemEx &item);
|
||||
|
||||
@@ -773,7 +773,7 @@ static HRESULT Update2(
|
||||
if (numThreads < 1)
|
||||
numThreads = 1;
|
||||
|
||||
const size_t kMemPerThread = (size_t)1 << 25;
|
||||
const size_t kMemPerThread = (size_t)sizeof(size_t) << 23;
|
||||
const size_t kBlockSize = 1 << 16;
|
||||
|
||||
bool mtMode = (numThreads > 1);
|
||||
@@ -791,6 +791,7 @@ static HRESULT Update2(
|
||||
|
||||
if (onem.FindProp(NCoderPropID::kNumThreads) < 0)
|
||||
{
|
||||
// fixme: we should check the number of threads for xz mehod also
|
||||
// fixed for 9.31. bzip2 default is just one thread.
|
||||
onem.AddProp_NumThreads(numThreads);
|
||||
}
|
||||
@@ -828,6 +829,7 @@ static HRESULT Update2(
|
||||
int numXzThreads = oneMethodMain->Get_Xz_NumThreads(numLzmaThreads);
|
||||
if (numXzThreads < 0)
|
||||
{
|
||||
// numXzThreads is unknown
|
||||
const UInt64 averageSize = numBytesToCompress / numFilesToCompress;
|
||||
const UInt64 blockSize = oneMethodMain->Get_Xz_BlockSize();
|
||||
UInt64 averageNumberOfBlocks = 1;
|
||||
@@ -844,18 +846,52 @@ static HRESULT Update2(
|
||||
}
|
||||
numThreads /= (unsigned)numXzThreads;
|
||||
}
|
||||
else if (
|
||||
method == NFileHeader::NCompressionMethod::kDeflate
|
||||
|| method == NFileHeader::NCompressionMethod::kDeflate64
|
||||
|| method == NFileHeader::NCompressionMethod::kPPMd)
|
||||
{
|
||||
if (numThreads > 1
|
||||
&& options._memUsage_WasSet
|
||||
&& !options._numThreads_WasForced)
|
||||
{
|
||||
UInt64 methodMemUsage;
|
||||
if (method == NFileHeader::NCompressionMethod::kPPMd)
|
||||
methodMemUsage = oneMethodMain->Get_Ppmd_MemSize();
|
||||
else
|
||||
methodMemUsage = (4 << 20); // for deflate
|
||||
const UInt64 threadMemUsage = kMemPerThread + methodMemUsage;
|
||||
const UInt64 numThreads64 = options._memUsage_Compress / threadMemUsage;
|
||||
if (numThreads64 < numThreads)
|
||||
numThreads = (UInt32)numThreads64;
|
||||
}
|
||||
}
|
||||
else if (method == NFileHeader::NCompressionMethod::kLZMA)
|
||||
{
|
||||
// we suppose that default LZMA is 2 thread. So we don't change it
|
||||
UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads();
|
||||
const UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads();
|
||||
numThreads /= numLZMAThreads;
|
||||
|
||||
if (numThreads > 1
|
||||
&& options._memUsage_WasSet
|
||||
&& !options._numThreads_WasForced)
|
||||
{
|
||||
const UInt64 methodMemUsage = oneMethodMain->Get_Lzma_MemUsage(true);
|
||||
const UInt64 threadMemUsage = kMemPerThread + methodMemUsage;
|
||||
const UInt64 numThreads64 = options._memUsage_Compress / threadMemUsage;
|
||||
if (numThreads64 < numThreads)
|
||||
numThreads = (UInt32)numThreads64;
|
||||
}
|
||||
}
|
||||
} // (oneMethodMain)
|
||||
|
||||
if (numThreads > numFilesToCompress)
|
||||
numThreads = (UInt32)numFilesToCompress;
|
||||
if (numThreads <= 1)
|
||||
{
|
||||
mtMode = false;
|
||||
numThreads = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// mtMode = true; // to test mtMode for seqMode
|
||||
|
||||
@@ -294,6 +294,14 @@ SOURCE=..\..\..\Common\DynamicBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -7,6 +7,7 @@ COMMON_OBJS = \
|
||||
$O\CommandLineParser.obj \
|
||||
$O\CRC.obj \
|
||||
$O\CrcReg.obj \
|
||||
$O\DynLimBuf.obj \
|
||||
$O\IntToString.obj \
|
||||
$O\ListFileUtils.obj \
|
||||
$O\LzFindPrepare.obj \
|
||||
|
||||
@@ -108,6 +108,7 @@ COMMON_OBJS = \
|
||||
$O/CommandLineParser.o \
|
||||
$O/CRC.o \
|
||||
$O/CrcReg.o \
|
||||
$O/DynLimBuf.o \
|
||||
$O/IntToString.o \
|
||||
$O/ListFileUtils.o \
|
||||
$O/LzFindPrepare.o \
|
||||
|
||||
@@ -290,6 +290,14 @@ SOURCE=..\..\..\Common\DynamicBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -8,6 +8,7 @@ COMMON_OBJS = \
|
||||
$O\CommandLineParser.obj \
|
||||
$O\CRC.obj \
|
||||
$O\CrcReg.obj \
|
||||
$O\DynLimBuf.obj \
|
||||
$O\IntToString.obj \
|
||||
$O\ListFileUtils.obj \
|
||||
$O\LzFindPrepare.obj \
|
||||
|
||||
@@ -73,6 +73,7 @@ LOCAL_FLAGS = \
|
||||
CONSOLE_OBJS = \
|
||||
$O/BenchCon.o \
|
||||
$O/ConsoleClose.o \
|
||||
$O/DynLimBuf.o \
|
||||
$O/ExtractCallbackConsole.o \
|
||||
$O/HashCon.o \
|
||||
$O/List.o \
|
||||
|
||||
@@ -1084,6 +1084,20 @@ SOURCE=..\..\..\..\C\MtDec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sha1.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sha1.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sha1Opt.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sha256.c
|
||||
|
||||
!IF "$(CFG)" == "FM - Win32 Release"
|
||||
@@ -1133,6 +1147,16 @@ SOURCE=..\..\..\..\C\Threads.c
|
||||
|
||||
SOURCE=..\..\..\..\C\Threads.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\XzCrc64.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\XzCrc64Opt.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
@@ -1483,6 +1507,14 @@ SOURCE=..\..\..\Common\DynamicBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Exception.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -1563,10 +1595,22 @@ SOURCE=..\..\..\Common\Random.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Sha1Prepare.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Sha1Reg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Sha256Prepare.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Sha256Reg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -1601,6 +1645,14 @@ SOURCE=..\..\..\Common\Wildcard.cpp
|
||||
|
||||
SOURCE=..\..\..\Common\Wildcard.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\XzCrc64Init.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\XzCrc64Reg.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "UI"
|
||||
|
||||
|
||||
@@ -537,6 +537,14 @@ SOURCE=..\..\..\Windows\Control\ListView.h
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Clipboard.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Clipboard.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\CommonDialog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -593,6 +601,14 @@ SOURCE=..\..\..\Windows\FileName.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\MemoryGlobal.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\MemoryGlobal.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariant.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -31,6 +31,7 @@ COMMON_OBJS = \
|
||||
$O\Wildcard.obj \
|
||||
|
||||
WIN_OBJS = \
|
||||
$O\Clipboard.obj \
|
||||
$O\CommonDialog.obj \
|
||||
$O\DLL.obj \
|
||||
$O\ErrorMsg.obj \
|
||||
@@ -38,6 +39,7 @@ WIN_OBJS = \
|
||||
$O\FileFind.obj \
|
||||
$O\FileIO.obj \
|
||||
$O\FileName.obj \
|
||||
$O\MemoryGlobal.obj \
|
||||
$O\PropVariant.obj \
|
||||
$O\PropVariantConv.obj \
|
||||
$O\ResourceString.obj \
|
||||
|
||||
@@ -118,6 +118,7 @@ HRESULT CExternalCodecs::Load()
|
||||
}
|
||||
RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
|
||||
RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
|
||||
RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kIsFilter, info.IsFilter));
|
||||
|
||||
Codecs.Add(info);
|
||||
}
|
||||
|
||||
@@ -35,8 +35,9 @@ struct CCodecInfoEx
|
||||
UInt32 NumStreams;
|
||||
bool EncoderIsAssigned;
|
||||
bool DecoderIsAssigned;
|
||||
bool IsFilter; // it's unused
|
||||
|
||||
CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {}
|
||||
CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false), IsFilter(false) {}
|
||||
};
|
||||
|
||||
struct CHasherInfoEx
|
||||
|
||||
@@ -53,7 +53,7 @@ static unsigned ParseStringToUInt64(const UString &srcString, UInt64 &number)
|
||||
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
||||
{
|
||||
// =VT_UI4
|
||||
// =VT_EMPTY
|
||||
// =VT_EMPTY : it doesn't change (resValue), and returns S_OK
|
||||
// {stringUInt32}=VT_EMPTY
|
||||
|
||||
if (prop.vt == VT_UI4)
|
||||
@@ -74,30 +74,91 @@ HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
|
||||
|
||||
|
||||
HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force)
|
||||
{
|
||||
force = false;
|
||||
UString s;
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
switch (prop.vt)
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
case VT_UI4:
|
||||
numThreads = prop.ulVal;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
bool val;
|
||||
RINOK(PROPVARIANT_to_bool(prop, val));
|
||||
numThreads = (val ? defaultNumThreads : 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
force = true;
|
||||
return S_OK;
|
||||
}
|
||||
bool val;
|
||||
HRESULT res = PROPVARIANT_to_bool(prop, val);
|
||||
if (res == S_OK)
|
||||
{
|
||||
if (!val)
|
||||
{
|
||||
numThreads = 1;
|
||||
force = true;
|
||||
}
|
||||
// force = true; for debug
|
||||
// "(VT_BOOL = VARIANT_TRUE)" set "force = false" and doesn't change numThreads
|
||||
return S_OK;
|
||||
}
|
||||
if (prop.vt != VT_BSTR)
|
||||
return res;
|
||||
s.SetFromBstr(prop.bstrVal);
|
||||
if (s.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prop.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
return ParsePropToUInt32(name, prop, numThreads);
|
||||
s = name;
|
||||
}
|
||||
|
||||
s.MakeLower_Ascii();
|
||||
const wchar_t *start = s;
|
||||
UInt32 v = numThreads;
|
||||
|
||||
/* we force up, if threads number specified
|
||||
only `d` will force it down */
|
||||
bool force_loc = true;
|
||||
for (;;)
|
||||
{
|
||||
const wchar_t c = *start;
|
||||
if (!c)
|
||||
break;
|
||||
if (c == 'd')
|
||||
{
|
||||
force_loc = false; // force down
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
if (c == 'u')
|
||||
{
|
||||
force_loc = true; // force up
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
bool isPercent = false;
|
||||
if (c == 'p')
|
||||
{
|
||||
isPercent = true;
|
||||
start++;
|
||||
}
|
||||
const wchar_t *end;
|
||||
v = ConvertStringToUInt32(start, &end);
|
||||
if (end == start)
|
||||
return E_INVALIDARG;
|
||||
if (isPercent)
|
||||
v = numThreads * v / 100;
|
||||
start = end;
|
||||
}
|
||||
|
||||
numThreads = v;
|
||||
force = force_loc;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static HRESULT SetLogSizeProp(UInt64 number, NCOM::CPropVariant &destProp)
|
||||
{
|
||||
@@ -263,9 +324,9 @@ HRESULT CProps::SetCoderProps_DSReduce_Aff(
|
||||
|
||||
int CMethodProps::FindProp(PROPID id) const
|
||||
{
|
||||
for (int i = (int)Props.Size() - 1; i >= 0; i--)
|
||||
if (Props[(unsigned)i].Id == id)
|
||||
return i;
|
||||
for (unsigned i = Props.Size(); i != 0;)
|
||||
if (Props[--i].Id == id)
|
||||
return (int)i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -511,6 +572,59 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads)
|
||||
{
|
||||
UInt32 hs = dict - 1;
|
||||
hs |= (hs >> 1);
|
||||
hs |= (hs >> 2);
|
||||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
if (hs >= (1 << 24))
|
||||
hs >>= 1;
|
||||
hs |= (1 << 16) - 1;
|
||||
// if (numHashBytes >= 5)
|
||||
if (!isBt)
|
||||
hs |= (256 << 10) - 1;
|
||||
hs++;
|
||||
UInt64 size1 = (UInt64)hs * 4;
|
||||
size1 += (UInt64)dict * 4;
|
||||
if (isBt)
|
||||
size1 += (UInt64)dict * 4;
|
||||
size1 += (2 << 20);
|
||||
|
||||
if (numThreads > 1 && isBt)
|
||||
size1 += (2 << 20) + (4 << 20);
|
||||
return size1;
|
||||
}
|
||||
|
||||
static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28;
|
||||
|
||||
UInt64 CMethodProps::Get_Lzma_MemUsage(bool addSlidingWindowSize) const
|
||||
{
|
||||
const UInt64 dicSize = Get_Lzma_DicSize();
|
||||
const bool isBt = Get_Lzma_MatchFinder_IsBt();
|
||||
const UInt32 dict32 = (dicSize >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dicSize);
|
||||
const UInt32 numThreads = Get_Lzma_NumThreads();
|
||||
UInt64 size = GetMemoryUsage_LZMA(dict32, isBt, numThreads);
|
||||
|
||||
if (addSlidingWindowSize)
|
||||
{
|
||||
const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16);
|
||||
UInt64 blockSize = (UInt64)dict32 + (1 << 16)
|
||||
+ (numThreads > 1 ? (1 << 20) : 0);
|
||||
blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2));
|
||||
if (blockSize >= kBlockSizeMax)
|
||||
blockSize = kBlockSizeMax;
|
||||
size += blockSize;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
|
||||
{
|
||||
MethodName.Empty();
|
||||
|
||||
@@ -12,12 +12,27 @@
|
||||
|
||||
#include "../ICoder.h"
|
||||
|
||||
// UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads);
|
||||
|
||||
bool StringToBool(const wchar_t *s, bool &res);
|
||||
HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
|
||||
unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number);
|
||||
|
||||
/*
|
||||
if (name.IsEmpty() && prop.vt == VT_EMPTY), it doesn't change (resValue) and returns S_OK.
|
||||
So you must set (resValue) for default value before calling */
|
||||
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
||||
|
||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
|
||||
/* input: (numThreads = the_number_of_processors) */
|
||||
HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force);
|
||||
|
||||
inline HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 numCPUs, UInt32 &numThreads)
|
||||
{
|
||||
bool forced = false;
|
||||
numThreads = numCPUs;
|
||||
return ParseMtProp2(name, prop, numThreads, forced);
|
||||
}
|
||||
|
||||
|
||||
struct CProp
|
||||
{
|
||||
@@ -123,9 +138,21 @@ public:
|
||||
return dictSize;
|
||||
}
|
||||
|
||||
bool Get_Lzma_MatchFinder_IsBt() const
|
||||
{
|
||||
const int i = FindProp(NCoderPropID::kMatchFinder);
|
||||
if (i >= 0)
|
||||
{
|
||||
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
||||
if (val.vt == VT_BSTR)
|
||||
return ((val.bstrVal[0] | 0x20) != 'h'); // check for "hc"
|
||||
}
|
||||
return GetLevel() >= 5;
|
||||
}
|
||||
|
||||
bool Get_Lzma_Eos() const
|
||||
{
|
||||
int i = FindProp(NCoderPropID::kEndMarker);
|
||||
const int i = FindProp(NCoderPropID::kEndMarker);
|
||||
if (i >= 0)
|
||||
{
|
||||
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
||||
@@ -153,6 +180,9 @@ public:
|
||||
return 2;
|
||||
}
|
||||
|
||||
UInt64 Get_Lzma_MemUsage(bool addSlidingWindowSize) const;
|
||||
|
||||
/* returns -1, if numThreads is unknown */
|
||||
int Get_Xz_NumThreads(UInt32 &lzmaThreads) const
|
||||
{
|
||||
lzmaThreads = 1;
|
||||
@@ -191,6 +221,7 @@ public:
|
||||
const UInt32 kMinSize = (UInt32)1 << 20;
|
||||
const UInt32 kMaxSize = (UInt32)1 << 28;
|
||||
const UInt64 dictSize = Get_Lzma_DicSize();
|
||||
/* lzma2 code uses fake 4 GiB to calculate ChunkSize. So we do same */
|
||||
UInt64 blockSize = (UInt64)dictSize << 2;
|
||||
if (blockSize < kMinSize) blockSize = kMinSize;
|
||||
if (blockSize > kMaxSize) blockSize = kMaxSize;
|
||||
@@ -268,6 +299,17 @@ public:
|
||||
AddPropBool(NCoderPropID::kEndMarker, eos);
|
||||
}
|
||||
|
||||
void AddProp_BlockSize2(UInt64 blockSize2)
|
||||
{
|
||||
if (FindProp(NCoderPropID::kBlockSize2) < 0)
|
||||
{
|
||||
CProp &prop = Props.AddNew();
|
||||
prop.IsOptional = true;
|
||||
prop.Id = NCoderPropID::kBlockSize2;
|
||||
prop.Value = blockSize2;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT ParseParamsFromString(const UString &srcString);
|
||||
HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
|
||||
};
|
||||
|
||||
@@ -11,8 +11,8 @@ class CBZip2Crc
|
||||
static UInt32 Table[256];
|
||||
public:
|
||||
static void InitTable();
|
||||
CBZip2Crc(): _value(0xFFFFFFFF) {};
|
||||
void Init() { _value = 0xFFFFFFFF; }
|
||||
CBZip2Crc(UInt32 initVal = 0xFFFFFFFF): _value(initVal) {};
|
||||
void Init(UInt32 initVal = 0xFFFFFFFF) { _value = initVal; }
|
||||
void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); }
|
||||
void UpdateByte(unsigned int b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); }
|
||||
UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
|
||||
|
||||
@@ -230,15 +230,12 @@ STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
|
||||
value->ulVal = (ULONG)codec.NumStreams;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case NMethodPropID::kIsFilter:
|
||||
// if (codec.IsFilter)
|
||||
{
|
||||
value->vt = VT_BOOL;
|
||||
value->boolVal = BoolToVARIANT_BOOL(codec.IsFilter);
|
||||
}
|
||||
break;
|
||||
*/
|
||||
/*
|
||||
case NMethodPropID::kDecoderFlags:
|
||||
{
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
11 IFolderScanProgress
|
||||
|
||||
20 IFileExtractCallback.h::IGetProp
|
||||
30 IFileExtractCallback.h::IFolderExtractToStreamCallback
|
||||
30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old)
|
||||
31 IFileExtractCallback.h::IFolderExtractToStreamCallback (new 21.04)
|
||||
|
||||
03 IStream.h
|
||||
|
||||
@@ -104,6 +105,7 @@
|
||||
80 IArchiveUpdateCallback
|
||||
82 IArchiveUpdateCallback2
|
||||
83 IArchiveUpdateCallbackFile
|
||||
84 IArchiveGetDiskProperty
|
||||
|
||||
A0 IOutArchive
|
||||
|
||||
|
||||
@@ -394,7 +394,8 @@ namespace NMethodPropID
|
||||
kDescription,
|
||||
kDecoderIsAssigned,
|
||||
kEncoderIsAssigned,
|
||||
kDigestSize
|
||||
kDigestSize,
|
||||
kIsFilter
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -103,6 +103,9 @@ enum
|
||||
kpidReadOnly,
|
||||
kpidOutName,
|
||||
kpidCopyLink,
|
||||
kpidArcFileName,
|
||||
kpidIsHash,
|
||||
|
||||
|
||||
kpid_NUM_DEFINED,
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ CCodecs *g_CodecsObj;
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CExternalCodecs g_ExternalCodecs;
|
||||
const CExternalCodecs *g_ExternalCodecs_Ptr;
|
||||
static CCodecs::CReleaser g_CodecsReleaser;
|
||||
#else
|
||||
extern
|
||||
@@ -53,6 +54,7 @@ void FreeGlobalCodecs()
|
||||
g_CodecsReleaser.Set(NULL);
|
||||
g_CodecsObj = NULL;
|
||||
g_ExternalCodecs.ClearAndRelease();
|
||||
g_ExternalCodecs_Ptr = NULL;
|
||||
#else
|
||||
g_CodecsRef.Release();
|
||||
#endif
|
||||
@@ -83,8 +85,11 @@ HRESULT LoadGlobalCodecs()
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
Codecs_AddHashArcHandler(g_CodecsObj);
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
RINOK(g_ExternalCodecs.Load());
|
||||
g_ExternalCodecs_Ptr = &g_ExternalCodecs;
|
||||
#endif
|
||||
|
||||
return S_OK;
|
||||
@@ -1223,7 +1228,11 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
|
||||
if (_agentSpec->Is_Attrib_ReadOnly())
|
||||
prop = true;
|
||||
else
|
||||
prop = _agentSpec->IsThereReadOnlyArc();
|
||||
prop = _agentSpec->IsThere_ReadOnlyArc();
|
||||
}
|
||||
else if (propID == kpidIsHash)
|
||||
{
|
||||
prop = _agentSpec->_isHashHandler;
|
||||
}
|
||||
else if (_proxy2)
|
||||
{
|
||||
@@ -1446,6 +1455,10 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
|
||||
IFolderArchiveExtractCallback *extractCallback2)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
|
||||
if (!testMode && _agentSpec->_isHashHandler)
|
||||
return E_NOTIMPL;
|
||||
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
UStringVector pathParts;
|
||||
@@ -1500,6 +1513,9 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
|
||||
if (_proxy2)
|
||||
extractCallbackSpec->SetBaseParentFolderIndex(_proxy2->Dirs[_proxyDirIndex].ArcIndex);
|
||||
|
||||
// do we need another base folder for subfolders ?
|
||||
extractCallbackSpec->DirPathPrefix_for_HashFiles = _agentSpec->_hashBaseFolderPrefix;
|
||||
|
||||
CUIntVector realIndices;
|
||||
GetRealIndices(indices, numItems, IntToBool(includeAltStreams),
|
||||
false, // includeFolderSubItemsInFlatMode
|
||||
@@ -1536,7 +1552,8 @@ CAgent::CAgent():
|
||||
_proxy(NULL),
|
||||
_proxy2(NULL),
|
||||
_updatePathPrefix_is_AltFolder(false),
|
||||
_isDeviceFile(false)
|
||||
_isDeviceFile(false),
|
||||
_isHashHandler(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1571,9 +1588,11 @@ STDMETHODIMP CAgent::Open(
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
_archiveFilePath = filePath;
|
||||
_hashBaseFolderPrefix.Empty();
|
||||
_attrib = 0;
|
||||
NFile::NFind::CFileInfo fi;
|
||||
_isDeviceFile = false;
|
||||
_isHashHandler = false;
|
||||
NFile::NFind::CFileInfo fi;
|
||||
if (!inStream)
|
||||
{
|
||||
if (!fi.Find(us2fs(_archiveFilePath)))
|
||||
@@ -1582,6 +1601,12 @@ STDMETHODIMP CAgent::Open(
|
||||
return E_FAIL;
|
||||
_attrib = fi.Attrib;
|
||||
_isDeviceFile = fi.IsDevice;
|
||||
FString dirPrefix, fileName;
|
||||
if (NFile::NDir::GetFullPathAndSplit(us2fs(_archiveFilePath), dirPrefix, fileName))
|
||||
{
|
||||
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
|
||||
_hashBaseFolderPrefix = dirPrefix;
|
||||
}
|
||||
}
|
||||
CArcInfoEx archiverInfo0, archiverInfo1;
|
||||
|
||||
@@ -1629,6 +1654,9 @@ STDMETHODIMP CAgent::Open(
|
||||
{
|
||||
RINOK(StringToBstr(ArchiveType, archiveType));
|
||||
}
|
||||
|
||||
if (arc.IsHashHandler(options))
|
||||
_isHashHandler = true;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -1745,6 +1773,10 @@ STDMETHODIMP CAgent::Extract(
|
||||
IFolderArchiveExtractCallback *extractCallback2)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
|
||||
if (!testMode && _isHashHandler)
|
||||
return E_NOTIMPL;
|
||||
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
extractCallbackSpec->InitForMulti(
|
||||
@@ -1769,6 +1801,8 @@ STDMETHODIMP CAgent::Extract(
|
||||
UStringVector(), false,
|
||||
(UInt64)(Int64)-1);
|
||||
|
||||
extractCallbackSpec->DirPathPrefix_for_HashFiles = _hashBaseFolderPrefix;
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
|
||||
if (!testMode)
|
||||
|
||||
@@ -234,7 +234,7 @@ public:
|
||||
UString ArchiveType;
|
||||
|
||||
FStringVector _names;
|
||||
FString _folderPrefix;
|
||||
FString _folderPrefix; // for new files from disk
|
||||
|
||||
bool _updatePathPrefix_is_AltFolder;
|
||||
UString _updatePathPrefix;
|
||||
@@ -243,6 +243,8 @@ public:
|
||||
UString _archiveFilePath;
|
||||
DWORD _attrib;
|
||||
bool _isDeviceFile;
|
||||
bool _isHashHandler;
|
||||
FString _hashBaseFolderPrefix;
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
CObjectVector<UString> m_PropNames;
|
||||
@@ -258,7 +260,7 @@ public:
|
||||
return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY);
|
||||
}
|
||||
|
||||
bool IsThereReadOnlyArc() const
|
||||
bool IsThere_ReadOnlyArc() const
|
||||
{
|
||||
FOR_VECTOR (i, _archiveLink.Arcs)
|
||||
{
|
||||
|
||||
@@ -158,6 +158,8 @@ static void SetInArchiveInterfaces(CAgent *agent, CArchiveUpdateCallback *upd)
|
||||
const CArc &arc = agent->GetArc();
|
||||
upd->Arc = &arc;
|
||||
upd->Archive = arc.Archive;
|
||||
|
||||
upd->ArcFileName = ExtractFileNameFromPath(arc.Path);
|
||||
}
|
||||
|
||||
struct CDirItemsCallback_AgentOut: public IDirItemsCallback
|
||||
@@ -190,6 +192,7 @@ struct CDirItemsCallback_AgentOut: public IDirItemsCallback
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
STDMETHODIMP CAgent::DoOperation(
|
||||
FStringVector *requestedPaths,
|
||||
FStringVector *processedPaths,
|
||||
|
||||
@@ -70,6 +70,9 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
const UInt32 *indices, UInt32 numItems,
|
||||
IProgress *progress)
|
||||
{
|
||||
if (moveMode && _agentSpec->_isHashHandler)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (!_agentSpec->CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ HRESULT CUpdateCallbackAgent::ReportExtractResult(Int32 opRes, Int32 isEncrypted
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir)
|
||||
HRESULT CUpdateCallbackAgent::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir)
|
||||
{
|
||||
if (Callback2)
|
||||
{
|
||||
|
||||
@@ -217,6 +217,7 @@ static const char * const kIncorrectCommand = "incorrect command";
|
||||
static const char * const kTestingString = "Testing ";
|
||||
static const char * const kExtractingString = "Extracting ";
|
||||
static const char * const kSkippingString = "Skipping ";
|
||||
static const char * const kReadingString = "Reading ";
|
||||
|
||||
static const char * const kUnsupportedMethod = "Unsupported Method";
|
||||
static const char * const kCRCFailed = "CRC Failed";
|
||||
@@ -419,6 +420,9 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
|
||||
case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break;
|
||||
case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break;
|
||||
case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break;
|
||||
case NArchive::NExtract::NAskMode::kReadExternal: Print(kReadingString); break;
|
||||
default:
|
||||
Print("??? "); break;
|
||||
};
|
||||
Print(_filePath);
|
||||
return S_OK;
|
||||
|
||||
@@ -133,6 +133,8 @@ enum Enum
|
||||
kSfx,
|
||||
kEmail,
|
||||
kHash,
|
||||
// kHashGenFile,
|
||||
kHashDir,
|
||||
|
||||
kStdIn,
|
||||
kStdOut,
|
||||
@@ -141,6 +143,7 @@ enum Enum
|
||||
kListfileCharSet,
|
||||
kConsoleCharSet,
|
||||
kTechMode,
|
||||
kListFields,
|
||||
|
||||
kPreserveATime,
|
||||
kShareForWrite,
|
||||
@@ -273,6 +276,8 @@ static const CSwitchForm kSwitchForms[] =
|
||||
{ "sfx", SWFRM_STRING },
|
||||
{ "seml", SWFRM_STRING_SINGL(0) },
|
||||
{ "scrc", SWFRM_STRING_MULT(0) },
|
||||
// { "scrf", SWFRM_STRING_SINGL(1) },
|
||||
{ "shd", SWFRM_STRING_SINGL(1) },
|
||||
|
||||
{ "si", SWFRM_STRING },
|
||||
{ "so", SWFRM_SIMPLE },
|
||||
@@ -281,6 +286,7 @@ static const CSwitchForm kSwitchForms[] =
|
||||
{ "scs", SWFRM_STRING },
|
||||
{ "scc", SWFRM_STRING },
|
||||
{ "slt", SWFRM_SIMPLE },
|
||||
{ "slf", SWFRM_STRING_SINGL(1) },
|
||||
|
||||
{ "ssp", SWFRM_SIMPLE },
|
||||
{ "ssw", SWFRM_SIMPLE },
|
||||
@@ -627,6 +633,20 @@ static void AddSwitchWildcardsToCensor(
|
||||
break;
|
||||
}
|
||||
|
||||
if (!include)
|
||||
{
|
||||
if (name.IsEqualTo_Ascii_NoCase("td"))
|
||||
{
|
||||
censor.ExcludeDirItems = true;
|
||||
continue;
|
||||
}
|
||||
if (name.IsEqualTo_Ascii_NoCase("tf"))
|
||||
{
|
||||
censor.ExcludeFileItems = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar)
|
||||
{
|
||||
pos++;
|
||||
@@ -875,6 +895,11 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
|
||||
options.StdInMode = parser[NKey::kStdIn].ThereIs;
|
||||
options.StdOutMode = parser[NKey::kStdOut].ThereIs;
|
||||
options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
|
||||
if (parser[NKey::kListFields].ThereIs)
|
||||
{
|
||||
const UString &s = parser[NKey::kListFields].PostStrings[0];
|
||||
options.ListFields = GetAnsiString(s);
|
||||
}
|
||||
options.TechMode = parser[NKey::kTechMode].ThereIs;
|
||||
options.ShowTime = parser[NKey::kShowTime].ThereIs;
|
||||
|
||||
@@ -1095,6 +1120,27 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
|
||||
if (parser[NKey::kHash].ThereIs)
|
||||
options.HashMethods = parser[NKey::kHash].PostStrings;
|
||||
|
||||
/*
|
||||
if (parser[NKey::kHashGenFile].ThereIs)
|
||||
{
|
||||
const UString &s = parser[NKey::kHashGenFile].PostStrings[0];
|
||||
for (unsigned i = 0 ; i < s.Len();)
|
||||
{
|
||||
const wchar_t c = s[i++];
|
||||
if (!options.HashOptions.ParseFlagCharOption(c, true))
|
||||
{
|
||||
if (c != '=')
|
||||
throw CArcCmdLineException("Unsupported hash mode switch:", s);
|
||||
options.HashOptions.HashFilePath = s.Ptr(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (parser[NKey::kHashDir].ThereIs)
|
||||
options.ExtractOptions.HashDir = parser[NKey::kHashDir].PostStrings[0];
|
||||
|
||||
if (parser[NKey::kElimDup].ThereIs)
|
||||
{
|
||||
options.ExtractOptions.ElimDup.Def = true;
|
||||
@@ -1232,6 +1278,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
|
||||
{
|
||||
CExtractOptionsBase &eo = options.ExtractOptions;
|
||||
|
||||
eo.ExcludeDirItems = options.Censor.ExcludeDirItems;
|
||||
eo.ExcludeFileItems = options.Censor.ExcludeFileItems;
|
||||
|
||||
{
|
||||
CExtractNtOptions &nt = eo.NtOptions;
|
||||
nt.NtSecurity = options.NtSecurity;
|
||||
@@ -1252,6 +1301,11 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
|
||||
|
||||
nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs;
|
||||
nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs;
|
||||
|
||||
if (parser[NKey::kPreserveATime].ThereIs)
|
||||
nt.PreserveATime = true;
|
||||
if (parser[NKey::kShareForWrite].ThereIs)
|
||||
nt.OpenShareForWrite = true;
|
||||
}
|
||||
|
||||
options.Censor.AddPathsToCensor(NWildcard::k_AbsPath);
|
||||
@@ -1422,6 +1476,7 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
|
||||
CHashOptions &hashOptions = options.HashOptions;
|
||||
hashOptions.PathMode = censorPathMode;
|
||||
hashOptions.Methods = options.HashMethods;
|
||||
// hashOptions.HashFilePath = options.HashFilePath;
|
||||
if (parser[NKey::kPreserveATime].ThereIs)
|
||||
hashOptions.PreserveATime = true;
|
||||
if (parser[NKey::kShareForWrite].ThereIs)
|
||||
|
||||
@@ -66,6 +66,8 @@ struct CArcCmdLineOptions
|
||||
bool TechMode;
|
||||
bool ShowTime;
|
||||
|
||||
AString ListFields;
|
||||
|
||||
int ConsoleCodePage;
|
||||
|
||||
NWildcard::CCensor Censor;
|
||||
@@ -79,6 +81,7 @@ struct CArcCmdLineOptions
|
||||
#endif
|
||||
|
||||
UStringVector HashMethods;
|
||||
// UString HashFilePath;
|
||||
|
||||
bool AppendName;
|
||||
// UStringVector ArchivePathsSorted;
|
||||
|
||||
@@ -47,6 +47,7 @@ static const char * const kCantRenameFile = "Cannot rename existing file";
|
||||
static const char * const kCantDeleteOutputFile = "Cannot delete output file";
|
||||
static const char * const kCantDeleteOutputDir = "Cannot delete output folder";
|
||||
static const char * const kCantOpenOutFile = "Cannot open output file";
|
||||
static const char * const kCantOpenInFile = "Cannot open input file";
|
||||
static const char * const kCantSetFileLen = "Cannot set length for output file";
|
||||
#ifdef SUPPORT_LINKS
|
||||
static const char * const kCantCreateHardLink = "Cannot create hard link";
|
||||
@@ -889,7 +890,8 @@ void CArchiveExtractCallback::CorrectPathParts()
|
||||
|
||||
void CArchiveExtractCallback::CreateFolders()
|
||||
{
|
||||
UStringVector &pathParts = _item.PathParts;
|
||||
// 21.04 : we don't change original (_item.PathParts) here
|
||||
UStringVector pathParts = _item.PathParts;
|
||||
|
||||
if (!_item.IsDir)
|
||||
{
|
||||
@@ -1078,18 +1080,19 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
|
||||
IInArchive *archive = _arc->Archive;
|
||||
#endif
|
||||
|
||||
const UStringVector &pathParts = _item.PathParts;
|
||||
const UInt32 index = _index;
|
||||
|
||||
bool isAnti = false;
|
||||
RINOK(_arc->IsItemAnti(index, isAnti));
|
||||
|
||||
CorrectPathParts();
|
||||
|
||||
UString processedPath (MakePathFromParts(pathParts));
|
||||
UString processedPath (MakePathFromParts(_item.PathParts));
|
||||
|
||||
if (!isAnti)
|
||||
{
|
||||
// 21.04: CreateFolders doesn't change (_item.PathParts)
|
||||
CreateFolders();
|
||||
}
|
||||
|
||||
FString fullProcessedPath (us2fs(processedPath));
|
||||
if (_pathMode != NExtract::NPathMode::kAbsPaths
|
||||
@@ -1295,7 +1298,25 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
|
||||
|
||||
|
||||
|
||||
HRESULT CArchiveExtractCallback::GetItem(UInt32 index)
|
||||
{
|
||||
#ifndef _SFX
|
||||
_item._use_baseParentFolder_mode = _use_baseParentFolder_mode;
|
||||
if (_use_baseParentFolder_mode)
|
||||
{
|
||||
_item._baseParentFolder = (int)_baseParentFolder;
|
||||
if (_pathMode == NExtract::NPathMode::kFullPaths ||
|
||||
_pathMode == NExtract::NPathMode::kAbsPaths)
|
||||
_item._baseParentFolder = -1;
|
||||
}
|
||||
#endif // _SFX
|
||||
|
||||
#ifdef SUPPORT_ALT_STREAMS
|
||||
_item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon;
|
||||
#endif
|
||||
|
||||
return _arc->GetItem(index, _item);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
|
||||
@@ -1339,22 +1360,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
|
||||
IInArchive *archive = _arc->Archive;
|
||||
|
||||
#ifndef _SFX
|
||||
_item._use_baseParentFolder_mode = _use_baseParentFolder_mode;
|
||||
if (_use_baseParentFolder_mode)
|
||||
{
|
||||
_item._baseParentFolder = (int)_baseParentFolder;
|
||||
if (_pathMode == NExtract::NPathMode::kFullPaths ||
|
||||
_pathMode == NExtract::NPathMode::kAbsPaths)
|
||||
_item._baseParentFolder = -1;
|
||||
}
|
||||
#endif // _SFX
|
||||
|
||||
#ifdef SUPPORT_ALT_STREAMS
|
||||
_item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon;
|
||||
#endif
|
||||
|
||||
RINOK(_arc->GetItem(index, _item));
|
||||
RINOK(GetItem(index));
|
||||
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
@@ -1382,6 +1388,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
return S_OK;
|
||||
#endif // SUPPORT_ALT_STREAMS
|
||||
|
||||
// we can change (_item.PathParts) in this function
|
||||
UStringVector &pathParts = _item.PathParts;
|
||||
|
||||
if (_wildcardCensor)
|
||||
@@ -1974,7 +1981,10 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
|
||||
|
||||
#ifndef _SFX
|
||||
if (ExtractToStreamCallback)
|
||||
return ExtractToStreamCallback->SetOperationResult7(opRes, BoolToInt(_encrypted));
|
||||
{
|
||||
GetUnpackSize();
|
||||
return ExtractToStreamCallback->SetOperationResult8(opRes, BoolToInt(_encrypted), _curSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
@@ -2103,6 +2113,82 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
|
||||
}
|
||||
|
||||
|
||||
// ---------- HASH functions ----------
|
||||
|
||||
FString CArchiveExtractCallback::Hash_GetFullFilePath()
|
||||
{
|
||||
// this function changes _item.PathParts.
|
||||
CorrectPathParts();
|
||||
const UStringVector &pathParts = _item.PathParts;
|
||||
const UString processedPath (MakePathFromParts(pathParts));
|
||||
FString fullProcessedPath (us2fs(processedPath));
|
||||
if (_pathMode != NExtract::NPathMode::kAbsPaths
|
||||
|| !NName::IsAbsolutePath(processedPath))
|
||||
{
|
||||
fullProcessedPath = MakePath_from_2_Parts(
|
||||
DirPathPrefix_for_HashFiles,
|
||||
// _dirPathPrefix,
|
||||
fullProcessedPath);
|
||||
}
|
||||
return fullProcessedPath;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
if (propID == kpidSize)
|
||||
{
|
||||
RINOK(GetItem(index));
|
||||
const FString fullProcessedPath = Hash_GetFullFilePath();
|
||||
NFile::NFind::CFileInfo fi;
|
||||
if (fi.Find_FollowLink(fullProcessedPath))
|
||||
if (!fi.IsDir())
|
||||
prop = (UInt64)fi.Size;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*inStream = NULL;
|
||||
// if (index != _index) return E_FAIL;
|
||||
if (mode != NUpdateNotifyOp::kHashRead)
|
||||
return E_FAIL;
|
||||
|
||||
RINOK(GetItem(index));
|
||||
const FString fullProcessedPath = Hash_GetFullFilePath();
|
||||
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<ISequentialInStream> inStreamRef = inStreamSpec;
|
||||
inStreamSpec->File.PreserveATime = _ntOptions.PreserveATime;
|
||||
if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite))
|
||||
{
|
||||
RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath));
|
||||
return S_OK;
|
||||
}
|
||||
*inStream = inStreamRef.Detach();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::ReportOperation(
|
||||
UInt32 /* indexType */, UInt32 /* index */, UInt32 /* op */)
|
||||
{
|
||||
// COM_TRY_BEGIN
|
||||
return S_OK;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
// ------------ After Extracting functions ------------
|
||||
|
||||
void CDirPathSortPair::SetNumSlashes(const FChar *s)
|
||||
{
|
||||
for (unsigned numSlashes = 0;;)
|
||||
|
||||
@@ -62,9 +62,15 @@ struct CExtractNtOptions
|
||||
|
||||
bool PreAllocateOutFile;
|
||||
|
||||
// used for hash arcs only, when we open external files
|
||||
bool PreserveATime;
|
||||
bool OpenShareForWrite;
|
||||
|
||||
CExtractNtOptions():
|
||||
ReplaceColonForAltStream(false),
|
||||
WriteToAltStreamIfColon(false)
|
||||
WriteToAltStreamIfColon(false),
|
||||
PreserveATime(false),
|
||||
OpenShareForWrite(false)
|
||||
{
|
||||
SymLinks.Val = true;
|
||||
SymLinks_AllowDangerous.Val = false;
|
||||
@@ -205,6 +211,8 @@ class CArchiveExtractCallback:
|
||||
public IArchiveExtractCallbackMessage,
|
||||
public ICryptoGetTextPassword,
|
||||
public ICompressProgressInfo,
|
||||
public IArchiveUpdateCallbackFile,
|
||||
public IArchiveGetDiskProperty,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
const CArc *_arc;
|
||||
@@ -342,6 +350,9 @@ class CArchiveExtractCallback:
|
||||
HRESULT GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
|
||||
HRESULT GetUnpackSize();
|
||||
|
||||
FString Hash_GetFullFilePath();
|
||||
|
||||
public:
|
||||
HRESULT SendMessageError(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);
|
||||
@@ -356,10 +367,20 @@ public:
|
||||
UInt64 UnpackSize;
|
||||
UInt64 AltStreams_UnpackSize;
|
||||
|
||||
MY_UNKNOWN_IMP3(IArchiveExtractCallbackMessage, ICryptoGetTextPassword, ICompressProgressInfo)
|
||||
FString DirPathPrefix_for_HashFiles;
|
||||
|
||||
MY_UNKNOWN_IMP5(
|
||||
IArchiveExtractCallbackMessage,
|
||||
ICryptoGetTextPassword,
|
||||
ICompressProgressInfo,
|
||||
IArchiveUpdateCallbackFile,
|
||||
IArchiveGetDiskProperty
|
||||
)
|
||||
|
||||
INTERFACE_IArchiveExtractCallback(;)
|
||||
INTERFACE_IArchiveExtractCallbackMessage(;)
|
||||
INTERFACE_IArchiveUpdateCallbackFile(;)
|
||||
INTERFACE_IArchiveGetDiskProperty(;)
|
||||
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
|
||||
@@ -453,6 +474,7 @@ private:
|
||||
bool _isRenamed;
|
||||
HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit);
|
||||
HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit);
|
||||
HRESULT GetItem(UInt32 index);
|
||||
|
||||
HRESULT CloseFile();
|
||||
HRESULT CloseReparseAndFile();
|
||||
|
||||
@@ -639,15 +639,22 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64
|
||||
|
||||
static const unsigned kSubBits = 8;
|
||||
|
||||
static UInt32 GetLogSize(UInt64 size)
|
||||
static unsigned GetLogSize(UInt64 size)
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (;;)
|
||||
{
|
||||
i++; size >>= 1; if (size == 0) break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static UInt32 GetLogSize_Sub(UInt64 size)
|
||||
{
|
||||
if (size <= 1)
|
||||
return 0;
|
||||
unsigned i;
|
||||
for (i = 2; i < 64; i++)
|
||||
if (size < ((UInt64)1 << i))
|
||||
break;
|
||||
i--;
|
||||
const unsigned i = GetLogSize(size) - 1;
|
||||
UInt32 v;
|
||||
if (i <= kSubBits)
|
||||
v = (UInt32)(size) << (kSubBits - i);
|
||||
@@ -656,14 +663,48 @@ static UInt32 GetLogSize(UInt64 size)
|
||||
return ((UInt32)i << kSubBits) + (v & (((UInt32)1 << kSubBits) - 1));
|
||||
}
|
||||
|
||||
static void NormalizeVals(UInt64 &v1, UInt64 &v2)
|
||||
|
||||
static UInt64 Get_UInt64_from_double(double v)
|
||||
{
|
||||
while (v1 >= ((UInt32)1 << ((64 - kBenchmarkUsageMultBits) / 2)))
|
||||
const UInt64 kMaxVal = (UInt64)1 << 62;
|
||||
if (v > (double)(Int64)kMaxVal)
|
||||
return kMaxVal;
|
||||
return (UInt64)v;
|
||||
}
|
||||
|
||||
static UInt64 MyMultDiv64(UInt64 m1, UInt64 m2, UInt64 d)
|
||||
{
|
||||
v1 >>= 1;
|
||||
v2 >>= 1;
|
||||
if (d == 0)
|
||||
d = 1;
|
||||
const double v =
|
||||
(double)(Int64)m1 *
|
||||
(double)(Int64)m2 /
|
||||
(double)(Int64)d;
|
||||
return Get_UInt64_from_double(v);
|
||||
/*
|
||||
unsigned n1 = GetLogSize(m1);
|
||||
unsigned n2 = GetLogSize(m2);
|
||||
while (n1 + n2 > 64)
|
||||
{
|
||||
if (n1 >= n2)
|
||||
{
|
||||
m1 >>= 1;
|
||||
n1--;
|
||||
}
|
||||
else
|
||||
{
|
||||
m2 >>= 1;
|
||||
n2--;
|
||||
}
|
||||
d >>= 1;
|
||||
}
|
||||
|
||||
if (d == 0)
|
||||
d = 1;
|
||||
return m1 * m2 / d;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
UInt64 CBenchInfo::GetUsage() const
|
||||
{
|
||||
@@ -671,45 +712,52 @@ UInt64 CBenchInfo::GetUsage() const
|
||||
UInt64 userFreq = UserFreq;
|
||||
UInt64 globalTime = GlobalTime;
|
||||
UInt64 globalFreq = GlobalFreq;
|
||||
NormalizeVals(userTime, userFreq);
|
||||
NormalizeVals(globalFreq, globalTime);
|
||||
|
||||
if (userFreq == 0)
|
||||
userFreq = 1;
|
||||
if (globalTime == 0)
|
||||
globalTime = 1;
|
||||
return userTime * globalFreq * kBenchmarkUsageMult / userFreq / globalTime;
|
||||
|
||||
const double v =
|
||||
((double)(Int64)userTime / (double)(Int64)userFreq)
|
||||
* ((double)(Int64)globalFreq / (double)(Int64)globalTime)
|
||||
* (double)(Int64)kBenchmarkUsageMult;
|
||||
return Get_UInt64_from_double(v);
|
||||
/*
|
||||
return MyMultDiv64(
|
||||
MyMultDiv64(kBenchmarkUsageMult, userTime, userFreq),
|
||||
globalFreq, globalTime);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
UInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const
|
||||
{
|
||||
UInt64 userTime = UserTime;
|
||||
UInt64 userFreq = UserFreq;
|
||||
UInt64 globalTime = GlobalTime;
|
||||
UInt64 globalFreq = GlobalFreq;
|
||||
NormalizeVals(userFreq, userTime);
|
||||
NormalizeVals(globalTime, globalFreq);
|
||||
if (globalFreq == 0)
|
||||
globalFreq = 1;
|
||||
if (userTime == 0)
|
||||
if (UserTime == 0)
|
||||
{
|
||||
return 0;
|
||||
// userTime = 1;
|
||||
}
|
||||
return userFreq * globalTime / globalFreq * rating / userTime;
|
||||
UInt64 globalFreq = GlobalFreq;
|
||||
if (globalFreq == 0)
|
||||
globalFreq = 1;
|
||||
|
||||
const double v =
|
||||
((double)(Int64)GlobalTime / (double)(Int64)globalFreq)
|
||||
* ((double)(Int64)UserFreq / (double)(Int64)UserTime)
|
||||
* (double)(Int64)rating;
|
||||
return Get_UInt64_from_double(v);
|
||||
/*
|
||||
return MyMultDiv64(
|
||||
MyMultDiv64(rating, UserFreq, UserTime),
|
||||
GlobalTime, globalFreq);
|
||||
*/
|
||||
}
|
||||
|
||||
static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
|
||||
{
|
||||
UInt64 elTime = elapsedTime;
|
||||
NormalizeVals(freq, elTime);
|
||||
if (elTime == 0)
|
||||
elTime = 1;
|
||||
return value * freq / elTime;
|
||||
}
|
||||
|
||||
UInt64 CBenchInfo::GetSpeed(UInt64 numUnits) const
|
||||
{
|
||||
return MyMultDiv64(numUnits, GlobalTime, GlobalFreq);
|
||||
return MyMultDiv64(numUnits, GlobalFreq, GlobalTime);
|
||||
}
|
||||
|
||||
struct CBenchProps
|
||||
@@ -764,24 +812,24 @@ UInt64 CBenchProps::GetCompressRating(UInt64 dictSize, UInt64 elapsedTime, UInt6
|
||||
/*
|
||||
for (UInt64 uu = 0; uu < (UInt64)0xf << 60;)
|
||||
{
|
||||
unsigned rr = GetLogSize(uu);
|
||||
unsigned rr = GetLogSize_Sub(uu);
|
||||
printf("\n%16I64x , log = %4x", uu, rr);
|
||||
uu += 1;
|
||||
uu += uu / 50;
|
||||
}
|
||||
*/
|
||||
// throw 1;
|
||||
const UInt32 t = GetLogSize(dictSize) - (kBenchMinDicLogSize << kSubBits);
|
||||
const UInt32 t = GetLogSize_Sub(dictSize) - (kBenchMinDicLogSize << kSubBits);
|
||||
encComplex = 870 + ((t * t * 5) >> (2 * kSubBits));
|
||||
}
|
||||
const UInt64 numCommands = (UInt64)size * encComplex;
|
||||
return MyMultDiv64(numCommands, elapsedTime, freq);
|
||||
return MyMultDiv64(numCommands, freq, elapsedTime);
|
||||
}
|
||||
|
||||
UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations)
|
||||
{
|
||||
const UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations;
|
||||
return MyMultDiv64(numCommands, elapsedTime, freq);
|
||||
return MyMultDiv64(numCommands, freq, elapsedTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -2675,8 +2723,8 @@ void CTotalBenchRes::Mult_For_Weight(unsigned weight)
|
||||
NumIterations2 *= weight;
|
||||
RPU *= weight;
|
||||
Rating *= weight;
|
||||
Usage += weight;
|
||||
Speed += weight;
|
||||
Usage *= weight;
|
||||
Speed *= weight;
|
||||
}
|
||||
|
||||
void CTotalBenchRes::Update_With_Res(const CTotalBenchRes &r)
|
||||
@@ -3712,7 +3760,7 @@ HRESULT Bench(
|
||||
start = 1;
|
||||
const UInt64 freq = GetFreq();
|
||||
// mips is constant in some compilers
|
||||
const UInt64 hz = MyMultDiv64(numMilCommands * 1000000, start, freq);
|
||||
const UInt64 hz = MyMultDiv64(numMilCommands * 1000000, freq, start);
|
||||
const UInt64 mipsVal = numMilCommands * freq / start;
|
||||
if (printCallback)
|
||||
{
|
||||
|
||||
@@ -265,22 +265,56 @@ void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bo
|
||||
MY_TRY_FINISH_VOID
|
||||
}
|
||||
|
||||
void TestArchives(const UStringVector &arcPaths)
|
||||
|
||||
void TestArchives(const UStringVector &arcPaths, bool hashMode)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
UString params ('t');
|
||||
if (hashMode)
|
||||
{
|
||||
params += kArchiveTypeSwitch;
|
||||
params += "hash";
|
||||
}
|
||||
ExtractGroupCommand(arcPaths, params, false);
|
||||
MY_TRY_FINISH_VOID
|
||||
}
|
||||
|
||||
void CalcChecksum(const UStringVector &paths, const UString &methodName)
|
||||
|
||||
void CalcChecksum(const UStringVector &paths,
|
||||
const UString &methodName,
|
||||
const UString &arcPathPrefix,
|
||||
const UString &arcFileName)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
|
||||
if (!arcFileName.IsEmpty())
|
||||
{
|
||||
CompressFiles(
|
||||
arcPathPrefix,
|
||||
arcFileName,
|
||||
UString("hash"),
|
||||
false, // addExtension,
|
||||
paths,
|
||||
false, // email,
|
||||
false, // showDialog,
|
||||
false // waitFinish
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
UString params ('h');
|
||||
if (!methodName.IsEmpty())
|
||||
{
|
||||
params += " -scrc";
|
||||
params += methodName;
|
||||
/*
|
||||
if (!arcFileName.IsEmpty())
|
||||
{
|
||||
// not used alternate method of generating file
|
||||
params += " -scrf=";
|
||||
params += GetQuotedString(arcPathPrefix + arcFileName);
|
||||
}
|
||||
*/
|
||||
}
|
||||
ExtractGroupCommand(paths, params, true);
|
||||
MY_TRY_FINISH_VOID
|
||||
|
||||
@@ -16,8 +16,13 @@ HRESULT CompressFiles(
|
||||
bool email, bool showDialog, bool waitFinish);
|
||||
|
||||
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup);
|
||||
void TestArchives(const UStringVector &arcPaths);
|
||||
void CalcChecksum(const UStringVector &paths, const UString &methodName);
|
||||
void TestArchives(const UStringVector &arcPaths, bool hashMode = false);
|
||||
|
||||
void CalcChecksum(const UStringVector &paths,
|
||||
const UString &methodName,
|
||||
const UString &arcPathPrefix,
|
||||
const UString &arcFileName);
|
||||
|
||||
void Benchmark(bool totalMode);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,8 @@ static void ThrowException_if_Error(HRESULT res)
|
||||
#define CREATE_CODECS \
|
||||
CCodecs *codecs = new CCodecs; \
|
||||
CMyComPtr<ICompressCodecsInfo> compressCodecsInfo = codecs; \
|
||||
ThrowException_if_Error(codecs->Load());
|
||||
ThrowException_if_Error(codecs->Load()); \
|
||||
Codecs_AddHashArcHandler(codecs);
|
||||
|
||||
#define LOAD_EXTERNAL_CODECS \
|
||||
CExternalCodecs __externalCodecs; \
|
||||
@@ -51,7 +52,8 @@ static void ThrowException_if_Error(HRESULT res)
|
||||
#define CREATE_CODECS \
|
||||
CCodecs *codecs = new CCodecs; \
|
||||
CMyComPtr<IUnknown> compressCodecsInfo = codecs; \
|
||||
ThrowException_if_Error(codecs->Load());
|
||||
ThrowException_if_Error(codecs->Load()); \
|
||||
Codecs_AddHashArcHandler(codecs);
|
||||
|
||||
#define LOAD_EXTERNAL_CODECS
|
||||
|
||||
@@ -150,7 +152,8 @@ HRESULT CompressFiles(
|
||||
|
||||
|
||||
static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
|
||||
bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false)
|
||||
bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false,
|
||||
const char *kType = NULL)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
|
||||
@@ -187,6 +190,15 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
|
||||
}
|
||||
|
||||
CObjectVector<COpenType> formatIndices;
|
||||
if (kType)
|
||||
{
|
||||
if (!ParseOpenTypes(*codecs, UString(kType), formatIndices))
|
||||
{
|
||||
throw CSystemException(E_INVALIDARG);
|
||||
// ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE);
|
||||
// return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
NWildcard::CCensor censor;
|
||||
{
|
||||
@@ -221,15 +233,35 @@ void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bo
|
||||
ExtractGroupCommand(arcPaths, showDialog, outFolder, false, elimDup);
|
||||
}
|
||||
|
||||
void TestArchives(const UStringVector &arcPaths)
|
||||
void TestArchives(const UStringVector &arcPaths, bool hashMode)
|
||||
{
|
||||
ExtractGroupCommand(arcPaths, true, UString(), true);
|
||||
ExtractGroupCommand(arcPaths, true, UString(), true,
|
||||
false, // elimDup
|
||||
hashMode ? "hash" : NULL);
|
||||
}
|
||||
|
||||
void CalcChecksum(const UStringVector &paths, const UString &methodName)
|
||||
void CalcChecksum(const UStringVector &paths,
|
||||
const UString &methodName,
|
||||
const UString &arcPathPrefix,
|
||||
const UString &arcFileName)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
|
||||
if (!arcFileName.IsEmpty())
|
||||
{
|
||||
CompressFiles(
|
||||
arcPathPrefix,
|
||||
arcFileName,
|
||||
UString("hash"),
|
||||
false, // addExtension,
|
||||
paths,
|
||||
false, // email,
|
||||
false, // showDialog,
|
||||
false // waitFinish
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
CREATE_CODECS
|
||||
LOAD_EXTERNAL_CODECS
|
||||
|
||||
@@ -245,6 +277,11 @@ void CalcChecksum(const UStringVector &paths, const UString &methodName)
|
||||
CHashOptions options;
|
||||
options.Methods.Add(methodName);
|
||||
|
||||
/*
|
||||
if (!arcFileName.IsEmpty())
|
||||
options.HashFilePath = arcPathPrefix + arcFileName;
|
||||
*/
|
||||
|
||||
result = HashCalcGUI(EXTERNAL_CODECS_VARS_L censor, options, messageWasDisplayed);
|
||||
if (result != S_OK)
|
||||
{
|
||||
|
||||
@@ -141,6 +141,15 @@ public:
|
||||
|
||||
bool SymLinks;
|
||||
bool ScanAltStreams;
|
||||
bool ExcludeDirItems;
|
||||
bool ExcludeFileItems;
|
||||
|
||||
/* it must be called after anotrher checks */
|
||||
bool CanIncludeItem(bool isDir) const
|
||||
{
|
||||
return isDir ? !ExcludeDirItems : !ExcludeFileItems;
|
||||
}
|
||||
|
||||
|
||||
CDirItemsStat Stat;
|
||||
|
||||
|
||||
@@ -146,6 +146,8 @@ bool InitLocalPrivileges();
|
||||
CDirItems::CDirItems():
|
||||
SymLinks(false),
|
||||
ScanAltStreams(false)
|
||||
, ExcludeDirItems(false)
|
||||
, ExcludeFileItems(false)
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
, ReadSecure(false)
|
||||
#endif
|
||||
@@ -318,6 +320,8 @@ HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phy
|
||||
*/
|
||||
#endif
|
||||
|
||||
if (CanIncludeItem(fi.IsDir()))
|
||||
{
|
||||
int secureIndex = -1;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (ReadSecure)
|
||||
@@ -325,8 +329,8 @@ HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phy
|
||||
RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex));
|
||||
}
|
||||
#endif
|
||||
|
||||
AddDirFileInfo(phyParent, logParent, secureIndex, fi);
|
||||
}
|
||||
|
||||
if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask)
|
||||
{
|
||||
@@ -392,6 +396,8 @@ HRESULT CDirItems::EnumerateItems2(
|
||||
phyParentCur = (int)AddPrefix(phyParent, logParent, fs2us(phyPrefixCur));
|
||||
}
|
||||
|
||||
if (CanIncludeItem(fi.IsDir()))
|
||||
{
|
||||
int secureIndex = -1;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (ReadSecure)
|
||||
@@ -399,8 +405,8 @@ HRESULT CDirItems::EnumerateItems2(
|
||||
RINOK(AddSecurityItem(phyPath, secureIndex));
|
||||
}
|
||||
#endif
|
||||
|
||||
AddDirFileInfo(phyParentCur, logParent, secureIndex, fi);
|
||||
}
|
||||
|
||||
if (fi.IsDir())
|
||||
{
|
||||
@@ -470,6 +476,9 @@ static HRESULT EnumerateAltStreams(
|
||||
bool addAllSubStreams,
|
||||
CDirItems &dirItems)
|
||||
{
|
||||
// we don't use (ExcludeFileItems) rules for AltStreams
|
||||
// if (dirItems.ExcludeFileItems) return S_OK;
|
||||
|
||||
NFind::CStreamEnumerator enumerator(phyPath);
|
||||
for (;;)
|
||||
{
|
||||
@@ -560,11 +569,22 @@ static HRESULT EnumerateForItem(
|
||||
int dirItemIndex = -1;
|
||||
#if defined(_WIN32)
|
||||
bool addAllSubStreams = false;
|
||||
bool needAltStreams = true;
|
||||
#endif // _WIN32
|
||||
#endif // !defined(UNDER_CE)
|
||||
|
||||
// check the path in inlcude rules
|
||||
if (curNode.CheckPathToRoot(true, newParts, !fi.IsDir()))
|
||||
{
|
||||
#if !defined(UNDER_CE)
|
||||
// dirItemIndex = (int)dirItems.Items.Size();
|
||||
#if defined(_WIN32)
|
||||
// we will not check include rules for substreams.
|
||||
addAllSubStreams = true;
|
||||
#endif // _WIN32
|
||||
#endif // !defined(UNDER_CE)
|
||||
|
||||
if (dirItems.CanIncludeItem(fi.IsDir()))
|
||||
{
|
||||
int secureIndex = -1;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
@@ -573,16 +593,18 @@ static HRESULT EnumerateForItem(
|
||||
RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(UNDER_CE)
|
||||
dirItemIndex = (int)dirItems.Items.Size();
|
||||
#if defined(_WIN32)
|
||||
// we will not check include rules for substreams.
|
||||
addAllSubStreams = true;
|
||||
#endif // _WIN32
|
||||
#endif // !defined(UNDER_CE)
|
||||
|
||||
dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
needAltStreams = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (fi.IsDir())
|
||||
enterToSubFolders = true;
|
||||
}
|
||||
@@ -600,7 +622,7 @@ static HRESULT EnumerateForItem(
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (dirItems.ScanAltStreams)
|
||||
if (needAltStreams && dirItems.ScanAltStreams)
|
||||
{
|
||||
RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
|
||||
phyPrefix + fi.Name, // with (fi.Name)
|
||||
@@ -814,6 +836,9 @@ static HRESULT EnumerateDirItems(
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (dirItems.CanIncludeItem(fi.IsDir()))
|
||||
{
|
||||
int secureIndex = -1;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (needSecurity && dirItems.ReadSecure)
|
||||
@@ -848,6 +873,7 @@ static HRESULT EnumerateDirItems(
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#endif // !defined(UNDER_CE)
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Windows/PropVariantConv.h"
|
||||
|
||||
#include "../Common/ExtractingFilePath.h"
|
||||
#include "../Common/HashCalc.h"
|
||||
|
||||
#include "Extract.h"
|
||||
#include "SetProperties.h"
|
||||
@@ -87,7 +89,7 @@ static HRESULT DecompressArchive(
|
||||
}
|
||||
}
|
||||
|
||||
bool allFilesAreAllowed = wildcardCensor.AreAllAllowed();
|
||||
const bool allFilesAreAllowed = wildcardCensor.AreAllAllowed();
|
||||
|
||||
if (!options.StdInMode)
|
||||
{
|
||||
@@ -98,9 +100,14 @@ static HRESULT DecompressArchive(
|
||||
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (elimIsPossible || !allFilesAreAllowed)
|
||||
if (elimIsPossible
|
||||
|| !allFilesAreAllowed
|
||||
|| options.ExcludeDirItems
|
||||
|| options.ExcludeFileItems)
|
||||
{
|
||||
RINOK(arc.GetItem(i, item));
|
||||
if (item.IsDir ? options.ExcludeDirItems : options.ExcludeFileItems)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -254,6 +261,7 @@ int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &n
|
||||
|
||||
|
||||
HRESULT Extract(
|
||||
// DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CCodecs *codecs,
|
||||
const CObjectVector<COpenType> &types,
|
||||
const CIntVector &excludedFormats,
|
||||
@@ -409,6 +417,31 @@ HRESULT Extract(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arcLink.Arcs.Size() != 0)
|
||||
{
|
||||
if (arcLink.GetArc()->IsHashHandler(op))
|
||||
{
|
||||
if (!options.TestMode)
|
||||
{
|
||||
/* real Extracting to files is possible.
|
||||
But user can think that hash archive contains real files.
|
||||
So we block extracting here. */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
FString dirPrefix = us2fs(options.HashDir);
|
||||
if (dirPrefix.IsEmpty())
|
||||
{
|
||||
if (!NFile::NDir::GetOnlyDirPrefix(us2fs(arcPath), dirPrefix))
|
||||
{
|
||||
// return GetLastError_noZero_HRESULT();
|
||||
}
|
||||
}
|
||||
if (!dirPrefix.IsEmpty())
|
||||
NName::NormalizeDirPathPrefix(dirPrefix);
|
||||
ecs->DirPathPrefix_for_HashFiles = dirPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.StdInMode)
|
||||
{
|
||||
// numVolumes += arcLink.VolumePaths.Size();
|
||||
|
||||
@@ -18,6 +18,9 @@ struct CExtractOptionsBase
|
||||
{
|
||||
CBoolPair ElimDup;
|
||||
|
||||
bool ExcludeDirItems;
|
||||
bool ExcludeFileItems;
|
||||
|
||||
bool PathMode_Force;
|
||||
bool OverwriteMode_Force;
|
||||
NExtract::NPathMode::EEnum PathMode;
|
||||
@@ -25,8 +28,11 @@ struct CExtractOptionsBase
|
||||
|
||||
FString OutputDir;
|
||||
CExtractNtOptions NtOptions;
|
||||
UString HashDir;
|
||||
|
||||
CExtractOptionsBase():
|
||||
ExcludeDirItems(false),
|
||||
ExcludeFileItems(false),
|
||||
PathMode_Force(false),
|
||||
OverwriteMode_Force(false),
|
||||
PathMode(NExtract::NPathMode::kFullPaths),
|
||||
@@ -48,9 +54,11 @@ struct CExtractOptions: public CExtractOptionsBase
|
||||
CObjectVector<CProperty> Properties;
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CCodecs *Codecs;
|
||||
#endif
|
||||
*/
|
||||
|
||||
CExtractOptions():
|
||||
StdInMode(false),
|
||||
@@ -77,6 +85,7 @@ struct CDecompressStat
|
||||
};
|
||||
|
||||
HRESULT Extract(
|
||||
// DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CCodecs *codecs,
|
||||
const CObjectVector<COpenType> &types,
|
||||
const CIntVector &excludedFormats,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,15 +3,17 @@
|
||||
#ifndef __HASH_CALC_H
|
||||
#define __HASH_CALC_H
|
||||
|
||||
#include "../../../Common/UTFConvert.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../Common/MethodProps.h"
|
||||
|
||||
#include "DirItem.h"
|
||||
#include "IFileExtractCallback.h"
|
||||
|
||||
const unsigned k_HashCalc_DigestSize_Max = 64;
|
||||
|
||||
const unsigned k_HashCalc_ExtraSize = 8;
|
||||
const unsigned k_HashCalc_NumGroups = 4;
|
||||
|
||||
enum
|
||||
@@ -27,9 +29,37 @@ struct CHasherState
|
||||
CMyComPtr<IHasher> Hasher;
|
||||
AString Name;
|
||||
UInt32 DigestSize;
|
||||
Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max];
|
||||
UInt64 NumSums[k_HashCalc_NumGroups];
|
||||
Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max + k_HashCalc_ExtraSize];
|
||||
|
||||
void InitDigestGroup(unsigned groupIndex)
|
||||
{
|
||||
NumSums[groupIndex] = 0;
|
||||
memset(Digests[groupIndex], 0, sizeof(Digests[groupIndex]));
|
||||
}
|
||||
|
||||
const Byte *GetExtraData_for_Group(unsigned groupIndex) const
|
||||
{
|
||||
return Digests[groupIndex] + k_HashCalc_DigestSize_Max;
|
||||
}
|
||||
|
||||
unsigned GetNumExtraBytes_for_Group(unsigned groupIndex) const
|
||||
{
|
||||
const Byte *p = GetExtraData_for_Group(groupIndex);
|
||||
// we use little-endian to read extra bytes
|
||||
for (unsigned i = k_HashCalc_ExtraSize; i != 0; i--)
|
||||
if (p[i - 1] != 0)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AddDigest(unsigned groupIndex, const Byte *data);
|
||||
|
||||
void WriteToString(unsigned digestIndex, char *s) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct IHashCalc
|
||||
{
|
||||
virtual void InitForNewFile() = 0;
|
||||
@@ -89,9 +119,68 @@ struct IHashCallbackUI: public IDirItemsCallback
|
||||
INTERFACE_IHashCallbackUI(=0)
|
||||
};
|
||||
|
||||
|
||||
struct CHashOptionsLocal
|
||||
{
|
||||
CBoolPair HashMode_Zero;
|
||||
CBoolPair HashMode_Tag;
|
||||
CBoolPair HashMode_Dirs;
|
||||
CBoolPair HashMode_OnlyHash;
|
||||
|
||||
void Init_HashOptionsLocal()
|
||||
{
|
||||
HashMode_Zero.Init();
|
||||
HashMode_Tag.Init();
|
||||
HashMode_Dirs.Init();
|
||||
HashMode_OnlyHash.Init();
|
||||
// HashMode_Dirs = true; // for debug
|
||||
}
|
||||
|
||||
CHashOptionsLocal()
|
||||
{
|
||||
Init_HashOptionsLocal();
|
||||
}
|
||||
|
||||
bool ParseFlagCharOption(wchar_t c, bool val)
|
||||
{
|
||||
c = MyCharLower_Ascii(c);
|
||||
if (c == 'z') HashMode_Zero.SetVal_as_Defined(val);
|
||||
else if (c == 't') HashMode_Tag.SetVal_as_Defined(val);
|
||||
else if (c == 'd') HashMode_Dirs.SetVal_as_Defined(val);
|
||||
else if (c == 'h') HashMode_OnlyHash.SetVal_as_Defined(val);
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseString(const UString &s)
|
||||
{
|
||||
for (unsigned i = 0; i < s.Len();)
|
||||
{
|
||||
const wchar_t c = s[i++];
|
||||
bool val = true;
|
||||
if (i < s.Len())
|
||||
{
|
||||
const wchar_t next = s[i];
|
||||
if (next == '-')
|
||||
{
|
||||
val = false;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!ParseFlagCharOption(c, val))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CHashOptions
|
||||
// : public CHashOptionsLocal
|
||||
{
|
||||
UStringVector Methods;
|
||||
// UString HashFilePath;
|
||||
|
||||
bool PreserveATime;
|
||||
bool OpenShareForWrite;
|
||||
bool StdInMode;
|
||||
@@ -108,6 +197,7 @@ struct CHashOptions
|
||||
PathMode(NWildcard::k_RelatPath) {};
|
||||
};
|
||||
|
||||
|
||||
HRESULT HashCalc(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
const NWildcard::CCensor &censor,
|
||||
@@ -115,6 +205,130 @@ HRESULT HashCalc(
|
||||
AString &errorInfo,
|
||||
IHashCallbackUI *callback);
|
||||
|
||||
void AddHashHexToString(char *dest, const Byte *data, UInt32 size);
|
||||
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
namespace NHash {
|
||||
|
||||
struct CHashPair
|
||||
{
|
||||
CByteBuffer Hash;
|
||||
char Mode;
|
||||
bool IsBSD;
|
||||
bool Size_from_Arc_Defined;
|
||||
bool Size_from_Disk_Defined;
|
||||
AString Method;
|
||||
AString Name;
|
||||
|
||||
AString FullLine;
|
||||
AString HashString;
|
||||
// unsigned HashLengthInBits;
|
||||
|
||||
// AString MethodName;
|
||||
UInt64 Size_from_Arc;
|
||||
UInt64 Size_from_Disk;
|
||||
|
||||
bool IsDir() const;
|
||||
|
||||
void Get_UString_Path(UString &path) const
|
||||
{
|
||||
path.Empty();
|
||||
if (!ConvertUTF8ToUnicode(Name, path))
|
||||
return;
|
||||
}
|
||||
|
||||
bool ParseCksum(const char *s);
|
||||
bool Parse(const char *s);
|
||||
|
||||
bool IsSupportedMode() const
|
||||
{
|
||||
return Mode != 'U' && Mode != '^';
|
||||
}
|
||||
|
||||
CHashPair():
|
||||
Mode(0)
|
||||
, IsBSD(false)
|
||||
, Size_from_Arc_Defined(false)
|
||||
, Size_from_Disk_Defined(false)
|
||||
// , HashLengthInBits(0)
|
||||
, Size_from_Arc(0)
|
||||
, Size_from_Disk(0)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public IArchiveGetRawProps,
|
||||
// public IGetArchiveHashHandler,
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
bool _isArc;
|
||||
UInt64 _phySize;
|
||||
CObjectVector<CHashPair> HashPairs;
|
||||
UString _nameExtenstion;
|
||||
// UString _method_fromName;
|
||||
AString _pgpMethod;
|
||||
bool _is_CksumMode;
|
||||
bool _is_PgpMethod;
|
||||
bool _is_ZeroMode;
|
||||
bool _are_there_Tags;
|
||||
bool _are_there_Dirs;
|
||||
bool _hashSize_Defined;
|
||||
unsigned _hashSize;
|
||||
|
||||
bool _crcSize_WasSet;
|
||||
UInt32 _crcSize;
|
||||
UStringVector _methods;
|
||||
|
||||
void ClearVars();
|
||||
|
||||
void InitProps()
|
||||
{
|
||||
_crcSize_WasSet = false;
|
||||
_crcSize = 4;
|
||||
_methods.Clear();
|
||||
_options.Init_HashOptionsLocal();
|
||||
}
|
||||
|
||||
CHashOptionsLocal _options;
|
||||
|
||||
bool CanUpdate() const
|
||||
{
|
||||
if (!_isArc || _is_PgpMethod || _is_CksumMode)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
HRESULT SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value);
|
||||
|
||||
public:
|
||||
|
||||
CHandler();
|
||||
|
||||
MY_UNKNOWN_IMP4(
|
||||
IInArchive,
|
||||
IArchiveGetRawProps,
|
||||
IOutArchive,
|
||||
ISetProperties
|
||||
/*, IGetArchiveHashHandler */
|
||||
)
|
||||
INTERFACE_IInArchive(;)
|
||||
INTERFACE_IOutArchive(;)
|
||||
INTERFACE_IArchiveGetRawProps(;)
|
||||
// STDMETHOD(GetArchiveHashHandler)(CHandler **handler);
|
||||
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void Codecs_AddHashArcHandler(CCodecs *codecs);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -103,9 +103,9 @@ DECL_INTERFACE_SUB(IGetProp, IUnknown, 0x01, 0x20)
|
||||
STDMETHOD(UseExtractToStream)(Int32 *res) x; \
|
||||
STDMETHOD(GetStream7)(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp) x; \
|
||||
STDMETHOD(PrepareOperation7)(Int32 askExtractMode) x; \
|
||||
STDMETHOD(SetOperationResult7)(Int32 resultEOperationResult, Int32 encrypted) x; \
|
||||
STDMETHOD(SetOperationResult8)(Int32 resultEOperationResult, Int32 encrypted, UInt64 size) x; \
|
||||
|
||||
DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x30)
|
||||
DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x31)
|
||||
{
|
||||
INTERFACE_IFolderExtractToStreamCallback(PURE)
|
||||
};
|
||||
|
||||
@@ -53,6 +53,7 @@ using namespace NWindows;
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/RegisterArc.h"
|
||||
#include "../../Common/RegisterCodec.h"
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
|
||||
@@ -193,9 +194,9 @@ void CArcInfoEx::AddExts(const UString &ext, const UString &addExt)
|
||||
static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector<CByteBuffer> &signatures)
|
||||
{
|
||||
signatures.Clear();
|
||||
while (size > 0)
|
||||
while (size != 0)
|
||||
{
|
||||
unsigned len = *data++;
|
||||
const unsigned len = *data++;
|
||||
size--;
|
||||
if (len > size)
|
||||
return false;
|
||||
@@ -252,6 +253,25 @@ static HRESULT GetCoderClass(Func_GetMethodProperty getMethodProperty, UInt32 in
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT GetMethodBoolProp(Func_GetMethodProperty getMethodProperty, UInt32 index,
|
||||
PROPID propId, bool &resVal, bool &isAssigned)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
resVal = false;
|
||||
isAssigned = false;
|
||||
RINOK(getMethodProperty(index, propId, &prop));
|
||||
if (prop.vt == VT_BOOL)
|
||||
{
|
||||
isAssigned = true;
|
||||
resVal = VARIANT_BOOLToBool(prop.boolVal);
|
||||
}
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
#define MY_GET_FUNC(dest, type, func) *(void **)(&dest) = (func);
|
||||
// #define MY_GET_FUNC(dest, type, func) dest = (type)(func);
|
||||
|
||||
@@ -279,6 +299,7 @@ HRESULT CCodecs::LoadCodecs()
|
||||
info.CodecIndex = i;
|
||||
RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));
|
||||
RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));
|
||||
RINOK(GetMethodBoolProp(lib.GetMethodProperty, i, NMethodPropID::kIsFilter, info.IsFilter, info.IsFilter_Assigned));
|
||||
Codecs.Add(info);
|
||||
}
|
||||
}
|
||||
@@ -647,8 +668,14 @@ HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPath)
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
if (fi.IsDir())
|
||||
continue;
|
||||
#else
|
||||
if (enumerator.DirEntry_IsDir(fi, true)) // followLink
|
||||
continue;
|
||||
#endif
|
||||
|
||||
RINOK(LoadDll(folderPrefix + fi.Name, true));
|
||||
}
|
||||
return S_OK;
|
||||
@@ -725,7 +752,10 @@ HRESULT CCodecs::Load()
|
||||
if (arc.IsMultiSignature())
|
||||
ParseSignatures(arc.Signature, arc.SignatureSize, item.Signatures);
|
||||
else
|
||||
{
|
||||
if (arc.SignatureSize != 0) // 21.04
|
||||
item.Signatures.AddNew().CopyFrom(arc.Signature, arc.SignatureSize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -776,6 +806,8 @@ HRESULT CCodecs::Load()
|
||||
|
||||
#endif
|
||||
|
||||
// we sort Formats to get fixed order of Formats after compilation.
|
||||
Formats.Sort();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -952,6 +984,15 @@ STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *valu
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (propID == NMethodPropID::kIsFilter && ci.IsFilter_Assigned)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
prop = (bool)ci.IsFilter;
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
const CCodecLib &lib = Libs[ci.LibIndex];
|
||||
return lib.GetMethodProperty(ci.CodecIndex, propID, value);
|
||||
#else
|
||||
@@ -1096,6 +1137,7 @@ bool CCodecs::GetCodec_DecoderIsAssigned(UInt32 index) const
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool CCodecs::GetCodec_EncoderIsAssigned(UInt32 index) const
|
||||
{
|
||||
#ifdef EXPORT_CODECS
|
||||
@@ -1118,6 +1160,38 @@ bool CCodecs::GetCodec_EncoderIsAssigned(UInt32 index) const
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool CCodecs::GetCodec_IsFilter(UInt32 index, bool &isAssigned) const
|
||||
{
|
||||
isAssigned = false;
|
||||
#ifdef EXPORT_CODECS
|
||||
if (index < g_NumCodecs)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (GetProperty(index, NMethodPropID::kIsFilter, &prop) == S_OK)
|
||||
{
|
||||
if (prop.vt == VT_BOOL)
|
||||
{
|
||||
isAssigned = true;
|
||||
return VARIANT_BOOLToBool(prop.boolVal);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
{
|
||||
const CDllCodecInfo &c = Codecs[index - NUM_EXPORT_CODECS];
|
||||
isAssigned = c.IsFilter_Assigned;
|
||||
return c.IsFilter;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
UInt32 CCodecs::GetCodec_NumStreams(UInt32 index)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
@@ -1203,3 +1277,45 @@ void CCodecs::GetCodecsErrorMessage(UString &s)
|
||||
}
|
||||
|
||||
#endif // EXTERNAL_CODECS
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
extern unsigned g_NumCodecs;
|
||||
extern const CCodecInfo *g_Codecs[];
|
||||
|
||||
void CCodecs::Get_CodecsInfoUser_Vector(CObjectVector<CCodecInfoUser> &v)
|
||||
{
|
||||
v.Clear();
|
||||
{
|
||||
for (unsigned i = 0; i < g_NumCodecs; i++)
|
||||
{
|
||||
const CCodecInfo &cod = *g_Codecs[i];
|
||||
CCodecInfoUser &u = v.AddNew();
|
||||
u.EncoderIsAssigned = (cod.CreateEncoder != NULL);
|
||||
u.DecoderIsAssigned = (cod.CreateDecoder != NULL);
|
||||
u.IsFilter_Assigned = true;
|
||||
u.IsFilter = cod.IsFilter;
|
||||
u.NumStreams = cod.NumStreams;
|
||||
u.Name = cod.Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
{
|
||||
UInt32 numMethods;
|
||||
if (GetNumMethods(&numMethods) == S_OK)
|
||||
for (UInt32 j = 0; j < numMethods; j++)
|
||||
{
|
||||
CCodecInfoUser &u = v.AddNew();
|
||||
u.EncoderIsAssigned = GetCodec_EncoderIsAssigned(j);
|
||||
u.DecoderIsAssigned = GetCodec_DecoderIsAssigned(j);
|
||||
u.IsFilter = GetCodec_IsFilter(j, u.IsFilter_Assigned);
|
||||
u.NumStreams = GetCodec_NumStreams(j);
|
||||
u.Name = GetCodec_Name(j);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -68,6 +68,8 @@ struct CDllCodecInfo
|
||||
UInt32 CodecIndex;
|
||||
bool EncoderIsAssigned;
|
||||
bool DecoderIsAssigned;
|
||||
bool IsFilter;
|
||||
bool IsFilter_Assigned;
|
||||
CLSID Encoder;
|
||||
CLSID Decoder;
|
||||
};
|
||||
@@ -119,6 +121,23 @@ struct CArcInfoEx
|
||||
CLSID ClassID;
|
||||
#endif
|
||||
|
||||
int Compare(const CArcInfoEx &a) const
|
||||
{
|
||||
int res = Name.Compare(a.Name);
|
||||
if (res != 0)
|
||||
return res;
|
||||
#ifdef EXTERNAL_CODECS
|
||||
return MyCompare(LibIndex, a.LibIndex);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
/*
|
||||
if (LibIndex < a.LibIndex) return -1;
|
||||
if (LibIndex > a.LibIndex) return 1;
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
|
||||
bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; }
|
||||
bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; }
|
||||
|
||||
@@ -133,6 +152,7 @@ struct CArcInfoEx
|
||||
bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; }
|
||||
bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; }
|
||||
bool Flags_ByExtOnlyOpen() const { return (Flags & NArcInfoFlags::kByExtOnlyOpen) != 0; }
|
||||
bool Flags_HashHandler() const { return (Flags & NArcInfoFlags::kHashHandler) != 0; }
|
||||
|
||||
UString GetMainExt() const
|
||||
{
|
||||
@@ -236,6 +256,21 @@ struct CCodecError
|
||||
CCodecError(): ErrorCode(0) {}
|
||||
};
|
||||
|
||||
|
||||
struct CCodecInfoUser
|
||||
{
|
||||
// unsigned LibIndex;
|
||||
// UInt32 CodecIndex;
|
||||
// UInt64 id;
|
||||
bool EncoderIsAssigned;
|
||||
bool DecoderIsAssigned;
|
||||
bool IsFilter;
|
||||
bool IsFilter_Assigned;
|
||||
UInt32 NumStreams;
|
||||
AString Name;
|
||||
};
|
||||
|
||||
|
||||
class CCodecs:
|
||||
#ifdef EXTERNAL_CODECS
|
||||
public ICompressCodecsInfo,
|
||||
@@ -353,6 +388,7 @@ public:
|
||||
int GetCodec_LibIndex(UInt32 index) const;
|
||||
bool GetCodec_DecoderIsAssigned(UInt32 index) const;
|
||||
bool GetCodec_EncoderIsAssigned(UInt32 index) const;
|
||||
bool GetCodec_IsFilter(UInt32 index, bool &isAssigned) const;
|
||||
UInt32 GetCodec_NumStreams(UInt32 index);
|
||||
HRESULT GetCodec_Id(UInt32 index, UInt64 &id);
|
||||
AString GetCodec_Name(UInt32 index);
|
||||
@@ -416,6 +452,8 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Get_CodecsInfoUser_Vector(CObjectVector<CCodecInfoUser> &v);
|
||||
|
||||
#endif // _SFX
|
||||
};
|
||||
|
||||
|
||||
@@ -1026,31 +1026,34 @@ static void MakeCheckOrder(CCodecs *codecs,
|
||||
{
|
||||
for (unsigned i = 0; i < numTypes; i++)
|
||||
{
|
||||
int index = orderIndices[i];
|
||||
const int index = orderIndices[i];
|
||||
if (index < 0)
|
||||
continue;
|
||||
const CArcInfoEx &ai = codecs->Formats[(unsigned)index];
|
||||
if (ai.SignatureOffset != 0)
|
||||
if (ai.SignatureOffset == 0)
|
||||
{
|
||||
orderIndices2.Add(index);
|
||||
orderIndices[i] = -1;
|
||||
if (ai.Signatures.IsEmpty())
|
||||
{
|
||||
if (dataSize != 0) // 21.04: no Sinature means Empty Signature
|
||||
continue;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
unsigned k;
|
||||
const CObjectVector<CByteBuffer> &sigs = ai.Signatures;
|
||||
FOR_VECTOR (k, sigs)
|
||||
for (k = 0; k < sigs.Size(); k++)
|
||||
{
|
||||
const CByteBuffer &sig = sigs[k];
|
||||
if ((sig.Size() == 0 && dataSize == 0)
|
||||
|| (sig.Size() != 0 && sig.Size() <= dataSize
|
||||
&& TestSignature(data, sig, sig.Size())))
|
||||
{
|
||||
orderIndices2.Add(index);
|
||||
orderIndices[i] = -1;
|
||||
if (sig.Size() <= dataSize && TestSignature(data, sig, sig.Size()))
|
||||
break;
|
||||
}
|
||||
if (k == sigs.Size())
|
||||
continue;
|
||||
}
|
||||
}
|
||||
orderIndices2.Add(index);
|
||||
orderIndices[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNDER_CE
|
||||
@@ -2143,7 +2146,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isNewStyleSignature = IsNewStyleSignature(ai);
|
||||
const bool isNewStyleSignature = IsNewStyleSignature(ai);
|
||||
bool needCheck = !isNewStyleSignature
|
||||
|| ai.Signatures.IsEmpty()
|
||||
|| ai.Flags_PureStartOpen()
|
||||
@@ -2156,13 +2159,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
|
||||
for (k = 0; k < ai.Signatures.Size(); k++)
|
||||
{
|
||||
const CByteBuffer &sig = ai.Signatures[k];
|
||||
UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size();
|
||||
if (processedSize < signatureEnd)
|
||||
if (processedSize < ai.SignatureOffset + sig.Size())
|
||||
{
|
||||
if (!endOfFile)
|
||||
needCheck = true;
|
||||
}
|
||||
else if (memcmp(sig, byteBuffer + ai.SignatureOffset, sig.Size()) == 0)
|
||||
else if (TestSignature(sig, byteBuffer + ai.SignatureOffset, sig.Size()))
|
||||
break;
|
||||
}
|
||||
if (k != ai.Signatures.Size())
|
||||
@@ -3390,7 +3392,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CArc::ReOpen(const COpenOptions &op)
|
||||
HRESULT CArc::ReOpen(const COpenOptions &op, IArchiveOpenCallback *openCallback_Additional)
|
||||
{
|
||||
ErrorInfo.ClearErrors();
|
||||
ErrorInfo.ErrorFormatIndex = -1;
|
||||
@@ -3420,7 +3422,10 @@ HRESULT CArc::ReOpen(const COpenOptions &op)
|
||||
// There are archives with embedded STUBs (like ZIP), so we must support signature scanning
|
||||
// But for another archives we can use 0 here. So the code can be fixed !!!
|
||||
UInt64 maxStartPosition = kMaxCheckStartPosition;
|
||||
HRESULT res = Archive->Open(stream2, &maxStartPosition, op.callback);
|
||||
IArchiveOpenCallback *openCallback = openCallback_Additional;
|
||||
if (!openCallback)
|
||||
openCallback = op.callback;
|
||||
HRESULT res = Archive->Open(stream2, &maxStartPosition, openCallback);
|
||||
|
||||
if (res == S_OK)
|
||||
{
|
||||
@@ -3476,7 +3481,7 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op)
|
||||
op.stream = stream;
|
||||
|
||||
CArc &arc = Arcs[0];
|
||||
HRESULT res = arc.ReOpen(op);
|
||||
HRESULT res = arc.ReOpen(op, openCallbackNew);
|
||||
|
||||
PasswordWasAsked = openCallbackSpec->PasswordWasAsked;
|
||||
// Password = openCallbackSpec->Password;
|
||||
@@ -3579,6 +3584,12 @@ static bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
|
||||
type.CanReturnArc = false;
|
||||
type.CanReturnParser = true;
|
||||
}
|
||||
else if (name.IsEqualTo_Ascii_NoCase("hash"))
|
||||
{
|
||||
// type.CanReturnArc = false;
|
||||
// type.CanReturnParser = false;
|
||||
type.IsHashType = true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -3606,6 +3617,7 @@ static bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
|
||||
bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types)
|
||||
{
|
||||
types.Clear();
|
||||
bool isHashType = false;
|
||||
for (unsigned pos = 0; pos < s.Len();)
|
||||
{
|
||||
int pos2 = s.Find(L'.', pos);
|
||||
@@ -3617,10 +3629,24 @@ bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType>
|
||||
COpenType type;
|
||||
if (!ParseType(codecs, name, type))
|
||||
return false;
|
||||
if (isHashType)
|
||||
return false;
|
||||
if (type.IsHashType)
|
||||
isHashType = true;
|
||||
types.Add(type);
|
||||
pos = (unsigned)pos2 + 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
bool IsHashType(const CObjectVector<COpenType> &types)
|
||||
{
|
||||
if (types.Size() != 1)
|
||||
return false;
|
||||
return types[0].IsHashType;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,6 +70,7 @@ struct COpenType
|
||||
|
||||
bool CanReturnArc;
|
||||
bool CanReturnParser;
|
||||
bool IsHashType;
|
||||
bool EachPos;
|
||||
|
||||
// bool SkipSfxStub;
|
||||
@@ -90,6 +91,7 @@ struct COpenType
|
||||
Recursive(true),
|
||||
CanReturnArc(true),
|
||||
CanReturnParser(false),
|
||||
IsHashType(false),
|
||||
EachPos(false),
|
||||
// SkipSfxStub(true),
|
||||
// ExeAsUnknown(true),
|
||||
@@ -285,7 +287,7 @@ public:
|
||||
UString Path;
|
||||
UString filePath;
|
||||
UString DefaultName;
|
||||
int FormatIndex; // - 1 means Parser.
|
||||
int FormatIndex; // -1 means Parser
|
||||
UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile
|
||||
FILETIME MTime;
|
||||
bool MTimeDefined;
|
||||
@@ -358,9 +360,16 @@ public:
|
||||
HRESULT OpenStream(const COpenOptions &options);
|
||||
HRESULT OpenStreamOrFile(COpenOptions &options);
|
||||
|
||||
HRESULT ReOpen(const COpenOptions &options);
|
||||
HRESULT ReOpen(const COpenOptions &options, IArchiveOpenCallback *openCallback_Additional);
|
||||
|
||||
HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream);
|
||||
|
||||
bool IsHashHandler(const COpenOptions &options) const
|
||||
{
|
||||
if (FormatIndex < 0)
|
||||
return false;
|
||||
return options.codecs->Formats[(unsigned)FormatIndex].Flags_HashHandler();
|
||||
}
|
||||
};
|
||||
|
||||
struct CArchiveLink
|
||||
@@ -421,6 +430,8 @@ struct CArchiveLink
|
||||
|
||||
bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types);
|
||||
|
||||
// bool IsHashType(const CObjectVector<COpenType> &types);
|
||||
|
||||
|
||||
struct CDirPathSortPair
|
||||
{
|
||||
|
||||
@@ -542,7 +542,7 @@ static HRESULT Compress(
|
||||
#endif
|
||||
}
|
||||
|
||||
if (outArchive == 0)
|
||||
if (!outArchive)
|
||||
throw kUpdateIsNotSupoorted;
|
||||
|
||||
NFileTimeType::EEnum fileTimeType;
|
||||
@@ -568,6 +568,8 @@ static HRESULT Compress(
|
||||
return E_NOTIMPL;
|
||||
if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure())
|
||||
return E_NOTIMPL;
|
||||
if (options.DeleteAfterCompressing && arcInfo.Flags_HashHandler())
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
CRecordVector<CUpdatePair2> updatePairs2;
|
||||
@@ -745,6 +747,11 @@ static HRESULT Compress(
|
||||
|
||||
updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses;
|
||||
|
||||
{
|
||||
const UString arcPath = archivePath.GetFinalPath();
|
||||
updateCallbackSpec->ArcFileName = ExtractFileNameFromPath(arcPath);
|
||||
}
|
||||
|
||||
if (options.RenamePairs.Size() != 0)
|
||||
updateCallbackSpec->NewNames = &newNames;
|
||||
|
||||
@@ -907,7 +914,7 @@ static HRESULT Compress(
|
||||
ft.dwHighDateTime = 0;
|
||||
FOR_VECTOR (i, updatePairs2)
|
||||
{
|
||||
CUpdatePair2 &pair2 = updatePairs2[i];
|
||||
const CUpdatePair2 &pair2 = updatePairs2[i];
|
||||
const FILETIME *ft2 = NULL;
|
||||
if (pair2.NewProps && pair2.DirIndex >= 0)
|
||||
ft2 = &dirItems.Items[(unsigned)pair2.DirIndex].MTime;
|
||||
@@ -945,9 +952,28 @@ static HRESULT Compress(
|
||||
result = outStreamSpec->Close();
|
||||
else if (volStreamSpec)
|
||||
result = volStreamSpec->Close();
|
||||
|
||||
RINOK(result)
|
||||
|
||||
if (processedItemsStatuses)
|
||||
{
|
||||
FOR_VECTOR (i, updatePairs2)
|
||||
{
|
||||
const CUpdatePair2 &up = updatePairs2[i];
|
||||
if (up.NewData && up.DirIndex >= 0)
|
||||
{
|
||||
const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex];
|
||||
if (di.AreReparseData() || (!di.IsDir() && di.Size == 0))
|
||||
processedItemsStatuses[(unsigned)up.DirIndex] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include);
|
||||
|
||||
static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item)
|
||||
@@ -1288,6 +1314,8 @@ HRESULT UpdateArchive(
|
||||
#endif
|
||||
|
||||
dirItems.ScanAltStreams = options.AltStreams.Val;
|
||||
dirItems.ExcludeDirItems = censor.ExcludeDirItems;
|
||||
dirItems.ExcludeFileItems = censor.ExcludeFileItems;
|
||||
|
||||
HRESULT res = EnumerateItems(censor,
|
||||
options.PathMode,
|
||||
@@ -1440,7 +1468,7 @@ HRESULT UpdateArchive(
|
||||
CByteBuffer processedItems;
|
||||
if (options.DeleteAfterCompressing)
|
||||
{
|
||||
unsigned num = dirItems.Items.Size();
|
||||
const unsigned num = dirItems.Items.Size();
|
||||
processedItems.Alloc(num);
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
processedItems[i] = 0;
|
||||
@@ -1654,17 +1682,27 @@ HRESULT UpdateArchive(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (processedItems[i] != 0 || dirItem.Size == 0)
|
||||
// 21.04: we have set processedItems[*] before for all required items
|
||||
if (processedItems[i] != 0
|
||||
// || dirItem.Size == 0
|
||||
// || dirItem.AreReparseData()
|
||||
)
|
||||
{
|
||||
NFind::CFileInfo fileInfo;
|
||||
/* here we compare Raw FileInfo that can be link with actual file info that was processed.
|
||||
we can fix it. */
|
||||
if (fileInfo.Find(phyPath))
|
||||
/* if (!SymLinks), we follow link here, similar to (dirItem) filling */
|
||||
if (fileInfo.Find(phyPath, !options.SymLinks.Val))
|
||||
{
|
||||
// FIXME: here we can check Find_FollowLink() also;
|
||||
bool is_SameSize = false;
|
||||
if (options.SymLinks.Val && dirItem.AreReparseData())
|
||||
{
|
||||
/* (dirItem.Size = dirItem.ReparseData.Size()) was set before.
|
||||
So we don't compare sizes for that case here */
|
||||
is_SameSize = fileInfo.IsOsSymLink();
|
||||
}
|
||||
else
|
||||
is_SameSize = (fileInfo.Size == dirItem.Size);
|
||||
|
||||
// maybe we must exclude also files with archive name: "a a.7z * -sdel"
|
||||
if (fileInfo.Size == dirItem.Size
|
||||
if (is_SameSize
|
||||
&& CompareFileTime(&fileInfo.MTime, &dirItem.MTime) == 0
|
||||
&& CompareFileTime(&fileInfo.CTime, &dirItem.CTime) == 0)
|
||||
{
|
||||
@@ -1675,11 +1713,11 @@ HRESULT UpdateArchive(
|
||||
}
|
||||
else
|
||||
{
|
||||
// file was skipped
|
||||
// file was skipped by some reason. We can throw error for debug:
|
||||
/*
|
||||
errorInfo.SystemError = 0;
|
||||
errorInfo.Message = "file was not processed";
|
||||
errorInfo.FileName = phyPath;
|
||||
errorInfo.FileNames.Add(phyPath);
|
||||
return E_FAIL;
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *val
|
||||
case kpidCTime: if (ParentDirItem) prop = ParentDirItem->CTime; break;
|
||||
case kpidATime: if (ParentDirItem) prop = ParentDirItem->ATime; break;
|
||||
case kpidMTime: if (ParentDirItem) prop = ParentDirItem->MTime; break;
|
||||
case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
@@ -475,6 +476,17 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
|
||||
static NSynchronization::CCriticalSection CS;
|
||||
#endif
|
||||
|
||||
void CArchiveUpdateCallback::UpdateProcessedItemStatus(unsigned dirIndex)
|
||||
{
|
||||
if (ProcessedItemsStatuses)
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
NSynchronization::CCriticalSectionLock lock(CS);
|
||||
#endif
|
||||
ProcessedItemsStatuses[dirIndex] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -544,6 +556,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
|
||||
CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
|
||||
inStreamSpec->Init(di.ReparseData, di.ReparseData.Size());
|
||||
*inStream = inStreamLoc.Detach();
|
||||
|
||||
UpdateProcessedItemStatus((unsigned)up.DirIndex);
|
||||
return S_OK;
|
||||
}
|
||||
#endif // !defined(UNDER_CE)
|
||||
@@ -600,13 +614,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (ProcessedItemsStatuses)
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
NSynchronization::CCriticalSectionLock lock(CS);
|
||||
#endif
|
||||
ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1;
|
||||
}
|
||||
UpdateProcessedItemStatus((unsigned)up.DirIndex);
|
||||
*inStream = inStreamLoc.Detach();
|
||||
}
|
||||
|
||||
@@ -649,7 +657,7 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
|
||||
isDir = DirItems->Items[(unsigned)up.DirIndex].IsDir();
|
||||
}
|
||||
}
|
||||
return Callback->ReportUpdateOpeartion(op, name.IsEmpty() ? NULL : name.Ptr(), isDir);
|
||||
return Callback->ReportUpdateOperation(op, name.IsEmpty() ? NULL : name.Ptr(), isDir);
|
||||
}
|
||||
|
||||
wchar_t temp[16];
|
||||
@@ -684,7 +692,7 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
|
||||
if (!s)
|
||||
s = L"";
|
||||
|
||||
return Callback->ReportUpdateOpeartion(op, s, isDir);
|
||||
return Callback->ReportUpdateOperation(op, s, isDir);
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ struct CArcToDoStat
|
||||
virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x; \
|
||||
virtual HRESULT SetOperationResult(Int32 opRes) x; \
|
||||
virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x; \
|
||||
virtual HRESULT ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir) x; \
|
||||
virtual HRESULT ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) x; \
|
||||
/* virtual HRESULT SetPassword(const UString &password) x; */ \
|
||||
virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \
|
||||
virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \
|
||||
@@ -87,6 +87,8 @@ class CArchiveUpdateCallback:
|
||||
UInt32 _hardIndex_From;
|
||||
UInt32 _hardIndex_To;
|
||||
|
||||
void UpdateProcessedItemStatus(unsigned dirIndex);
|
||||
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile)
|
||||
@@ -121,6 +123,7 @@ public:
|
||||
CRecordVector<UInt64> VolumesSizes;
|
||||
FString VolName;
|
||||
FString VolExt;
|
||||
UString ArcFileName; // without path prefix
|
||||
|
||||
IUpdateCallbackUI *Callback;
|
||||
|
||||
@@ -147,7 +150,6 @@ public:
|
||||
|
||||
Byte *ProcessedItemsStatuses;
|
||||
|
||||
|
||||
CArchiveUpdateCallback();
|
||||
|
||||
bool IsDir(const CUpdatePair2 &up) const
|
||||
|
||||
@@ -405,6 +405,14 @@ SOURCE=..\..\..\Common\Defs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -886,6 +894,14 @@ SOURCE=..\..\..\..\C\Threads.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ItemNameUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -187,6 +187,7 @@ static NSynchronization::CCriticalSection g_CriticalSection;
|
||||
static const char * const kTestString = "T";
|
||||
static const char * const kExtractString = "-";
|
||||
static const char * const kSkipString = ".";
|
||||
static const char * const kReadString = "H";
|
||||
|
||||
// static const char * const kCantAutoRename = "cannot create file with auto name\n";
|
||||
// static const char * const kCantRenameFile = "cannot rename existing file\n";
|
||||
@@ -317,7 +318,7 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
|
||||
return CheckBreak2();
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 *position)
|
||||
STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position)
|
||||
{
|
||||
MT_LOCK
|
||||
|
||||
@@ -331,6 +332,7 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
|
||||
case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break;
|
||||
case NArchive::NExtract::NAskMode::kTest: s = kTestString; break;
|
||||
case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; requiredLevel = 2; break;
|
||||
case NArchive::NExtract::NAskMode::kReadExternal: s = kReadString; requiredLevel = 0; break;
|
||||
default: s = "???"; requiredLevel = 2;
|
||||
};
|
||||
|
||||
@@ -350,6 +352,12 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
|
||||
{
|
||||
_tempU = name;
|
||||
_so->Normalize_UString(_tempU);
|
||||
// 21.04
|
||||
if (isFolder)
|
||||
{
|
||||
if (!_tempU.IsEmpty() && _tempU.Back() != WCHAR_PATH_SEPARATOR)
|
||||
_tempU.Add_PathSepar();
|
||||
}
|
||||
}
|
||||
_so->PrintUString(_tempU, _tempA);
|
||||
if (position)
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
#include "../../../Windows/FileName.h"
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
#include "HashCon.h"
|
||||
|
||||
@@ -33,13 +35,15 @@ HRESULT CHashCallbackConsole::StartScanning()
|
||||
return CheckBreak2();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */)
|
||||
HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir)
|
||||
{
|
||||
if (NeedPercents())
|
||||
{
|
||||
_percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams;
|
||||
_percent.Completed = st.GetTotalBytes();
|
||||
_percent.FileName = fs2us(path);
|
||||
if (isDir)
|
||||
NWindows::NFile::NName::NormalizeDirPathPrefix(_percent.FileName);
|
||||
_percent.Print();
|
||||
}
|
||||
return CheckBreak2();
|
||||
@@ -111,6 +115,15 @@ static void SetSpacesAndNul(char *s, unsigned num)
|
||||
s[num] = 0;
|
||||
}
|
||||
|
||||
static void SetSpacesAndNul_if_Positive(char *s, int num)
|
||||
{
|
||||
if (num < 0)
|
||||
return;
|
||||
for (int i = 0; i < num; i++)
|
||||
s[i] = ' ';
|
||||
s[num] = 0;
|
||||
}
|
||||
|
||||
static const unsigned kSizeField_Len = 13;
|
||||
static const unsigned kNameField_Len = 12;
|
||||
|
||||
@@ -122,33 +135,49 @@ static unsigned GetColumnWidth(unsigned digestSize)
|
||||
return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width;
|
||||
}
|
||||
|
||||
|
||||
AString CHashCallbackConsole::GetFields() const
|
||||
{
|
||||
AString s = PrintFields;
|
||||
if (s.IsEmpty())
|
||||
s = "hsn";
|
||||
s.MakeLower_Ascii();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers)
|
||||
{
|
||||
_s.Empty();
|
||||
|
||||
const AString fields = GetFields();
|
||||
for (unsigned pos = 0; pos < fields.Len(); pos++)
|
||||
{
|
||||
const char c = fields[pos];
|
||||
if (c == 'h')
|
||||
{
|
||||
for (unsigned i = 0; i < hashers.Size(); i++)
|
||||
{
|
||||
if (i != 0)
|
||||
_s.Add_Space();
|
||||
AddSpace();
|
||||
const CHasherState &h = hashers[i];
|
||||
AddMinuses(_s, GetColumnWidth(h.DigestSize));
|
||||
}
|
||||
|
||||
if (PrintSize)
|
||||
}
|
||||
else if (c == 's')
|
||||
{
|
||||
_s.Add_Space();
|
||||
AddSpace();
|
||||
AddMinuses(_s, kSizeField_Len);
|
||||
}
|
||||
|
||||
if (PrintName)
|
||||
else if (c == 'n')
|
||||
{
|
||||
AddSpacesBeforeName();
|
||||
AddMinuses(_s, kNameField_Len);
|
||||
}
|
||||
}
|
||||
|
||||
*_so << _s << endl;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
|
||||
{
|
||||
if (PrintHeaders && _so)
|
||||
@@ -156,28 +185,34 @@ HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
|
||||
_s.Empty();
|
||||
ClosePercents_for_so();
|
||||
|
||||
const AString fields = GetFields();
|
||||
for (unsigned pos = 0; pos < fields.Len(); pos++)
|
||||
{
|
||||
const char c = fields[pos];
|
||||
if (c == 'h')
|
||||
{
|
||||
FOR_VECTOR (i, hb.Hashers)
|
||||
{
|
||||
if (i != 0)
|
||||
_s.Add_Space();
|
||||
AddSpace();
|
||||
const CHasherState &h = hb.Hashers[i];
|
||||
_s += h.Name;
|
||||
AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len());
|
||||
}
|
||||
}
|
||||
|
||||
if (PrintSize)
|
||||
else if (c == 's')
|
||||
{
|
||||
_s.Add_Space();
|
||||
AddSpace();
|
||||
const AString s2 ("Size");
|
||||
AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());
|
||||
_s += s2;
|
||||
}
|
||||
|
||||
if (PrintName)
|
||||
else if (c == 'n')
|
||||
{
|
||||
AddSpacesBeforeName();
|
||||
_s += "Name";
|
||||
}
|
||||
}
|
||||
|
||||
*_so << _s << endl;
|
||||
PrintSeparatorLine(hb.Hashers);
|
||||
@@ -191,9 +226,11 @@ HRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemErr
|
||||
return OpenFileError_Base(path, systemError);
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */)
|
||||
HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool isDir)
|
||||
{
|
||||
_fileName = name;
|
||||
if (isDir)
|
||||
NWindows::NFile::NName::NormalizeDirPathPrefix(_fileName);
|
||||
|
||||
if (NeedPercents())
|
||||
{
|
||||
@@ -208,57 +245,81 @@ HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */
|
||||
return CheckBreak2();
|
||||
}
|
||||
|
||||
|
||||
static const unsigned k_DigestStringSize = k_HashCalc_DigestSize_Max * 2 + k_HashCalc_ExtraSize * 2 + 16;
|
||||
|
||||
|
||||
|
||||
void CHashCallbackConsole::PrintResultLine(UInt64 fileSize,
|
||||
const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash)
|
||||
const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash,
|
||||
const AString &path)
|
||||
{
|
||||
ClosePercents_for_so();
|
||||
|
||||
_s.Empty();
|
||||
const AString fields = GetFields();
|
||||
|
||||
for (unsigned pos = 0; pos < fields.Len(); pos++)
|
||||
{
|
||||
const char c = fields[pos];
|
||||
if (c == 'h')
|
||||
{
|
||||
FOR_VECTOR (i, hashers)
|
||||
{
|
||||
AddSpace();
|
||||
const CHasherState &h = hashers[i];
|
||||
char s[k_HashCalc_DigestSize_Max * 2 + 64];
|
||||
char s[k_DigestStringSize];
|
||||
s[0] = 0;
|
||||
if (showHash)
|
||||
AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
|
||||
const unsigned pos = (unsigned)strlen(s);
|
||||
SetSpacesAndNul(s + pos, GetColumnWidth(h.DigestSize) - pos);
|
||||
if (i != 0)
|
||||
_s.Add_Space();
|
||||
h.WriteToString(digestIndex, s);
|
||||
const unsigned len = (unsigned)strlen(s);
|
||||
SetSpacesAndNul_if_Positive(s + len, (int)GetColumnWidth(h.DigestSize) - (int)len);
|
||||
_s += s;
|
||||
}
|
||||
|
||||
if (PrintSize)
|
||||
}
|
||||
else if (c == 's')
|
||||
{
|
||||
_s.Add_Space();
|
||||
|
||||
AddSpace();
|
||||
char s[kSizeField_Len + 32];
|
||||
char *p = s;
|
||||
|
||||
SetSpacesAndNul(s, kSizeField_Len);
|
||||
if (showHash)
|
||||
{
|
||||
p = s + kSizeField_Len;
|
||||
ConvertUInt64ToString(fileSize, p);
|
||||
int numSpaces = (int)kSizeField_Len - (int)strlen(p);
|
||||
const int numSpaces = (int)kSizeField_Len - (int)strlen(p);
|
||||
if (numSpaces > 0)
|
||||
p -= (unsigned)numSpaces;
|
||||
}
|
||||
|
||||
_s += p;
|
||||
}
|
||||
|
||||
if (PrintName)
|
||||
else if (c == 'n')
|
||||
{
|
||||
AddSpacesBeforeName();
|
||||
_s += path;
|
||||
}
|
||||
}
|
||||
|
||||
*_so << _s;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash)
|
||||
{
|
||||
if (_so)
|
||||
{
|
||||
AString s;
|
||||
if (_fileName.IsEmpty())
|
||||
s = kEmptyFileAlias;
|
||||
else
|
||||
{
|
||||
UString temp = _fileName;
|
||||
_so->Normalize_UString(temp);
|
||||
_so->Convert_UString_to_AString(temp, s);
|
||||
}
|
||||
PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash, s);
|
||||
|
||||
/*
|
||||
PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash);
|
||||
if (PrintName)
|
||||
{
|
||||
@@ -267,6 +328,8 @@ HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBun
|
||||
else
|
||||
_so->NormalizePrint_UString(_fileName);
|
||||
}
|
||||
*/
|
||||
// if (PrintNewLine)
|
||||
*_so << endl;
|
||||
}
|
||||
|
||||
@@ -299,9 +362,9 @@ static void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIn
|
||||
|
||||
so << k_DigestTitles[digestIndex];
|
||||
|
||||
char s[k_HashCalc_DigestSize_Max * 2 + 64];
|
||||
s[0] = 0;
|
||||
AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
|
||||
char s[k_DigestStringSize];
|
||||
// s[0] = 0;
|
||||
h.WriteToString(digestIndex, s);
|
||||
so << s << endl;
|
||||
}
|
||||
|
||||
@@ -336,7 +399,7 @@ HRESULT CHashCallbackConsole::AfterLastFile(CHashBundle &hb)
|
||||
{
|
||||
PrintSeparatorLine(hb.Hashers);
|
||||
|
||||
PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true);
|
||||
PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true, AString());
|
||||
|
||||
*_so << endl << endl;
|
||||
|
||||
|
||||
@@ -12,15 +12,23 @@ class CHashCallbackConsole: public IHashCallbackUI, public CCallbackConsoleBase
|
||||
UString _fileName;
|
||||
AString _s;
|
||||
|
||||
void AddSpace()
|
||||
{
|
||||
_s.Add_Space_if_NotEmpty();
|
||||
}
|
||||
|
||||
void AddSpacesBeforeName()
|
||||
{
|
||||
if (!_s.IsEmpty())
|
||||
{
|
||||
_s.Add_Space();
|
||||
_s.Add_Space();
|
||||
}
|
||||
}
|
||||
|
||||
void PrintSeparatorLine(const CObjectVector<CHasherState> &hashers);
|
||||
void PrintResultLine(UInt64 fileSize,
|
||||
const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash);
|
||||
const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash, const AString &path);
|
||||
void PrintProperty(const char *name, UInt64 value);
|
||||
|
||||
public:
|
||||
@@ -28,14 +36,17 @@ public:
|
||||
|
||||
bool PrintHeaders;
|
||||
|
||||
bool PrintSize;
|
||||
bool PrintName;
|
||||
// bool PrintSize;
|
||||
// bool PrintNewLine; // set it too (false), if you need only hash for single file without LF char.
|
||||
AString PrintFields;
|
||||
|
||||
AString GetFields() const;
|
||||
|
||||
CHashCallbackConsole():
|
||||
PrintNameInPercents(true),
|
||||
PrintHeaders(false),
|
||||
PrintSize(true),
|
||||
PrintName(true)
|
||||
PrintHeaders(false)
|
||||
// , PrintSize(true),
|
||||
// , PrintNewLine(true)
|
||||
{}
|
||||
|
||||
virtual ~CHashCallbackConsole() {}
|
||||
|
||||
@@ -505,7 +505,7 @@ static void PrintTime(char *dest, const FILETIME *ft)
|
||||
|
||||
static inline char GetHex(Byte value)
|
||||
{
|
||||
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
|
||||
return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10)));
|
||||
}
|
||||
|
||||
static void HexToString(char *dest, const Byte *data, UInt32 size)
|
||||
@@ -1019,7 +1019,9 @@ HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const
|
||||
|
||||
bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
|
||||
|
||||
HRESULT ListArchives(CCodecs *codecs,
|
||||
HRESULT ListArchives(
|
||||
const CListOptions &listOptions,
|
||||
CCodecs *codecs,
|
||||
const CObjectVector<COpenType> &types,
|
||||
const CIntVector &excludedFormats,
|
||||
bool stdInMode,
|
||||
@@ -1271,6 +1273,9 @@ HRESULT ListArchives(CCodecs *codecs,
|
||||
|
||||
RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir));
|
||||
|
||||
if (fp.IsDir ? listOptions.ExcludeDirItems : listOptions.ExcludeFileItems)
|
||||
continue;
|
||||
|
||||
if (!allFilesAreAllowed)
|
||||
{
|
||||
if (isAltStream)
|
||||
|
||||
@@ -7,7 +7,20 @@
|
||||
|
||||
#include "../Common/LoadCodecs.h"
|
||||
|
||||
HRESULT ListArchives(CCodecs *codecs,
|
||||
struct CListOptions
|
||||
{
|
||||
bool ExcludeDirItems;
|
||||
bool ExcludeFileItems;
|
||||
|
||||
CListOptions():
|
||||
ExcludeDirItems(false),
|
||||
ExcludeFileItems(false)
|
||||
{}
|
||||
};
|
||||
|
||||
HRESULT ListArchives(
|
||||
const CListOptions &listOptions,
|
||||
CCodecs *codecs,
|
||||
const CObjectVector<COpenType> &types,
|
||||
const CIntVector &excludedFormats,
|
||||
bool stdInMode,
|
||||
|
||||
@@ -71,6 +71,9 @@ extern const CCodecInfo *g_Codecs[];
|
||||
extern unsigned g_NumHashers;
|
||||
extern const CHasherInfo *g_Hashers[];
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
const CExternalCodecs *g_ExternalCodecs_Ptr;
|
||||
#endif
|
||||
|
||||
#if defined(PROG_VARIANT_Z)
|
||||
#define PROG_POSTFIX "z"
|
||||
@@ -859,9 +862,11 @@ int Main2(
|
||||
codecs->CaseSensitiveChange = options.CaseSensitiveChange;
|
||||
codecs->CaseSensitive = options.CaseSensitive;
|
||||
ThrowException_if_Error(codecs->Load());
|
||||
Codecs_AddHashArcHandler(codecs);
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
{
|
||||
g_ExternalCodecs_Ptr = &__externalCodecs;
|
||||
UString s;
|
||||
codecs->GetCodecsErrorMessage(s);
|
||||
if (!s.IsEmpty())
|
||||
@@ -872,8 +877,7 @@ int Main2(
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
|
||||
const bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
|
||||
|
||||
if (codecs->Formats.Size() == 0 &&
|
||||
(isExtractGroupCommand
|
||||
@@ -888,13 +892,15 @@ int Main2(
|
||||
throw s;
|
||||
}
|
||||
#endif
|
||||
|
||||
throw kNoFormats;
|
||||
}
|
||||
|
||||
CObjectVector<COpenType> types;
|
||||
if (!ParseOpenTypes(*codecs, options.ArcType, types))
|
||||
{
|
||||
throw kUnsupportedArcTypeMessage;
|
||||
}
|
||||
|
||||
|
||||
CIntVector excludedFormats;
|
||||
FOR_VECTOR (k, options.ExcludedArcTypes)
|
||||
@@ -903,13 +909,16 @@ int Main2(
|
||||
if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices)
|
||||
|| tempIndices.Size() != 1)
|
||||
throw kUnsupportedArcTypeMessage;
|
||||
|
||||
|
||||
|
||||
excludedFormats.AddToUniqueSorted(tempIndices[0]);
|
||||
// excludedFormats.Sort();
|
||||
}
|
||||
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
if (isExtractGroupCommand
|
||||
|| options.Command.IsFromUpdateGroup()
|
||||
|| options.Command.CommandType == NCommandType::kHash
|
||||
|| options.Command.CommandType == NCommandType::kBenchmark)
|
||||
ThrowException_if_Error(__externalCodecs.Load());
|
||||
@@ -943,7 +952,7 @@ int Main2(
|
||||
|
||||
so << endl << "Formats:" << endl;
|
||||
|
||||
const char * const kArcFlags = "KSNFMGOPBELHX";
|
||||
const char * const kArcFlags = "KSNFMGOPBELHXC";
|
||||
const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags);
|
||||
|
||||
for (i = 0; i < codecs->Formats.Size(); i++)
|
||||
@@ -989,6 +998,8 @@ int Main2(
|
||||
if (arc.SignatureOffset != 0)
|
||||
so << "offset=" << arc.SignatureOffset << ' ';
|
||||
|
||||
// so << "numSignatures = " << arc.Signatures.Size() << " ";
|
||||
|
||||
FOR_VECTOR(si, arc.Signatures)
|
||||
{
|
||||
if (si != 0)
|
||||
@@ -1030,6 +1041,7 @@ int Main2(
|
||||
|
||||
so << (char)(cod.CreateEncoder ? 'E' : ' ');
|
||||
so << (char)(cod.CreateDecoder ? 'D' : ' ');
|
||||
so << (char)(cod.IsFilter ? 'F' : ' ');
|
||||
|
||||
so << ' ';
|
||||
PrintHexId(so, cod.Id);
|
||||
@@ -1053,6 +1065,12 @@ int Main2(
|
||||
|
||||
so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' ');
|
||||
so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' ');
|
||||
{
|
||||
bool isFilter_Assigned;
|
||||
const bool isFilter = codecs->GetCodec_IsFilter(j, isFilter_Assigned);
|
||||
so << (char)(isFilter ? 'F' : isFilter_Assigned ? ' ' : '*');
|
||||
}
|
||||
|
||||
|
||||
so << ' ';
|
||||
UInt64 id;
|
||||
@@ -1215,6 +1233,7 @@ int Main2(
|
||||
}
|
||||
|
||||
hresultMain = Extract(
|
||||
// EXTERNAL_CODECS_VARS_L
|
||||
codecs,
|
||||
types,
|
||||
excludedFormats,
|
||||
@@ -1329,7 +1348,12 @@ int Main2(
|
||||
|
||||
// options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed
|
||||
|
||||
CListOptions lo;
|
||||
lo.ExcludeDirItems = options.Censor.ExcludeDirItems;
|
||||
lo.ExcludeFileItems = options.Censor.ExcludeFileItems;
|
||||
|
||||
hresultMain = ListArchives(
|
||||
lo,
|
||||
codecs,
|
||||
types,
|
||||
excludedFormats,
|
||||
@@ -1429,6 +1453,7 @@ int Main2(
|
||||
|
||||
callback.Init(g_StdStream, g_ErrStream, percentsStream);
|
||||
callback.PrintHeaders = options.EnableHeaders;
|
||||
callback.PrintFields = options.ListFields;
|
||||
|
||||
AString errorInfoString;
|
||||
hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
@@ -470,7 +471,7 @@ HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const
|
||||
return CheckBreak2();
|
||||
}
|
||||
|
||||
HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *command, bool showInLog)
|
||||
HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog)
|
||||
{
|
||||
MT_LOCK
|
||||
|
||||
@@ -489,6 +490,8 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *com
|
||||
if (name)
|
||||
{
|
||||
_tempU = name;
|
||||
if (isDir)
|
||||
NWindows::NFile::NName::NormalizeDirPathPrefix(_tempU);
|
||||
_so->Normalize_UString(_tempU);
|
||||
}
|
||||
_so->PrintUString(_tempU, _tempA);
|
||||
@@ -516,7 +519,7 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *com
|
||||
return CheckBreak2();
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool /* isDir */, bool isAnti, UInt32 mode)
|
||||
HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode)
|
||||
{
|
||||
if (StdOutMode)
|
||||
return S_OK;
|
||||
@@ -546,7 +549,7 @@ HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool /* isDir */,
|
||||
s = "Reading";
|
||||
}
|
||||
|
||||
return PrintProgress(name, s, LogLevel >= requiredLevel);
|
||||
return PrintProgress(name, isDir, s, LogLevel >= requiredLevel);
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::OpenFileError(const FString &path, DWORD systemError)
|
||||
@@ -594,7 +597,7 @@ HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypt
|
||||
}
|
||||
|
||||
|
||||
HRESULT CUpdateCallbackConsole::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool /* isDir */)
|
||||
HRESULT CUpdateCallbackConsole::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir)
|
||||
{
|
||||
// if (StdOutMode) return S_OK;
|
||||
|
||||
@@ -622,7 +625,7 @@ HRESULT CUpdateCallbackConsole::ReportUpdateOpeartion(UInt32 op, const wchar_t *
|
||||
}
|
||||
}
|
||||
|
||||
return PrintProgress(name, s, LogLevel >= requiredLevel);
|
||||
return PrintProgress(name, isDir, s, LogLevel >= requiredLevel);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -694,7 +697,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool /* isDir */)
|
||||
HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool isDir)
|
||||
{
|
||||
if (StdOutMode)
|
||||
return S_OK;
|
||||
@@ -703,7 +706,7 @@ HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool /* isDi
|
||||
{
|
||||
if (!name || name[0] == 0)
|
||||
name = kEmptyFileAlias;
|
||||
return PrintProgress(name, "D", true);
|
||||
return PrintProgress(name, isDir, "D", true);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
CErrorPathCodes ScanErrors;
|
||||
UInt64 NumNonOpenFiles;
|
||||
|
||||
HRESULT PrintProgress(const wchar_t *name, const char *command, bool showInLog);
|
||||
HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ CFLAGS = $(CFLAGS) \
|
||||
COMMON_OBJS = \
|
||||
$O\CommandLineParser.obj \
|
||||
$O\CRC.obj \
|
||||
$O\DynLimBuf.obj \
|
||||
$O\IntToString.obj \
|
||||
$O\ListFileUtils.obj \
|
||||
$O\NewHandler.obj \
|
||||
@@ -48,6 +49,7 @@ WIN_OBJS = \
|
||||
$O\UniqBlocks.obj \
|
||||
|
||||
AR_COMMON_OBJS = \
|
||||
$O\ItemNameUtils.obj \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
|
||||
COMPRESS_OBJS = \
|
||||
|
||||
@@ -100,6 +100,7 @@ COMMON_OBJS = \
|
||||
$O/CommandLineParser.o \
|
||||
$O/CRC.o \
|
||||
$O/CrcReg.o \
|
||||
$O/DynLimBuf.o \
|
||||
$O/IntToString.o \
|
||||
$O/ListFileUtils.o \
|
||||
$O/NewHandler.o \
|
||||
@@ -148,6 +149,9 @@ WIN_OBJS = \
|
||||
COMPRESS_OBJS = \
|
||||
$O/CopyCoder.o \
|
||||
|
||||
AR_COMMON_OBJS = \
|
||||
$O/ItemNameUtils.o \
|
||||
|
||||
C_OBJS = \
|
||||
$O/Alloc.o \
|
||||
$O/CpuArch.o \
|
||||
@@ -163,6 +167,7 @@ OBJS = \
|
||||
$(WIN_OBJS) \
|
||||
$(SYS_OBJS) \
|
||||
$(COMPRESS_OBJS) \
|
||||
$(AR_COMMON_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$(UI_COMMON_OBJS) \
|
||||
$(CONSOLE_OBJS) \
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/COM.h"
|
||||
@@ -15,12 +16,15 @@
|
||||
#include "../../../Windows/ProcessUtils.h"
|
||||
#include "../../../Windows/Shell.h"
|
||||
|
||||
#include "../../PropID.h"
|
||||
|
||||
#include "../Common/ArchiveName.h"
|
||||
#include "../Common/CompressCall.h"
|
||||
#include "../Common/ExtractingFilePath.h"
|
||||
#include "../Common/ZipRegistry.h"
|
||||
|
||||
#include "../FileManager/FormatUtils.h"
|
||||
#include "../FileManager/PropertyName.h"
|
||||
|
||||
#ifdef LANG
|
||||
#include "../FileManager/LangUtils.h"
|
||||
@@ -52,16 +56,65 @@ extern LONG g_DllRefCount;
|
||||
extern HINSTANCE g_hInstance;
|
||||
#endif
|
||||
|
||||
#ifdef SHOW_DEBUG_CTX_MENU
|
||||
|
||||
void Print_Ptr(void *p, char *s)
|
||||
{
|
||||
char temp[64];
|
||||
ConvertUInt64ToHex((UInt64)(void *)p, temp);
|
||||
AString s2;
|
||||
s2 += temp;
|
||||
s2.Add_Space();
|
||||
s2 += s;
|
||||
OutputDebugStringA(s2);
|
||||
}
|
||||
|
||||
void Print_Number(UInt32 number, char *s)
|
||||
{
|
||||
char temp[64];
|
||||
ConvertUInt64ToString(number, temp);
|
||||
AString s2;
|
||||
s2 += temp;
|
||||
s2.Add_Space();
|
||||
s2 += s;
|
||||
OutputDebugStringA(s2);
|
||||
}
|
||||
|
||||
#define ODS(sz) Print_Ptr(this, sz)
|
||||
#define ODS_U(s) OutputDebugStringW(s);
|
||||
// #define ODS(sz)
|
||||
// #define ODS_U(s)
|
||||
|
||||
#define ODS2(sz) Print_Ptr(this, sz)
|
||||
|
||||
#else
|
||||
|
||||
#define Print_Number(number, s)
|
||||
#define ODS(sz)
|
||||
#define ODS_U(s)
|
||||
#define ODS2(sz)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
CZipContextMenu::CZipContextMenu():
|
||||
_isMenuForFM(false),
|
||||
_bitmap(NULL)
|
||||
_dropMode(false),
|
||||
_bitmap(NULL),
|
||||
IsSeparator(false),
|
||||
IsRoot(true),
|
||||
CurrentSubCommand(0)
|
||||
{
|
||||
ODS("-- CZipContextMenu()");
|
||||
|
||||
InterlockedIncrement(&g_DllRefCount);
|
||||
_bitmap = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_MENU_LOGO));
|
||||
}
|
||||
|
||||
CZipContextMenu::~CZipContextMenu()
|
||||
{
|
||||
ODS("== ~CZipContextMenu");
|
||||
if (_bitmap != NULL)
|
||||
DeleteObject(_bitmap);
|
||||
InterlockedDecrement(&g_DllRefCount);
|
||||
@@ -184,7 +237,9 @@ static const CHashCommand g_HashCommands[] =
|
||||
{ CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" },
|
||||
{ CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" },
|
||||
{ CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" },
|
||||
{ CZipContextMenu::kHash_All, "*", "*" }
|
||||
{ CZipContextMenu::kHash_All, "*", "*" },
|
||||
{ CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" },
|
||||
{ CZipContextMenu::kHash_TestArc, "Checksum : Test", "Hash" }
|
||||
};
|
||||
|
||||
|
||||
@@ -209,10 +264,20 @@ void CZipContextMenu::FillCommand(ECommandInternalID id, UString &mainString, CC
|
||||
cmi.Verb += command.Verb;
|
||||
// cmi.HelpString = cmi.Verb;
|
||||
LangString(command.ResourceID, mainString);
|
||||
cmi.UserString = mainString;
|
||||
// return true;
|
||||
}
|
||||
|
||||
|
||||
static UString LangStringAlt(UInt32 id, const char *altString)
|
||||
{
|
||||
UString s = LangString(id);
|
||||
if (s.IsEmpty())
|
||||
s = altString;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void CZipContextMenu::AddCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi)
|
||||
{
|
||||
FillCommand(id, mainString, cmi);
|
||||
@@ -222,6 +287,8 @@ void CZipContextMenu::AddCommand(ECommandInternalID id, UString &mainString, CCo
|
||||
|
||||
static void MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s, HBITMAP bitmap)
|
||||
{
|
||||
if (!menu)
|
||||
return;
|
||||
CMenuItem mi;
|
||||
mi.fType = MFT_STRING;
|
||||
mi.fMask = MIIM_TYPE | MIIM_ID;
|
||||
@@ -247,9 +314,14 @@ static void MyAddSubMenu(
|
||||
CZipContextMenu::CCommandMapItem cmi;
|
||||
cmi.CommandInternalID = CZipContextMenu::kCommandNULL;
|
||||
cmi.Verb = verb;
|
||||
cmi.IsPopup = true;
|
||||
// cmi.HelpString = verb;
|
||||
cmi.UserString = s;
|
||||
_commandMap.Add(cmi);
|
||||
|
||||
if (!menu)
|
||||
return;
|
||||
|
||||
CMenuItem mi;
|
||||
mi.fType = MFT_STRING;
|
||||
mi.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
|
||||
@@ -329,7 +401,7 @@ static void MyFormatNew_ReducedName(UString &s, const UString &name)
|
||||
s = MyFormatNew(s, GetQuotedReducedString(name));
|
||||
}
|
||||
|
||||
static const char * const kExtractExludeExtensions =
|
||||
static const char * const kExtractExcludeExtensions =
|
||||
" 3gp"
|
||||
" aac ans ape asc asm asp aspx avi awk"
|
||||
" bas bat bmp"
|
||||
@@ -403,7 +475,7 @@ static bool FindExt(const char *p, const FString &name)
|
||||
|
||||
static bool DoNeedExtract(const FString &name)
|
||||
{
|
||||
return !FindExt(kExtractExludeExtensions, name);
|
||||
return !FindExt(kExtractExcludeExtensions, name);
|
||||
}
|
||||
|
||||
// we must use diferent Verbs for Popup subMenu.
|
||||
@@ -427,12 +499,12 @@ static HRESULT RETURN_WIN32_LastError_AS_HRESULT()
|
||||
|
||||
|
||||
/*
|
||||
we add CCommandMapItem to _commandMap for each new Mene ID.
|
||||
we add CCommandMapItem to _commandMap for each new Menu ID.
|
||||
so then we use _commandMap[offset].
|
||||
That way we can execute commands that have menu item.
|
||||
Another non-implemented way:
|
||||
We can return the number off all possible commnad in QueryContextMenu().
|
||||
so the caller could call InvokeCommand() via string verb aven
|
||||
We can return the number off all possible commands in QueryContextMenu().
|
||||
so the caller could call InvokeCommand() via string verb even
|
||||
without using menu items.
|
||||
*/
|
||||
|
||||
@@ -441,6 +513,7 @@ static HRESULT RETURN_WIN32_LastError_AS_HRESULT()
|
||||
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
UINT commandIDFirst, UINT commandIDLast, UINT flags)
|
||||
{
|
||||
ODS("+ QueryContextMenu()");
|
||||
COM_TRY_BEGIN
|
||||
try {
|
||||
|
||||
@@ -494,8 +567,11 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
|
||||
UINT subIndex = indexMenu;
|
||||
|
||||
ODS("### 50");
|
||||
|
||||
if (ci.Cascaded.Val)
|
||||
{
|
||||
if (hMenu)
|
||||
if (!popupMenu.CreatePopup())
|
||||
return RETURN_WIN32_LastError_AS_HRESULT();
|
||||
menuDestroyer.Attach(popupMenu);
|
||||
@@ -514,6 +590,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
CMenuItem mi;
|
||||
mi.fType = MFT_SEPARATOR;
|
||||
mi.fMask = MIIM_TYPE;
|
||||
if (hMenu)
|
||||
popupMenu.InsertItem(subIndex++, true, mi);
|
||||
}
|
||||
|
||||
@@ -551,6 +628,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
}
|
||||
}
|
||||
|
||||
ODS("### 100");
|
||||
|
||||
UString mainString;
|
||||
|
||||
if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast)
|
||||
@@ -567,12 +646,14 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
}
|
||||
if ((contextMenuFlags & NContextMenuFlags::kOpenAs) != 0
|
||||
// && (!thereIsMainOpenItem || !FindExt(kNoOpenAsExtensions, fi0.Name))
|
||||
&& hMenu // we want to reduce number of menu items below 16
|
||||
)
|
||||
{
|
||||
CMenu subMenu;
|
||||
if (subMenu.CreatePopup())
|
||||
if (!hMenu || subMenu.CreatePopup())
|
||||
{
|
||||
MyAddSubMenu(_commandMap, kOpenCascadedVerb, popupMenu, subIndex++, currentCommandID++, LangString(IDS_CONTEXT_OPEN), subMenu, bitmap);
|
||||
_commandMap.Back().CtxCommandType = CtxCommandType_OpenRoot;
|
||||
|
||||
UINT subIndex2 = 0;
|
||||
for (unsigned i = (thereIsMainOpenItem ? 1 : 0); i < ARRAY_SIZE(kOpenTypes); i++)
|
||||
@@ -589,8 +670,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
cmi.Verb += mainString;
|
||||
// cmi.HelpString = cmi.Verb;
|
||||
cmi.ArcType = mainString;
|
||||
cmi.CtxCommandType = CtxCommandType_OpenChild;
|
||||
}
|
||||
_commandMap.Add(cmi);
|
||||
Set_UserString_in_LastCommand(mainString);
|
||||
MyInsertMenu(subMenu, subIndex2++, currentCommandID++, mainString, bitmap);
|
||||
}
|
||||
|
||||
@@ -662,6 +745,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
cmi.Folder = baseFolder + specFolder;
|
||||
AddCommand(kExtractTo, s, cmi);
|
||||
MyFormatNew_ReducedName(s, specFolder);
|
||||
Set_UserString_in_LastCommand(s);
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
|
||||
}
|
||||
}
|
||||
@@ -720,6 +804,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
cmi.ArcType = "7z";
|
||||
AddCommand(kCompressTo7z, s, cmi);
|
||||
MyFormatNew_ReducedName(s, arcName7z);
|
||||
Set_UserString_in_LastCommand(s);
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
|
||||
}
|
||||
|
||||
@@ -733,6 +818,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
cmi.ArcType = "7z";
|
||||
AddCommand(kCompressTo7zEmail, s, cmi);
|
||||
MyFormatNew_ReducedName(s, arcName7z);
|
||||
Set_UserString_in_LastCommand(s);
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
|
||||
}
|
||||
#endif
|
||||
@@ -751,6 +837,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
cmi.ArcType = "zip";
|
||||
AddCommand(kCompressToZip, s, cmi);
|
||||
MyFormatNew_ReducedName(s, arcNameZip);
|
||||
Set_UserString_in_LastCommand(s);
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
|
||||
}
|
||||
|
||||
@@ -764,6 +851,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
cmi.ArcType = "zip";
|
||||
AddCommand(kCompressToZipEmail, s, cmi);
|
||||
MyFormatNew_ReducedName(s, arcNameZip);
|
||||
Set_UserString_in_LastCommand(s);
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
|
||||
}
|
||||
#endif
|
||||
@@ -779,32 +867,56 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
CMenu menu;
|
||||
menu.Attach(hMenu);
|
||||
menuDestroyer.Disable();
|
||||
MyAddSubMenu(_commandMap, kMainVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip", popupMenu.Detach(), bitmap);
|
||||
MyAddSubMenu(_commandMap, kMainVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip",
|
||||
popupMenu, // popupMenu.Detach(),
|
||||
bitmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
popupMenu.Detach();
|
||||
// popupMenu.Detach();
|
||||
indexMenu = subIndex;
|
||||
}
|
||||
|
||||
const bool needCrc = ((contextMenuFlags &
|
||||
(NContextMenuFlags::kCRC |
|
||||
NContextMenuFlags::kCRC_Cascaded)) != 0);
|
||||
|
||||
if (!_isMenuForFM &&
|
||||
((contextMenuFlags & NContextMenuFlags::kCRC) != 0
|
||||
&& currentCommandID + 1 < commandIDLast))
|
||||
if (
|
||||
// !_isMenuForFM && // 21.04: we don't hide CRC SHA menu in 7-Zip FM
|
||||
needCrc
|
||||
&& currentCommandID + 1 < commandIDLast)
|
||||
{
|
||||
CMenu subMenu;
|
||||
// CMenuDestroyer menuDestroyer_CRC;
|
||||
|
||||
UINT subIndex_CRC = 0;
|
||||
|
||||
if (subMenu.CreatePopup())
|
||||
if (!hMenu || subMenu.CreatePopup())
|
||||
{
|
||||
// menuDestroyer_CRC.Attach(subMenu);
|
||||
const bool insertHashMenuTo7zipMenu = (ci.Cascaded.Val
|
||||
&& (contextMenuFlags & NContextMenuFlags::kCRC_Cascaded) != 0);
|
||||
|
||||
CMenu menu;
|
||||
{
|
||||
int indexInParent;
|
||||
if (insertHashMenuTo7zipMenu)
|
||||
{
|
||||
indexInParent = subIndex;
|
||||
menu.Attach(popupMenu);
|
||||
}
|
||||
else
|
||||
{
|
||||
indexInParent = indexMenu;
|
||||
menu.Attach(hMenu);
|
||||
// menuDestroyer_CRC.Disable();
|
||||
MyAddSubMenu(_commandMap, kCheckSumCascadedVerb, menu, indexMenu++, currentCommandID++, (UString)"CRC SHA", subMenu, bitmap);
|
||||
}
|
||||
MyAddSubMenu(_commandMap, kCheckSumCascadedVerb, menu, indexInParent++, currentCommandID++, (UString)"CRC SHA", subMenu,
|
||||
/* insertHashMenuTo7zipMenu ? NULL : */ bitmap);
|
||||
_commandMap.Back().CtxCommandType = CtxCommandType_CrcRoot;
|
||||
if (!insertHashMenuTo7zipMenu)
|
||||
indexMenu = indexInParent;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
|
||||
{
|
||||
@@ -816,15 +928,57 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
cmi.Verb = kCheckSumCascadedVerb;
|
||||
cmi.Verb += '.';
|
||||
cmi.Verb += hc.MethodName;
|
||||
UString s;
|
||||
s += hc.UserName;
|
||||
|
||||
if (hc.CommandInternalID == kHash_Generate_SHA256)
|
||||
{
|
||||
{
|
||||
popupMenu.Attach(hMenu);
|
||||
CMenuItem mi;
|
||||
mi.fType = MFT_SEPARATOR;
|
||||
mi.fMask = MIIM_TYPE;
|
||||
subMenu.InsertItem(subIndex_CRC++, true, mi);
|
||||
}
|
||||
|
||||
UString name;
|
||||
if (_fileNames.Size() > 1)
|
||||
name = CreateArchiveName(_fileNames, _fileNames.Size() == 1 ? &fi0 : NULL);
|
||||
else
|
||||
name = fs2us(fi0.Name);
|
||||
name += ".sha256";
|
||||
cmi.Folder= folderPrefix;
|
||||
cmi.ArcName = name;
|
||||
s = "SHA-256 -> ";
|
||||
s += name;
|
||||
}
|
||||
else if (hc.CommandInternalID == kHash_TestArc)
|
||||
{
|
||||
s = LangStringAlt(IDS_CONTEXT_TEST, "Test archive");
|
||||
s += " : ";
|
||||
s += GetNameOfProperty(kpidChecksum, UString("Checksum"));
|
||||
}
|
||||
|
||||
// cmi.HelpString = cmi.Verb;
|
||||
cmi.UserString = s;
|
||||
cmi.CtxCommandType = CtxCommandType_CrcChild;
|
||||
_commandMap.Add(cmi);
|
||||
MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, (UString)hc.UserName, bitmap);
|
||||
MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, s, bitmap);
|
||||
}
|
||||
|
||||
subMenu.Detach();
|
||||
}
|
||||
}
|
||||
|
||||
popupMenu.Detach();
|
||||
|
||||
/*
|
||||
if (!ci.Cascaded.Val)
|
||||
indexMenu = subIndex;
|
||||
*/
|
||||
|
||||
ODS("### 400");
|
||||
|
||||
#ifdef SHOW_DEBUG_CTX_MENU
|
||||
{ char s[256]; sprintf(s, "Commands=%d currentCommandID - commandIDFirst = %d",
|
||||
_commandMap.Size(), currentCommandID - commandIDFirst); OutputDebugStringA(s); }
|
||||
@@ -981,9 +1135,15 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
|
||||
if (commandOffset < 0 || (unsigned)commandOffset >= _commandMap.Size())
|
||||
return E_INVALIDARG;
|
||||
|
||||
const CCommandMapItem &cmi = _commandMap[(unsigned)commandOffset];
|
||||
ECommandInternalID cmdID = cmi.CommandInternalID;
|
||||
return InvokeCommandCommon(cmi);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi)
|
||||
{
|
||||
const ECommandInternalID cmdID = cmi.CommandInternalID;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1023,18 +1183,20 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
case kCompressToZip:
|
||||
case kCompressToZipEmail:
|
||||
{
|
||||
bool email =
|
||||
const bool email =
|
||||
(cmdID == kCompressEmail) ||
|
||||
(cmdID == kCompressTo7zEmail) ||
|
||||
(cmdID == kCompressToZipEmail);
|
||||
bool showDialog =
|
||||
const bool showDialog =
|
||||
(cmdID == kCompress) ||
|
||||
(cmdID == kCompressEmail);
|
||||
bool addExtension = (cmdID == kCompress || cmdID == kCompressEmail);
|
||||
const bool addExtension = (cmdID == kCompress || cmdID == kCompressEmail);
|
||||
CompressFiles(cmi.Folder,
|
||||
cmi.ArcName, cmi.ArcType,
|
||||
addExtension,
|
||||
_fileNames, email, showDialog, false);
|
||||
_fileNames, email, showDialog,
|
||||
false // waitFinish
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1043,13 +1205,24 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
case kHash_SHA1:
|
||||
case kHash_SHA256:
|
||||
case kHash_All:
|
||||
case kHash_Generate_SHA256:
|
||||
case kHash_TestArc:
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
|
||||
{
|
||||
const CHashCommand &hc = g_HashCommands[i];
|
||||
if (hc.CommandInternalID == cmdID)
|
||||
{
|
||||
CalcChecksum(_fileNames, (UString)hc.MethodName);
|
||||
if (cmdID == kHash_TestArc)
|
||||
{
|
||||
TestArchives(_fileNames, true); // hashMode
|
||||
break;
|
||||
}
|
||||
UString generateName;
|
||||
if (cmdID == kHash_Generate_SHA256)
|
||||
generateName = cmi.ArcName;
|
||||
CalcChecksum(_fileNames, (UString)hc.MethodName,
|
||||
cmi.Folder, generateName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1064,7 +1237,6 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
::MessageBoxW(0, L"Error", L"7-Zip", MB_ICONERROR);
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
@@ -1136,3 +1308,371 @@ STDMETHODIMP CZipContextMenu::GetCommandString(UINT_PTR commandOffset, UINT uTyp
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------- IExplorerCommand ----------
|
||||
|
||||
static HRESULT WINAPI My_SHStrDupW(LPCWSTR src, LPWSTR *dest)
|
||||
{
|
||||
if (src)
|
||||
{
|
||||
const SIZE_T size = (wcslen(src) + 1) * sizeof(WCHAR);
|
||||
WCHAR *p = (WCHAR *)CoTaskMemAlloc(size);
|
||||
if (p)
|
||||
{
|
||||
memcpy(p, src, size);
|
||||
*dest = p;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
*dest = NULL;
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
|
||||
#define CZipExplorerCommand CZipContextMenu
|
||||
|
||||
class CCoTaskWSTR
|
||||
{
|
||||
LPWSTR m_str;
|
||||
CLASS_NO_COPY(CCoTaskWSTR)
|
||||
public:
|
||||
CCoTaskWSTR(): m_str(NULL) {}
|
||||
~CCoTaskWSTR() { ::CoTaskMemFree(m_str); }
|
||||
LPWSTR* operator&() { return &m_str; }
|
||||
operator LPCWSTR () const { return m_str; }
|
||||
// operator LPCOLESTR() const { return m_str; }
|
||||
operator bool() const { return m_str != NULL; }
|
||||
// bool operator!() const { return m_str == NULL; }
|
||||
|
||||
/*
|
||||
void Wipe_and_Free()
|
||||
{
|
||||
if (m_str)
|
||||
{
|
||||
memset(m_str, 0, ::SysStringLen(m_str) * sizeof(*m_str));
|
||||
Empty();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private:
|
||||
/*
|
||||
CCoTaskWSTR(LPCOLESTR src) { m_str = ::CoTaskMemAlloc(src); }
|
||||
|
||||
CCoTaskWSTR& operator=(LPCOLESTR src)
|
||||
{
|
||||
::CoTaskMemFree(m_str);
|
||||
m_str = ::SysAllocString(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Empty()
|
||||
{
|
||||
::CoTaskMemFree(m_str);
|
||||
m_str = NULL;
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
static void LoadPaths(IShellItemArray *psiItemArray, UStringVector &paths)
|
||||
{
|
||||
if (psiItemArray)
|
||||
{
|
||||
DWORD numItems = 0;
|
||||
if (psiItemArray->GetCount(&numItems) == S_OK)
|
||||
{
|
||||
for (DWORD i = 0; i < numItems; i++)
|
||||
{
|
||||
CMyComPtr<IShellItem> item;
|
||||
if (psiItemArray->GetItemAt(i, &item) == S_OK && item)
|
||||
{
|
||||
CCoTaskWSTR displayName;
|
||||
if (item->GetDisplayName(SIGDN_FILESYSPATH, &displayName) == S_OK
|
||||
&& (bool)displayName)
|
||||
{
|
||||
OutputDebugStringW(displayName);
|
||||
paths.Add((LPCWSTR)displayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CZipExplorerCommand::LoadItems(IShellItemArray *psiItemArray)
|
||||
{
|
||||
SubCommands.Clear();
|
||||
|
||||
UStringVector paths;
|
||||
LoadPaths(psiItemArray, paths);
|
||||
_fileNames = paths;
|
||||
|
||||
HRESULT res = QueryContextMenu(
|
||||
NULL, // hMenu,
|
||||
0, // indexMenu,
|
||||
0, // commandIDFirst,
|
||||
0 + 999, // commandIDLast,
|
||||
CMF_NORMAL);
|
||||
|
||||
if (FAILED(res))
|
||||
return /* res */;
|
||||
|
||||
|
||||
CZipExplorerCommand *crcHandler = NULL;
|
||||
CZipExplorerCommand *openHandler = NULL;
|
||||
|
||||
bool useCascadedCrc = true; // false;
|
||||
bool useCascadedOpen = true; // false;
|
||||
|
||||
for (unsigned i = 0; i < _commandMap.Size(); i++)
|
||||
{
|
||||
const CCommandMapItem &cmi = _commandMap[i];
|
||||
|
||||
|
||||
if (cmi.IsPopup)
|
||||
if (!cmi.IsSubMenu())
|
||||
continue;
|
||||
|
||||
// if (cmi.IsSubMenu()) continue // for debug
|
||||
|
||||
CZipContextMenu *shellExt = new CZipContextMenu();
|
||||
shellExt->IsRoot = false;
|
||||
|
||||
if (cmi.CtxCommandType == CtxCommandType_CrcRoot && !useCascadedCrc)
|
||||
shellExt->IsSeparator = true;
|
||||
|
||||
{
|
||||
CZipExplorerCommand *handler = this;
|
||||
if (cmi.CtxCommandType == CtxCommandType_CrcChild && crcHandler)
|
||||
handler = crcHandler;
|
||||
else if (cmi.CtxCommandType == CtxCommandType_OpenChild && openHandler)
|
||||
handler = openHandler;
|
||||
handler->SubCommands.AddNew() = shellExt;
|
||||
}
|
||||
|
||||
shellExt->_commandMap_Cur.Add(cmi);
|
||||
|
||||
ODS_U(cmi.UserString);
|
||||
|
||||
if (cmi.CtxCommandType == CtxCommandType_CrcRoot && useCascadedCrc)
|
||||
crcHandler = shellExt;
|
||||
if (cmi.CtxCommandType == CtxCommandType_OpenRoot && useCascadedOpen)
|
||||
{
|
||||
// ODS2("cmi.CtxCommandType == CtxCommandType_OpenRoot");
|
||||
openHandler = shellExt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipExplorerCommand::GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName)
|
||||
{
|
||||
ODS("- GetTitle()");
|
||||
// COM_TRY_BEGIN
|
||||
if (IsSeparator)
|
||||
{
|
||||
*ppszName = NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
UString name;
|
||||
if (IsRoot)
|
||||
{
|
||||
LoadItems(psiItemArray);
|
||||
name = "7-Zip"; // "New"
|
||||
}
|
||||
else
|
||||
name = "7-Zip item";
|
||||
|
||||
if (!_commandMap_Cur.IsEmpty())
|
||||
{
|
||||
const CCommandMapItem &mi = _commandMap_Cur[0];
|
||||
// s += mi.Verb;
|
||||
// s += " : ";
|
||||
name = mi.UserString;
|
||||
}
|
||||
|
||||
return My_SHStrDupW(name, ppszName);
|
||||
// return S_OK;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipExplorerCommand::GetIcon(IShellItemArray * /* psiItemArray */, LPWSTR *ppszIcon)
|
||||
{
|
||||
ODS("- GetIcon()");
|
||||
// COM_TRY_BEGIN
|
||||
*ppszIcon = NULL;
|
||||
// return E_NOTIMPL;
|
||||
UString imageName = fs2us(NWindows::NDLL::GetModuleDirPrefix());
|
||||
// imageName += "7zG.exe";
|
||||
imageName += "7-zip.dll";
|
||||
// imageName += ",190";
|
||||
return My_SHStrDupW(imageName, ppszIcon);
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipExplorerCommand::GetToolTip (IShellItemArray * /* psiItemArray */, LPWSTR *ppszInfotip)
|
||||
{
|
||||
// COM_TRY_BEGIN
|
||||
ODS("- GetToolTip()");
|
||||
*ppszInfotip = NULL;
|
||||
return E_NOTIMPL;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipExplorerCommand::GetCanonicalName(GUID *pguidCommandName)
|
||||
{
|
||||
// COM_TRY_BEGIN
|
||||
ODS("- GetCanonicalName()");
|
||||
*pguidCommandName = GUID_NULL;
|
||||
return E_NOTIMPL;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipExplorerCommand::GetState(IShellItemArray * /* psiItemArray */, BOOL /* fOkToBeSlow */, EXPCMDSTATE *pCmdState)
|
||||
{
|
||||
// COM_TRY_BEGIN
|
||||
ODS("- GetState()");
|
||||
*pCmdState = ECS_ENABLED;
|
||||
return S_OK;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CZipExplorerCommand::Invoke(IShellItemArray *psiItemArray, IBindCtx * /* pbc */)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
|
||||
if (_commandMap_Cur.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
|
||||
ODS("- Invoke()");
|
||||
UStringVector paths;
|
||||
LoadPaths(psiItemArray, paths);
|
||||
_fileNames = paths;
|
||||
return InvokeCommandCommon(_commandMap_Cur[0]);
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipExplorerCommand::GetFlags(EXPCMDFLAGS *pFlags)
|
||||
{
|
||||
ODS("- GetFlags()");
|
||||
// COM_TRY_BEGIN
|
||||
EXPCMDFLAGS f = ECF_DEFAULT;
|
||||
if (IsSeparator)
|
||||
f = ECF_ISSEPARATOR;
|
||||
else if (IsRoot)
|
||||
f = ECF_HASSUBCOMMANDS;
|
||||
else
|
||||
{
|
||||
if (!_commandMap_Cur.IsEmpty())
|
||||
{
|
||||
// const CCommandMapItem &cmi = ;
|
||||
if (_commandMap_Cur[0].IsSubMenu())
|
||||
{
|
||||
// ODS("ECF_HASSUBCOMMANDS");
|
||||
f = ECF_HASSUBCOMMANDS;
|
||||
}
|
||||
}
|
||||
}
|
||||
*pFlags = f;
|
||||
return S_OK;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipExplorerCommand::EnumSubCommands(IEnumExplorerCommand **ppEnum)
|
||||
{
|
||||
ODS("- EnumSubCommands()");
|
||||
// COM_TRY_BEGIN
|
||||
*ppEnum = NULL;
|
||||
|
||||
if (!_commandMap_Cur.IsEmpty() && _commandMap_Cur[0].IsSubMenu())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsRoot)
|
||||
return E_NOTIMPL;
|
||||
if (SubCommands.IsEmpty())
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
// shellExt->
|
||||
return QueryInterface(IID_IEnumExplorerCommand, (void **)ppEnum);
|
||||
|
||||
// return S_OK;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipContextMenu::Next(ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched)
|
||||
{
|
||||
ODS("CZipContextMenu::Next()");
|
||||
Print_Number(celt, "celt");
|
||||
Print_Number(CurrentSubCommand, "CurrentSubCommand");
|
||||
Print_Number(SubCommands.Size(), "SubCommands.Size()");
|
||||
|
||||
COM_TRY_BEGIN
|
||||
ULONG fetched = 0;
|
||||
|
||||
ULONG i;
|
||||
for (i = 0; i < celt; i++)
|
||||
{
|
||||
pUICommand[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < celt && CurrentSubCommand < SubCommands.Size(); i++)
|
||||
{
|
||||
pUICommand[i] = SubCommands[CurrentSubCommand++];
|
||||
pUICommand[i]->AddRef();
|
||||
fetched++;
|
||||
}
|
||||
|
||||
if (pceltFetched)
|
||||
*pceltFetched = fetched;
|
||||
|
||||
ODS(fetched == celt ? " === OK === " : "=== ERROR ===");
|
||||
|
||||
// we return S_FALSE for (fetched == 0)
|
||||
return (fetched == celt) ? S_OK : S_FALSE;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipContextMenu::Skip(ULONG celt)
|
||||
{
|
||||
ODS("CZipContextMenu::Skip()");
|
||||
celt = celt;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipContextMenu::Reset(void)
|
||||
{
|
||||
ODS("CZipContextMenu::Reset()");
|
||||
CurrentSubCommand = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipContextMenu::Clone(IEnumExplorerCommand **ppenum)
|
||||
{
|
||||
ODS("CZipContextMenu::Clone()");
|
||||
*ppenum = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -7,13 +7,27 @@
|
||||
|
||||
#include <ShlObj.h>
|
||||
|
||||
#include "MyExplorerCommand.h"
|
||||
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#include "../FileManager/MyCom2.h"
|
||||
|
||||
enum ECtxCommandType
|
||||
{
|
||||
CtxCommandType_Normal,
|
||||
CtxCommandType_OpenRoot,
|
||||
CtxCommandType_OpenChild,
|
||||
CtxCommandType_CrcRoot,
|
||||
CtxCommandType_CrcChild,
|
||||
};
|
||||
|
||||
|
||||
class CZipContextMenu:
|
||||
public IContextMenu,
|
||||
public IShellExtInit,
|
||||
public IExplorerCommand,
|
||||
public IEnumExplorerCommand,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
@@ -36,10 +50,17 @@ public:
|
||||
kHash_CRC64,
|
||||
kHash_SHA1,
|
||||
kHash_SHA256,
|
||||
kHash_All
|
||||
kHash_All,
|
||||
kHash_Generate_SHA256,
|
||||
kHash_TestArc
|
||||
};
|
||||
|
||||
MY_UNKNOWN_IMP2_MT(IContextMenu, IShellExtInit)
|
||||
MY_UNKNOWN_IMP4_MT(
|
||||
IContextMenu,
|
||||
IShellExtInit,
|
||||
IExplorerCommand,
|
||||
IEnumExplorerCommand
|
||||
)
|
||||
|
||||
// IShellExtInit
|
||||
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY hkeyProgID);
|
||||
@@ -51,6 +72,24 @@ public:
|
||||
|
||||
HRESULT InitContextMenu(const wchar_t *folder, const wchar_t * const *names, unsigned numFiles);
|
||||
|
||||
void LoadItems(IShellItemArray *psiItemArray);
|
||||
|
||||
// IExplorerCommand
|
||||
STDMETHOD (GetTitle) (IShellItemArray *psiItemArray, LPWSTR *ppszName);
|
||||
STDMETHOD (GetIcon) (IShellItemArray *psiItemArray, LPWSTR *ppszIcon);
|
||||
STDMETHOD (GetToolTip) (IShellItemArray *psiItemArray, LPWSTR *ppszInfotip);
|
||||
STDMETHOD (GetCanonicalName) (GUID *pguidCommandName);
|
||||
STDMETHOD (GetState) (IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState);
|
||||
STDMETHOD (Invoke) (IShellItemArray *psiItemArray, IBindCtx *pbc);
|
||||
STDMETHOD (GetFlags) (EXPCMDFLAGS *pFlags);
|
||||
STDMETHOD (EnumSubCommands) (IEnumExplorerCommand **ppEnum);
|
||||
|
||||
// IEnumExplorerCommand
|
||||
STDMETHOD (Next) (ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched);
|
||||
STDMETHOD (Skip) (ULONG celt);
|
||||
STDMETHOD (Reset) (void);
|
||||
STDMETHOD (Clone) (IEnumExplorerCommand **ppenum);
|
||||
|
||||
CZipContextMenu();
|
||||
~CZipContextMenu();
|
||||
|
||||
@@ -58,10 +97,25 @@ public:
|
||||
{
|
||||
ECommandInternalID CommandInternalID;
|
||||
UString Verb;
|
||||
UString UserString;
|
||||
// UString HelpString;
|
||||
UString Folder;
|
||||
UString ArcName;
|
||||
UString ArcType;
|
||||
bool IsPopup;
|
||||
ECtxCommandType CtxCommandType;
|
||||
|
||||
CCommandMapItem():
|
||||
IsPopup(false),
|
||||
CtxCommandType(CtxCommandType_Normal)
|
||||
{}
|
||||
|
||||
bool IsSubMenu() const
|
||||
{
|
||||
return
|
||||
CtxCommandType == CtxCommandType_CrcRoot ||
|
||||
CtxCommandType == CtxCommandType_OpenRoot;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -71,16 +125,28 @@ private:
|
||||
bool _dropMode;
|
||||
UString _dropPath;
|
||||
CObjectVector<CCommandMapItem> _commandMap;
|
||||
CObjectVector<CCommandMapItem> _commandMap_Cur;
|
||||
|
||||
HBITMAP _bitmap;
|
||||
|
||||
CBoolPair _elimDup;
|
||||
|
||||
bool IsSeparator;
|
||||
bool IsRoot;
|
||||
CObjectVector< CMyComPtr<IExplorerCommand> > SubCommands;
|
||||
ULONG CurrentSubCommand;
|
||||
|
||||
void Set_UserString_in_LastCommand(const UString &s)
|
||||
{
|
||||
_commandMap.Back().UserString = s;
|
||||
}
|
||||
|
||||
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
|
||||
int FindVerb(const UString &verb);
|
||||
void FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi);
|
||||
void AddCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi);
|
||||
void AddMapItem_ForSubMenu(const char *ver);
|
||||
|
||||
HRESULT InvokeCommandCommon(const CCommandMapItem &cmi);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace NContextMenuFlags
|
||||
const UInt32 kCompressToZip = 1 << 12;
|
||||
const UInt32 kCompressToZipEmail = 1 << 13;
|
||||
|
||||
const UInt32 kCRC_Cascaded = (UInt32)1 << 30;
|
||||
const UInt32 kCRC = (UInt32)1 << 31;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
// #include "../../../Common/IntToString.h"
|
||||
|
||||
#include <OleCtl.h>
|
||||
|
||||
@@ -52,7 +53,8 @@ LONG g_DllRefCount;
|
||||
LONG g_DllRefCount = 0; // Reference count of this DLL.
|
||||
|
||||
|
||||
// #define ODS(sz) OutputDebugString(L#sz)
|
||||
// #define ODS(sz) OutputDebugStringW(L#sz)
|
||||
#define ODS(sz)
|
||||
|
||||
class CShellExtClassFactory:
|
||||
public IClassFactory,
|
||||
@@ -71,7 +73,12 @@ public:
|
||||
STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
|
||||
REFIID riid, void **ppvObj)
|
||||
{
|
||||
// ODS("CShellExtClassFactory::CreateInstance()\r\n");
|
||||
ODS("CShellExtClassFactory::CreateInstance()\r\n");
|
||||
/*
|
||||
char s[64];
|
||||
ConvertUInt32ToHex(riid.Data1, s);
|
||||
OutputDebugStringA(s);
|
||||
*/
|
||||
*ppvObj = NULL;
|
||||
if (pUnkOuter)
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
@@ -123,12 +130,12 @@ BOOL WINAPI DllMain(
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
g_hInstance = (HINSTANCE)hInstance;
|
||||
// ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n");
|
||||
ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n");
|
||||
NT_CHECK
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
// ODS("In DLLMain, DLL_PROCESS_DETACH\r\n");
|
||||
ODS("In DLLMain, DLL_PROCESS_DETACH\r\n");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -138,13 +145,19 @@ BOOL WINAPI DllMain(
|
||||
|
||||
STDAPI DllCanUnloadNow(void)
|
||||
{
|
||||
// ODS("In DLLCanUnloadNow\r\n");
|
||||
ODS("In DLLCanUnloadNow\r\n");
|
||||
/*
|
||||
if (g_DllRefCount == 0)
|
||||
ODS( "g_DllRefCount == 0");
|
||||
else
|
||||
ODS( "g_DllRefCount != 0");
|
||||
*/
|
||||
return (g_DllRefCount == 0 ? S_OK : S_FALSE);
|
||||
}
|
||||
|
||||
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
{
|
||||
// ODS("In DllGetClassObject\r\n");
|
||||
ODS("In DllGetClassObject\r\n");
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(rclsid, CLSID_CZipContextMenu))
|
||||
{
|
||||
@@ -168,6 +181,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
|
||||
static BOOL RegisterServer()
|
||||
{
|
||||
ODS("RegisterServer\r\n");
|
||||
FString modulePath;
|
||||
if (!NDLL::MyGetModuleFileName(modulePath))
|
||||
return FALSE;
|
||||
@@ -197,6 +211,7 @@ static BOOL RegisterServer()
|
||||
key.SetValue(k_Clsid, k_ShellExtName);
|
||||
}
|
||||
|
||||
ODS("RegisterServer :: return TRUE");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Util\7-Zip.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Explorer - Win32 Debug"
|
||||
@@ -82,7 +82,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\7-Zip.dll" /pdbtype:sept
|
||||
|
||||
!ELSEIF "$(CFG)" == "Explorer - Win32 ReleaseU"
|
||||
|
||||
@@ -110,7 +110,7 @@ BSC32=bscmake.exe
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98
|
||||
# SUBTRACT BASE LINK32 /pdb:none
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zipn.dll" /opt:NOWIN98
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Util\7-Zip.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Explorer - Win32 DebugU"
|
||||
@@ -138,7 +138,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\7-Zip.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -226,6 +226,10 @@ SOURCE=.\ContextMenu.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MyExplorerCommand.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MyMessages.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -274,6 +278,14 @@ SOURCE=..\FileManager\ProgramLocation.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\FileManager\PropertyName.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\FileManager\PropertyName.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\FileManager\RegistryUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
173
CPP/7zip/UI/Explorer/MyExplorerCommand.h
Normal file
173
CPP/7zip/UI/Explorer/MyExplorerCommand.h
Normal file
@@ -0,0 +1,173 @@
|
||||
// MyExplorerCommand.h
|
||||
|
||||
#ifndef __MY_EXPLORER_COMMAND_H
|
||||
#define __MY_EXPLORER_COMMAND_H
|
||||
|
||||
#if _MSC_VER >= 1910
|
||||
#define USE_SYS_shobjidl_core
|
||||
#endif
|
||||
|
||||
#ifdef USE_SYS_shobjidl_core
|
||||
|
||||
// #include <shobjidl_core.h>
|
||||
|
||||
#else
|
||||
|
||||
#ifndef __IShellItemArray_INTERFACE_DEFINED__
|
||||
#define __IShellItemArray_INTERFACE_DEFINED__
|
||||
|
||||
// propsys.h
|
||||
|
||||
typedef /* [v1_enum] */
|
||||
enum GETPROPERTYSTOREFLAGS
|
||||
{
|
||||
GPS_DEFAULT = 0,
|
||||
GPS_HANDLERPROPERTIESONLY = 0x1,
|
||||
GPS_READWRITE = 0x2,
|
||||
GPS_TEMPORARY = 0x4,
|
||||
GPS_FASTPROPERTIESONLY = 0x8,
|
||||
GPS_OPENSLOWITEM = 0x10,
|
||||
GPS_DELAYCREATION = 0x20,
|
||||
GPS_BESTEFFORT = 0x40,
|
||||
GPS_NO_OPLOCK = 0x80,
|
||||
GPS_PREFERQUERYPROPERTIES = 0x100,
|
||||
GPS_EXTRINSICPROPERTIES = 0x200,
|
||||
GPS_EXTRINSICPROPERTIESONLY = 0x400,
|
||||
GPS_VOLATILEPROPERTIES = 0x800,
|
||||
GPS_VOLATILEPROPERTIESONLY = 0x1000,
|
||||
GPS_MASK_VALID = 0x1fff
|
||||
} GETPROPERTYSTOREFLAGS;
|
||||
|
||||
// DEFINE_ENUM_FLAG_OPERATORS(GETPROPERTYSTOREFLAGS)
|
||||
|
||||
|
||||
#ifndef PROPERTYKEY_DEFINED
|
||||
#define PROPERTYKEY_DEFINED
|
||||
|
||||
typedef
|
||||
struct _tagpropertykey
|
||||
{
|
||||
GUID fmtid;
|
||||
DWORD pid;
|
||||
} PROPERTYKEY;
|
||||
|
||||
#endif // PROPERTYKEY_DEFINED
|
||||
|
||||
// propkeydef.h
|
||||
#define REFPROPERTYKEY const PROPERTYKEY &
|
||||
|
||||
#ifdef INITGUID
|
||||
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
|
||||
#else
|
||||
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY name
|
||||
#endif // INITGUID
|
||||
|
||||
|
||||
// <shobjidl_core.h>
|
||||
typedef /* [v1_enum] */
|
||||
enum SIATTRIBFLAGS
|
||||
{
|
||||
SIATTRIBFLAGS_AND = 0x1,
|
||||
SIATTRIBFLAGS_OR = 0x2,
|
||||
SIATTRIBFLAGS_APPCOMPAT = 0x3,
|
||||
SIATTRIBFLAGS_MASK = 0x3,
|
||||
SIATTRIBFLAGS_ALLITEMS = 0x4000
|
||||
} SIATTRIBFLAGS;
|
||||
|
||||
// DEFINE_ENUM_FLAG_OPERATORS(SIATTRIBFLAGS)
|
||||
|
||||
|
||||
// MIDL_INTERFACE("70629033-e363-4a28-a567-0db78006e6d7")
|
||||
DEFINE_GUID(IID_IEnumShellItems, 0x70629033, 0xe363, 0xe363, 0xa5, 0x67, 0x0d, 0xb7, 0x80, 0x06, 0xe6, 0xd7);
|
||||
|
||||
struct IEnumShellItems : public IUnknown
|
||||
{
|
||||
STDMETHOD (Next) (ULONG celt, IShellItem **rgelt, ULONG *pceltFetched) = 0;
|
||||
STDMETHOD (Skip) (ULONG celt) = 0;
|
||||
STDMETHOD (Reset) (void) = 0;
|
||||
STDMETHOD (Clone) (IEnumShellItems **ppenum) = 0;
|
||||
};
|
||||
|
||||
|
||||
// MIDL_INTERFACE("b63ea76d-1f85-456f-a19c-48159efa858b")
|
||||
DEFINE_GUID(IID_IShellItemArray, 0xb63ea76d, 0x1f85, 0x456f, 0xa1, 0x9c, 0x48, 0x15, 0x9e, 0xfa, 0x85, 0x8b);
|
||||
|
||||
struct IShellItemArray : public IUnknown
|
||||
{
|
||||
STDMETHOD (BindToHandler) (IBindCtx *pbc, REFGUID bhid, REFIID riid, void **ppvOut) = 0;
|
||||
STDMETHOD (GetPropertyStore) (GETPROPERTYSTOREFLAGS flags, REFIID riid, void **ppv) = 0;
|
||||
STDMETHOD (GetPropertyDescriptionList) (REFPROPERTYKEY keyType, REFIID riid, void **ppv) = 0;
|
||||
STDMETHOD (GetAttributes) ( SIATTRIBFLAGS AttribFlags, SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs) = 0;
|
||||
STDMETHOD (GetCount) (DWORD *pdwNumItems) = 0;
|
||||
STDMETHOD (GetItemAt) (DWORD dwIndex, IShellItem **ppsi) = 0;
|
||||
STDMETHOD (EnumItems) (IEnumShellItems **ppenumShellItems) = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifndef __IEnumExplorerCommand_INTERFACE_DEFINED__
|
||||
#define __IEnumExplorerCommand_INTERFACE_DEFINED__
|
||||
|
||||
struct IExplorerCommand;
|
||||
|
||||
// MIDL_INTERFACE("a88826f8-186f-4987-aade-ea0cef8fbfe8")
|
||||
DEFINE_GUID(IID_IEnumExplorerCommand , 0xa88826f8, 0x186f, 0x4987, 0xaa, 0xde, 0xea, 0x0c, 0xef, 0x8f, 0xbf, 0xe8);
|
||||
|
||||
struct IEnumExplorerCommand : public IUnknown
|
||||
{
|
||||
STDMETHOD (Next) (ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) = 0;
|
||||
STDMETHOD (Skip) (ULONG celt) = 0;
|
||||
STDMETHOD (Reset) (void) = 0;
|
||||
STDMETHOD (Clone) (IEnumExplorerCommand **ppenum) = 0;
|
||||
};
|
||||
|
||||
|
||||
enum _EXPCMDSTATE
|
||||
{
|
||||
ECS_ENABLED = 0,
|
||||
ECS_DISABLED = 0x1,
|
||||
ECS_HIDDEN = 0x2,
|
||||
ECS_CHECKBOX = 0x4,
|
||||
ECS_CHECKED = 0x8,
|
||||
ECS_RADIOCHECK = 0x10
|
||||
};
|
||||
|
||||
typedef DWORD EXPCMDSTATE;
|
||||
|
||||
/* [v1_enum] */
|
||||
enum _EXPCMDFLAGS
|
||||
{
|
||||
ECF_DEFAULT = 0,
|
||||
ECF_HASSUBCOMMANDS = 0x1,
|
||||
ECF_HASSPLITBUTTON = 0x2,
|
||||
ECF_HIDELABEL = 0x4,
|
||||
ECF_ISSEPARATOR = 0x8,
|
||||
ECF_HASLUASHIELD = 0x10,
|
||||
ECF_SEPARATORBEFORE = 0x20,
|
||||
ECF_SEPARATORAFTER = 0x40,
|
||||
ECF_ISDROPDOWN = 0x80,
|
||||
ECF_TOGGLEABLE = 0x100,
|
||||
ECF_AUTOMENUICONS = 0x200
|
||||
};
|
||||
typedef DWORD EXPCMDFLAGS;
|
||||
|
||||
|
||||
// MIDL_INTERFACE("a08ce4d0-fa25-44ab-b57c-c7b1c323e0b9")
|
||||
DEFINE_GUID(IID_IExplorerCommand, 0xa08ce4d0, 0xfa25, 0x44ab, 0xb5, 0x7c, 0xc7, 0xb1, 0xc3, 0x23, 0xe0, 0xb9);
|
||||
|
||||
struct IExplorerCommand : public IUnknown
|
||||
{
|
||||
STDMETHOD (GetTitle) (IShellItemArray *psiItemArray, LPWSTR *ppszName) = 0;
|
||||
STDMETHOD (GetIcon) (IShellItemArray *psiItemArray, LPWSTR *ppszIcon) = 0;
|
||||
STDMETHOD (GetToolTip) (IShellItemArray *psiItemArray, LPWSTR *ppszInfotip) = 0;
|
||||
STDMETHOD (GetCanonicalName) (GUID *pguidCommandName) = 0;
|
||||
STDMETHOD (GetState) (IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState) = 0;
|
||||
STDMETHOD (Invoke) (IShellItemArray *psiItemArray, IBindCtx *pbc) = 0;
|
||||
STDMETHOD (GetFlags) (EXPCMDFLAGS *pFlags) = 0;
|
||||
STDMETHOD (EnumSubCommands) (IEnumExplorerCommand **ppEnum) = 0;
|
||||
};
|
||||
|
||||
#endif // IShellItemArray
|
||||
#endif // __IEnumExplorerCommand_INTERFACE_DEFINED__
|
||||
#endif // USE_SYS_shobjidl_core
|
||||
|
||||
#endif // __MY_EXPLORER_COMMAND_H
|
||||
@@ -65,6 +65,7 @@ FM_OBJS = \
|
||||
$O\HelpUtils.obj \
|
||||
$O\LangUtils.obj \
|
||||
$O\ProgramLocation.obj \
|
||||
$O\PropertyName.obj \
|
||||
$O\RegistryUtils.obj \
|
||||
|
||||
C_OBJS = \
|
||||
|
||||
@@ -6,3 +6,5 @@ MY_VERSION_INFO_DLL("7-Zip Shell Extension", "7-zip")
|
||||
#ifndef UNDER_CE
|
||||
1 24 MOVEABLE PURE "7-zip.dll.manifest"
|
||||
#endif
|
||||
|
||||
IDI_ICON ICON "..\FileManager\FM.ico"
|
||||
|
||||
@@ -130,6 +130,7 @@ STDMETHODIMP CExtractCallbackImp::AskOverwrite(
|
||||
static const char * const kTestString = "Testing";
|
||||
static const char * const kExtractString = "Extracting";
|
||||
static const char * const kSkipString = "Skipping";
|
||||
static const char * const kReadString = "Reading";
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 * /* position */)
|
||||
{
|
||||
@@ -143,6 +144,7 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /*
|
||||
case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break;
|
||||
case NArchive::NExtract::NAskMode::kTest: s = kTestString; break;
|
||||
case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; break;
|
||||
case NArchive::NExtract::NAskMode::kReadExternal: s = kReadString; break;
|
||||
default: s = "???"; // return E_FAIL;
|
||||
};
|
||||
|
||||
|
||||
@@ -118,6 +118,14 @@ SOURCE=..\..\..\Common\CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\DynLimBuf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -430,6 +438,14 @@ SOURCE=..\Common\HandlerLoader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\HashCalc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\HashCalc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\LoadCodecs.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -622,6 +638,14 @@ SOURCE=..\..\Common\LimitedStreams.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MethodProps.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MethodProps.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -712,6 +736,14 @@ SOURCE=..\..\..\..\C\Threads.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\ItemNameUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -686,9 +686,14 @@ struct CArchiveItemProperty
|
||||
VARTYPE Type;
|
||||
};
|
||||
|
||||
static inline char GetHex(Byte value)
|
||||
static inline char GetHex_Upper(unsigned v)
|
||||
{
|
||||
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
|
||||
return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10)));
|
||||
}
|
||||
|
||||
static inline char GetHex_Lower(unsigned v)
|
||||
{
|
||||
return (char)((v < 10) ? ('0' + v) : ('a' + (v - 10)));
|
||||
}
|
||||
|
||||
HRESULT CPlugin::ShowAttributesWindow()
|
||||
@@ -810,11 +815,21 @@ HRESULT CPlugin::ShowAttributesWindow()
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool needUpper = (dataSize <= 8)
|
||||
&& (property.ID == kpidCRC || property.ID == kpidChecksum);
|
||||
for (UInt32 k = 0; k < dataSize; k++)
|
||||
{
|
||||
Byte b = ((const Byte *)data)[k];
|
||||
s += GetHex((Byte)((b >> 4) & 0xF));
|
||||
s += GetHex((Byte)(b & 0xF));
|
||||
unsigned b = ((const Byte *)data)[k];
|
||||
if (needUpper)
|
||||
{
|
||||
s += GetHex_Upper((b >> 4) & 0xF);
|
||||
s += GetHex_Upper(b & 0xF);
|
||||
}
|
||||
else
|
||||
{
|
||||
s += GetHex_Lower((b >> 4) & 0xF);
|
||||
s += GetHex_Lower(b & 0xF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, int opMode)
|
||||
{
|
||||
if (numItems == 0)
|
||||
return FALSE;
|
||||
if (_agent->IsThereReadOnlyArc())
|
||||
if (_agent->IsThere_ReadOnlyArc())
|
||||
{
|
||||
g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
|
||||
return FALSE;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user