Update to 7-Zip Version 18.06

This commit is contained in:
Tino Reichardt
2018-12-30 12:50:20 +01:00
parent 093cf20bad
commit a488536124
116 changed files with 1830 additions and 955 deletions

View File

@@ -23,6 +23,7 @@
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
#ifdef _WIN32
@@ -39,7 +40,9 @@
extern bool g_CaseSensitive;
extern bool g_PathTrailReplaceMode;
#ifdef _7ZIP_LARGE_PAGES
bool g_LargePagesMode = false;
#endif
#ifdef UNDER_CE
@@ -410,8 +413,19 @@ static void AddToCensorFromListFile(
UStringVector names;
if (!NFind::DoesFileExist(us2fs(fileName)))
throw CArcCmdLineException(kCannotFindListFile, fileName);
if (!ReadNamesFromListFile(us2fs(fileName), names, codePage))
DWORD lastError = 0;
if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError))
{
if (lastError != 0)
{
UString m;
m = "The file operation error for listfile";
m.Add_LF();
m += NError::MyFormatMessage(lastError);
throw CArcCmdLineException(m, fileName);
}
throw CArcCmdLineException(kIncorrectListFile, fileName);
}
if (renamePairs)
{
if ((names.Size() & 1) != 0)

View File

@@ -1182,7 +1182,9 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
bool needDelete = true;
if (needDelete)
{
if (NFind::DoesFileExist(fullProcessedPath))
if (!DeleteFileAlways(fullProcessedPath))
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath));
return S_OK;
@@ -1368,13 +1370,35 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
// UInt64 ticks = GetCpuTicks();
bool res = _outFileStreamSpec->File.SetLength(_curSize);
_fileLengthWasSet = res;
_outFileStreamSpec->File.SeekToBegin();
// ticks = GetCpuTicks() - ticks;
// printf("\nticks = %10d\n", (unsigned)ticks);
if (!res)
{
RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath));
}
/*
_outFileStreamSpec->File.Close();
ticks = GetCpuTicks() - ticks;
printf("\nticks = %10d\n", (unsigned)ticks);
return S_FALSE;
*/
/*
File.SetLength() on FAT (xp64): is fast, but then File.Close() can be slow,
if we don't write any data.
File.SetLength() for remote share file (exFAT) can be slow in some cases,
and the Windows can return "network error" after 1 minute,
while remote file still can grow.
We need some way to detect such bad cases and disable PreAllocateOutFile mode.
*/
res = _outFileStreamSpec->File.SeekToBegin();
if (!res)
{
RINOK(SendMessageError_with_LastError("Can not seek to begin of file", fullProcessedPath));
}
}
#ifdef SUPPORT_ALT_STREAMS

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
@@ -11,7 +13,7 @@
using namespace NWindows;
using namespace NFile;
UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
{
FString resultName = fi.Name;
if (!fi.IsDir() && !keepName)
@@ -72,7 +74,75 @@ static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepN
return resultName;
}
UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName)
UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi)
{
return Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(path), fromPrev, keepName)));
bool keepName = false;
/*
if (paths.Size() == 1)
{
const UString &name = paths[0];
if (name.Len() > 4)
if (CompareFileNames(name.RightPtr(4), L".tar") == 0)
keepName = true;
}
*/
UString name;
if (fi)
name = CreateArchiveName(*fi, keepName);
else
{
if (paths.IsEmpty())
return L"archive";
bool fromPrev = (paths.Size() > 1);
name = Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(paths.Front()), fromPrev, keepName)));
}
UString postfix;
UInt32 index = 1;
for (;;)
{
// we don't want cases when we include archive to itself.
// so we find first available name for archive
const UString name2 = name + postfix;
const UString name2_zip = name2 + L".zip";
const UString name2_7z = name2 + L".7z";
const UString name2_tar = name2 + L".tar";
const UString name2_wim = name2 + L".wim";
unsigned i = 0;
for (i = 0; i < paths.Size(); i++)
{
const UString &fn = paths[i];
NFind::CFileInfo fi2;
const NFind::CFileInfo *fp;
if (fi && paths.Size() == 1)
fp = fi;
else
{
if (!fi2.Find(us2fs(fn)))
continue;
fp = &fi2;
}
const UString fname = fs2us(fp->Name);
if ( 0 == CompareFileNames(fname, name2_zip)
|| 0 == CompareFileNames(fname, name2_7z)
|| 0 == CompareFileNames(fname, name2_tar)
|| 0 == CompareFileNames(fname, name2_wim))
break;
}
if (i == paths.Size())
break;
index++;
postfix = "_";
postfix.Add_UInt32(index);
}
name += postfix;
return name;
}

View File

@@ -3,11 +3,8 @@
#ifndef __ARCHIVE_NAME_H
#define __ARCHIVE_NAME_H
#include "../../../Common/MyString.h"
#include "../../../Windows/FileFind.h"
UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName);
UString CreateArchiveName(const NWindows::NFile::NFind::CFileInfo &fileInfo, bool keepName);
UString CreateArchiveName(const UStringVector &paths, const NWindows::NFile::NFind::CFileInfo *fi = NULL);
#endif

View File

@@ -522,10 +522,9 @@ class CBenchProgressInfo:
{
public:
CBenchProgressStatus *Status;
HRESULT Res;
IBenchCallback *Callback;
CBenchProgressInfo(): Callback(0) {}
CBenchProgressInfo(): Callback(NULL) {}
MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
@@ -758,7 +757,7 @@ struct CEncoderInfo
fileData(NULL),
CheckCrc_Enc(true),
CheckCrc_Dec(true),
outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {}
outStreamSpec(NULL), callback(NULL), printCallback(NULL), propStreamSpec(NULL) {}
#ifndef _7ZIP_ST
@@ -1144,7 +1143,7 @@ static const UInt32 kNumThreadsMax = (1 << 12);
struct CBenchEncoders
{
CEncoderInfo *encoders;
CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }
CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; }
~CBenchEncoders() { delete []encoders; }
};
@@ -1545,7 +1544,7 @@ struct CFreqThreads
CFreqInfo *Items;
UInt32 NumThreads;
CFreqThreads(): Items(0), NumThreads(0) {}
CFreqThreads(): Items(NULL), NumThreads(0) {}
void WaitAll()
{
for (UInt32 i = 0; i < NumThreads; i++)
@@ -1603,7 +1602,7 @@ struct CCrcThreads
CCrcInfo *Items;
UInt32 NumThreads;
CCrcThreads(): Items(0), NumThreads(0) {}
CCrcThreads(): Items(NULL), NumThreads(0) {}
void WaitAll()
{
for (UInt32 i = 0; i < NumThreads; i++)
@@ -1885,8 +1884,51 @@ AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
}
static void PrintSize(AString &s, UInt64 v)
{
char c = 0;
if ((v & 0x3FF) == 0) { v >>= 10; c = 'K';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'M';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'G';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'T';
}}}}
else
{
PrintHex(s, v);
return;
}
char temp[32];
ConvertUInt64ToString(v, temp);
s += temp;
if (c)
s += c;
}
#ifdef _7ZIP_LARGE_PAGES
extern bool g_LargePagesMode;
extern "C"
{
extern SIZE_T g_LargePageSize;
}
void Add_LargePages_String(AString &s)
{
if (g_LargePagesMode || g_LargePageSize != 0)
{
s += " (LP-";
PrintSize(s, g_LargePageSize);
if (!g_LargePagesMode)
s += "-NA";
s += ")";
}
}
#endif
static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
@@ -1898,8 +1940,15 @@ static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
else
f.Print(" ?");
f.Print(" MB");
if (g_LargePagesMode)
f.Print(" LP");
#ifdef _7ZIP_LARGE_PAGES
{
AString s;
Add_LargePages_String(s);
f.Print(s);
}
#endif
f.Print(", # ");
f.Print(threadsString);
PrintNumber(f, numThreads, 3);
@@ -2539,26 +2588,7 @@ static const char * const k_PF[] =
#endif
static void PrintSize(AString &s, UInt64 v)
{
char c = 0;
if ((v & 0x3FF) == 0) { v >>= 10; c = 'K';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'M';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'G';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'T';
}}}}
else
{
PrintHex(s, v);
return;
}
char temp[32];
ConvertUInt64ToString(v, temp);
s += temp;
if (c)
s += c;
}
static void PrintPage(AString &s, UInt32 v)
{
@@ -2707,8 +2737,9 @@ void GetCpuName(AString &s)
#endif
if (g_LargePagesMode)
s += " (LP)";
#ifdef _7ZIP_LARGE_PAGES
Add_LargePages_String(s);
#endif
}
@@ -2968,6 +2999,9 @@ HRESULT Bench(
UInt64 start = ::GetTimeCount();
UInt32 sum = (UInt32)start;
sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp);
if (sum == 0xF1541213)
if (printCallback)
printCallback->Print("");
const UInt64 realDelta = ::GetTimeCount() - start;
start = realDelta;
if (start == 0)
@@ -2984,7 +3018,7 @@ HRESULT Bench(
else
{
// PrintNumber(*printCallback, start, 0);
PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0));
PrintNumber(*printCallback, mipsVal, 5);
}
}
/*

View File

@@ -68,5 +68,10 @@ void GetSysInfo(AString &s1, AString &s2);
void GetCpuName(AString &s);
void GetCpuFeatures(AString &s);
#ifdef _7ZIP_LARGE_PAGES
void Add_LargePages_String(AString &s);
#else
// #define Add_LargePages_String
#endif
#endif

View File

@@ -1084,3 +1084,13 @@ CMessagePathException::CMessagePathException(const char *a, const wchar_t *u)
(*this) += u;
}
}
CMessagePathException::CMessagePathException(const wchar_t *a, const wchar_t *u)
{
(*this) += a;
if (u)
{
Add_LF();
(*this) += u;
}
}

View File

@@ -22,6 +22,7 @@ HRESULT EnumerateItems(
struct CMessagePathException: public UString
{
CMessagePathException(const char *a, const wchar_t *u = NULL);
CMessagePathException(const wchar_t *a, const wchar_t *u = NULL);
};

View File

@@ -230,7 +230,7 @@ HRESULT HashCalc(
unsigned i;
CHashBundle hb;
RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods));
hb.Init();
// hb.Init();
hb.NumErrors = dirItems.Stat.NumErrors;

View File

@@ -51,9 +51,13 @@ struct CHashBundle: public IHashCalc
UInt64 CurSize;
UString MainName;
UString FirstFileName;
HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods);
void Init()
// void Init() {}
CHashBundle()
{
NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0;
}
@@ -76,7 +80,7 @@ struct CHashBundle: public IHashCalc
virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \
virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \
virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \
virtual HRESULT AfterLastFile(const CHashBundle &hb) x; \
virtual HRESULT AfterLastFile(CHashBundle &hb) x; \
struct IHashCallbackUI: public IDirItemsCallback
{

View File

@@ -563,6 +563,8 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
UInt32 parentType = 0;
RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType));
// 18.06: fixed : we don't want to split name to parts
/*
if (parentType != NParentType::kAltStream)
{
for (;;)
@@ -576,6 +578,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
s.DeleteFrom(pos);
}
}
*/
parts.Insert(0, s);
@@ -2014,7 +2017,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
else
{
const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
const CArcInfoEx &ai = op.codecs->Formats[(unsigned)formatIndex];
if (ai.FindExtension(extension) >= 0)
{
if (ai.Flags_FindSignature() && searchMarkerInHandler)

View File

@@ -288,29 +288,27 @@ void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode)
if (mode == k_ArcNameMode_Add)
return;
if (mode == k_ArcNameMode_Exact)
{
BaseExtension.Empty();
return;
}
int dotPos = Name.ReverseFind_Dot();
if (dotPos < 0)
return;
if ((unsigned)dotPos == Name.Len() - 1)
if (mode != k_ArcNameMode_Exact)
{
Name.DeleteBack();
BaseExtension.Empty();
return;
int dotPos = Name.ReverseFind_Dot();
if (dotPos < 0)
return;
if ((unsigned)dotPos == Name.Len() - 1)
Name.DeleteBack();
else
{
const UString ext = Name.Ptr(dotPos + 1);
if (BaseExtension.IsEqualTo_NoCase(ext))
{
BaseExtension = ext;
Name.DeleteFrom(dotPos);
return;
}
}
}
const UString ext = Name.Ptr(dotPos + 1);
if (BaseExtension.IsEqualTo_NoCase(ext))
{
BaseExtension = ext;
Name.DeleteFrom(dotPos);
}
else
BaseExtension.Empty();
BaseExtension.Empty();
}
UString CArchivePath::GetFinalPath() const
@@ -327,6 +325,7 @@ UString CArchivePath::GetFinalPath() const
UString CArchivePath::GetFinalVolPath() const
{
UString path = GetPathWithoutExt();
// if BaseExtension is empty, we must ignore VolExtension also.
if (!BaseExtension.IsEmpty())
{
path += '.';
@@ -1166,7 +1165,7 @@ HRESULT UpdateArchive(
{
errorInfo.SystemError = ERROR_ACCESS_DENIED;
errorInfo.Message = "The file is read-only";
errorInfo.FileNames.Add(arcPath);
errorInfo.FileNames.Add(us2fs(arcPath));
return errorInfo.Get_HRESULT_Error();
}
@@ -1377,6 +1376,31 @@ HRESULT UpdateArchive(
unsigned ci;
// self including protection
if (options.DeleteAfterCompressing)
{
for (ci = 0; ci < options.Commands.Size(); ci++)
{
CArchivePath &ap = options.Commands[ci].ArchivePath;
const FString path = us2fs(ap.GetFinalPath());
// maybe we must compare absolute paths path here
FOR_VECTOR (i, dirItems.Items)
{
const FString phyPath = dirItems.GetPhyPath(i);
if (phyPath == path)
{
UString s;
s = "It is not allowed to include archive to itself";
s.Add_LF();
s += path;
throw s;
}
}
}
}
for (ci = 0; ci < options.Commands.Size(); ci++)
{
CArchivePath &ap = options.Commands[ci].ArchivePath;
@@ -1562,26 +1586,39 @@ HRESULT UpdateArchive(
}
CCurrentDirRestorer curDirRestorer;
AStringVector paths;
AStringVector names;
for (i = 0; i < fullPaths.Size(); i++)
{
const UString arcPath2 = fs2us(fullPaths[i]);
const UString fileName = ExtractFileNameFromPath(arcPath2);
const AString path (GetAnsiString(arcPath2));
const AString name (GetAnsiString(fileName));
paths.Add(GetAnsiString(arcPath2));
names.Add(GetAnsiString(fileName));
// const AString path (GetAnsiString(arcPath2));
// const AString name (GetAnsiString(fileName));
// Warning!!! MAPISendDocuments function changes Current directory
// fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
}
MapiFileDesc f;
CRecordVector<MapiFileDesc> files;
files.ClearAndSetSize(paths.Size());
for (i = 0; i < paths.Size(); i++)
{
MapiFileDesc &f = files[i];
memset(&f, 0, sizeof(f));
f.nPosition = 0xFFFFFFFF;
f.lpszPathName = (char *)(const char *)path;
f.lpszFileName = (char *)(const char *)name;
f.lpszPathName = (char *)(const char *)paths[i];
f.lpszFileName = (char *)(const char *)names[i];
}
{
MapiMessage m;
memset(&m, 0, sizeof(m));
m.nFileCount = 1;
m.lpFiles = &f;
m.nFileCount = files.Size();
m.lpFiles = &files.Front();
const AString addr (GetAnsiString(options.EMailAddress));
MapiRecipDesc rec;