This commit is contained in:
Igor Pavlov
2021-11-28 19:03:01 -08:00
committed by fn ⌃ ⌥
parent d789d4137d
commit 1194dc9353
152 changed files with 6049 additions and 946 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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 \

View File

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

View File

@@ -11,6 +11,7 @@ LIB_OBJS = \
C_OBJS = \
$O\Alloc.obj \
$O\CpuArch.obj \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\LzFindOpt.obj \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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 \

View File

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

View File

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

View 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 \

View File

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

View File

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

View File

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

View 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 \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -394,7 +394,8 @@ namespace NMethodPropID
kDescription,
kDecoderIsAssigned,
kEncoderIsAssigned,
kDigestSize
kDigestSize,
kIsFilter
};
}

View File

@@ -103,6 +103,9 @@ enum
kpidReadOnly,
kpidOutName,
kpidCopyLink,
kpidArcFileName,
kpidIsHash,
kpid_NUM_DEFINED,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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;
*/
}

View File

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

View File

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

View File

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

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

View File

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

View File

@@ -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() {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

@@ -65,6 +65,7 @@ FM_OBJS = \
$O\HelpUtils.obj \
$O\LangUtils.obj \
$O\ProgramLocation.obj \
$O\PropertyName.obj \
$O\RegistryUtils.obj \
C_OBJS = \

View File

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

View File

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

View File

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

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

View File

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