Update to 7-Zip Version 21.04

- first test... no release!!!
This commit is contained in:
Tino Reichardt
2021-11-06 22:17:34 +01:00
parent 0f6bcfd2ed
commit 09497b7ba0
152 changed files with 6166 additions and 1341 deletions

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 },
@@ -626,7 +632,21 @@ static void AddSwitchWildcardsToCensor(
errorMessage = "Too short switch";
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;
@@ -1094,6 +1119,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)
{
@@ -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,60 +663,101 @@ 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)))
{
v1 >>= 1;
v2 >>= 1;
}
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)
{
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
{
UInt64 userTime = UserTime;
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

@@ -347,22 +347,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,14 +233,34 @@ 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,7 +141,16 @@ 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;
#if !defined(UNDER_CE)

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,29 +569,42 @@ 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()))
{
int secureIndex = -1;
#ifdef _USE_SECURITY_CODE
if (dirItems.ReadSecure)
{
RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex));
}
#endif
#if !defined(UNDER_CE)
dirItemIndex = (int)dirItems.Items.Size();
// 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);
if (dirItems.CanIncludeItem(fi.IsDir()))
{
int secureIndex = -1;
#ifdef _USE_SECURITY_CODE
if (dirItems.ReadSecure)
{
RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex));
}
#endif
#if !defined(UNDER_CE)
dirItemIndex = (int)dirItems.Items.Size();
#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

@@ -17,7 +17,10 @@
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;
@@ -99,7 +188,7 @@ struct CHashOptions
CBoolPair SymLinks;
NWildcard::ECensorPathMode PathMode;
CHashOptions():
PreserveATime(false),
OpenShareForWrite(false),
@@ -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
item.Signatures.AddNew().CopyFrom(arc.Signature, arc.SignatureSize);
{
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
};
@@ -432,5 +470,5 @@ public:
CCodecs *codecs = new CCodecs; \
CMyComPtr<IUnknown> __codecsRef = codecs;
#endif
#endif

View File

@@ -1026,30 +1026,33 @@ 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;
continue;
}
const CObjectVector<CByteBuffer> &sigs = ai.Signatures;
FOR_VECTOR (k, sigs)
{
const CByteBuffer &sig = sigs[k];
if ((sig.Size() == 0 && dataSize == 0)
|| (sig.Size() != 0 && sig.Size() <= dataSize
&& TestSignature(data, sig, sig.Size())))
if (ai.Signatures.IsEmpty())
{
orderIndices2.Add(index);
orderIndices[i] = -1;
break;
if (dataSize != 0) // 21.04: no Sinature means Empty Signature
continue;
}
else
{
unsigned k;
const CObjectVector<CByteBuffer> &sigs = ai.Signatures;
for (k = 0; k < sigs.Size(); k++)
{
const CByteBuffer &sig = sigs[k];
if (sig.Size() <= dataSize && TestSignature(data, sig, sig.Size()))
break;
}
if (k == sigs.Size())
continue;
}
}
orderIndices2.Add(index);
orderIndices[i] = -1;
}
}
@@ -2144,7 +2147,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()
@@ -2157,13 +2160,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())
@@ -3391,7 +3393,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;
@@ -3421,7 +3423,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)
{
@@ -3477,7 +3482,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;
@@ -3580,6 +3585,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;
}
@@ -3607,6 +3618,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);
@@ -3618,10 +3630,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,9 +542,9 @@ static HRESULT Compress(
#endif
}
if (outArchive == 0)
if (!outArchive)
throw kUpdateIsNotSupoorted;
NFileTimeType::EEnum fileTimeType;
{
UInt32 value;
@@ -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,61 +135,83 @@ 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();
for (unsigned i = 0; i < hashers.Size(); i++)
const AString fields = GetFields();
for (unsigned pos = 0; pos < fields.Len(); pos++)
{
if (i != 0)
_s.Add_Space();
const CHasherState &h = hashers[i];
AddMinuses(_s, GetColumnWidth(h.DigestSize));
}
if (PrintSize)
{
_s.Add_Space();
AddMinuses(_s, kSizeField_Len);
}
if (PrintName)
{
AddSpacesBeforeName();
AddMinuses(_s, kNameField_Len);
const char c = fields[pos];
if (c == 'h')
{
for (unsigned i = 0; i < hashers.Size(); i++)
{
AddSpace();
const CHasherState &h = hashers[i];
AddMinuses(_s, GetColumnWidth(h.DigestSize));
}
}
else if (c == 's')
{
AddSpace();
AddMinuses(_s, kSizeField_Len);
}
else if (c == 'n')
{
AddSpacesBeforeName();
AddMinuses(_s, kNameField_Len);
}
}
*_so << _s << endl;
}
HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
{
if (PrintHeaders && _so)
{
_s.Empty();
ClosePercents_for_so();
FOR_VECTOR (i, hb.Hashers)
const AString fields = GetFields();
for (unsigned pos = 0; pos < fields.Len(); pos++)
{
if (i != 0)
_s.Add_Space();
const CHasherState &h = hb.Hashers[i];
_s += h.Name;
AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len());
}
if (PrintSize)
{
_s.Add_Space();
const AString s2 ("Size");
AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());
_s += s2;
}
if (PrintName)
{
AddSpacesBeforeName();
_s += "Name";
const char c = fields[pos];
if (c == 'h')
{
FOR_VECTOR (i, hb.Hashers)
{
AddSpace();
const CHasherState &h = hb.Hashers[i];
_s += h.Name;
AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len());
}
}
else if (c == 's')
{
AddSpace();
const AString s2 ("Size");
AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());
_s += s2;
}
else if (c == 'n')
{
AddSpacesBeforeName();
_s += "Name";
}
}
*_so << _s << endl;
@@ -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();
FOR_VECTOR (i, hashers)
{
const CHasherState &h = hashers[i];
char s[k_HashCalc_DigestSize_Max * 2 + 64];
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();
_s += s;
}
const AString fields = GetFields();
if (PrintSize)
for (unsigned pos = 0; pos < fields.Len(); pos++)
{
_s.Add_Space();
char s[kSizeField_Len + 32];
char *p = s;
SetSpacesAndNul(s, kSizeField_Len);
if (showHash)
const char c = fields[pos];
if (c == 'h')
{
p = s + kSizeField_Len;
ConvertUInt64ToString(fileSize, p);
int numSpaces = (int)kSizeField_Len - (int)strlen(p);
if (numSpaces > 0)
p -= (unsigned)numSpaces;
FOR_VECTOR (i, hashers)
{
AddSpace();
const CHasherState &h = hashers[i];
char s[k_DigestStringSize];
s[0] = 0;
if (showHash)
h.WriteToString(digestIndex, s);
const unsigned len = (unsigned)strlen(s);
SetSpacesAndNul_if_Positive(s + len, (int)GetColumnWidth(h.DigestSize) - (int)len);
_s += s;
}
}
else if (c == 's')
{
AddSpace();
char s[kSizeField_Len + 32];
char *p = s;
SetSpacesAndNul(s, kSizeField_Len);
if (showHash)
{
p = s + kSizeField_Len;
ConvertUInt64ToString(fileSize, p);
const int numSpaces = (int)kSizeField_Len - (int)strlen(p);
if (numSpaces > 0)
p -= (unsigned)numSpaces;
}
_s += p;
}
else if (c == 'n')
{
AddSpacesBeforeName();
_s += path;
}
_s += p;
}
if (PrintName)
AddSpacesBeforeName();
*_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,7 +328,9 @@ HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBun
else
_so->NormalizePrint_UString(_fileName);
}
*_so << endl;
*/
// if (PrintNewLine)
*_so << endl;
}
if (NeedPercents())
@@ -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()
{
_s.Add_Space();
_s.Add_Space();
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,
@@ -15,12 +28,12 @@ HRESULT ListArchives(CCodecs *codecs,
bool processAltStreams, bool showAltStreams,
const NWildcard::CCensorNode &wildcardCensor,
bool enableHeaders, bool techMode,
#ifndef _NO_CRYPTO
#ifndef _NO_CRYPTO
bool &passwordEnabled, UString &password,
#endif
#ifndef _SFX
#endif
#ifndef _SFX
const CObjectVector<CProperty> *props,
#endif
#endif
UInt64 &errors,
UInt64 &numWarnings);

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++)
@@ -953,7 +962,7 @@ int Main2(
#ifdef EXTERNAL_CODECS
PrintLibIndex(so, arc.LibIndex);
#else
so << " ";
so << " ";
#endif
so << (char)(arc.UpdateEnabled ? 'C' : ' ');
@@ -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);
@@ -193,7 +246,9 @@ static const CHashCommand g_HashCommands[] =
{ CZipContextMenu::kHash_SHA512, "SHA-512", "SHA512" },
{ CZipContextMenu::kHash_BLAKE2sp, "BLAKE2sp", "BLAKE2sp" },
{ CZipContextMenu::kHash_BLAKE3, "BLAKE3", "BLAKE3" },
{ CZipContextMenu::kHash_All, "*", "*" }
{ CZipContextMenu::kHash_All, "*", "*" },
{ CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" },
{ CZipContextMenu::kHash_TestArc, "Checksum : Test", "Hash" }
};
@@ -218,9 +273,19 @@ 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)
{
@@ -231,6 +296,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;
@@ -256,9 +323,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;
@@ -343,7 +415,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"
@@ -417,7 +489,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.
@@ -441,12 +513,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.
*/
@@ -455,6 +527,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 {
@@ -507,9 +580,12 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
bitmap = _bitmap;
UINT subIndex = indexMenu;
ODS("### 50");
if (ci.Cascaded.Val)
{
if (hMenu)
if (!popupMenu.CreatePopup())
return RETURN_WIN32_LastError_AS_HRESULT();
menuDestroyer.Attach(popupMenu);
@@ -528,6 +604,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);
}
@@ -565,6 +642,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
}
ODS("### 100");
UString mainString;
if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast)
@@ -581,13 +660,15 @@ 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++)
{
@@ -603,8 +684,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);
}
@@ -676,6 +759,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);
}
}
@@ -734,6 +818,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);
}
@@ -747,6 +832,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
@@ -765,6 +851,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);
}
@@ -778,6 +865,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
@@ -793,32 +881,56 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
CMenu menu;
menu.Attach(hMenu);
menuDestroyer.Disable();
MyAddSubMenu(_commandMap, kMainVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip ZS", popupMenu.Detach(), bitmap);
MyAddSubMenu(_commandMap, kMainVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip ZS",
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;
menu.Attach(hMenu);
// menuDestroyer_CRC.Disable();
MyAddSubMenu(_commandMap, kCheckSumCascadedVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip ZS Hash", subMenu, bitmap);
{
int indexInParent;
if (insertHashMenuTo7zipMenu)
{
indexInParent = subIndex;
menu.Attach(popupMenu);
}
else
{
indexInParent = indexMenu;
menu.Attach(hMenu);
// menuDestroyer_CRC.Disable();
}
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++)
{
@@ -830,15 +942,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); }
@@ -995,9 +1149,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
{
@@ -1037,18 +1197,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;
}
@@ -1066,13 +1228,24 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
case kHash_BLAKE2sp:
case kHash_BLAKE3:
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;
}
}
@@ -1087,7 +1260,6 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
::MessageBoxW(0, L"Error", L"7-Zip ZS", MB_ICONERROR);
}
return S_OK;
COM_TRY_END
}
@@ -1159,3 +1331,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:
@@ -45,10 +59,17 @@ public:
kHash_SHA512,
kHash_BLAKE2sp,
kHash_BLAKE3,
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);
@@ -60,6 +81,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();
@@ -67,10 +106,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:
@@ -80,16 +134,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 \
$O\StringUtils.obj \

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;

View File

@@ -37,6 +37,12 @@ HRESULT CPlugin::ExtractFiles(
const UString &destPath,
bool passwordIsDefined, const UString &password)
{
if (_agent->_isHashHandler)
{
g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
return NFileOperationReturnCode::kError;
}
CScreenRestorer screenRestorer;
CProgressBox progressBox;
CProgressBox *progressBoxPointer = NULL;

View File

@@ -81,18 +81,17 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
struct PluginPanelItem *panelItems, int numItems,
int moveMode, int opMode)
{
/*
if (moveMode != 0)
if (moveMode != 0
&& _agent->_isHashHandler)
{
g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
return NFileOperationReturnCode::kError;
}
*/
if (numItems <= 0)
return NFileOperationReturnCode::kError;
if (_agent->IsThereReadOnlyArc())
if (_agent->IsThere_ReadOnlyArc())
{
g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
return NFileOperationReturnCode::kError;
@@ -231,8 +230,11 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
updateCallbackSpec->PasswordIsDefined = PasswordIsDefined;
updateCallbackSpec->Password = Password;
if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK)
return NFileOperationReturnCode::kError;
if (!_agent->_isHashHandler)
{
if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK)
return NFileOperationReturnCode::kError;
}
/*
outArchive->SetFolder(_folder);
@@ -726,7 +728,7 @@ static const char * const k_CreateFolder_History = "NewFolder"; // we use defaul
HRESULT CPlugin::CreateFolder()
{
if (_agent->IsThereReadOnlyArc())
if (_agent->IsThere_ReadOnlyArc())
{
g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
return TRUE;

View File

@@ -22,6 +22,7 @@ CURRENT_OBJS = \
$O\UpdateCallbackFar.obj \
COMMON_OBJS = \
$O\DynLimBuf.obj \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \
@@ -52,6 +53,7 @@ WIN_OBJS = \
$O\FileStreams.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
$O\MethodProps.obj \
$O\ProgressUtils.obj \
$O\PropId.obj \
$O\StreamObjects.obj \
@@ -64,6 +66,7 @@ UI_COMMON_OBJS = \
$O\DefaultName.obj \
$O\EnumDirItems.obj \
$O\ExtractingFilePath.obj \
$O\HashCalc.obj \
$O\LoadCodecs.obj \
$O\OpenArchive.obj \
$O\PropIDUtils.obj \
@@ -77,6 +80,7 @@ UI_COMMON_OBJS = \
$O\ZipRegistry.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \
AGENT_OBJS = \

View File

@@ -9,3 +9,4 @@
#include "../Agent/Agent.h"
#include "MyWindowsNew.h"
#include "../Explorer/MyExplorerCommand.h"

View File

@@ -44,6 +44,7 @@ void CExtractCallbackImp::Init()
_lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING);
_lang_Testing = LangString(IDS_PROGRESS_TESTING);
_lang_Skipping = LangString(IDS_PROGRESS_SKIPPING);
_lang_Reading = "Reading";
NumArchiveErrors = 0;
ThereAreMessageErrors = false;
@@ -233,6 +234,7 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 is
case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break;
case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break;
case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break;
case NArchive::NExtract::NAskMode::kReadExternal: msg = &_lang_Reading; break;
// default: s = "Unknown operation";
}
@@ -911,8 +913,10 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode)
{
COM_TRY_BEGIN
_needUpdateStat = (
askExtractMode == NArchive::NExtract::NAskMode::kExtract ||
askExtractMode == NArchive::NExtract::NAskMode::kTest);
askExtractMode == NArchive::NExtract::NAskMode::kExtract
|| askExtractMode == NArchive::NExtract::NAskMode::kTest
|| askExtractMode == NArchive::NExtract::NAskMode::kReadExternal
);
/*
_extractMode = false;
@@ -930,7 +934,7 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode)
COM_TRY_END
}
STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypted)
STDMETHODIMP CExtractCallbackImp::SetOperationResult8(Int32 opRes, Int32 encrypted, UInt64 size)
{
COM_TRY_BEGIN
if (VirtFileSystem && _newVirtFileWasAdded)
@@ -950,7 +954,7 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypt
}
else if (_hashCalc && _needUpdateStat)
{
_hashCalc->SetSize(_curSize);
_hashCalc->SetSize(size); // (_curSize) before 21.04
_hashCalc->Final(_isFolder, _isAltStream, _filePath);
}
return SetOperationResult(opRes, encrypted);

View File

@@ -282,6 +282,7 @@ public:
UString _lang_Extracting;
UString _lang_Testing;
UString _lang_Skipping;
UString _lang_Reading;
UString _lang_Empty;
bool _totalFilesDefined;

View File

@@ -1076,6 +1076,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
@@ -1419,6 +1427,10 @@ SOURCE=..\Explorer\ContextMenuFlags.h
# End Source File
# Begin Source File
SOURCE=..\Explorer\MyExplorerCommand.h
# End Source File
# Begin Source File
SOURCE=..\Explorer\RegistryContextMenu.cpp
# End Source File
# Begin Source File
@@ -1491,6 +1503,18 @@ SOURCE=..\..\IStream.h
SOURCE=..\..\PropID.h
# End Source File
# End Group
# Begin Group "ArchiveCommon"
# 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
# End Group
# Begin Source File
SOURCE=.\7zFM.exe.manifest

View File

@@ -1,7 +1,7 @@
#include "ListViewDialogRes.h"
#include "../../GuiCommon.rc"
#define xc 440
#define xc 480
#define yc 320
IDD_LISTVIEW DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT

View File

@@ -63,7 +63,8 @@ static const CContextMenuItem kMenuItems[] =
{ IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressToZipEmail },
#endif
{ IDS_PROP_CHECKSUM, kCRC }
{ IDS_PROP_CHECKSUM, kCRC },
{ IDS_PROP_CHECKSUM, kCRC_Cascaded },
};
@@ -188,9 +189,12 @@ bool CMenuPage::OnInit()
UString s = LangString(menuItem.ControlID);
if (menuItem.Flag == kCRC)
s = "HASH";
if (menuItem.Flag == kOpenAs ||
menuItem.Flag == kCRC)
s += " >";
else if (menuItem.Flag == kCRC_Cascaded)
s = "7-Zip > HASH";
if (menuItem.Flag == kOpenAs
|| menuItem.Flag == kCRC
|| menuItem.Flag == kCRC_Cascaded)
s += " >";
switch (menuItem.ControlID)
{

View File

@@ -2,7 +2,7 @@
#include "../../GuiCommon.rc"
#define xc 240
#define yc 224
#define yc 252
IDD_MENU MY_PAGE
#include "MenuPage2.rc"

View File

@@ -36,4 +36,12 @@ STDMETHOD_(ULONG, Release)() { InterlockedDecrement((LONG *)&__m_RefCount); if (
MY_QUERYINTERFACE_ENTRY(i3) \
)
#define MY_UNKNOWN_IMP4_MT(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC_MT2( \
i1, \
MY_QUERYINTERFACE_ENTRY(i1) \
MY_QUERYINTERFACE_ENTRY(i2) \
MY_QUERYINTERFACE_ENTRY(i3) \
MY_QUERYINTERFACE_ENTRY(i4) \
)
#endif

View File

@@ -536,6 +536,31 @@ void CFileMenu::Load(HMENU hMenu, unsigned startPos)
disable = true;
}
}
if (isHashFolder)
{
switch (item.wID)
{
case IDM_OPEN:
case IDM_OPEN_INSIDE:
case IDM_OPEN_INSIDE_ONE:
case IDM_OPEN_INSIDE_PARSER:
case IDM_OPEN_OUTSIDE:
case IDM_FILE_VIEW:
case IDM_FILE_EDIT:
// case IDM_RENAME:
case IDM_COPY_TO:
case IDM_MOVE_TO:
// case IDM_DELETE:
case IDM_COMMENT:
case IDM_CREATE_FOLDER:
case IDM_CREATE_FILE:
case IDM_LINK:
case IDM_DIFF:
disable = true;
}
}
if (item.wID == IDM_LINK && numItems != 1)
disable = true;

View File

@@ -14,16 +14,18 @@ struct CFileMenu
{
bool programMenu;
bool readOnly;
bool isHashFolder;
bool isFsFolder;
bool allAreFiles;
bool isAltStreamsSupported;
int numItems;
UString FilePath;
FString FilePath;
CFileMenu():
programMenu(false),
readOnly(false),
isHashFolder(false),
isFsFolder(false),
allAreFiles(false),
isAltStreamsSupported(true),

View File

@@ -797,6 +797,18 @@ bool CPanel::IsArcFolder() const
return GetFolderTypeID().IsPrefixedBy_Ascii_NoCase("7-Zip");
}
bool CPanel::IsHashFolder() const
{
if (_folder)
{
NCOM::CPropVariant prop;
if (_folder->GetFolderProperty(kpidIsHash, &prop) == S_OK)
if (prop.vt == VT_BOOL)
return VARIANT_BOOLToBool(prop.boolVal);
}
return false;
}
UString CPanel::GetFsPath() const
{
if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix() && !IsSuperDrivesPrefix())

View File

@@ -647,6 +647,7 @@ public:
bool IsFSDrivesFolder() const;
bool IsAltStreamsFolder() const;
bool IsArcFolder() const;
bool IsHashFolder() const;
/*
c:\Dir

View File

@@ -126,6 +126,12 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UStringVector *messages,
bool &usePassword, UString &password)
{
if (IsHashFolder())
{
if (!options.testMode)
return E_NOTIMPL;
}
if (!_folderOperations)
{
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
@@ -290,6 +296,11 @@ struct CThreadUpdate
HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStringVector &filePaths,
bool showErrorMessages, UStringVector *messages)
{
if (IsHashFolder())
{
if (moveMode)
return E_NOTIMPL;
}
// CDisableNotify disableNotify(*this);
HRESULT res;

View File

@@ -1566,6 +1566,10 @@ tryInternal tryExternal
void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bool editMode, bool useEditor, const wchar_t *type)
{
// we don't want to change hash data here
if (IsHashFolder())
return;
const UString name = GetItemName(index);
const UString relPath = GetItemRelPath(index);
@@ -1793,6 +1797,8 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
tpi->UsePassword = usePassword;
tpi->Password = password;
tpi->ReadOnly = IsThereReadOnlyFolder();
if (IsHashFolder())
tpi->ReadOnly = true;
if (!tpi->FileInfo.Find(tempFilePath))
return;

View File

@@ -92,11 +92,16 @@ UString ConvertSizeToString(UInt64 value)
return s;
}
static inline unsigned GetHex(unsigned v)
static inline unsigned GetHex_Upper(unsigned v)
{
return (v < 10) ? ('0' + v) : ('A' + (v - 10));
}
static inline unsigned GetHex_Lower(unsigned v)
{
return (v < 10) ? ('0' + v) : ('a' + (v - 10));
}
/*
static void HexToString(char *dest, const Byte *data, UInt32 size)
{
@@ -350,11 +355,21 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
if (dataSize > limit)
dataSize = limit;
WCHAR *dest = text;
const bool needUpper = (dataSize <= 8)
&& (propID == kpidCRC || propID == kpidChecksum);
for (UInt32 i = 0; i < dataSize; i++)
{
unsigned b = ((const Byte *)data)[i];
dest[0] = (WCHAR)GetHex((b >> 4) & 0xF);
dest[1] = (WCHAR)GetHex(b & 0xF);
if (needUpper)
{
dest[0] = (WCHAR)GetHex_Upper((b >> 4) & 0xF);
dest[1] = (WCHAR)GetHex_Upper(b & 0xF);
}
else
{
dest[0] = (WCHAR)GetHex_Lower((b >> 4) & 0xF);
dest[1] = (WCHAR)GetHex_Lower(b & 0xF);
}
dest += 2;
}
*dest = 0;

View File

@@ -133,9 +133,14 @@ static void AddPropertyString(PROPID propID, UInt64 val, CListViewDialog &dialog
}
static inline char GetHex(Byte value)
static inline unsigned GetHex_Upper(unsigned v)
{
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
return (v < 10) ? ('0' + v) : ('A' + (v - 10));
}
static inline unsigned GetHex_Lower(unsigned v)
{
return (v < 10) ? ('0' + v) : ('a' + (v - 10));
}
static const Byte kSpecProps[] =
@@ -225,11 +230,21 @@ void CPanel::Properties()
}
else
{
const bool needUpper = (dataSize <= 8)
&& (propID == kpidCRC || propID == 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));
const Byte b = ((const Byte *)data)[k];
if (needUpper)
{
s += (char)GetHex_Upper((b >> 4) & 0xF);
s += (char)GetHex_Upper(b & 0xF);
}
else
{
s += (char)GetHex_Lower((b >> 4) & 0xF);
s += (char)GetHex_Lower(b & 0xF);
}
}
}
}
@@ -931,6 +946,7 @@ void CPanel::CreateFileMenu(HMENU menuSpec,
CFileMenu fm;
fm.readOnly = IsThereReadOnlyFolder();
fm.isHashFolder = IsHashFolder();
fm.isFsFolder = Is_IO_FS_Folder();
fm.programMenu = programMenu;
fm.allAreFiles = allAreFiles;
@@ -939,7 +955,7 @@ void CPanel::CreateFileMenu(HMENU menuSpec,
fm.isAltStreamsSupported = false;
if (fm.numItems == 1)
fm.FilePath = GetItemFullPath(operatedIndices[0]);
fm.FilePath = us2fs(GetItemFullPath(operatedIndices[0]));
if (_folderAltStreams)
{

View File

@@ -355,6 +355,9 @@ bool Dlg_CreateFolder(HWND wnd, UString &destName);
void CPanel::CreateFolder()
{
if (IsHashFolder())
return;
if (!CheckBeforeUpdate(IDS_CREATE_FOLDER_ERROR))
return;
@@ -415,6 +418,9 @@ void CPanel::CreateFolder()
void CPanel::CreateFile()
{
if (IsHashFolder())
return;
if (!CheckBeforeUpdate(IDS_CREATE_FILE_ERROR))
return;
@@ -473,6 +479,8 @@ void CPanel::RenameFile()
void CPanel::ChangeComment()
{
if (IsHashFolder())
return;
if (!CheckBeforeUpdate(IDS_COMMENT))
return;
CDisableTimerProcessing disableTimerProcessing2(*this);

View File

@@ -5,7 +5,7 @@
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/Control/Static.h"
#include "../../../Windows/Clipboard.h"
#include "../../../Windows/ErrorMsg.h"
#include "../GUI/ExtractRes.h"
@@ -239,7 +239,7 @@ void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name)
CProgressDialog::CProgressDialog():
_timer(0),
CompressingMode(true),
MainWindow(0)
MainWindow(NULL)
{
_isDir = false;
@@ -280,7 +280,7 @@ CProgressDialog::~CProgressDialog()
}
void CProgressDialog::AddToTitle(LPCWSTR s)
{
if (MainWindow != 0)
if (MainWindow)
{
CWindow window(MainWindow);
window.SetText((UString)s + MainTitle);
@@ -357,6 +357,7 @@ bool CProgressDialog::OnInit()
m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
_messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES));
_messageList.SetUnicodeFormat();
_messageList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
_wasCreated = true;
_dialogCreatedEvent.Set();
@@ -1046,6 +1047,8 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
}
if (_inCancelMessageBox)
{
/* if user is in MessageBox(), we will call OnExternalCloseMessage()
later, when MessageBox() will be closed */
_externalCloseMessageWasReceived = true;
break;
}
@@ -1142,13 +1145,16 @@ void CProgressDialog::OnPriorityButton()
void CProgressDialog::AddMessageDirect(LPCWSTR message, bool needNumber)
{
int itemIndex = _messageList.GetItemCount();
wchar_t sz[16];
sz[0] = 0;
if (needNumber)
ConvertUInt32ToString(_numMessages + 1, sz);
_messageList.InsertItem(itemIndex, sz);
_messageList.SetSubItem(itemIndex, 1, message);
const unsigned itemIndex = _messageStrings.Size(); // _messageList.GetItemCount();
if (_messageList.InsertItem((int)itemIndex, sz) == (int)itemIndex)
{
_messageList.SetSubItem((int)itemIndex, 1, message);
_messageStrings.Add(message);
}
}
void CProgressDialog::AddMessage(LPCWSTR message)
@@ -1217,24 +1223,42 @@ bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
End(IDCLOSE);
break;
}
if (_cancelWasPressed)
return true;
bool paused = Sync.Get_Paused();
const bool paused = Sync.Get_Paused();
if (!paused)
OnPauseButton();
_inCancelMessageBox = true;
int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL);
_inCancelMessageBox = false;
if (!paused)
OnPauseButton();
if (res == IDCANCEL || res == IDNO)
{
if (_externalCloseMessageWasReceived)
OnExternalCloseMessage();
OnPauseButton();
}
_inCancelMessageBox = true;
const int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL);
_inCancelMessageBox = false;
if (res == IDYES)
_cancelWasPressed = true;
if (!paused)
{
OnPauseButton();
}
if (_externalCloseMessageWasReceived)
{
/* we have received kCloseMessage while we were in MessageBoxW().
so we call OnExternalCloseMessage() here.
it can show MessageBox and it can close dialog */
OnExternalCloseMessage();
return true;
}
_cancelWasPressed = true;
if (!_cancelWasPressed)
return true;
MessagesDisplayed = true;
// we will call Sync.Set_Stopped(true) in OnButtonClicked() : OnCancel()
break;
}
@@ -1270,6 +1294,87 @@ void CProgressDialog::ProcessWasFinished()
}
bool CProgressDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
{
if (header->hwndFrom != _messageList)
return false;
switch (header->code)
{
case LVN_KEYDOWN:
{
LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header);
switch (keyDownInfo->wVKey)
{
case 'A':
{
if (IsKeyDown(VK_CONTROL))
{
_messageList.SelectAll();
return true;
}
break;
}
case VK_INSERT:
case 'C':
{
if (IsKeyDown(VK_CONTROL))
{
CopyToClipboard();
return true;
}
break;
}
}
}
}
return false;
}
static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector)
{
vector.Clear();
int index = -1;
for (;;)
{
index = listView.GetNextSelectedItem(index);
if (index < 0)
break;
vector.Add(index);
}
}
void CProgressDialog::CopyToClipboard()
{
CUIntVector indexes;
ListView_GetSelected(_messageList, indexes);
UString s;
unsigned numIndexes = indexes.Size();
if (numIndexes == 0)
numIndexes = _messageList.GetItemCount();
for (unsigned i = 0; i < numIndexes; i++)
{
const unsigned index = (i < indexes.Size() ? indexes[i] : i);
// s.Add_UInt32(index);
// s += ": ";
s += _messageStrings[index];
{
s +=
#ifdef _WIN32
"\r\n"
#else
"\n"
#endif
;
}
}
ClipboardSetText(*this, s);
}
static THREAD_FUNC_DECL MyThreadFunction(void *param)
{
CProgressThreadVirt *p = (CProgressThreadVirt *)param;

View File

@@ -152,6 +152,7 @@ class CProgressDialog: public NWindows::NControl::CModalDialog
NWindows::NControl::CListView _messageList;
int _numMessages;
UStringVector _messageStrings;
#ifdef __ITaskbarList3_INTERFACE_DEFINED__
CMyComPtr<ITaskbarList3> _taskbarList;
@@ -212,6 +213,9 @@ class CProgressDialog: public NWindows::NControl::CModalDialog
virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
virtual void OnCancel();
virtual void OnOK();
virtual bool OnNotify(UINT /* controlID */, LPNMHDR header);
void CopyToClipboard();
NWindows::NSynchronization::CManualResetEvent _createDialogEvent;
NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
#ifndef _SFX

View File

@@ -18,10 +18,10 @@ using namespace NFile;
using namespace NFind;
using namespace NDir;
static UString ConvertPath_to_Ctrl(const UString &path)
static FString ConvertPath_to_Ctrl(const FString &path)
{
UString s = path;
s.Replace(L':', L'_');
FString s = path;
s.Replace(FChar(':'), FChar('_'));
return s;
}
@@ -33,11 +33,11 @@ struct CFileDataInfo
CFileDataInfo(): IsOpen (false) {}
UInt64 GetSize() const { return (((UInt64)Info.nFileSizeHigh) << 32) + Info.nFileSizeLow; }
bool Read(const UString &path);
bool Read(const FString &path);
};
bool CFileDataInfo::Read(const UString &path)
bool CFileDataInfo::Read(const FString &path)
{
IsOpen = false;
NIO::CInFile file;
@@ -69,7 +69,7 @@ bool CFileDataInfo::Read(const UString &path)
}
static bool CreateComplexDir_for_File(const UString &path)
static bool CreateComplexDir_for_File(const FString &path)
{
FString resDirPrefix;
FString resFileName;
@@ -81,7 +81,7 @@ static bool CreateComplexDir_for_File(const UString &path)
static bool ParseNumberString(const FString &s, UInt32 &number)
{
const wchar_t *end;
const FChar *end;
UInt64 result = ConvertStringToUInt64(s, &end);
if (*end != 0 || s.IsEmpty() || result > (UInt32)0x7FFFFFFF)
return false;
@@ -145,7 +145,7 @@ void CApp::VerCtrl(unsigned id)
return;
}
const UString path = panel.GetItemFullPath(indices[0]);
const FString path = us2fs(panel.GetItemFullPath(indices[0]));
UString vercPath;
ReadReg_VerCtrlPath(vercPath);
@@ -161,8 +161,8 @@ void CApp::VerCtrl(unsigned id)
return;
}
const UString dirPrefix2 = vercPath + ConvertPath_to_Ctrl(dirPrefix);
const UString path2 = dirPrefix2 + fileName;
const FString dirPrefix2 = us2fs(vercPath) + ConvertPath_to_Ctrl(dirPrefix);
const FString path2 = dirPrefix2 + fileName;
bool sameTime = false;
bool sameData = false;
@@ -362,6 +362,6 @@ void CApp::VerCtrl(unsigned id)
{
if (!fdi2.IsOpen)
return;
DiffFiles(path2, path);
DiffFiles(fs2us(path2), fs2us(path));
}
}

View File

@@ -5,6 +5,7 @@ CFLAGS = $(CFLAGS) \
!include "FM.mak"
COMMON_OBJS = \
$O\DynLimBuf.obj \
$O\IntToString.obj \
$O\Lang.obj \
$O\MyString.obj \
@@ -93,6 +94,10 @@ GUI_OBJS = \
COMPRESS_OBJS = \
$O\CopyCoder.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
C_OBJS = $(C_OBJS) \
$O\Alloc.obj \
$O\CpuArch.obj \

View File

File diff suppressed because it is too large Load Diff

View File

@@ -34,7 +34,7 @@ namespace NCompressDialog
NWildcard::ECensorPathMode PathMode;
bool SolidIsSpecified;
bool MultiThreadIsAllowed;
// bool MultiThreadIsAllowed;
UInt64 SolidBlockSize;
UInt32 NumThreads;
@@ -81,6 +81,8 @@ namespace NCompressDialog
FormatIndex(-1)
{
Level = Order = (UInt32)(Int32)-1;
NumThreads = (UInt32)(Int32)-1;
SolidIsSpecified = false;
Dict64 = (UInt64)(Int64)(-1);
OrderMode = false;
Method.Empty();
@@ -102,16 +104,23 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
NWindows::NControl::CComboBox m_Order;
NWindows::NControl::CComboBox m_Solid;
NWindows::NControl::CComboBox m_NumThreads;
NWindows::NControl::CComboBox m_Volume;
NWindows::NControl::CDialogChildControl m_Params;
NWindows::NControl::CComboBox m_UpdateMode;
NWindows::NControl::CComboBox m_PathMode;
NWindows::NControl::CComboBox m_Volume;
NWindows::NControl::CDialogChildControl m_Params;
NWindows::NControl::CEdit _password1Control;
NWindows::NControl::CEdit _password2Control;
NWindows::NControl::CComboBox _encryptionMethod;
int _auto_MethodId;
UInt32 _auto_Dict; // (UInt32)(Int32)-1 means unknown
UInt32 _auto_Order;
UInt64 _auto_Solid;
UInt32 _auto_NumThreads;
int _default_encryptionMethod_Index;
NCompression::CInfo m_RegistryInfo;
@@ -120,13 +129,30 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
UString DirPrefix;
UString StartDirPrefix;
bool _ramSize_Defined;
UInt64 _ramSize;
UInt64 _ramUsage_Auto;
UInt64 _ramUsage_Limit;
void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2);
void GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2);
void SetArchiveName(const UString &name);
int FindRegistryFormat(const UString &name);
int FindRegistryFormatAlways(const UString &name);
const CArcInfoEx &Get_ArcInfoEx()
{
return (*ArcFormats)[GetFormatIndex()];
}
NCompression::CFormatOptions &Get_FormatOptions()
{
const CArcInfoEx &ai = Get_ArcInfoEx();
return m_RegistryInfo.Formats[ FindRegistryFormatAlways(ai.Name) ];
}
void CheckSFXNameChange();
void SetArchiveName2(bool prevWasSFX);
@@ -134,11 +160,35 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void SetNearestSelectComboBox(NWindows::NControl::CComboBox &comboBox, UInt32 value);
void SetLevel();
void SetLevel2();
void SetLevel()
{
SetLevel2();
EnableMultiCombo(IDC_COMPRESS_LEVEL);
SetMethod();
}
void SetMethod(int keepMethodId = -1);
void SetMethod2(int keepMethodId);
void SetMethod(int keepMethodId = -1)
{
SetMethod2(keepMethodId);
EnableMultiCombo(IDC_COMPRESS_METHOD);
}
void MethodChanged()
{
SetDictionary2();
EnableMultiCombo(IDC_COMPRESS_DICTIONARY);
SetOrder2();
EnableMultiCombo(IDC_COMPRESS_ORDER);
}
int GetMethodID_RAW();
int GetMethodID();
UString GetMethodSpec(UString &estimatedName);
UString GetMethodSpec();
bool IsMethodEqualTo(const UString &s);
UString GetEncryptionMethodSpec();
bool IsZipFormat();
@@ -146,10 +196,10 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void SetEncryptionMethod();
void AddDict2(size_t sizeReal, size_t sizeShow);
void AddDict(size_t size);
void SetDictionary();
int AddDict2(size_t sizeReal, size_t sizeShow);
int AddDict(size_t size);
void SetDictionary2();
UInt32 GetComboValue(NWindows::NControl::CComboBox &c, int defMax = 0);
UInt64 GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax = 0);
@@ -157,24 +207,60 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
UInt32 GetLevel() { return GetComboValue(m_Level); }
UInt32 GetLevelSpec() { return GetComboValue(m_Level, 1); }
UInt32 GetLevel2();
UInt64 GetDict() { return GetComboValue_64(m_Dictionary); }
UInt64 GetDictSpec() { return GetComboValue_64(m_Dictionary, 1); }
UInt32 GetOrder() { return GetComboValue(m_Order); }
UInt64 GetDict2()
{
UInt64 num = GetDictSpec();
if (num == (UInt64)(Int64)-1)
{
if (_auto_Dict == (UInt32)(Int32)-1)
return (UInt64)(Int64)-1; // unknown
num = _auto_Dict;
}
return num;
}
// UInt32 GetOrder() { return GetComboValue(m_Order); }
UInt32 GetOrderSpec() { return GetComboValue(m_Order, 1); }
UInt32 GetNumThreadsSpec() { return GetComboValue(m_NumThreads, 1); }
UInt32 GetNumThreads2() { UInt32 num = GetNumThreadsSpec(); if (num == UInt32(-1)) num = 1; return num; }
UInt32 GetNumThreads2()
{
UInt32 num = GetNumThreadsSpec();
if (num == (UInt32)(Int32)-1)
num = _auto_NumThreads;
return num;
}
UInt32 GetBlockSizeSpec() { return GetComboValue(m_Solid, 1); }
int AddOrder(UInt32 size);
void SetOrder();
int AddOrder_Auto();
void SetOrder2();
bool GetOrderMode();
void SetSolidBlockSize(bool useDictionary = false);
void SetNumThreads();
void SetSolidBlockSize2();
void SetSolidBlockSize(/* bool useDictionary = false */)
{
SetSolidBlockSize2();
EnableMultiCombo(IDC_COMPRESS_SOLID);
}
void SetNumThreads2();
void SetNumThreads()
{
SetNumThreads2();
EnableMultiCombo(IDC_COMPRESS_THREADS);
}
UInt64 GetMemoryUsage_Dict_DecompMem(UInt64 dict, UInt64 &decompressMemory);
UInt64 GetMemoryUsage_Threads_Dict_DecompMem(UInt32 numThreads, UInt64 dict, UInt64 &decompressMemory);
UInt64 GetMemoryUsage_DecompMem(UInt64 &decompressMemory);
UInt64 GetMemoryUsageComp_Dict(UInt64 dict64);
UInt64 GetMemoryUsageComp_Threads_Dict(UInt32 numThreads, UInt64 dict64);
void PrintMemUsage(UINT res, UInt64 value);
void SetMemoryUsage();
@@ -188,9 +274,32 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
bool SetArcPathFields(const UString &path, UString &name, bool always);
bool GetFinalPath_Smart(UString &resPath);
void CheckSFXControlsEnable();
// void CheckVolumeEnable();
void EnableMultiCombo(unsigned id);
void FormatChanged();
void OnButtonSetArchive();
bool IsSFX();
void OnButtonSFX();
virtual bool OnInit();
virtual bool OnCommand(int code, int itemID, LPARAM lParam);
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
virtual void OnOK();
virtual void OnHelp();
void MessageBoxError(LPCWSTR message)
{
MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR);
}
public:
CObjectVector<CArcInfoEx> *ArcFormats;
const CObjectVector<CArcInfoEx> *ArcFormats;
CUIntVector ArcIndices; // can not be empty, must contain Info.FormatIndex, if Info.FormatIndex >= 0
AStringVector ExternalMethods;
void SetMethods(const CObjectVector<CCodecInfoUser> &userCodecs);
NCompressDialog::CInfo Info;
UString OriginalFileName; // for bzip2, gzip2
@@ -203,28 +312,6 @@ public:
}
CCompressDialog(): CurrentDirWasChanged(false) {};
void MessageBoxError(LPCWSTR message)
{
MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR);
}
protected:
void CheckSFXControlsEnable();
// void CheckVolumeEnable();
void CheckControlsEnable();
void OnButtonSetArchive();
bool IsSFX();
void OnButtonSFX();
virtual bool OnInit();
virtual bool OnCommand(int code, int itemID, LPARAM lParam);
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
virtual void OnOK();
virtual void OnHelp();
};
#endif

View File

@@ -64,6 +64,12 @@ class CThreadExtracting: public CProgressThreadVirt
{
HRESULT ProcessVirt();
public:
/*
#ifdef EXTERNAL_CODECS
const CExternalCodecs *externalCodecs;
#endif
*/
CCodecs *codecs;
CExtractCallbackImp *ExtractCallbackSpec;
const CObjectVector<COpenType> *FormatIndices;
@@ -105,7 +111,13 @@ HRESULT CThreadExtracting::ProcessVirt()
*/
#endif
HRESULT res = Extract(codecs,
HRESULT res = Extract(
/*
#ifdef EXTERNAL_CODECS
externalCodecs,
#endif
*/
codecs,
*FormatIndices, *ExcludedFormatIndices,
*ArchivePaths, *ArchivePathsFull,
*WildcardCensor, *Options, ExtractCallbackSpec, ExtractCallback,
@@ -154,6 +166,7 @@ HRESULT CThreadExtracting::ProcessVirt()
HRESULT ExtractGUI(
// DECL_EXTERNAL_CODECS_LOC_VARS
CCodecs *codecs,
const CObjectVector<COpenType> &formatIndices,
const CIntVector &excludedFormatIndices,
@@ -172,6 +185,11 @@ HRESULT ExtractGUI(
messageWasDisplayed = false;
CThreadExtracting extracter;
/*
#ifdef EXTERNAL_CODECS
extracter.externalCodecs = __externalCodecs;
#endif
*/
extracter.codecs = codecs;
extracter.FormatIndices = &formatIndices;
extracter.ExcludedFormatIndices = &excludedFormatIndices;

View File

@@ -20,6 +20,7 @@
*/
HRESULT ExtractGUI(
// DECL_EXTERNAL_CODECS_LOC_VARS
CCodecs *codecs,
const CObjectVector<COpenType> &formatIndices,
const CIntVector &excludedFormatIndices,

View File

@@ -34,6 +34,10 @@
using namespace NWindows;
#ifdef EXTERNAL_CODECS
const CExternalCodecs *g_ExternalCodecs_Ptr;
#endif
extern
HINSTANCE g_hInstance;
HINSTANCE g_hInstance;
@@ -134,18 +138,22 @@ static 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())
{
MessageBoxW(0, s, L"7-Zip", MB_ICONERROR);
}
}
#endif
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
const bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
if (codecs->Formats.Size() == 0 &&
(isExtractGroupCommand
@@ -170,7 +178,7 @@ static int Main2()
return NExitCode::kFatalError;
}
CIntVector excludedFormatIndices;
CIntVector excludedFormats;
FOR_VECTOR (k, options.ExcludedArcTypes)
{
CIntVector tempIndices;
@@ -180,12 +188,13 @@ static int Main2()
ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE);
return NExitCode::kFatalError;
}
excludedFormatIndices.AddToUniqueSorted(tempIndices[0]);
// excludedFormatIndices.Sort();
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());
@@ -270,8 +279,10 @@ static int Main2()
ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1);
HRESULT result = ExtractGUI(codecs,
formatIndices, excludedFormatIndices,
HRESULT result = ExtractGUI(
// EXTERNAL_CODECS_VARS_L
codecs,
formatIndices, excludedFormats,
ArchivePathsSorted,
ArchivePathsFullSorted,
options.Censor.Pairs.Front().Head,

View File

@@ -872,6 +872,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
@@ -1188,6 +1196,14 @@ SOURCE=..\..\..\Windows\Window.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

@@ -174,10 +174,12 @@ HRESULT CHashCallbackGUI::SetOperationResult(UInt64 /* fileSize */, const CHashB
return CheckBreak();
}
static const unsigned k_DigestStringSize = k_HashCalc_DigestSize_Max * 2 + k_HashCalc_ExtraSize * 2 + 16;
static void AddHashString(CProperty &s, const CHasherState &h, unsigned digestIndex)
{
char temp[k_HashCalc_DigestSize_Max * 2 + 4];
AddHashHexToString(temp, h.Digests[digestIndex], h.DigestSize);
char temp[k_DigestStringSize];
h.WriteToString(digestIndex, temp);
s.Value = temp;
}

View File

@@ -156,7 +156,7 @@ HRESULT CUpdateCallbackGUI::ReportExtractResult(Int32 opRes, Int32 isEncrypted,
return S_OK;
}
HRESULT CUpdateCallbackGUI::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir)
HRESULT CUpdateCallbackGUI::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir)
{
return SetOperation_Base(op, name, isDir);
}

View File

@@ -146,7 +146,8 @@ static void SetOutProperties(
bool orderMode,
UInt32 order,
bool solidIsSpecified, UInt64 solidBlockSize,
bool multiThreadIsAllowed, UInt32 numThreads,
// bool multiThreadIsAllowed,
UInt32 numThreads,
const UString &encryptionMethod,
bool encryptHeadersIsAllowed, bool encryptHeaders,
bool /* sfxMode */)
@@ -182,7 +183,9 @@ static void SetOutProperties(
AddProp(properties, "he", encryptHeaders);
if (solidIsSpecified)
AddProp(properties, "s", GetNumInBytesString(solidBlockSize));
if (multiThreadIsAllowed)
if (
// multiThreadIsAllowed &&
numThreads != (UInt32)(Int32)-1)
AddProp(properties, "mt", numThreads);
}
@@ -287,6 +290,11 @@ static HRESULT ShowDialog(
CCompressDialog dialog;
NCompressDialog::CInfo &di = dialog.Info;
dialog.ArcFormats = &codecs->Formats;
{
CObjectVector<CCodecInfoUser> userCodecs;
codecs->Get_CodecsInfoUser_Vector(userCodecs);
dialog.SetMethods(userCodecs);
}
if (options.MethodMode.Type_Defined)
di.FormatIndex = options.MethodMode.Type.FormatIndex;
@@ -299,9 +307,13 @@ static HRESULT ShowDialog(
if (!oneFile && ai.Flags_KeepName())
continue;
if ((int)i != di.FormatIndex)
{
if (ai.Flags_HashHandler())
continue;
if (ai.Name.IsEqualTo_Ascii_NoCase("swfc"))
if (!oneFile || name.Len() < 4 || !StringsAreEqualNoCase_Ascii(name.RightPtr(4), ".swf"))
continue;
}
dialog.ArcIndices.Add(i);
}
if (dialog.ArcIndices.IsEmpty())
@@ -392,7 +404,8 @@ static HRESULT ShowDialog(
di.Dict64,
di.OrderMode, di.Order,
di.SolidIsSpecified, di.SolidBlockSize,
di.MultiThreadIsAllowed, di.NumThreads,
// di.MultiThreadIsAllowed,
di.NumThreads,
di.EncryptionMethod,
di.EncryptHeadersIsAllowed, di.EncryptHeaders,
di.SFXMode);
@@ -464,6 +477,13 @@ HRESULT UpdateGUI(
tu.UpdateCallbackGUI->Init();
UString title = LangString(IDS_PROGRESS_COMPRESSING);
if (!formatIndices.IsEmpty())
{
const int fin = formatIndices[0].FormatIndex;
if (fin >= 0)
if (codecs->Formats[fin].Flags_HashHandler())
title = LangString(IDS_CHECKSUM_CALCULATING);
}
/*
if (hwndParent != 0)

View File

@@ -24,6 +24,7 @@ GUI_OBJS = \
COMMON_OBJS = \
$O\CommandLineParser.obj \
$O\CRC.obj \
$O\DynLimBuf.obj \
$O\IntToString.obj \
$O\Lang.obj \
$O\ListFileUtils.obj \
@@ -102,6 +103,7 @@ UI_COMMON_OBJS = \
$O\ZipRegistry.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \
FM_OBJS = \