mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 10:07:10 -06:00
Update to 7-Zip Version 21.04
- first test... no release!!!
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -66,6 +66,8 @@ struct CArcCmdLineOptions
|
||||
bool TechMode;
|
||||
bool ShowTime;
|
||||
|
||||
AString ListFields;
|
||||
|
||||
int ConsoleCodePage;
|
||||
|
||||
NWildcard::CCensor Censor;
|
||||
@@ -79,6 +81,7 @@ struct CArcCmdLineOptions
|
||||
#endif
|
||||
|
||||
UStringVector HashMethods;
|
||||
// UString HashFilePath;
|
||||
|
||||
bool AppendName;
|
||||
// UStringVector ArchivePathsSorted;
|
||||
|
||||
@@ -47,6 +47,7 @@ static const char * const kCantRenameFile = "Cannot rename existing file";
|
||||
static const char * const kCantDeleteOutputFile = "Cannot delete output file";
|
||||
static const char * const kCantDeleteOutputDir = "Cannot delete output folder";
|
||||
static const char * const kCantOpenOutFile = "Cannot open output file";
|
||||
static const char * const kCantOpenInFile = "Cannot open input file";
|
||||
static const char * const kCantSetFileLen = "Cannot set length for output file";
|
||||
#ifdef SUPPORT_LINKS
|
||||
static const char * const kCantCreateHardLink = "Cannot create hard link";
|
||||
@@ -889,7 +890,8 @@ void CArchiveExtractCallback::CorrectPathParts()
|
||||
|
||||
void CArchiveExtractCallback::CreateFolders()
|
||||
{
|
||||
UStringVector &pathParts = _item.PathParts;
|
||||
// 21.04 : we don't change original (_item.PathParts) here
|
||||
UStringVector pathParts = _item.PathParts;
|
||||
|
||||
if (!_item.IsDir)
|
||||
{
|
||||
@@ -1078,18 +1080,19 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
|
||||
IInArchive *archive = _arc->Archive;
|
||||
#endif
|
||||
|
||||
const UStringVector &pathParts = _item.PathParts;
|
||||
const UInt32 index = _index;
|
||||
|
||||
bool isAnti = false;
|
||||
RINOK(_arc->IsItemAnti(index, isAnti));
|
||||
|
||||
CorrectPathParts();
|
||||
|
||||
UString processedPath (MakePathFromParts(pathParts));
|
||||
UString processedPath (MakePathFromParts(_item.PathParts));
|
||||
|
||||
if (!isAnti)
|
||||
{
|
||||
// 21.04: CreateFolders doesn't change (_item.PathParts)
|
||||
CreateFolders();
|
||||
}
|
||||
|
||||
FString fullProcessedPath (us2fs(processedPath));
|
||||
if (_pathMode != NExtract::NPathMode::kAbsPaths
|
||||
@@ -1295,7 +1298,25 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
|
||||
|
||||
|
||||
|
||||
HRESULT CArchiveExtractCallback::GetItem(UInt32 index)
|
||||
{
|
||||
#ifndef _SFX
|
||||
_item._use_baseParentFolder_mode = _use_baseParentFolder_mode;
|
||||
if (_use_baseParentFolder_mode)
|
||||
{
|
||||
_item._baseParentFolder = (int)_baseParentFolder;
|
||||
if (_pathMode == NExtract::NPathMode::kFullPaths ||
|
||||
_pathMode == NExtract::NPathMode::kAbsPaths)
|
||||
_item._baseParentFolder = -1;
|
||||
}
|
||||
#endif // _SFX
|
||||
|
||||
#ifdef SUPPORT_ALT_STREAMS
|
||||
_item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon;
|
||||
#endif
|
||||
|
||||
return _arc->GetItem(index, _item);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
|
||||
@@ -1339,22 +1360,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
|
||||
IInArchive *archive = _arc->Archive;
|
||||
|
||||
#ifndef _SFX
|
||||
_item._use_baseParentFolder_mode = _use_baseParentFolder_mode;
|
||||
if (_use_baseParentFolder_mode)
|
||||
{
|
||||
_item._baseParentFolder = (int)_baseParentFolder;
|
||||
if (_pathMode == NExtract::NPathMode::kFullPaths ||
|
||||
_pathMode == NExtract::NPathMode::kAbsPaths)
|
||||
_item._baseParentFolder = -1;
|
||||
}
|
||||
#endif // _SFX
|
||||
|
||||
#ifdef SUPPORT_ALT_STREAMS
|
||||
_item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon;
|
||||
#endif
|
||||
|
||||
RINOK(_arc->GetItem(index, _item));
|
||||
RINOK(GetItem(index));
|
||||
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
@@ -1382,6 +1388,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
return S_OK;
|
||||
#endif // SUPPORT_ALT_STREAMS
|
||||
|
||||
// we can change (_item.PathParts) in this function
|
||||
UStringVector &pathParts = _item.PathParts;
|
||||
|
||||
if (_wildcardCensor)
|
||||
@@ -1974,7 +1981,10 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
|
||||
|
||||
#ifndef _SFX
|
||||
if (ExtractToStreamCallback)
|
||||
return ExtractToStreamCallback->SetOperationResult7(opRes, BoolToInt(_encrypted));
|
||||
{
|
||||
GetUnpackSize();
|
||||
return ExtractToStreamCallback->SetOperationResult8(opRes, BoolToInt(_encrypted), _curSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
@@ -2103,6 +2113,82 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
|
||||
}
|
||||
|
||||
|
||||
// ---------- HASH functions ----------
|
||||
|
||||
FString CArchiveExtractCallback::Hash_GetFullFilePath()
|
||||
{
|
||||
// this function changes _item.PathParts.
|
||||
CorrectPathParts();
|
||||
const UStringVector &pathParts = _item.PathParts;
|
||||
const UString processedPath (MakePathFromParts(pathParts));
|
||||
FString fullProcessedPath (us2fs(processedPath));
|
||||
if (_pathMode != NExtract::NPathMode::kAbsPaths
|
||||
|| !NName::IsAbsolutePath(processedPath))
|
||||
{
|
||||
fullProcessedPath = MakePath_from_2_Parts(
|
||||
DirPathPrefix_for_HashFiles,
|
||||
// _dirPathPrefix,
|
||||
fullProcessedPath);
|
||||
}
|
||||
return fullProcessedPath;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
if (propID == kpidSize)
|
||||
{
|
||||
RINOK(GetItem(index));
|
||||
const FString fullProcessedPath = Hash_GetFullFilePath();
|
||||
NFile::NFind::CFileInfo fi;
|
||||
if (fi.Find_FollowLink(fullProcessedPath))
|
||||
if (!fi.IsDir())
|
||||
prop = (UInt64)fi.Size;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*inStream = NULL;
|
||||
// if (index != _index) return E_FAIL;
|
||||
if (mode != NUpdateNotifyOp::kHashRead)
|
||||
return E_FAIL;
|
||||
|
||||
RINOK(GetItem(index));
|
||||
const FString fullProcessedPath = Hash_GetFullFilePath();
|
||||
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<ISequentialInStream> inStreamRef = inStreamSpec;
|
||||
inStreamSpec->File.PreserveATime = _ntOptions.PreserveATime;
|
||||
if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite))
|
||||
{
|
||||
RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath));
|
||||
return S_OK;
|
||||
}
|
||||
*inStream = inStreamRef.Detach();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::ReportOperation(
|
||||
UInt32 /* indexType */, UInt32 /* index */, UInt32 /* op */)
|
||||
{
|
||||
// COM_TRY_BEGIN
|
||||
return S_OK;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
// ------------ After Extracting functions ------------
|
||||
|
||||
void CDirPathSortPair::SetNumSlashes(const FChar *s)
|
||||
{
|
||||
for (unsigned numSlashes = 0;;)
|
||||
|
||||
@@ -62,9 +62,15 @@ struct CExtractNtOptions
|
||||
|
||||
bool PreAllocateOutFile;
|
||||
|
||||
// used for hash arcs only, when we open external files
|
||||
bool PreserveATime;
|
||||
bool OpenShareForWrite;
|
||||
|
||||
CExtractNtOptions():
|
||||
ReplaceColonForAltStream(false),
|
||||
WriteToAltStreamIfColon(false)
|
||||
WriteToAltStreamIfColon(false),
|
||||
PreserveATime(false),
|
||||
OpenShareForWrite(false)
|
||||
{
|
||||
SymLinks.Val = true;
|
||||
SymLinks_AllowDangerous.Val = false;
|
||||
@@ -205,6 +211,8 @@ class CArchiveExtractCallback:
|
||||
public IArchiveExtractCallbackMessage,
|
||||
public ICryptoGetTextPassword,
|
||||
public ICompressProgressInfo,
|
||||
public IArchiveUpdateCallbackFile,
|
||||
public IArchiveGetDiskProperty,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
const CArc *_arc;
|
||||
@@ -342,6 +350,9 @@ class CArchiveExtractCallback:
|
||||
HRESULT GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
|
||||
HRESULT GetUnpackSize();
|
||||
|
||||
FString Hash_GetFullFilePath();
|
||||
|
||||
public:
|
||||
HRESULT SendMessageError(const char *message, const FString &path);
|
||||
HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
|
||||
HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2);
|
||||
@@ -356,10 +367,20 @@ public:
|
||||
UInt64 UnpackSize;
|
||||
UInt64 AltStreams_UnpackSize;
|
||||
|
||||
MY_UNKNOWN_IMP3(IArchiveExtractCallbackMessage, ICryptoGetTextPassword, ICompressProgressInfo)
|
||||
FString DirPathPrefix_for_HashFiles;
|
||||
|
||||
MY_UNKNOWN_IMP5(
|
||||
IArchiveExtractCallbackMessage,
|
||||
ICryptoGetTextPassword,
|
||||
ICompressProgressInfo,
|
||||
IArchiveUpdateCallbackFile,
|
||||
IArchiveGetDiskProperty
|
||||
)
|
||||
|
||||
INTERFACE_IArchiveExtractCallback(;)
|
||||
INTERFACE_IArchiveExtractCallbackMessage(;)
|
||||
INTERFACE_IArchiveUpdateCallbackFile(;)
|
||||
INTERFACE_IArchiveGetDiskProperty(;)
|
||||
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
|
||||
@@ -453,6 +474,7 @@ private:
|
||||
bool _isRenamed;
|
||||
HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit);
|
||||
HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit);
|
||||
HRESULT GetItem(UInt32 index);
|
||||
|
||||
HRESULT CloseFile();
|
||||
HRESULT CloseReparseAndFile();
|
||||
|
||||
@@ -639,15 +639,22 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64
|
||||
|
||||
static const unsigned kSubBits = 8;
|
||||
|
||||
static UInt32 GetLogSize(UInt64 size)
|
||||
static unsigned GetLogSize(UInt64 size)
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (;;)
|
||||
{
|
||||
i++; size >>= 1; if (size == 0) break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static UInt32 GetLogSize_Sub(UInt64 size)
|
||||
{
|
||||
if (size <= 1)
|
||||
return 0;
|
||||
unsigned i;
|
||||
for (i = 2; i < 64; i++)
|
||||
if (size < ((UInt64)1 << i))
|
||||
break;
|
||||
i--;
|
||||
const unsigned i = GetLogSize(size) - 1;
|
||||
UInt32 v;
|
||||
if (i <= kSubBits)
|
||||
v = (UInt32)(size) << (kSubBits - i);
|
||||
@@ -656,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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,8 +16,13 @@ HRESULT CompressFiles(
|
||||
bool email, bool showDialog, bool waitFinish);
|
||||
|
||||
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup);
|
||||
void TestArchives(const UStringVector &arcPaths);
|
||||
void CalcChecksum(const UStringVector &paths, const UString &methodName);
|
||||
void TestArchives(const UStringVector &arcPaths, bool hashMode = false);
|
||||
|
||||
void CalcChecksum(const UStringVector &paths,
|
||||
const UString &methodName,
|
||||
const UString &arcPathPrefix,
|
||||
const UString &arcFileName);
|
||||
|
||||
void Benchmark(bool totalMode);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,8 @@ static void ThrowException_if_Error(HRESULT res)
|
||||
#define CREATE_CODECS \
|
||||
CCodecs *codecs = new CCodecs; \
|
||||
CMyComPtr<ICompressCodecsInfo> compressCodecsInfo = codecs; \
|
||||
ThrowException_if_Error(codecs->Load());
|
||||
ThrowException_if_Error(codecs->Load()); \
|
||||
Codecs_AddHashArcHandler(codecs);
|
||||
|
||||
#define LOAD_EXTERNAL_CODECS \
|
||||
CExternalCodecs __externalCodecs; \
|
||||
@@ -51,7 +52,8 @@ static void ThrowException_if_Error(HRESULT res)
|
||||
#define CREATE_CODECS \
|
||||
CCodecs *codecs = new CCodecs; \
|
||||
CMyComPtr<IUnknown> compressCodecsInfo = codecs; \
|
||||
ThrowException_if_Error(codecs->Load());
|
||||
ThrowException_if_Error(codecs->Load()); \
|
||||
Codecs_AddHashArcHandler(codecs);
|
||||
|
||||
#define LOAD_EXTERNAL_CODECS
|
||||
|
||||
@@ -150,7 +152,8 @@ HRESULT CompressFiles(
|
||||
|
||||
|
||||
static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
|
||||
bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false)
|
||||
bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false,
|
||||
const char *kType = NULL)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
|
||||
@@ -187,6 +190,15 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
|
||||
}
|
||||
|
||||
CObjectVector<COpenType> formatIndices;
|
||||
if (kType)
|
||||
{
|
||||
if (!ParseOpenTypes(*codecs, UString(kType), formatIndices))
|
||||
{
|
||||
throw CSystemException(E_INVALIDARG);
|
||||
// ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE);
|
||||
// return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
NWildcard::CCensor censor;
|
||||
{
|
||||
@@ -221,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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,15 +3,17 @@
|
||||
#ifndef __HASH_CALC_H
|
||||
#define __HASH_CALC_H
|
||||
|
||||
#include "../../../Common/UTFConvert.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../Common/MethodProps.h"
|
||||
|
||||
#include "DirItem.h"
|
||||
#include "IFileExtractCallback.h"
|
||||
|
||||
const unsigned k_HashCalc_DigestSize_Max = 64;
|
||||
|
||||
const unsigned k_HashCalc_ExtraSize = 8;
|
||||
const unsigned k_HashCalc_NumGroups = 4;
|
||||
|
||||
enum
|
||||
@@ -27,9 +29,37 @@ struct CHasherState
|
||||
CMyComPtr<IHasher> Hasher;
|
||||
AString Name;
|
||||
UInt32 DigestSize;
|
||||
Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max];
|
||||
UInt64 NumSums[k_HashCalc_NumGroups];
|
||||
Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max + k_HashCalc_ExtraSize];
|
||||
|
||||
void InitDigestGroup(unsigned groupIndex)
|
||||
{
|
||||
NumSums[groupIndex] = 0;
|
||||
memset(Digests[groupIndex], 0, sizeof(Digests[groupIndex]));
|
||||
}
|
||||
|
||||
const Byte *GetExtraData_for_Group(unsigned groupIndex) const
|
||||
{
|
||||
return Digests[groupIndex] + k_HashCalc_DigestSize_Max;
|
||||
}
|
||||
|
||||
unsigned GetNumExtraBytes_for_Group(unsigned groupIndex) const
|
||||
{
|
||||
const Byte *p = GetExtraData_for_Group(groupIndex);
|
||||
// we use little-endian to read extra bytes
|
||||
for (unsigned i = k_HashCalc_ExtraSize; i != 0; i--)
|
||||
if (p[i - 1] != 0)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AddDigest(unsigned groupIndex, const Byte *data);
|
||||
|
||||
void WriteToString(unsigned digestIndex, char *s) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct IHashCalc
|
||||
{
|
||||
virtual void InitForNewFile() = 0;
|
||||
@@ -89,9 +119,68 @@ struct IHashCallbackUI: public IDirItemsCallback
|
||||
INTERFACE_IHashCallbackUI(=0)
|
||||
};
|
||||
|
||||
|
||||
struct CHashOptionsLocal
|
||||
{
|
||||
CBoolPair HashMode_Zero;
|
||||
CBoolPair HashMode_Tag;
|
||||
CBoolPair HashMode_Dirs;
|
||||
CBoolPair HashMode_OnlyHash;
|
||||
|
||||
void Init_HashOptionsLocal()
|
||||
{
|
||||
HashMode_Zero.Init();
|
||||
HashMode_Tag.Init();
|
||||
HashMode_Dirs.Init();
|
||||
HashMode_OnlyHash.Init();
|
||||
// HashMode_Dirs = true; // for debug
|
||||
}
|
||||
|
||||
CHashOptionsLocal()
|
||||
{
|
||||
Init_HashOptionsLocal();
|
||||
}
|
||||
|
||||
bool ParseFlagCharOption(wchar_t c, bool val)
|
||||
{
|
||||
c = MyCharLower_Ascii(c);
|
||||
if (c == 'z') HashMode_Zero.SetVal_as_Defined(val);
|
||||
else if (c == 't') HashMode_Tag.SetVal_as_Defined(val);
|
||||
else if (c == 'd') HashMode_Dirs.SetVal_as_Defined(val);
|
||||
else if (c == 'h') HashMode_OnlyHash.SetVal_as_Defined(val);
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseString(const UString &s)
|
||||
{
|
||||
for (unsigned i = 0; i < s.Len();)
|
||||
{
|
||||
const wchar_t c = s[i++];
|
||||
bool val = true;
|
||||
if (i < s.Len())
|
||||
{
|
||||
const wchar_t next = s[i];
|
||||
if (next == '-')
|
||||
{
|
||||
val = false;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!ParseFlagCharOption(c, val))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CHashOptions
|
||||
// : public CHashOptionsLocal
|
||||
{
|
||||
UStringVector Methods;
|
||||
// UString HashFilePath;
|
||||
|
||||
bool PreserveATime;
|
||||
bool OpenShareForWrite;
|
||||
bool StdInMode;
|
||||
@@ -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
|
||||
|
||||
@@ -103,9 +103,9 @@ DECL_INTERFACE_SUB(IGetProp, IUnknown, 0x01, 0x20)
|
||||
STDMETHOD(UseExtractToStream)(Int32 *res) x; \
|
||||
STDMETHOD(GetStream7)(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp) x; \
|
||||
STDMETHOD(PrepareOperation7)(Int32 askExtractMode) x; \
|
||||
STDMETHOD(SetOperationResult7)(Int32 resultEOperationResult, Int32 encrypted) x; \
|
||||
STDMETHOD(SetOperationResult8)(Int32 resultEOperationResult, Int32 encrypted, UInt64 size) x; \
|
||||
|
||||
DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x30)
|
||||
DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x31)
|
||||
{
|
||||
INTERFACE_IFolderExtractToStreamCallback(PURE)
|
||||
};
|
||||
|
||||
@@ -53,6 +53,7 @@ using namespace NWindows;
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/RegisterArc.h"
|
||||
#include "../../Common/RegisterCodec.h"
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
|
||||
@@ -193,9 +194,9 @@ void CArcInfoEx::AddExts(const UString &ext, const UString &addExt)
|
||||
static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector<CByteBuffer> &signatures)
|
||||
{
|
||||
signatures.Clear();
|
||||
while (size > 0)
|
||||
while (size != 0)
|
||||
{
|
||||
unsigned len = *data++;
|
||||
const unsigned len = *data++;
|
||||
size--;
|
||||
if (len > size)
|
||||
return false;
|
||||
@@ -252,6 +253,25 @@ static HRESULT GetCoderClass(Func_GetMethodProperty getMethodProperty, UInt32 in
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT GetMethodBoolProp(Func_GetMethodProperty getMethodProperty, UInt32 index,
|
||||
PROPID propId, bool &resVal, bool &isAssigned)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
resVal = false;
|
||||
isAssigned = false;
|
||||
RINOK(getMethodProperty(index, propId, &prop));
|
||||
if (prop.vt == VT_BOOL)
|
||||
{
|
||||
isAssigned = true;
|
||||
resVal = VARIANT_BOOLToBool(prop.boolVal);
|
||||
}
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
#define MY_GET_FUNC(dest, type, func) *(void **)(&dest) = (func);
|
||||
// #define MY_GET_FUNC(dest, type, func) dest = (type)(func);
|
||||
|
||||
@@ -279,6 +299,7 @@ HRESULT CCodecs::LoadCodecs()
|
||||
info.CodecIndex = i;
|
||||
RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));
|
||||
RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));
|
||||
RINOK(GetMethodBoolProp(lib.GetMethodProperty, i, NMethodPropID::kIsFilter, info.IsFilter, info.IsFilter_Assigned));
|
||||
Codecs.Add(info);
|
||||
}
|
||||
}
|
||||
@@ -647,8 +668,14 @@ HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPath)
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
if (fi.IsDir())
|
||||
continue;
|
||||
#else
|
||||
if (enumerator.DirEntry_IsDir(fi, true)) // followLink
|
||||
continue;
|
||||
#endif
|
||||
|
||||
RINOK(LoadDll(folderPrefix + fi.Name, true));
|
||||
}
|
||||
return S_OK;
|
||||
@@ -725,7 +752,10 @@ HRESULT CCodecs::Load()
|
||||
if (arc.IsMultiSignature())
|
||||
ParseSignatures(arc.Signature, arc.SignatureSize, item.Signatures);
|
||||
else
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -70,6 +70,7 @@ struct COpenType
|
||||
|
||||
bool CanReturnArc;
|
||||
bool CanReturnParser;
|
||||
bool IsHashType;
|
||||
bool EachPos;
|
||||
|
||||
// bool SkipSfxStub;
|
||||
@@ -90,6 +91,7 @@ struct COpenType
|
||||
Recursive(true),
|
||||
CanReturnArc(true),
|
||||
CanReturnParser(false),
|
||||
IsHashType(false),
|
||||
EachPos(false),
|
||||
// SkipSfxStub(true),
|
||||
// ExeAsUnknown(true),
|
||||
@@ -285,7 +287,7 @@ public:
|
||||
UString Path;
|
||||
UString filePath;
|
||||
UString DefaultName;
|
||||
int FormatIndex; // - 1 means Parser.
|
||||
int FormatIndex; // -1 means Parser
|
||||
UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile
|
||||
FILETIME MTime;
|
||||
bool MTimeDefined;
|
||||
@@ -358,9 +360,16 @@ public:
|
||||
HRESULT OpenStream(const COpenOptions &options);
|
||||
HRESULT OpenStreamOrFile(COpenOptions &options);
|
||||
|
||||
HRESULT ReOpen(const COpenOptions &options);
|
||||
HRESULT ReOpen(const COpenOptions &options, IArchiveOpenCallback *openCallback_Additional);
|
||||
|
||||
HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream);
|
||||
|
||||
bool IsHashHandler(const COpenOptions &options) const
|
||||
{
|
||||
if (FormatIndex < 0)
|
||||
return false;
|
||||
return options.codecs->Formats[(unsigned)FormatIndex].Flags_HashHandler();
|
||||
}
|
||||
};
|
||||
|
||||
struct CArchiveLink
|
||||
@@ -421,6 +430,8 @@ struct CArchiveLink
|
||||
|
||||
bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types);
|
||||
|
||||
// bool IsHashType(const CObjectVector<COpenType> &types);
|
||||
|
||||
|
||||
struct CDirPathSortPair
|
||||
{
|
||||
|
||||
@@ -542,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;
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *val
|
||||
case kpidCTime: if (ParentDirItem) prop = ParentDirItem->CTime; break;
|
||||
case kpidATime: if (ParentDirItem) prop = ParentDirItem->ATime; break;
|
||||
case kpidMTime: if (ParentDirItem) prop = ParentDirItem->MTime; break;
|
||||
case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
@@ -475,6 +476,17 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
|
||||
static NSynchronization::CCriticalSection CS;
|
||||
#endif
|
||||
|
||||
void CArchiveUpdateCallback::UpdateProcessedItemStatus(unsigned dirIndex)
|
||||
{
|
||||
if (ProcessedItemsStatuses)
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
NSynchronization::CCriticalSectionLock lock(CS);
|
||||
#endif
|
||||
ProcessedItemsStatuses[dirIndex] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -544,6 +556,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
|
||||
CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
|
||||
inStreamSpec->Init(di.ReparseData, di.ReparseData.Size());
|
||||
*inStream = inStreamLoc.Detach();
|
||||
|
||||
UpdateProcessedItemStatus((unsigned)up.DirIndex);
|
||||
return S_OK;
|
||||
}
|
||||
#endif // !defined(UNDER_CE)
|
||||
@@ -600,13 +614,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (ProcessedItemsStatuses)
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
NSynchronization::CCriticalSectionLock lock(CS);
|
||||
#endif
|
||||
ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1;
|
||||
}
|
||||
UpdateProcessedItemStatus((unsigned)up.DirIndex);
|
||||
*inStream = inStreamLoc.Detach();
|
||||
}
|
||||
|
||||
@@ -649,7 +657,7 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
|
||||
isDir = DirItems->Items[(unsigned)up.DirIndex].IsDir();
|
||||
}
|
||||
}
|
||||
return Callback->ReportUpdateOpeartion(op, name.IsEmpty() ? NULL : name.Ptr(), isDir);
|
||||
return Callback->ReportUpdateOperation(op, name.IsEmpty() ? NULL : name.Ptr(), isDir);
|
||||
}
|
||||
|
||||
wchar_t temp[16];
|
||||
@@ -684,7 +692,7 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
|
||||
if (!s)
|
||||
s = L"";
|
||||
|
||||
return Callback->ReportUpdateOpeartion(op, s, isDir);
|
||||
return Callback->ReportUpdateOperation(op, s, isDir);
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ struct CArcToDoStat
|
||||
virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x; \
|
||||
virtual HRESULT SetOperationResult(Int32 opRes) x; \
|
||||
virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x; \
|
||||
virtual HRESULT ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir) x; \
|
||||
virtual HRESULT ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) x; \
|
||||
/* virtual HRESULT SetPassword(const UString &password) x; */ \
|
||||
virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \
|
||||
virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \
|
||||
@@ -87,6 +87,8 @@ class CArchiveUpdateCallback:
|
||||
UInt32 _hardIndex_From;
|
||||
UInt32 _hardIndex_To;
|
||||
|
||||
void UpdateProcessedItemStatus(unsigned dirIndex);
|
||||
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile)
|
||||
@@ -121,6 +123,7 @@ public:
|
||||
CRecordVector<UInt64> VolumesSizes;
|
||||
FString VolName;
|
||||
FString VolExt;
|
||||
UString ArcFileName; // without path prefix
|
||||
|
||||
IUpdateCallbackUI *Callback;
|
||||
|
||||
@@ -147,7 +150,6 @@ public:
|
||||
|
||||
Byte *ProcessedItemsStatuses;
|
||||
|
||||
|
||||
CArchiveUpdateCallback();
|
||||
|
||||
bool IsDir(const CUpdatePair2 &up) const
|
||||
|
||||
Reference in New Issue
Block a user