Update to 7-Zip Version 21.02

This commit is contained in:
Tino Reichardt
2021-05-13 16:39:14 +02:00
parent 3724ecfedc
commit 48fa49f76c
620 changed files with 35032 additions and 10925 deletions

View File

@@ -19,6 +19,7 @@
#include "../../../../C/Alloc.h"
#endif
#include "../../../Common/IntToString.h"
#include "../../../Common/ListFileUtils.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
@@ -26,6 +27,7 @@
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
#include "../../../Windows/System.h"
#ifdef _WIN32
#include "../../../Windows/FileMapping.h"
#include "../../../Windows/MemoryLock.h"
@@ -41,22 +43,37 @@ extern bool g_CaseSensitive;
extern bool g_PathTrailReplaceMode;
#ifdef _7ZIP_LARGE_PAGES
extern
bool g_LargePagesMode;
bool g_LargePagesMode = false;
#endif
/*
#ifdef ENV_HAVE_LSTAT
EXTERN_C_BEGIN
extern int global_use_lstat;
EXTERN_C_END
#endif
*/
#ifdef UNDER_CE
#define MY_IS_TERMINAL(x) false;
#else
#if _MSC_VER >= 1400
#define MY_isatty_fileno(x) _isatty(_fileno(x))
#else
#define MY_isatty_fileno(x) isatty(fileno(x))
#endif
#define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0);
// #define MY_isatty_fileno(x) (isatty(fileno(x)))
// #define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0);
static inline bool MY_IS_TERMINAL(FILE *x)
{
return (
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
_isatty(_fileno(x))
#else
isatty(fileno(x))
#endif
!= 0);
}
#endif
@@ -74,8 +91,6 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v)
}
int g_CodePage = -1;
namespace NKey {
enum Enum
{
@@ -127,6 +142,7 @@ enum Enum
kConsoleCharSet,
kTechMode,
kPreserveATime,
kShareForWrite,
kStopAfterOpenError,
kCaseSensitive,
@@ -137,6 +153,7 @@ enum Enum
kFullPathMode,
kHardLinks,
kSymLinks_AllowDangerous,
kSymLinks,
kNtSecurity,
@@ -164,7 +181,7 @@ static const char * const k_ArcNameMode_PostCharSet = "sea";
static const char * const k_Stream_PostCharSet = "012";
static inline const EArcNameMode ParseArcNameMode(int postCharIndex)
static inline EArcNameMode ParseArcNameMode(int postCharIndex)
{
switch (postCharIndex)
{
@@ -182,12 +199,15 @@ namespace NRecursedPostCharIndex {
};
}
static const char kImmediateNameID = '!';
static const char kMapNameID = '#';
static const char kFileListID = '@';
// static const char
#define kImmediateNameID '!'
#ifdef _WIN32
#define kMapNameID '#'
#endif
#define kFileListID '@'
static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
static const Byte kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
static const Byte kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
static const char * const kOverwritePostCharSet = "asut";
@@ -199,80 +219,95 @@ static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
NExtract::NOverwriteMode::kRenameExisting
};
#define SWFRM_3(t, mu, mi) t, mu, mi, NULL
#define SWFRM_1(t) SWFRM_3(t, false, 0)
#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple)
#define SWFRM_MINUS SWFRM_1(NSwitchType::kMinus)
#define SWFRM_STRING SWFRM_1(NSwitchType::kString)
#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi)
#define SWFRM_STRING_MULT(mi) SWFRM_3(NSwitchType::kString, true, mi)
static const CSwitchForm kSwitchForms[] =
{
{ "?" },
{ "h" },
{ "-help" },
{ "?", SWFRM_SIMPLE },
{ "h", SWFRM_SIMPLE },
{ "-help", SWFRM_SIMPLE },
{ "ba" },
{ "bd" },
{ "bt" },
{ "bb", NSwitchType::kString, false, 0 },
{ "ba", SWFRM_SIMPLE },
{ "bd", SWFRM_SIMPLE },
{ "bt", SWFRM_SIMPLE },
{ "bb", SWFRM_STRING_SINGL(0) },
{ "bso", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
{ "bse", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
{ "bsp", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
{ "y" },
{ "y", SWFRM_SIMPLE },
{ "ad" },
{ "ad", SWFRM_SIMPLE },
{ "ao", NSwitchType::kChar, false, 1, kOverwritePostCharSet},
{ "t", NSwitchType::kString, false, 1 },
{ "stx", NSwitchType::kString, true, 1 },
{ "t", SWFRM_STRING_SINGL(1) },
{ "stx", SWFRM_STRING_MULT(1) },
{ "m", NSwitchType::kString, true, 1 },
{ "o", NSwitchType::kString, false, 1 },
{ "w", NSwitchType::kString },
{ "m", SWFRM_STRING_MULT(1) },
{ "o", SWFRM_STRING_SINGL(1) },
{ "w", SWFRM_STRING },
{ "i", NSwitchType::kString, true, kSomeCludePostStringMinSize},
{ "x", NSwitchType::kString, true, kSomeCludePostStringMinSize},
{ "ai", NSwitchType::kString, true, kSomeCludePostStringMinSize},
{ "ax", NSwitchType::kString, true, kSomeCludePostStringMinSize},
{ "an" },
{ "i", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) },
{ "x", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) },
{ "ai", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) },
{ "ax", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) },
{ "an", SWFRM_SIMPLE },
{ "u", NSwitchType::kString, true, 1},
{ "v", NSwitchType::kString, true, 1},
{ "u", SWFRM_STRING_MULT(1) },
{ "v", SWFRM_STRING_MULT(1) },
{ "r", NSwitchType::kChar, false, 0, kRecursedPostCharSet },
{ "stm", NSwitchType::kString },
{ "sfx", NSwitchType::kString },
{ "seml", NSwitchType::kString, false, 0},
{ "scrc", NSwitchType::kString, true, 0 },
{ "stm", SWFRM_STRING },
{ "sfx", SWFRM_STRING },
{ "seml", SWFRM_STRING_SINGL(0) },
{ "scrc", SWFRM_STRING_MULT(0) },
{ "si", NSwitchType::kString },
{ "so" },
{ "si", SWFRM_STRING },
{ "so", SWFRM_SIMPLE },
{ "slp", NSwitchType::kString },
{ "scs", NSwitchType::kString },
{ "scc", NSwitchType::kString },
{ "slt" },
{ "slp", SWFRM_STRING },
{ "scs", SWFRM_STRING },
{ "scc", SWFRM_STRING },
{ "slt", SWFRM_SIMPLE },
{ "ssw" },
{ "sse" },
{ "ssc", NSwitchType::kMinus },
{ "ssp", SWFRM_SIMPLE },
{ "ssw", SWFRM_SIMPLE },
{ "sse", SWFRM_SIMPLE },
{ "ssc", SWFRM_MINUS },
{ "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet },
{ "spd" },
{ "spe", NSwitchType::kMinus },
{ "spf", NSwitchType::kString, false, 0 },
{ "spd", SWFRM_SIMPLE },
{ "spe", SWFRM_MINUS },
{ "spf", SWFRM_STRING_SINGL(0) },
{ "snh", NSwitchType::kMinus },
{ "snl", NSwitchType::kMinus },
{ "sni" },
{ "snh", SWFRM_MINUS },
{ "snld", SWFRM_MINUS },
{ "snl", SWFRM_MINUS },
{ "sni", SWFRM_SIMPLE },
{ "sns", NSwitchType::kMinus },
{ "snr" },
{ "snc" },
{ "sns", SWFRM_MINUS },
{ "snr", SWFRM_SIMPLE },
{ "snc", SWFRM_SIMPLE },
{ "snt", NSwitchType::kMinus },
{ "snt", SWFRM_MINUS },
{ "sdel" },
{ "stl" }
{ "sdel", SWFRM_SIMPLE },
{ "stl", SWFRM_SIMPLE }
#ifndef _NO_CRYPTO
, { "p", NSwitchType::kString }
, { "p", SWFRM_STRING }
#endif
};
@@ -281,7 +316,7 @@ static const unsigned kMinNonSwitchWords = 1;
static const unsigned kCommandIndex = 0;
// static const char * const kUserErrorMessage = "Incorrect command line";
static const char * const kCannotFindListFile = "Cannot find listfile";
// static const char * const kCannotFindListFile = "Cannot find listfile";
static const char * const kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
static const char * const kTerminalOutError = "I won't write compressed data to a terminal";
static const char * const kSameTerminalError = "I won't write data and program's messages to same stream";
@@ -295,8 +330,9 @@ bool CArcCommand::IsFromExtractGroup() const
case NCommandType::kExtract:
case NCommandType::kExtractFull:
return true;
default:
return false;
}
return false;
}
NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const
@@ -306,8 +342,9 @@ NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const
case NCommandType::kTest:
case NCommandType::kExtractFull:
return NExtract::NPathMode::kFullPaths;
default:
return NExtract::NPathMode::kNoPaths;
}
return NExtract::NPathMode::kNoPaths;
}
bool CArcCommand::IsFromUpdateGroup() const
@@ -319,8 +356,9 @@ bool CArcCommand::IsFromUpdateGroup() const
case NCommandType::kDelete:
case NCommandType::kRename:
return true;
default:
return false;
}
return false;
}
static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
@@ -376,6 +414,8 @@ static void AddNameToCensor(NWildcard::CCensor &censor,
case NRecursedType::kRecursed:
recursed = true;
break;
default:
break;
}
censor.AddPreItem(include, name, recursed, wildcardMatching);
}
@@ -408,11 +448,13 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
static void AddToCensorFromListFile(
CObjectVector<CRenamePair> *renamePairs,
NWildcard::CCensor &censor,
LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, Int32 codePage)
LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, UInt32 codePage)
{
UStringVector names;
if (!NFind::DoesFileExist(us2fs(fileName)))
/*
if (!NFind::DoesFileExist_FollowLink(us2fs(fileName)))
throw CArcCmdLineException(kCannotFindListFile, fileName);
*/
DWORD lastError = 0;
if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError))
{
@@ -449,7 +491,7 @@ static void AddToCensorFromNonSwitchesStrings(
int stopSwitchIndex,
NRecursedType::EEnum type,
bool wildcardMatching,
bool thereAreSwitchIncludes, Int32 codePage)
bool thereAreSwitchIncludes, UInt32 codePage)
{
if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
AddNameToCensor(censor, UString(kUniversalWildcard), true, type,
@@ -459,7 +501,7 @@ static void AddToCensorFromNonSwitchesStrings(
int oldIndex = -1;
if (stopSwitchIndex < 0)
stopSwitchIndex = nonSwitchStrings.Size();
stopSwitchIndex = (int)nonSwitchStrings.Size();
for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++)
{
@@ -471,11 +513,11 @@ static void AddToCensorFromNonSwitchesStrings(
else if (renamePairs)
{
if (oldIndex == -1)
oldIndex = i;
oldIndex = (int)i;
else
{
// NRecursedType::EEnum type is used for global wildcard (-i! switches)
AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching);
AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching);
// AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type);
oldIndex = -1;
}
@@ -486,7 +528,7 @@ static void AddToCensorFromNonSwitchesStrings(
if (oldIndex != -1)
{
throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[oldIndex]);
throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[(unsigned)oldIndex]);
}
}
@@ -517,23 +559,23 @@ static const char *ParseMapWithPaths(
int pos = s.Find(L':');
if (pos < 0)
return k_IncorrectMapCommand;
int pos2 = s.Find(L':', pos + 1);
int pos2 = s.Find(L':', (unsigned)(pos + 1));
if (pos2 < 0)
return k_IncorrectMapCommand;
CEventSetEnd eventSetEnd((const wchar_t *)s + ((unsigned)pos2 + 1));
s.DeleteFrom(pos2);
CEventSetEnd eventSetEnd((const wchar_t *)s + (unsigned)(pos2 + 1));
s.DeleteFrom((unsigned)pos2);
UInt32 size;
if (!StringToUInt32(s.Ptr(pos + 1), size)
if (!StringToUInt32(s.Ptr((unsigned)(pos + 1)), size)
|| size < sizeof(wchar_t)
|| size > ((UInt32)1 << 31)
|| size % sizeof(wchar_t) != 0)
return "Unsupported Map data size";
s.DeleteFrom(pos);
s.DeleteFrom((unsigned)pos);
CFileMapping map;
if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0)
return "Can not open mapping";
return "Cannot open mapping";
LPVOID data = map.Map(FILE_MAP_READ, 0, size);
if (!data)
return "MapViewOfFile error";
@@ -569,7 +611,7 @@ static void AddSwitchWildcardsToCensor(
const UStringVector &strings, bool include,
NRecursedType::EEnum commonRecursedType,
bool wildcardMatching,
Int32 codePage)
UInt32 codePage)
{
const char *errorMessage = NULL;
unsigned i;
@@ -667,9 +709,9 @@ static bool ParseUpdateCommandString2(const UString &command,
if (i >= command.Len())
return false;
c = command[i];
if (c < '0' || c >= '0' + kNumUpdatePairActions)
if (c < '0' || c >= (wchar_t)('0' + kNumUpdatePairActions))
return false;
unsigned actionPos = c - '0';
unsigned actionPos = (unsigned)(c - '0');
actionSet.StateActions[(unsigned)statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos);
if (kUpdatePairStateNotSupportedActions[(unsigned)statePos] == (int)actionPos)
return false;
@@ -791,8 +833,8 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr
int index = prop.Name.Find(L'=');
if (index >= 0)
{
prop.Value = prop.Name.Ptr(index + 1);
prop.Name.DeleteFrom(index);
prop.Value = prop.Name.Ptr((unsigned)(index + 1));
prop.Name.DeleteFrom((unsigned)index);
}
properties.Add(prop);
}
@@ -803,13 +845,24 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr
static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res)
{
if (sw.ThereIs)
res = sw.PostCharIndex;
res = (unsigned)sw.PostCharIndex;
}
#if defined(_WIN32) && !defined(UNDER_CE)
static void PrintHex(UString &s, UInt64 v)
{
char temp[32];
ConvertUInt64ToHex(v, temp);
s += temp;
}
#endif
void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
CArcCmdLineOptions &options)
{
Parse1Log.Empty();
if (!parser.ParseStrings(kSwitchForms, ARRAY_SIZE(kSwitchForms), commandStrings))
throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine);
@@ -879,14 +932,16 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
#ifdef _7ZIP_LARGE_PAGES
if (slp >
#ifndef UNDER_CE
#if defined(_WIN32) && !defined(UNDER_CE)
(unsigned)NSecurity::Get_LargePages_RiskLevel()
#else
0
#endif
)
{
#ifdef _WIN32 // change it !
SetLargePageSize();
#endif
// note: this process also can inherit that Privilege from parent process
g_LargePagesMode =
#if defined(_WIN32) && !defined(UNDER_CE)
@@ -906,32 +961,83 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
const UString &s = parser[NKey::kAffinity].PostStrings[0];
if (!s.IsEmpty())
{
UInt32 v = 0;
AString a;
a.SetFromWStr_if_Ascii(s);
if (!a.IsEmpty())
Parse1Log += "Set process affinity mask: ";
#ifdef _WIN32
UInt64 v = 0;
{
const char *end;
v = ConvertHexStringToUInt32(a, &end);
v = ConvertHexStringToUInt64(a, &end);
if (*end != 0)
a.Empty();
}
if (a.IsEmpty())
throw CArcCmdLineException("Unsupported switch postfix -stm", s);
{
#ifndef _WIN64
if (v >= ((UInt64)1 << 32))
throw CArcCmdLineException("unsupported value -stm", s);
#endif
{
PrintHex(Parse1Log, v);
if (!SetProcessAffinityMask(GetCurrentProcess(), (DWORD_PTR)v))
{
DWORD lastError = GetLastError();
Parse1Log += " : ERROR : ";
Parse1Log += NError::MyFormatMessage(lastError);
}
}
}
#ifdef _WIN32
SetProcessAffinityMask(GetCurrentProcess(), v);
#endif
#else // _WIN32
{
Parse1Log += a;
NSystem::CProcessAffinity aff;
aff.CpuZero();
for (unsigned i = 0; i < a.Len(); i++)
{
char c = a[i];
unsigned v;
if (c >= '0' && c <= '9') v = (unsigned)(c - '0');
else if (c >= 'A' && c <= 'F') v = 10 + (unsigned)(c - 'A');
else if (c >= 'a' && c <= 'f') v = 10 + (unsigned)(c - 'a');
else
throw CArcCmdLineException("Unsupported switch postfix -stm", s);
for (unsigned k = 0; k < 4; k++)
{
const unsigned cpu = (a.Len() - 1 - i) * 4 + k;
if (v & ((unsigned)1 << k))
aff.CpuSet(cpu);
}
}
if (!aff.SetProcAffinity())
{
DWORD lastError = GetLastError();
Parse1Log += " : ERROR : ";
Parse1Log += NError::MyFormatMessage(lastError);
}
}
#endif // _WIN32
Parse1Log.Add_LF();
}
}
#endif
}
struct CCodePagePair
{
const char *Name;
Int32 CodePage;
UInt32 CodePage;
};
static const unsigned kNumByteOnlyCodePages = 3;
@@ -964,7 +1070,7 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key
throw CArcCmdLineException("Unsupported charset:", name);
const CCodePagePair &pair = g_CodePagePairs[i];
if (name.IsEqualTo(pair.Name))
return pair.CodePage;
return (Int32)pair.CodePage;
}
}
@@ -1023,8 +1129,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (parser[NKey::kDisableWildcardParsing].ThereIs)
wildcardMatching = false;
g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1);
Int32 codePage = FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8);
options.ConsoleCodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1);
UInt32 codePage = (UInt32)FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8);
bool thereAreSwitchIncludes = false;
@@ -1097,6 +1204,30 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
SetBoolPair(parser, NKey::kHardLinks, options.HardLinks);
SetBoolPair(parser, NKey::kSymLinks, options.SymLinks);
CBoolPair symLinks_AllowDangerous;
SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous);
/*
bool supportSymLink = options.SymLinks.Val;
if (!options.SymLinks.Def)
{
if (isExtractOrList)
supportSymLink = true;
else
supportSymLink = false;
}
#ifdef ENV_HAVE_LSTAT
if (supportSymLink)
global_use_lstat = 1;
else
global_use_lstat = 0;
#endif
*/
if (isExtractOrList)
{
CExtractOptionsBase &eo = options.ExtractOptions;
@@ -1117,6 +1248,8 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (!options.SymLinks.Def)
nt.SymLinks.Val = true;
nt.SymLinks_AllowDangerous = symLinks_AllowDangerous;
nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs;
nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs;
}
@@ -1174,6 +1307,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (parser[NKey::kOutputDir].ThereIs)
{
eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
#ifdef _WIN32
NFile::NName::NormalizeDirSeparators(eo.OutputDir);
#endif
NFile::NName::NormalizeDirPathPrefix(eo.OutputDir);
}
@@ -1213,6 +1349,8 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
updateOptions.MethodMode.Properties = options.Properties;
if (parser[NKey::kPreserveATime].ThereIs)
updateOptions.PreserveATime = true;
if (parser[NKey::kShareForWrite].ThereIs)
updateOptions.OpenShareForWrite = true;
if (parser[NKey::kStopAfterOpenError].ThereIs)
@@ -1270,7 +1408,7 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (curCommandIndex < numNonSwitchStrings)
{
if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations))
throw CArcCmdLineException("Incorrect Number of benmchmark iterations", nonSwitchStrings[curCommandIndex]);
throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]);
curCommandIndex++;
}
}
@@ -1282,10 +1420,13 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
CHashOptions &hashOptions = options.HashOptions;
hashOptions.PathMode = censorPathMode;
hashOptions.Methods = options.HashMethods;
if (parser[NKey::kPreserveATime].ThereIs)
hashOptions.PreserveATime = true;
if (parser[NKey::kShareForWrite].ThereIs)
hashOptions.OpenShareForWrite = true;
hashOptions.StdInMode = options.StdInMode;
hashOptions.AltStreamsMode = options.AltStreams.Val;
hashOptions.SymLinks = options.SymLinks;
}
else if (options.Command.CommandType == NCommandType::kInfo)
{
@@ -1293,3 +1434,45 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
else
throw 20150919;
}
#ifndef _WIN32
static AString g_ModuleDirPrefix;
void Set_ModuleDirPrefix_From_ProgArg0(const char *s);
void Set_ModuleDirPrefix_From_ProgArg0(const char *s)
{
AString a (s);
int sep = a.ReverseFind_PathSepar();
a.DeleteFrom((unsigned)(sep + 1));
g_ModuleDirPrefix = a;
}
namespace NWindows {
namespace NDLL {
FString GetModuleDirPrefix();
FString GetModuleDirPrefix()
{
FString s;
s = g_ModuleDirPrefix;
if (s.IsEmpty())
s = FTEXT(".") FSTRING_PATH_SEPARATOR;
return s;
/*
setenv("_7ZIP_HOME_DIR", "/test/", 0);
const char *home = getenv("_7ZIP_HOME_DIR");
if (home)
s = home;
else
s = FTEXT(".") FSTRING_PATH_SEPARATOR;
return s;
*/
}
}}
#endif // ! _WIN32

View File

@@ -63,6 +63,11 @@ struct CArcCmdLineOptions
bool YesToAll;
bool ShowDialog;
bool TechMode;
bool ShowTime;
int ConsoleCodePage;
NWildcard::CCensor Censor;
CArcCommand Command;
@@ -73,9 +78,6 @@ struct CArcCmdLineOptions
UString Password;
#endif
bool TechMode;
bool ShowTime;
UStringVector HashMethods;
bool AppendName;
@@ -109,13 +111,27 @@ struct CArcCmdLineOptions
UInt32 NumIterations;
CArcCmdLineOptions():
HelpMode(false),
// LargePages(false),
CaseSensitiveChange(false),
CaseSensitive(false),
IsInTerminal(false),
IsStdOutTerminal(false),
IsStdErrTerminal(false),
StdInMode(false),
StdOutMode(false),
EnableHeaders(false),
YesToAll(false),
ShowDialog(false),
TechMode(false),
ShowTime(false),
ConsoleCodePage(-1),
Number_for_Out(k_OutStream_stdout),
Number_for_Errors(k_OutStream_stderr),
Number_for_Percents(k_OutStream_stdout),
@@ -129,6 +145,7 @@ class CArcCmdLineParser
{
NCommandLineParser::CParser parser;
public:
UString Parse1Log;
void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options);
void Parse2(CArcCmdLineOptions &options);
};

View File

File diff suppressed because it is too large Load Diff

View File

@@ -4,12 +4,14 @@
#define __ARCHIVE_EXTRACT_CALLBACK_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/Wildcard.h"
#include "../../IPassword.h"
#include "../../Common/FileStreams.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h"
#include "../../Archive/IArchive.h"
@@ -52,6 +54,7 @@ struct CExtractNtOptions
{
CBoolPair NtSecurity;
CBoolPair SymLinks;
CBoolPair SymLinks_AllowDangerous;
CBoolPair HardLinks;
CBoolPair AltStreams;
bool ReplaceColonForAltStream;
@@ -64,9 +67,10 @@ struct CExtractNtOptions
WriteToAltStreamIfColon(false)
{
SymLinks.Val = true;
SymLinks_AllowDangerous.Val = false;
HardLinks.Val = true;
AltStreams.Val = true;
PreAllocateOutFile =
#ifdef _WIN32
true;
@@ -165,10 +169,36 @@ struct CDirPathTime
FString Path;
bool SetDirTime();
bool SetDirTime() const;
};
#ifdef SUPPORT_LINKS
struct CLinkInfo
{
// bool isCopyLink;
bool isHardLink;
bool isJunction;
bool isRelative;
bool isWSL;
UString linkPath;
void Clear()
{
// IsCopyLink = false;
isHardLink = false;
isJunction = false;
isRelative = false;
isWSL = false;
linkPath.Empty();
}
bool Parse(const Byte *data, size_t dataSize, bool isLinuxData);
};
#endif // SUPPORT_LINKS
class CArchiveExtractCallback:
public IArchiveExtractCallback,
@@ -225,15 +255,53 @@ class CArchiveExtractCallback:
bool ATimeDefined;
bool MTimeDefined;
bool AttribDefined;
bool IsReparse() const
{
return (AttribDefined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
}
bool IsLinuxSymLink() const
{
return (AttribDefined && MY_LIN_S_ISLNK(Attrib >> 16));
}
void SetFromPosixAttrib(UInt32 a)
{
// here we set only part of combined attribute required by SetFileAttrib() call
#ifdef _WIN32
// Windows sets FILE_ATTRIBUTE_NORMAL, if we try to set 0 as attribute.
Attrib = MY_LIN_S_ISDIR(a) ?
FILE_ATTRIBUTE_DIRECTORY :
FILE_ATTRIBUTE_ARCHIVE;
if ((a & 0222) == 0) // (& S_IWUSR) in p7zip
Attrib |= FILE_ATTRIBUTE_READONLY;
#else
Attrib = (a << 16) | FILE_ATTRIBUTE_UNIX_EXTENSION;
#endif
AttribDefined = true;
}
} _fi;
bool _is_SymLink_in_Data;
bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX
bool _fileWasExtracted;
UInt32 _index;
UInt64 _curSize;
bool _curSizeDefined;
bool _fileLengthWasSet;
UInt64 _fileLength_that_WasSet;
COutFileStream *_outFileStreamSpec;
CMyComPtr<ISequentialOutStream> _outFileStream;
CByteBuffer _outMemBuf;
CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec;
CMyComPtr<ISequentialOutStream> _bufPtrSeqOutStream;
#ifndef _SFX
COutStreamWithHash *_hashStreamSpec;
@@ -261,6 +329,10 @@ class CArchiveExtractCallback:
bool _progressTotal_Defined;
CObjectVector<CDirPathTime> _extractedFolders;
#ifndef _WIN32
// CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks;
#endif
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
bool _saclEnabled;
@@ -272,7 +344,7 @@ class CArchiveExtractCallback:
HRESULT SendMessageError(const char *message, const FString &path);
HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2);
public:
@@ -335,10 +407,12 @@ public:
private:
CHardLinks _hardLinks;
UString linkPath;
CLinkInfo _link;
// FString _CopyFile_Path;
// HRESULT MyCopyFile(ISequentialOutStream *outStream);
HRESULT Link(const FString &fullProcessedPath);
HRESULT ReadLink();
public:
// call PrepareHardLinks() after Init()
@@ -367,10 +441,33 @@ private:
void ClearExtractedDirsInfo()
{
_extractedFolders.Clear();
#ifndef _WIN32
// _delayedSymLinks.Clear();
#endif
}
HRESULT Read_fi_Props();
void CorrectPathParts();
void CreateFolders();
bool _isRenamed;
HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit);
HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit);
HRESULT CloseFile();
HRESULT CloseReparseAndFile();
HRESULT CloseReparseAndFile2();
HRESULT SetDirsTimes();
const void *NtReparse_Data;
UInt32 NtReparse_Size;
#ifdef SUPPORT_LINKS
HRESULT SetFromLinkPath(
const FString &fullProcessedPath,
const CLinkInfo &linkInfo,
bool &linkWasSet);
#endif
};

View File

@@ -21,7 +21,7 @@ static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
int dotPos = resultName.ReverseFind_Dot();
if (dotPos > 0)
{
FString archiveName2 = resultName.Left(dotPos);
FString archiveName2 = resultName.Left((unsigned)dotPos);
if (archiveName2.ReverseFind_Dot() < 0)
resultName = archiveName2;
}
@@ -64,7 +64,7 @@ static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepN
int dotPos = resultName.ReverseFind_Dot();
if (dotPos > 0)
{
FString name2 = resultName.Left(dotPos);
FString name2 = resultName.Left((unsigned)dotPos);
if (name2.ReverseFind_Dot() < 0)
resultName = name2;
}

View File

@@ -63,7 +63,7 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
struct CInFileStreamVol: public CInFileStream
{
int FileNameIndex;
unsigned FileNameIndex;
COpenCallbackImp *OpenCallbackImp;
CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
@@ -116,7 +116,7 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
FString fullPath;
if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath))
return S_FALSE;
if (!_fileInfo.Find(fullPath))
if (!_fileInfo.Find_FollowLink(fullPath))
return S_FALSE;
if (_fileInfo.IsDir())
return S_FALSE;
@@ -124,10 +124,7 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
CMyComPtr<IInStream> inStreamTemp = inFile;
if (!inFile->Open(fullPath))
{
DWORD lastError = ::GetLastError();
if (lastError == 0)
return E_FAIL;
return HRESULT_FROM_WIN32(lastError);
return GetLastError_noZero_HRESULT();
}
FileSizes.Add(_fileInfo.Size);

View File

@@ -6,6 +6,7 @@
#include "../../../Common/MyCom.h"
#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileIO.h"
#ifndef _NO_CRYPTO
#include "../../IPassword.h"
@@ -88,24 +89,28 @@ public:
CMyComPtr<IArchiveOpenCallback> ReOpenCallback;
// UInt64 TotalSize;
COpenCallbackImp(): Callback(NULL), _subArchiveMode(false) {}
COpenCallbackImp(): _subArchiveMode(false), Callback(NULL) {}
void Init(const FString &folderPrefix, const FString &fileName)
HRESULT Init2(const FString &folderPrefix, const FString &fileName)
{
_folderPrefix = folderPrefix;
if (!_fileInfo.Find(_folderPrefix + fileName))
throw 20121118;
FileNames.Clear();
FileNames_WasUsed.Clear();
FileSizes.Clear();
_subArchiveMode = false;
// TotalSize = 0;
PasswordWasAsked = false;
_folderPrefix = folderPrefix;
if (!_fileInfo.Find_FollowLink(_folderPrefix + fileName))
{
// throw 20121118;
return GetLastError_noZero_HRESULT();
}
return S_OK;
}
bool SetSecondFileInfo(CFSTR newName)
{
return _fileInfo.Find(newName) && !_fileInfo.IsDir();
return _fileInfo.Find_FollowLink(newName) && !_fileInfo.IsDir();
}
};

View File

File diff suppressed because it is too large Load Diff

View File

@@ -66,7 +66,7 @@ AString GetProcessThreadsInfo(const NWindows::NSystem::CProcessAffinity &ti);
void GetSysInfo(AString &s1, AString &s2);
void GetCpuName(AString &s);
void GetCpuFeatures(AString &s);
void AddCpuFeatures(AString &s);
#ifdef _7ZIP_LARGE_PAGES
void Add_LargePages_String(AString &s);

View File

@@ -79,11 +79,12 @@ static HRESULT Call7zGui(const UString &params,
imageName += k7zGui;
CProcess process;
WRes res = process.Create(imageName, params, NULL); // curDir);
if (res != 0)
const WRes wres = process.Create(imageName, params, NULL); // curDir);
if (wres != 0)
{
ErrorMessageHRESULT(res, imageName);
return res;
HRESULT hres = HRESULT_FROM_WIN32(wres);
ErrorMessageHRESULT(hres, imageName);
return hres;
}
if (waitFinish)
process.Wait();
@@ -133,12 +134,11 @@ static HRESULT CreateMap(const UStringVector &names,
for (;;)
{
random.GenerateName(mappingName, "7zMap");
WRes res = fileMapping.Create(PAGE_READWRITE, totalSize, GetSystemString(mappingName));
if (fileMapping.IsCreated() && res == 0)
const WRes wres = fileMapping.Create(PAGE_READWRITE, totalSize, GetSystemString(mappingName));
if (fileMapping.IsCreated() && wres == 0)
break;
if (res != ERROR_ALREADY_EXISTS)
return res;
if (wres != ERROR_ALREADY_EXISTS)
return HRESULT_FROM_WIN32(wres);
fileMapping.Close();
}
@@ -146,11 +146,11 @@ static HRESULT CreateMap(const UStringVector &names,
for (;;)
{
random.GenerateName(eventName, "7zEvent");
WRes res = event.CreateWithName(false, GetSystemString(eventName));
if (event.IsCreated() && res == 0)
const WRes wres = event.CreateWithName(false, GetSystemString(eventName));
if (event.IsCreated() && wres == 0)
break;
if (res != ERROR_ALREADY_EXISTS)
return res;
if (wres != ERROR_ALREADY_EXISTS)
return HRESULT_FROM_WIN32(wres);
event.Close();
}

View File

@@ -6,6 +6,8 @@
#include "../../UI/Common/EnumDirItems.h"
#include "../../UI/FileManager/LangUtils.h"
#include "../../UI/GUI/BenchmarkDialog.h"
#include "../../UI/GUI/ExtractGUI.h"
#include "../../UI/GUI/UpdateGUI.h"

View File

@@ -20,7 +20,7 @@ static UString GetDefaultName3(const UString &fileName,
int dotPos = fileName.ReverseFind_Dot();
if (dotPos > 0)
return fileName.Left(dotPos) + addSubExtension;
return fileName.Left((unsigned)dotPos) + addSubExtension;
if (addSubExtension.IsEmpty())
return fileName + L'~';

View File

@@ -3,6 +3,10 @@
#ifndef __DIR_ITEM_H
#define __DIR_ITEM_H
#ifdef _WIN32
#include "../../../Common/MyLinux.h"
#endif
#include "../../../Common/MyString.h"
#include "../../../Windows/FileFind.h"
@@ -84,13 +88,18 @@ struct CDirItem
FILETIME MTime;
UString Name;
#if defined(_WIN32) && !defined(UNDER_CE)
// UString ShortName;
#ifndef UNDER_CE
CByteBuffer ReparseData;
CByteBuffer ReparseData2; // fixed (reduced) absolute links
#ifdef _WIN32
// UString ShortName;
CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format
bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; }
#endif
#else
bool AreReparseData() const { return ReparseData.Size() != 0; }
#endif // _WIN32
#endif // !UNDER_CE
UInt32 Attrib;
int PhyParent;
@@ -100,9 +109,23 @@ struct CDirItem
bool IsAltStream;
CDirItem(): PhyParent(-1), LogParent(-1), SecureIndex(-1), IsAltStream(false) {}
bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; }
bool IsReadOnly() const { return (Attrib & FILE_ATTRIBUTE_READONLY) != 0; }
bool Has_Attrib_ReparsePoint() const { return (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0; }
#ifdef _WIN32
UInt32 GetPosixAttrib() const
{
UInt32 v = IsDir() ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG;
v |= (IsReadOnly() ? 0555 : 0777);
return v;
}
#endif
};
class CDirItems
{
UStringVector Prefixes;
@@ -117,17 +140,15 @@ public:
CObjectVector<CDirItem> Items;
bool SymLinks;
bool ScanAltStreams;
CDirItemsStat Stat;
#ifndef UNDER_CE
#if !defined(UNDER_CE)
HRESULT SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi,
const FString &phyPrefix);
#endif
#if defined(_WIN32) && !defined(UNDER_CE)
CUniqBlocks SecureBlocks;
@@ -136,6 +157,7 @@ public:
bool ReadSecure;
HRESULT AddSecurityItem(const FString &path, int &secureIndex);
HRESULT FillFixedReparse();
#endif
@@ -157,6 +179,9 @@ public:
unsigned AddPrefix(int phyParent, int logParent, const UString &prefix);
void DeleteLastPrefix();
// HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CDirEntry> &files);
HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CFileInfo> &files);
HRESULT EnumerateItems2(
const FString &phyPrefix,
@@ -164,13 +189,10 @@ public:
const FStringVector &filePaths,
FStringVector *requestedPaths);
#if defined(_WIN32) && !defined(UNDER_CE)
void FillFixedReparse();
#endif
void ReserveDown();
};
struct CArcItem
{
UInt64 Size;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -5,12 +5,8 @@
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileFind.h"
#include "DirItem.h"
void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
const NWindows::NFile::NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems);
HRESULT EnumerateItems(
const NWildcard::CCensor &censor,

View File

@@ -7,6 +7,7 @@
#include "../../../Common/StringConvert.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/PropVariantConv.h"
@@ -19,6 +20,19 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
static void SetErrorMessage(const char *message,
const FString &path, HRESULT errorCode,
UString &s)
{
s = message;
s += " : ";
s += NError::MyFormatMessage(errorCode);
s += " : ";
s += fs2us(path);
}
static HRESULT DecompressArchive(
CCodecs *codecs,
const CArchiveLink &arcLink,
@@ -47,7 +61,7 @@ static HRESULT DecompressArchive(
// So it extracts different archives to one folder.
// We will use top level archive name
const CArc &arc0 = arcLink.Arcs[0];
if (StringsAreEqualNoCase_Ascii(codecs->Formats[arc0.FormatIndex].Name, "pe"))
if (arc0.FormatIndex >= 0 && StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)arc0.FormatIndex].Name, "pe"))
replaceName = arc0.DefaultName;
}
@@ -164,11 +178,8 @@ static HRESULT DecompressArchive(
*/
else if (!CreateComplexDir(outDir))
{
HRESULT res = ::GetLastError();
if (res == S_OK)
res = E_FAIL;
errorMessage = "Can not create output directory: ";
errorMessage += fs2us(outDir);
const HRESULT res = GetLastError_noZero_HRESULT();
SetErrorMessage("Cannot create output directory", outDir, res, errorMessage);
return res;
}
@@ -221,6 +232,7 @@ static HRESULT DecompressArchive(
Sorted list for file paths was sorted with case insensitive compare function.
But FindInSorted function did binary search via case sensitive compare function */
int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name);
int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name)
{
unsigned left = 0, right = fileName.Size();
@@ -230,7 +242,7 @@ int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &n
const UString &midValue = fileName[mid];
int compare = CompareFileNames(name, midValue);
if (compare == 0)
return mid;
return (int)mid;
if (compare < 0)
right = mid;
else
@@ -239,6 +251,8 @@ int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &n
return -1;
}
HRESULT Extract(
CCodecs *codecs,
const CObjectVector<COpenType> &types,
@@ -268,11 +282,19 @@ HRESULT Extract(
fi.Size = 0;
if (!options.StdInMode)
{
const FString &arcPath = us2fs(arcPaths[i]);
if (!fi.Find(arcPath))
throw "there is no such archive";
const FString arcPath = us2fs(arcPaths[i]);
if (!fi.Find_FollowLink(arcPath))
{
const HRESULT errorCode = GetLastError_noZero_HRESULT();
SetErrorMessage("Cannot find archive file", arcPath, errorCode, errorMessage);
return errorCode;
}
if (fi.IsDir())
throw "can't decompress folder";
{
HRESULT errorCode = E_FAIL;
SetErrorMessage("The item is a directory", arcPath, errorCode, errorMessage);
return errorCode;
}
}
arcSizes.Add(fi.Size);
totalPackSize += fi.Size;
@@ -314,8 +336,12 @@ HRESULT Extract(
}
else
{
if (!fi.Find(us2fs(arcPath)) || fi.IsDir())
throw "there is no such archive";
if (!fi.Find_FollowLink(us2fs(arcPath)) || fi.IsDir())
{
const HRESULT errorCode = GetLastError_noZero_HRESULT();
SetErrorMessage("Cannot find archive file", us2fs(arcPath), errorCode, errorMessage);
return errorCode;
}
}
/*
@@ -379,12 +405,7 @@ HRESULT Extract(
{
thereAreNotOpenArcs = true;
if (!options.StdInMode)
{
NFind::CFileInfo fi2;
if (fi2.Find(us2fs(arcPath)))
if (!fi2.IsDir())
totalPackProcessed += fi2.Size;
}
totalPackProcessed += fi.Size;
continue;
}
@@ -397,7 +418,7 @@ HRESULT Extract(
// numArcs = arcPaths.Size();
if (arcLink.VolumePaths.Size() != 0)
{
Int64 correctionSize = arcLink.VolumesSize;
Int64 correctionSize = (Int64)arcLink.VolumesSize;
FOR_VECTOR (v, arcLink.VolumePaths)
{
int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]);
@@ -415,7 +436,7 @@ HRESULT Extract(
Int64 newPackSize = (Int64)totalPackSize + correctionSize;
if (newPackSize < 0)
newPackSize = 0;
totalPackSize = newPackSize;
totalPackSize = (UInt64)newPackSize;
RINOK(extractCallback->SetTotal(totalPackSize));
}
}

View File

@@ -53,10 +53,10 @@ struct CExtractOptions: public CExtractOptionsBase
#endif
CExtractOptions():
TestMode(false),
StdInMode(false),
StdOutMode(false),
YesToAll(false)
YesToAll(false),
TestMode(false)
{}
};

View File

@@ -8,6 +8,8 @@
#include "ExtractingFilePath.h"
extern
bool g_PathTrailReplaceMode;
bool g_PathTrailReplaceMode =
#ifdef _WIN32
true
@@ -17,6 +19,7 @@ bool g_PathTrailReplaceMode =
;
#ifdef _WIN32
static void ReplaceIncorrectChars(UString &s)
{
{
@@ -31,7 +34,10 @@ static void ReplaceIncorrectChars(UString &s)
||
#endif
c == WCHAR_PATH_SEPARATOR)
s.ReplaceOneCharAtPos(i, '_');
s.ReplaceOneCharAtPos(i,
'_' // default
// (wchar_t)(0xf000 + c) // 21.02 debug: WSL encoding for unsupported characters
);
}
}
@@ -72,8 +78,7 @@ static void ReplaceIncorrectChars(UString &s)
}
}
}
#ifdef _WIN32
#endif
/* WinXP-64 doesn't support ':', '\\' and '/' symbols in name of alt stream.
But colon in postfix ":$DATA" is allowed.
@@ -98,6 +103,8 @@ void Correct_AltStream_Name(UString &s)
s = '_';
}
#ifdef _WIN32
static const unsigned g_ReservedWithNum_Index = 4;
static const char * const g_ReservedNames[] =
@@ -149,7 +156,7 @@ static void Correct_PathPart(UString &s)
if (s.IsEmpty())
return;
if (s[0] == '.' && (s[1] == 0 || s[1] == '.' && s[2] == 0))
if (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
s.Empty();
#ifdef _WIN32
else

View File

@@ -5,9 +5,9 @@
#include "../../../Common/MyString.h"
#ifdef _WIN32
// #ifdef _WIN32
void Correct_AltStream_Name(UString &s);
#endif
// #endif
// replaces unsuported characters, and replaces "." , ".." and "" to "[]"
UString Get_Correct_FsFile_Name(const UString &name);

View File

@@ -8,6 +8,7 @@
#include "../../Common/FileStreams.h"
#include "../../Common/StreamUtils.h"
#include "../../Common/StreamObjects.h"
#ifdef WANT_OPTIONAL_LOWERCASE
#include "../FileManager/RegistryUtils.h"
@@ -215,6 +216,8 @@ HRESULT HashCalc(
else
{
RINOK(callback->StartScanning());
dirItems.SymLinks = options.SymLinks.Val;
dirItems.ScanAltStreams = options.AltStreamsMode;
HRESULT res = EnumerateItems(censor,
@@ -262,31 +265,47 @@ HRESULT HashCalc(
UString path;
bool isDir = false;
bool isAltStream = false;
if (options.StdInMode)
{
inStream = new CStdInFileStream;
}
else
{
CInFileStream *inStreamSpec = new CInFileStream;
inStream = inStreamSpec;
const CDirItem &dirItem = dirItems.Items[i];
isDir = dirItem.IsDir();
isAltStream = dirItem.IsAltStream;
path = dirItems.GetLogPath(i);
if (!isDir)
const CDirItem &di = dirItems.Items[i];
isAltStream = di.IsAltStream;
#ifndef UNDER_CE
// if (di.AreReparseData())
if (di.ReparseData.Size() != 0)
{
FString phyPath = dirItems.GetPhyPath(i);
if (!inStreamSpec->OpenShared(phyPath, options.OpenShareForWrite))
CBufInStream *inStreamSpec = new CBufInStream();
inStream = inStreamSpec;
inStreamSpec->Init(di.ReparseData, di.ReparseData.Size());
}
else
#endif
{
CInFileStream *inStreamSpec = new CInFileStream;
inStreamSpec->File.PreserveATime = options.PreserveATime;
inStream = inStreamSpec;
isDir = di.IsDir();
if (!isDir)
{
HRESULT res = callback->OpenFileError(phyPath, ::GetLastError());
hb.NumErrors++;
if (res != S_FALSE)
return res;
continue;
const FString phyPath = dirItems.GetPhyPath(i);
if (!inStreamSpec->OpenShared(phyPath, options.OpenShareForWrite))
{
HRESULT res = callback->OpenFileError(phyPath, ::GetLastError());
hb.NumErrors++;
if (res != S_FALSE)
return res;
continue;
}
}
}
}
RINOK(callback->GetStream(path, isDir));
UInt64 fileSize = 0;

View File

@@ -62,6 +62,8 @@ struct CHashBundle: public IHashCalc
NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0;
}
virtual ~CHashBundle() {};
void InitForNewFile();
void Update(const void *data, UInt32 size);
void SetSize(UInt64 size);
@@ -90,12 +92,20 @@ struct IHashCallbackUI: public IDirItemsCallback
struct CHashOptions
{
UStringVector Methods;
bool PreserveATime;
bool OpenShareForWrite;
bool StdInMode;
bool AltStreamsMode;
CBoolPair SymLinks;
NWildcard::ECensorPathMode PathMode;
CHashOptions(): StdInMode(false), OpenShareForWrite(false), AltStreamsMode(false), PathMode(NWildcard::k_RelatPath) {};
CHashOptions():
PreserveATime(false),
OpenShareForWrite(false),
StdInMode(false),
AltStreamsMode(false),
PathMode(NWildcard::k_RelatPath) {};
};
HRESULT HashCalc(

View File

@@ -39,6 +39,8 @@ EXPORT_CODECS
#include "../../../Common/StringToInt.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/FileIO.h"
#include "../../../Windows/PropVariant.h"
#include "LoadCodecs.h"
@@ -82,11 +84,11 @@ using namespace NFile;
static CFSTR const kMainDll =
// #ifdef _WIN32
#ifdef _WIN32
FTEXT("7z.dll");
// #else
// FTEXT("7z.so");
// #endif
#else
FTEXT("7z.so");
#endif
#ifdef _WIN32
@@ -110,7 +112,7 @@ static bool ReadPathFromRegistry(HKEY baseKey, LPCWSTR value, FString &path)
{
path = us2fs(pathU);
NName::NormalizeDirPathPrefix(path);
return NFind::DoesFileExist(path + kMainDll);
return NFind::DoesFileExist_Raw(path + kMainDll);
}
}
return false;
@@ -163,7 +165,7 @@ int CArcInfoEx::FindExtension(const UString &ext) const
{
FOR_VECTOR (i, Exts)
if (ext.IsEqualTo_NoCase(Exts[i].Ext))
return i;
return (int)i;
return -1;
}
@@ -206,15 +208,18 @@ static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector<CByte
#endif // _SFX
// #include <stdio.h>
#ifdef EXTERNAL_CODECS
static FString GetBaseFolderPrefixFromRegistry()
{
FString moduleFolderPrefix = NDLL::GetModuleDirPrefix();
#ifdef _WIN32
if (!NFind::DoesFileExist(moduleFolderPrefix + kMainDll) &&
!NFind::DoesDirExist(moduleFolderPrefix + kCodecsFolderName) &&
!NFind::DoesDirExist(moduleFolderPrefix + kFormatsFolderName))
if ( !NFind::DoesFileOrDirExist(moduleFolderPrefix + kMainDll)
&& !NFind::DoesFileOrDirExist(moduleFolderPrefix + kCodecsFolderName)
&& !NFind::DoesFileOrDirExist(moduleFolderPrefix + kFormatsFolderName))
{
FString path;
if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPath2Value, path)) return path;
@@ -223,6 +228,8 @@ static FString GetBaseFolderPrefixFromRegistry()
if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPathValue, path)) return path;
}
#endif
// printf("\nmoduleFolderPrefix = %s\n", (const char *)GetAnsiString(moduleFolderPrefix));
return moduleFolderPrefix;
}
@@ -238,25 +245,29 @@ static HRESULT GetCoderClass(Func_GetMethodProperty getMethodProperty, UInt32 in
if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID))
return E_FAIL;
isAssigned = true;
clsId = *(const GUID *)prop.bstrVal;
clsId = *(const GUID *)(const void *)prop.bstrVal;
}
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);
HRESULT CCodecs::LoadCodecs()
{
CCodecLib &lib = Libs.Back();
lib.CreateDecoder = (Func_CreateDecoder)lib.Lib.GetProc("CreateDecoder");
lib.CreateEncoder = (Func_CreateEncoder)lib.Lib.GetProc("CreateEncoder");
lib.GetMethodProperty = (Func_GetMethodProperty)lib.Lib.GetProc("GetMethodProperty");
MY_GET_FUNC (lib.CreateDecoder, Func_CreateDecoder, lib.Lib.GetProc("CreateDecoder"));
MY_GET_FUNC (lib.CreateEncoder, Func_CreateEncoder, lib.Lib.GetProc("CreateEncoder"));
MY_GET_FUNC (lib.GetMethodProperty, Func_GetMethodProperty, lib.Lib.GetProc("GetMethodProperty"));
if (lib.GetMethodProperty)
{
UInt32 numMethods = 1;
Func_GetNumberOfMethods getNumberOfMethods = (Func_GetNumberOfMethods)lib.Lib.GetProc("GetNumberOfMethods");
Func_GetNumberOfMethods getNumberOfMethods;
MY_GET_FUNC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib.GetProc("GetNumberOfMethods"));
if (getNumberOfMethods)
{
RINOK(getNumberOfMethods(&numMethods));
@@ -272,7 +283,8 @@ HRESULT CCodecs::LoadCodecs()
}
}
Func_GetHashers getHashers = (Func_GetHashers)lib.Lib.GetProc("GetHashers");
Func_GetHashers getHashers;
MY_GET_FUNC (getHashers, Func_GetHashers, lib.Lib.GetProc("GetHashers"));
if (getHashers)
{
RINOK(getHashers(&lib.ComHashers));
@@ -381,14 +393,17 @@ HRESULT CCodecs::LoadFormats()
const NDLL::CLibrary &lib = Libs.Back().Lib;
Func_GetHandlerProperty getProp = NULL;
Func_GetHandlerProperty2 getProp2 = (Func_GetHandlerProperty2)lib.GetProc("GetHandlerProperty2");
Func_GetIsArc getIsArc = (Func_GetIsArc)lib.GetProc("GetIsArc");
Func_GetHandlerProperty2 getProp2;
MY_GET_FUNC (getProp2, Func_GetHandlerProperty2, lib.GetProc("GetHandlerProperty2"));
Func_GetIsArc getIsArc;
MY_GET_FUNC (getIsArc, Func_GetIsArc, lib.GetProc("GetIsArc"));
UInt32 numFormats = 1;
if (getProp2)
{
Func_GetNumberOfFormats getNumberOfFormats = (Func_GetNumberOfFormats)lib.GetProc("GetNumberOfFormats");
Func_GetNumberOfFormats getNumberOfFormats;
MY_GET_FUNC (getNumberOfFormats, Func_GetNumberOfFormats, lib.GetProc("GetNumberOfFormats"));
if (getNumberOfFormats)
{
RINOK(getNumberOfFormats(&numFormats));
@@ -396,7 +411,7 @@ HRESULT CCodecs::LoadFormats()
}
else
{
getProp = (Func_GetHandlerProperty)lib.GetProc("GetHandlerProperty");
MY_GET_FUNC (getProp, Func_GetHandlerProperty, lib.GetProc("GetHandlerProperty"));
if (!getProp)
return S_OK;
}
@@ -404,7 +419,7 @@ HRESULT CCodecs::LoadFormats()
for (UInt32 i = 0; i < numFormats; i++)
{
CArcInfoEx item;
item.LibIndex = Libs.Size() - 1;
item.LibIndex = (int)(Libs.Size() - 1);
item.FormatIndex = i;
RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name));
@@ -417,7 +432,7 @@ HRESULT CCodecs::LoadFormats()
continue;
if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID))
return E_FAIL;
item.ClassID = *(const GUID *)prop.bstrVal;
item.ClassID = *(const GUID *)(const void *)prop.bstrVal;
prop.Clear();
}
@@ -473,23 +488,53 @@ extern "C"
}
#endif
void CCodecs::AddLastError(const FString &path)
{
HRESULT res = GetLastError_noZero_HRESULT();
CCodecError &error = Errors.AddNew();
error.Path = path;
error.ErrorCode = res;
}
HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loadedOK)
{
if (loadedOK)
*loadedOK = false;
// needCheckDll = 1;
#ifdef _WIN32
if (needCheckDll)
{
NDLL::CLibrary lib;
if (!lib.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE))
{
/* if is not win32
// %1 is not a valid Win32 application.
// #define ERROR_BAD_EXE_FORMAT 193L
*/
// return GetLastError_noZero_HRESULT();
DWORD lastError = GetLastError();
if (lastError != ERROR_BAD_EXE_FORMAT)
{
CCodecError &error = Errors.AddNew();
error.Path = dllPath;
error.Message = "cannot load file as datafile library";
error.ErrorCode = HRESULT_FROM_WIN32(lastError);
}
return S_OK;
}
}
#else
UNUSED_VAR(needCheckDll)
#endif
Libs.AddNew();
CCodecLib &lib = Libs.Back();
lib.Path = dllPath;
bool used = false;
HRESULT res = S_OK;
// HRESULT res = S_OK;
if (lib.Lib.Load(dllPath))
{
@@ -499,10 +544,28 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
lib.LoadIcons();
#endif
/*
{
Func_LibStartup _LibStartup;
MY_GET_FUNC (_LibStartup, Func_LibStartup, lib.Lib.GetProc("LibStartup"));
if (_LibStartup)
{
HRESULT res = _LibStartup();
if (res != 0)
{
CCodecError &error = Errors.AddNew();
error.Path = dllPath;
error.ErrorCode = res;
}
}
}
*/
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0)
{
Func_SetLargePageMode setLargePageMode = (Func_SetLargePageMode)lib.Lib.GetProc("SetLargePageMode");
Func_SetLargePageMode setLargePageMode;
MY_GET_FUNC (setLargePageMode, Func_SetLargePageMode, lib.Lib.GetProc("SetLargePageMode"));
if (setLargePageMode)
setLargePageMode();
}
@@ -510,16 +573,18 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
if (CaseSensitiveChange)
{
Func_SetCaseSensitive setCaseSensitive = (Func_SetCaseSensitive)lib.Lib.GetProc("SetCaseSensitive");
Func_SetCaseSensitive setCaseSensitive;
MY_GET_FUNC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib.GetProc("SetCaseSensitive"));
if (setCaseSensitive)
setCaseSensitive(CaseSensitive ? 1 : 0);
}
lib.CreateObject = (Func_CreateObject)lib.Lib.GetProc("CreateObject");
MY_GET_FUNC (lib.CreateObject, Func_CreateObject, lib.Lib.GetProc("CreateObject"));
{
unsigned startSize = Codecs.Size() + Hashers.Size();
res = LoadCodecs();
used = (startSize != Codecs.Size() + Hashers.Size());
HRESULT res = LoadCodecs();
if (startSize != Codecs.Size() + Hashers.Size())
used = true;
if (res == S_OK && lib.CreateObject)
{
startSize = Formats.Size();
@@ -527,22 +592,61 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
if (startSize != Formats.Size())
used = true;
}
if (res != S_OK)
{
CCodecError &error = Errors.AddNew();
error.Path = dllPath;
error.ErrorCode = res;
}
}
// plugins can use non-7-zip dlls, so we silently ignore non7zip DLLs
/*
if (!used)
{
CCodecError &error = Errors.AddNew();
error.Path = dllPath;
error.Message = "no 7-Zip code";
}
*/
}
else
{
AddLastError(dllPath);
}
if (!used)
Libs.DeleteBack();
return res;
return S_OK;
}
HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix)
HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPath)
{
if (!NFile::NFind::DoesDirExist_FollowLink(folderPath))
// if (!NFile::NFind::DoesDirExist(folderPath))
{
// AddLastError(folderPath);
return S_OK;
}
FString folderPrefix = folderPath;
folderPrefix.Add_PathSepar();
NFile::NFind::CEnumerator enumerator;
enumerator.SetDirPrefix(folderPrefix);
NFile::NFind::CFileInfo fi;
while (enumerator.Next(fi))
NFile::NFind::CDirEntry fi;
for (;;)
{
bool found;
if (!enumerator.Next(fi, found))
{
// it can be wrong Symbolic link to folder here
AddLastError(folderPath);
break;
// return GetLastError_noZero_HRESULT();
}
if (!found)
break;
if (fi.IsDir())
continue;
RINOK(LoadDll(folderPrefix + fi.Name, true));
@@ -585,6 +689,7 @@ HRESULT CCodecs::Load()
Formats.Clear();
#ifdef EXTERNAL_CODECS
Errors.Clear();
MainDll_ErrorPath.Empty();
Codecs.Clear();
Hashers.Clear();
@@ -627,6 +732,8 @@ HRESULT CCodecs::Load()
Formats.Add(item);
}
// printf("\nLoad codecs \n");
#ifdef EXTERNAL_CODECS
const FString baseFolder = GetBaseFolderPrefixFromRegistry();
{
@@ -635,8 +742,8 @@ HRESULT CCodecs::Load()
if (!loadedOK)
MainDll_ErrorPath = kMainDll;
}
RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName FSTRING_PATH_SEPARATOR));
RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName FSTRING_PATH_SEPARATOR));
RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName));
RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName));
NeedSetLibCodecs = true;
@@ -659,7 +766,7 @@ HRESULT CCodecs::Load()
FOR_VECTOR(i, Libs)
{
CCodecLib &lib = Libs[i];
lib.SetCodecs = (Func_SetCodecs)lib.Lib.GetProc("SetCodecs");
MY_GET_FUNC (lib.SetCodecs, Func_SetCodecs, lib.Lib.GetProc("SetCodecs"));
if (lib.SetCodecs)
{
RINOK(lib.SetCodecs(this));
@@ -679,7 +786,7 @@ int CCodecs::FindFormatForArchiveName(const UString &arcPath) const
int dotPos = arcPath.ReverseFind_Dot();
if (dotPos <= arcPath.ReverseFind_PathSepar())
return -1;
const UString ext = arcPath.Ptr(dotPos + 1);
const UString ext = arcPath.Ptr((unsigned)(dotPos + 1));
if (ext.IsEmpty())
return -1;
if (ext.IsEqualTo_Ascii_NoCase("exe"))
@@ -692,7 +799,7 @@ int CCodecs::FindFormatForArchiveName(const UString &arcPath) const
continue;
*/
if (arc.FindExtension(ext) >= 0)
return i;
return (int)i;
}
return -1;
}
@@ -703,7 +810,7 @@ int CCodecs::FindFormatForExtension(const UString &ext) const
return -1;
FOR_VECTOR (i, Formats)
if (Formats[i].FindExtension(ext) >= 0)
return i;
return (int)i;
return -1;
}
@@ -711,7 +818,7 @@ int CCodecs::FindFormatForArchiveType(const UString &arcType) const
{
FOR_VECTOR (i, Formats)
if (Formats[i].Name.IsEqualTo_NoCase(arcType))
return i;
return (int)i;
return -1;
}
@@ -722,8 +829,8 @@ bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &forma
{
int pos2 = arcType.Find(L'.', pos);
if (pos2 < 0)
pos2 = arcType.Len();
const UString name = arcType.Mid(pos, pos2 - pos);
pos2 = (int)arcType.Len();
const UString name = arcType.Mid(pos, (unsigned)pos2 - pos);
if (name.IsEmpty())
return false;
int index = FindFormatForArchiveType(name);
@@ -733,7 +840,7 @@ bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &forma
return false;
}
formatIndices.Add(index);
pos = pos2 + 1;
pos = (unsigned)pos2 + 1;
}
return true;
}
@@ -756,19 +863,19 @@ void CCodecIcons::LoadIcons(HMODULE m)
CIconPair iconPair;
iconPair.IconIndex = -1;
if (pos < 0)
pos = s.Len();
pos = (int)s.Len();
else
{
UString num = s.Ptr(pos + 1);
const UString num = s.Ptr((unsigned)pos + 1);
if (!num.IsEmpty())
{
const wchar_t *end;
iconPair.IconIndex = ConvertStringToUInt32(num, &end);
iconPair.IconIndex = (int)ConvertStringToUInt32(num, &end);
if (*end != 0)
continue;
}
}
iconPair.Ext = s.Left(pos);
iconPair.Ext = s.Left((unsigned)pos);
IconPairs.Add(iconPair);
}
}
@@ -946,7 +1053,7 @@ int CCodecs::GetCodec_LibIndex(UInt32 index) const
#ifdef EXTERNAL_CODECS
const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS];
return ci.LibIndex;
return (int)ci.LibIndex;
#else
return -1;
#endif
@@ -961,7 +1068,7 @@ int CCodecs::GetHasherLibIndex(UInt32 index)
#ifdef EXTERNAL_CODECS
const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS];
return ci.LibIndex;
return (int)ci.LibIndex;
#else
return -1;
#endif
@@ -1014,7 +1121,8 @@ bool CCodecs::GetCodec_EncoderIsAssigned(UInt32 index) const
UInt32 CCodecs::GetCodec_NumStreams(UInt32 index)
{
NCOM::CPropVariant prop;
RINOK(GetProperty(index, NMethodPropID::kPackStreams, &prop));
if (GetProperty(index, NMethodPropID::kPackStreams, &prop) != S_OK)
return 0;
if (prop.vt == VT_UI4)
return (UInt32)prop.ulVal;
if (prop.vt == VT_EMPTY)
@@ -1065,10 +1173,33 @@ AString CCodecs::GetHasherName(UInt32 index)
UInt32 CCodecs::GetHasherDigestSize(UInt32 index)
{
NCOM::CPropVariant prop;
RINOK(GetHasherProp(index, NMethodPropID::kDigestSize, &prop));
if (GetHasherProp(index, NMethodPropID::kDigestSize, &prop) != S_OK)
return 0;
if (prop.vt != VT_UI4)
return 0;
return prop.ulVal;
}
void CCodecs::GetCodecsErrorMessage(UString &s)
{
s.Empty();
FOR_VECTOR (i, Errors)
{
const CCodecError &ce = Errors[i];
s += "Codec Load Error: ";
s += fs2us(ce.Path);
if (ce.ErrorCode != 0)
{
s += " : ";
s += NWindows::NError::MyFormatMessage(ce.ErrorCode);
}
if (!ce.Message.IsEmpty())
{
s += " : ";
s += ce.Message;
}
s.Add_LF();
}
}
#endif // EXTERNAL_CODECS

View File

@@ -132,7 +132,8 @@ struct CArcInfoEx
bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; }
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; }
UString GetMainExt() const
{
if (Exts.IsEmpty())
@@ -227,6 +228,13 @@ struct CCodecLib
#endif
struct CCodecError
{
FString Path;
HRESULT ErrorCode;
AString Message;
CCodecError(): ErrorCode(0) {}
};
class CCodecs:
#ifdef EXTERNAL_CODECS
@@ -243,7 +251,9 @@ public:
CObjectVector<CCodecLib> Libs;
FString MainDll_ErrorPath;
CObjectVector<CCodecError> Errors;
void AddLastError(const FString &path);
void CloseLibs();
class CReleaser
@@ -272,7 +282,7 @@ public:
HRESULT CreateArchiveHandler(const CArcInfoEx &ai, bool outHandler, void **archive) const
{
return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
return Libs[(unsigned)ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
}
#endif
@@ -306,11 +316,11 @@ public:
const wchar_t *GetFormatNamePtr(int formatIndex) const
{
return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name;
return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[(unsigned)formatIndex].Name;
}
HRESULT Load();
#ifndef _SFX
int FindFormatForArchiveName(const UString &arcPath) const;
int FindFormatForExtension(const UString &ext) const;
@@ -352,6 +362,8 @@ public:
AString GetHasherName(UInt32 index);
UInt32 GetHasherDigestSize(UInt32 index);
void GetCodecsErrorMessage(UString &s);
#endif
HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr<IInArchive> &archive) const
@@ -399,7 +411,7 @@ public:
if (!arc.UpdateEnabled)
continue;
if (arc.Name.IsEqualTo_NoCase(name))
return i;
return (int)i;
}
return -1;
}

View File

@@ -14,6 +14,7 @@
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
@@ -32,11 +33,13 @@
#include "SetProperties.h"
#endif
#ifndef _SFX
#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#define PRF(x)
#endif
#endif
// increase it, if you need to support larger SFX stubs
static const UInt64 kMaxCheckStartPosition = 1 << 23;
@@ -64,7 +67,7 @@ Open:
- open FAIL:
Try to open with all other types from offset 0 only.
If some open type is OK and physical archive size is uequal or larger
than file size, then return that archive with warning that can not be open as [extension type].
than file size, then return that archive with warning that cannot be open as [extension type].
If extension was EXE, it will try to open as unknown_extension case
- file has unknown extension (like a.hhh)
It tries to open via parser code.
@@ -141,14 +144,14 @@ struct CParseItem
bool LenIsUnknown;
CParseItem():
LenIsUnknown(false),
// OkSize(0),
FileTime_Defined(false),
UnpackSize_Defined(false),
NumSubFiles_Defined(false),
NumSubDirs_Defined(false),
NumSubFiles_Defined(false),
IsSelfExe(false),
IsNotArcType(false)
// OkSize(0)
IsNotArcType(false),
LenIsUnknown(false)
{}
/*
@@ -214,15 +217,17 @@ int CHandler::FindInsertPos(const CParseItem &item) const
left = mid + 1;
else if (item.Size < midItem.Size)
right = mid;
/*
else if (item.Size > midItem.Size)
left = mid + 1;
*/
else
{
left = mid + 1;
// return -1;
}
}
return left;
return (int)left;
}
void CHandler::AddUnknownItem(UInt64 next)
@@ -260,7 +265,7 @@ void CHandler::AddItem(const CParseItem &item)
int pos = FindInsertPos(item);
if (pos >= 0)
{
_items.Insert(pos, item);
_items.Insert((unsigned)pos, item);
UInt64 next = item.Offset + item.Size;
if (_maxEndOffset < next)
_maxEndOffset = next;
@@ -401,7 +406,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i];
UInt32 index = allFilesMode ? i : indices[i];
const CParseItem &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -417,7 +422,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
outStreamSpec->Init(skipMode ? 0 : unpackSize, true);
Int32 opRes = NExtract::NOperationResult::kOK;
RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL));
RINOK(_stream->Seek((Int64)item.Offset, STREAM_SEEK_SET, NULL));
streamSpec->Init(unpackSize);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
@@ -496,13 +501,14 @@ static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &r
RINOK(arc->GetArchiveProperty(propid, &prop));
switch (prop.vt)
{
case VT_UI4: result = prop.ulVal; defined = true; break;
case VT_I4: result = (Int64)prop.lVal; defined = true; break;
case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break;
case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break;
case VT_EMPTY: break;
case VT_UI4: result = prop.ulVal; break;
case VT_I4: result = (UInt64)(Int64)prop.lVal; break;
case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; break;
case VT_I8: result = (UInt64)prop.hVal.QuadPart; break;
case VT_EMPTY: return S_OK;
default: return E_FAIL;
}
defined = true;
return S_OK;
}
@@ -513,13 +519,14 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res
RINOK(arc->GetArchiveProperty(propid, &prop));
switch (prop.vt)
{
case VT_UI4: result = prop.ulVal; defined = true; break;
case VT_I4: result = prop.lVal; defined = true; break;
case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break;
case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break;
case VT_EMPTY: break;
case VT_UI4: result = prop.ulVal; break;
case VT_I4: result = prop.lVal; break;
case VT_UI8: result = (Int64)prop.uhVal.QuadPart; break;
case VT_I8: result = (Int64)prop.hVal.QuadPart; break;
case VT_EMPTY: return S_OK;
default: return E_FAIL;
}
defined = true;
return S_OK;
}
@@ -607,6 +614,8 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
#endif
HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
{
#ifdef MY_CPU_LE
@@ -621,19 +630,42 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
propType == NPropDataType::kUtf16z)
{
unsigned len = size / 2 - 1;
// (len) doesn't include null terminator
/*
#if WCHAR_MAX > 0xffff
len = (unsigned)Utf16LE__Get_Num_WCHARs(p, len);
wchar_t *s = result.GetBuf(len);
wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, len, s);
if (s + len != sEnd) return E_FAIL;
*sEnd = 0;
#else
*/
wchar_t *s = result.GetBuf(len);
for (unsigned i = 0; i < len; i++)
{
wchar_t c = GetUi16(p);
p = (const void *)((const Byte *)p + 2);
#if WCHAR_PATH_SEPARATOR != L'/'
if (c == L'/')
c = WCHAR_PATH_SEPARATOR;
else if (c == L'\\')
c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
#endif
*s++ = c;
}
*s = 0;
// #endif
result.ReleaseBuf_SetLen(len);
Convert_UnicodeEsc16_To_UnicodeEscHigh(result);
if (len != 0)
return S_OK;
}
@@ -721,6 +753,8 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
if (result.IsEmpty())
return GetDefaultItemPath(index, result);
Convert_UnicodeEsc16_To_UnicodeEscHigh(result);
return S_OK;
}
@@ -772,7 +806,7 @@ int FindAltStreamColon_in_Path(const wchar_t *path)
if (c == ':')
{
if (colonPos < 0)
colonPos = i;
colonPos = (int)i;
continue;
}
if (c == WCHAR_PATH_SEPARATOR)
@@ -865,8 +899,8 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
int colon = FindAltStreamColon_in_Path(item.Path);
if (colon >= 0)
{
item.MainPath.DeleteFrom(colon);
item.AltStreamName = item.Path.Ptr(colon + 1);
item.MainPath.DeleteFrom((unsigned)colon);
item.AltStreamName = item.Path.Ptr((unsigned)(colon + 1));
item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1]));
item.IsAltStream = true;
}
@@ -877,7 +911,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
#ifndef _SFX
if (item._use_baseParentFolder_mode)
{
RINOK(GetItemPathToParent(mainIndex, item._baseParentFolder, item.PathParts));
RINOK(GetItemPathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts));
#ifdef SUPPORT_ALT_STREAMS
if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty())
@@ -888,10 +922,10 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
colon = FindAltStreamColon_in_Path(s);
if (colon >= 0)
{
item.AltStreamName = s.Ptr(colon + 1);
item.AltStreamName = s.Ptr((unsigned)(colon + 1));
item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1]));
item.IsAltStream = true;
s.DeleteFrom(colon);
s.DeleteFrom((unsigned)colon);
}
}
if (colon == 0)
@@ -1007,9 +1041,9 @@ static void MakeCheckOrder(CCodecs *codecs,
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 ((sig.Size() == 0 && dataSize == 0)
|| (sig.Size() != 0 && sig.Size() <= dataSize
&& TestSignature(data, sig, sig.Size())))
{
orderIndices2.Add(index);
orderIndices[i] = -1;
@@ -1019,8 +1053,6 @@ static void MakeCheckOrder(CCodecs *codecs,
}
}
#endif
#ifdef UNDER_CE
static const unsigned kNumHashBytes = 1;
#define HASH_VAL(buf) ((buf)[0])
@@ -1030,9 +1062,6 @@ static void MakeCheckOrder(CCodecs *codecs,
#define HASH_VAL(buf) GetUi16(buf)
#endif
#ifndef _SFX
static bool IsExeExt(const UString &ext)
{
return ext.IsEqualTo_Ascii_NoCase("exe");
@@ -1244,11 +1273,11 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
bool offsetDefined;
RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined));
Int64 globalOffset = startPos + Offset;
AvailPhySize = FileSize - globalOffset;
Int64 globalOffset = (Int64)startPos + Offset;
AvailPhySize = (UInt64)((Int64)FileSize - globalOffset);
if (PhySizeDefined)
{
UInt64 endPos = globalOffset + PhySize;
UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize);
if (endPos < FileSize)
{
AvailPhySize = PhySize;
@@ -1264,11 +1293,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
}
/*
static PrintNumber(const char *s, int n)
static void PrintNumber(const char *s, int n)
{
char temp[100];
sprintf(temp, "%s %d", s, n);
OutputDebugStringA(temp);
// OutputDebugStringA(temp);
printf(temp);
}
*/
@@ -1287,7 +1317,7 @@ HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyCom
{
const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
if (ai.LibIndex >= 0 ?
!op.codecs->Libs[ai.LibIndex].SetCodecs :
!op.codecs->Libs[(unsigned)ai.LibIndex].SetCodecs :
!op.codecs->Libs.IsEmpty())
{
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
@@ -1438,7 +1468,7 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset)
{
if (!op.stream)
return S_OK;
RINOK(op.stream->Seek(offset, STREAM_SEEK_SET, NULL));
RINOK(op.stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL));
const UInt32 kBufSize = 1 << 11;
Byte buf[kBufSize];
@@ -1464,6 +1494,8 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset)
}
}
#ifndef _SFX
class CExtractCallback_To_OpenCallback:
@@ -1511,7 +1543,7 @@ STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize
STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)
{
*outStream = 0;
*outStream = NULL;
return S_OK;
}
@@ -1525,6 +1557,7 @@ STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* opera
return S_OK;
}
static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
IInStream *stream, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openCallback,
@@ -1548,22 +1581,32 @@ static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
if (phySize_Defined)
return S_OK;
bool phySizeCantBeDetected = false;;
bool phySizeCantBeDetected = false;
RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
if (!phySizeCantBeDetected)
{
RINOK(archive->Extract(0, (UInt32)(Int32)-1, BoolToInt(true), extractCallback));
PRF(printf("\n-- !phySize_Defined after Open, call archive->Extract()"));
// It's for bzip2/gz and some xz archives, where Open operation doesn't know phySize.
// But the Handler will know phySize after full archive testing.
RINOK(archive->Extract(NULL, (UInt32)(Int32)-1, BoolToInt(true), extractCallback));
PRF(printf("\n-- OK"));
}
}
return S_OK;
}
static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name)
{
FOR_VECTOR (i, orderIndices)
if (StringsAreEqualNoCase_Ascii(codecs->Formats[orderIndices[i]].Name, name))
return i;
{
int oi = orderIndices[i];
if (oi >= 0)
if (StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)oi].Name, name))
return (int)i;
}
return -1;
}
@@ -1591,7 +1634,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
{
int dotPos = fileName.ReverseFind_Dot();
if (dotPos >= 0)
extension = fileName.Ptr(dotPos + 1);
extension = fileName.Ptr((unsigned)(dotPos + 1));
}
CIntVector orderIndices;
@@ -1616,13 +1659,18 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool isUnknownExt = false;
#endif
#ifndef _SFX
bool isForced = false;
#endif
unsigned numMainTypes = 0;
int formatIndex = op.openType.FormatIndex;
if (formatIndex >= 0)
{
#ifndef _SFX
isForced = true;
#endif
orderIndices.Add(formatIndex);
numMainTypes = 1;
isMainFormatArr[(unsigned)formatIndex] = true;
@@ -1659,10 +1707,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
isNumber = true;
}
if (isNumber)
{
if (c == 'z' || c == 'Z')
isZip = true;
else
isRar = true;
}
}
#endif
@@ -1674,7 +1724,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (IgnoreSplit || !op.openType.CanReturnArc)
if (ai.IsSplit())
continue;
if (op.excludedFormats->FindInSorted(i) >= 0)
if (op.excludedFormats->FindInSorted((int)i) >= 0)
continue;
#ifndef _SFX
@@ -1684,17 +1734,17 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (ai.FindExtension(extension) >= 0
#ifndef _SFX
|| isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip")
|| isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar")
|| (isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip"))
|| (isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar"))
#endif
)
{
// PrintNumber("orderIndices.Insert", i);
orderIndices.Insert(numFinded++, i);
orderIndices.Insert(numFinded++, (int)i);
isMainFormatArr[i] = true;
}
else
orderIndices.Add(i);
orderIndices.Add((int)i);
}
}
@@ -1740,8 +1790,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 };
if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0)
{
orderIndices2.Add(orderIndices[i]);
orderIndices[i] = -1;
orderIndices2.Add(orderIndices[(unsigned)i]);
orderIndices[(unsigned)i] = -1;
if (i >= (int)numFinded)
numFinded++;
}
@@ -1786,10 +1836,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf");
if (iUdf > iIso && iIso >= 0)
{
int isoIndex = orderIndices[iIso];
int udfIndex = orderIndices[iUdf];
orderIndices[iUdf] = isoIndex;
orderIndices[iIso] = udfIndex;
int isoIndex = orderIndices[(unsigned)iIso];
int udfIndex = orderIndices[(unsigned)iUdf];
orderIndices[(unsigned)iUdf] = isoIndex;
orderIndices[(unsigned)iIso] = udfIndex;
}
}
@@ -1843,12 +1893,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
for (unsigned i = 0; i < numCheckTypes; i++)
{
FormatIndex = orderIndices[i];
// orderIndices[] item cannot be negative here
bool exactOnly = false;
#ifndef _SFX
const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex];
// OutputDebugStringW(ai.Name);
if (i >= numMainTypes)
{
@@ -1872,7 +1924,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
CMyComPtr<IInArchive> archive;
RINOK(PrepareToOpen(op, FormatIndex, archive));
RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive));
if (!archive)
continue;
@@ -1949,7 +2001,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool thereIsTail = ErrorInfo.ThereIsTail;
if (thereIsTail && mode.ZerosTailIsAllowed)
{
RINOK(CheckZerosTail(op, Offset + PhySize));
RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize)));
if (ErrorInfo.IgnoreTail)
thereIsTail = false;
}
@@ -2064,16 +2116,22 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
for (i = 0; i < orderIndices.Size(); i++)
{
unsigned form = orderIndices[i];
// orderIndices[] item cannot be negative here
unsigned form = (unsigned)orderIndices[i];
if (skipFrontalFormat[form])
continue;
const CArcInfoEx &ai = op.codecs->Formats[form];
if (ai.IsSplit())
{
splitIndex = form;
splitIndex = (int)form;
continue;
}
if (ai.Flags_ByExtOnlyOpen())
continue;
if (ai.IsArcFunc)
{
UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize);
@@ -2119,12 +2177,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
if (splitIndex >= 0)
sortedFormats.Insert(0, splitIndex);
sortedFormats.Insert(0, (unsigned)splitIndex);
for (i = 0; i < sortedFormats.Size(); i++)
{
FormatIndex = sortedFormats[i];
const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
FormatIndex = (int)sortedFormats[i];
const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex];
if (op.callback)
RINOK(op.callback->SetTotal(NULL, &fileSize));
@@ -2132,7 +2190,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
CMyComPtr<IInArchive> archive;
RINOK(PrepareToOpen(op, FormatIndex, archive));
RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive));
if (!archive)
continue;
@@ -2145,7 +2203,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
result = archive->Open(op.stream, &searchLimit, op.callback);
else
*/
result = OpenArchiveSpec(archive, !mode.CanReturnArc, op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback);
// if (!CanReturnArc), it's ParserMode, and we need phy size
result = OpenArchiveSpec(archive,
!mode.CanReturnArc, // needPhySize
op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback);
}
if (result == S_FALSE)
@@ -2167,7 +2228,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
NArchive::NParser::CParseItem pi;
pi.Offset = Offset;
pi.Offset = (UInt64)Offset;
pi.Size = AvailPhySize;
// bool needScan = false;
@@ -2204,7 +2265,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
{
if (mode.ZerosTailIsAllowed)
{
RINOK(CheckZerosTail(op, Offset + PhySize));
RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize)));
if (ErrorInfo.IgnoreTail)
openCur = true;
}
@@ -2300,6 +2361,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (index < 0)
continue;
const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index];
if (ai.Flags_ByExtOnlyOpen())
continue;
bool isDifficult = false;
// if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31)
if (!ai.NewInterface)
@@ -2330,7 +2393,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
if (isDifficult)
{
difficultFormats.Add(index);
difficultFormats.Add((unsigned)index);
difficultBools[(unsigned)index] = true;
}
}
@@ -2399,7 +2462,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
size_t processedSize = kBufSize - bytesInBuf;
// printf("\nRead ask = %d", (unsigned)processedSize);
UInt64 seekPos = bufPhyPos + bytesInBuf;
RINOK(op.stream->Seek(bufPhyPos + bytesInBuf, STREAM_SEEK_SET, NULL));
RINOK(op.stream->Seek((Int64)(bufPhyPos + bytesInBuf), STREAM_SEEK_SET, NULL));
RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize));
// printf(" processed = %d", (unsigned)processedSize);
if (processedSize == 0)
@@ -2472,7 +2535,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
}
size_t availSize = bytesInBuf - (size_t)posInBuf;
const size_t availSize = bytesInBuf - (size_t)posInBuf;
if (availSize < kNumHashBytes)
break;
size_t scanSize = availSize -
@@ -2503,7 +2566,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (!needCheckStartOpen)
{
for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++);
ppp = buf - (byteBuffer + (size_t)posInBuf);
ppp = (size_t)(buf - (byteBuffer + (size_t)posInBuf));
pos += ppp;
if (buf == bufLimit)
continue;
@@ -2600,13 +2663,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
// printf("\nIsArc OK: %S", (const wchar_t *)ai.Name);
}
/*
if (pos == 67109888)
pos = pos;
*/
PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name));
bool isMainFormat = isMainFormatArr[index];
const bool isMainFormat = isMainFormatArr[index];
const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
CMyComPtr<IInArchive> archive;
@@ -2616,14 +2675,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
// OutputDebugStringW(ai.Name);
UInt64 rem = fileSize - startArcPos;
const UInt64 rem = fileSize - startArcPos;
UInt64 arcStreamOffset = 0;
if (ai.Flags_UseGlobalOffset())
{
limitedStreamSpec->InitAndSeek(0, fileSize);
limitedStream->Seek(startArcPos, STREAM_SEEK_SET, NULL);
limitedStream->Seek((Int64)startArcPos, STREAM_SEEK_SET, NULL);
}
else
{
@@ -2643,20 +2702,23 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
extractCallback_To_OpenCallback_Spec->Files = 0;
extractCallback_To_OpenCallback_Spec->Offset = startArcPos;
HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition,
HRESULT result = OpenArchiveSpec(archive,
true, // needPhySize
limitedStream, &maxCheckStartPosition,
useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback,
extractCallback_To_OpenCallback);
RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result));
bool isOpen = false;
if (result == S_FALSE)
{
if (!mode.CanReturnParser)
{
if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen())
{
ErrorInfo.ErrorFormatIndex = index;
ErrorInfo.ErrorFormatIndex = (int)index;
NonOpen_ErrorInfo = ErrorInfo;
// if archive was detected, we don't need additional open attempts
return S_FALSE;
@@ -2668,6 +2730,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
else
{
if (PhySizeDefined && PhySize == 0)
{
PRF(printf(" phySizeDefined && PhySize == 0 "));
// we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function.
continue;
}
isOpen = true;
RINOK(result);
PRF(printf(" OK "));
@@ -2681,9 +2749,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
pi.Offset = startArcPos;
if (ai.Flags_UseGlobalOffset())
pi.Offset = Offset;
pi.Offset = (UInt64)Offset;
else if (Offset != 0)
return E_FAIL;
UInt64 arcRem = FileSize - pi.Offset;
UInt64 phySize = arcRem;
bool phySizeDefined = PhySizeDefined;
@@ -2715,7 +2784,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (isOpen && !phySizeDefined)
{
// it's for Z format
// it's for Z format, or bzip2,gz,xz with phySize that was not detected
pi.LenIsUnknown = true;
needScan = true;
phySize = arcRem;
@@ -2787,7 +2856,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool thereIsTail = ErrorInfo.ThereIsTail;
if (thereIsTail && mode.ZerosTailIsAllowed)
{
RINOK(CheckZerosTail(op, arcStreamOffset + Offset + PhySize));
RINOK(CheckZerosTail(op, (UInt64)((Int64)arcStreamOffset + Offset + (Int64)PhySize)));
if (ErrorInfo.IgnoreTail)
thereIsTail = false;
}
@@ -2795,10 +2864,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (pi.Offset != 0)
{
if (!pi.IsNotArcType)
{
if (thereIsTail)
openCur = specFlags.CanReturnMid;
else
openCur = specFlags.CanReturnTail;
}
}
else
{
@@ -2806,11 +2877,11 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
openCur = true;
else
openCur = specFlags.CanReturnFrontal;
if (formatIndex >= -2)
openCur = true;
}
if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */)
openCur = false;
@@ -2837,7 +2908,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
{
InStream = op.stream;
Archive = archive;
FormatIndex = index;
FormatIndex = (int)index;
ArcStreamOffset = arcStreamOffset;
return S_OK;
}
@@ -2851,7 +2922,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
*/
pi.FormatIndex = index;
pi.FormatIndex = (int)index;
// printf("\nAdd offset = %d", (int)pi.Offset);
handlerSpec->AddItem(pi);
@@ -2906,6 +2977,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
return S_OK;
}
HRESULT CArc::OpenStream(const COpenOptions &op)
{
RINOK(OpenStream2(op));
@@ -2930,13 +3004,13 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
{
int dotPos = fileName.ReverseFind_Dot();
if (dotPos >= 0)
extension = fileName.Ptr(dotPos + 1);
extension = fileName.Ptr((unsigned)(dotPos + 1));
}
DefaultName.Empty();
if (FormatIndex >= 0)
{
const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex];
if (ai.Exts.Size() == 0)
DefaultName = GetDefaultName2(fileName, UString(), UString());
else
@@ -2944,7 +3018,7 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
int subExtIndex = ai.FindExtension(extension);
if (subExtIndex < 0)
subExtIndex = 0;
const CArcExtInfo &extInfo = ai.Exts[subExtIndex];
const CArcExtInfo &extInfo = ai.Exts[(unsigned)subExtIndex];
DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);
}
}
@@ -2982,9 +3056,7 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
fileStream = fileStreamSpec;
Path = filePath;
if (!fileStreamSpec->Open(us2fs(Path)))
{
return GetLastError();
}
return GetLastError_noZero_HRESULT();
op.stream = fileStream;
#ifdef _SFX
IgnoreSplit = true;
@@ -3289,7 +3361,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI)
if (!op.stream && !op.stdInMode)
{
NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name);
openCallbackSpec->Init(prefix, name);
RINOK(openCallbackSpec->Init2(prefix, name));
}
else
{
@@ -3341,7 +3413,7 @@ HRESULT CArc::ReOpen(const COpenOptions &op)
CTailInStream *tailStreamSpec = new CTailInStream;
stream2 = tailStreamSpec;
tailStreamSpec->Stream = op.stream;
tailStreamSpec->Offset = globalOffset;
tailStreamSpec->Offset = (UInt64)globalOffset;
tailStreamSpec->Init();
RINOK(tailStreamSpec->SeekToStart());
}
@@ -3353,8 +3425,8 @@ HRESULT CArc::ReOpen(const COpenOptions &op)
if (res == S_OK)
{
RINOK(ReadBasicProps(Archive, globalOffset, res));
ArcStreamOffset = globalOffset;
RINOK(ReadBasicProps(Archive, (UInt64)globalOffset, res));
ArcStreamOffset = (UInt64)globalOffset;
if (ArcStreamOffset != 0)
InStream = op.stream;
}
@@ -3394,14 +3466,14 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op)
{
FString dirPrefix, fileName;
NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName);
openCallbackSpec->Init(dirPrefix, fileName);
RINOK(openCallbackSpec->Init2(dirPrefix, fileName));
}
CInFileStream *fileStreamSpec = new CInFileStream;
CMyComPtr<IInStream> stream(fileStreamSpec);
if (!fileStreamSpec->Open(us2fs(op.filePath)))
return GetLastError();
return GetLastError_noZero_HRESULT();
op.stream = stream;
CArc &arc = Arcs[0];
@@ -3416,6 +3488,7 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op)
#ifndef _SFX
bool ParseComplexSize(const wchar_t *s, UInt64 &result);
bool ParseComplexSize(const wchar_t *s, UInt64 &result)
{
result = 0;
@@ -3473,7 +3546,7 @@ static bool ParseTypeParams(const UString &s, COpenType &type)
return false;
}
bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
static bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
{
int pos2 = s.Find(L':');
@@ -3482,11 +3555,11 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
if (pos2 < 0)
{
name = s;
pos2 = s.Len();
pos2 = (int)s.Len();
}
else
{
name = s.Left(pos2);
name = s.Left((unsigned)pos2);
pos2++;
}
@@ -3515,17 +3588,17 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
}
for (unsigned i = pos2; i < s.Len();)
for (unsigned i = (unsigned)pos2; i < s.Len();)
{
int next = s.Find(L':', i);
if (next < 0)
next = s.Len();
const UString name = s.Mid(i, next - i);
next = (int)s.Len();
const UString name = s.Mid(i, (unsigned)next - i);
if (name.IsEmpty())
return false;
if (!ParseTypeParams(name, type))
return false;
i = next + 1;
i = (unsigned)next + 1;
}
return true;
@@ -3538,15 +3611,15 @@ bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType>
{
int pos2 = s.Find(L'.', pos);
if (pos2 < 0)
pos2 = s.Len();
UString name = s.Mid(pos, pos2 - pos);
pos2 = (int)s.Len();
UString name = s.Mid(pos, (unsigned)pos2 - pos);
if (name.IsEmpty())
return false;
COpenType type;
if (!ParseType(codecs, name, type))
return false;
types.Add(type);
pos = pos2 + 1;
pos = (unsigned)pos2 + 1;
}
return true;
}

View File

@@ -88,9 +88,9 @@ struct COpenType
COpenType():
FormatIndex(-1),
Recursive(true),
EachPos(false),
CanReturnArc(true),
CanReturnParser(false),
EachPos(false),
// SkipSfxStub(true),
// ExeAsUnknown(true),
ZerosTailIsAllowed(false),
@@ -121,7 +121,7 @@ struct COpenOptions
IInStream *stream;
ISequentialInStream *seqStream;
IArchiveOpenCallback *callback;
COpenCallbackImp *callbackSpec;
COpenCallbackImp *callbackSpec; // it's used for SFX only
OPEN_PROPS_DECL
// bool openOnlySpecifiedByExtension,
@@ -286,7 +286,7 @@ public:
UString filePath;
UString DefaultName;
int FormatIndex; // - 1 means Parser.
int SubfileIndex;
UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile
FILETIME MTime;
bool MTimeDefined;
@@ -302,7 +302,7 @@ public:
UInt64 GetEstmatedPhySize() const { return PhySizeDefined ? PhySize : FileSize; }
UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler
Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive
Int64 GetGlobalOffset() const { return (Int64)ArcStreamOffset + Offset; } // it's global offset of archive
// AString ErrorFlagsText;
@@ -397,6 +397,13 @@ struct CArchiveLink
IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; }
IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; }
/*
Open() opens archive and COpenOptions::callback
Open2() uses COpenCallbackImp that implements Volumes and password callback
Open3() calls Open2() and callbackUI->Open_Finished();
Open_Strict() returns S_FALSE also in case, if there is non-open expected nested archive.
*/
HRESULT Open(COpenOptions &options);
HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI);
HRESULT Open3(COpenOptions &options, IOpenCallbackUI *callbackUI);

View File

@@ -14,8 +14,10 @@
#include "PropIDUtils.h"
#ifndef _SFX
#define Get16(x) GetUi16(x)
#define Get32(x) GetUi32(x)
#endif
using namespace NWindows;
@@ -63,9 +65,9 @@ static void ConvertPosixAttribToString(char *s, UInt32 a) throw()
s[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w');
s[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x');
}
if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S');
if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S');
if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T');
if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S'); // S_ISUID
if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S'); // S_ISGID
if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T'); // S_ISVTX
s[10] = 0;
a &= ~(UInt32)0xFFFF;
@@ -213,13 +215,13 @@ void ConvertPropertyToString2(UString &dest, const PROPVARIANT &prop, PROPID pro
dest = temp;
}
#ifndef _SFX
static inline unsigned GetHex(unsigned v)
{
return (v < 10) ? ('0' + v) : ('A' + (v - 10));
}
#ifndef _SFX
static inline void AddHexToString(AString &res, unsigned v)
{
res += (char)GetHex(v >> 4);
@@ -272,7 +274,7 @@ static int FindPairIndex(const CSecID2Name * pairs, unsigned num, UInt32 id)
{
for (unsigned i = 0; i < num; i++)
if (pairs[i].n == id)
return i;
return (int)i;
return -1;
}
@@ -479,11 +481,16 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName
*/
}
/*
#define MY_SE_OWNER_DEFAULTED (0x0001)
#define MY_SE_GROUP_DEFAULTED (0x0002)
*/
#define MY_SE_DACL_PRESENT (0x0004)
/*
#define MY_SE_DACL_DEFAULTED (0x0008)
*/
#define MY_SE_SACL_PRESENT (0x0010)
/*
#define MY_SE_SACL_DEFAULTED (0x0020)
#define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100)
#define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200)
@@ -493,6 +500,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName
#define MY_SE_SACL_PROTECTED (0x2000)
#define MY_SE_RM_CONTROL_VALID (0x4000)
#define MY_SE_SELF_RELATIVE (0x8000)
*/
void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s)
{
@@ -590,25 +598,45 @@ static const CSecID2Name k_ReparseTags[] =
{ 0x80000014, "NFS" },
{ 0x80000015, "FILE_PLACEHOLDER" },
{ 0x80000016, "DFM" },
{ 0x80000017, "WOF" }
{ 0x80000017, "WOF" },
{ 0x80000018, "WCI" },
{ 0x8000001B, "APPEXECLINK" },
{ 0xA000001D, "LX_SYMLINK" },
{ 0x80000023, "AF_UNIX" },
{ 0x80000024, "LX_FIFO" },
{ 0x80000025, "LX_CHR" },
{ 0x80000026, "LX_BLK" }
};
bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
{
s.Empty();
NFile::CReparseAttr attr;
DWORD errorCode = 0;
if (attr.Parse(data, size, errorCode))
if (attr.Parse(data, size))
{
if (!attr.IsSymLink())
s += "Junction: ";
s += attr.GetPath();
if (!attr.IsOkNamePair())
if (attr.IsSymLink_WSL())
{
s += " : ";
s += attr.PrintName;
s += "WSL: ";
s += attr.GetPath();
}
else
{
if (!attr.IsSymLink_Win())
s += "Junction: ";
s += attr.GetPath();
if (s.IsEmpty())
s += "Link: ";
if (!attr.IsOkNamePair())
{
s += " : ";
s += attr.PrintName;
}
}
if (attr.MinorError)
s += " : MINOR_ERROR";
return true;
// s += " "; // for debug
}
if (size < 8)
@@ -651,7 +679,7 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
for (UInt32 i = 0; i < len; i++)
{
if (i >= 8)
if (i >= 16)
{
s += "...";
break;

View File

@@ -27,6 +27,21 @@ static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
prop = result;
}
struct CPropPropetiesVector
{
CPropVariant *values;
CPropPropetiesVector(unsigned num)
{
values = new CPropVariant[num];
}
~CPropPropetiesVector()
{
delete []values;
}
};
HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
{
if (properties.IsEmpty())
@@ -37,8 +52,7 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
return S_OK;
UStringVector realNames;
CPropVariant *values = new CPropVariant[properties.Size()];
try
CPropPropetiesVector values(properties.Size());
{
unsigned i;
for (i = 0; i < properties.Size(); i++)
@@ -62,19 +76,12 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
else
ParseNumberString(property.Value, propVariant);
realNames.Add(name);
values[i] = propVariant;
values.values[i] = propVariant;
}
CRecordVector<const wchar_t *> names;
for (i = 0; i < realNames.Size(); i++)
names.Add((const wchar_t *)realNames[i]);
RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
return setProperties->SetProperties(&names.Front(), values.values, names.Size());
}
catch(...)
{
delete []values;
throw;
}
delete []values;
return S_OK;
}

View File

@@ -32,7 +32,7 @@
static const char * const kUpdateIsNotSupoorted =
"update operations are not supported for this archive";
static const char * const kUpdateIsNotSupoorted_MultiVol =
static const char * const kUpdateIsNotSupported_MultiVol =
"Updating for multivolume archives is not implemented";
using namespace NWindows;
@@ -41,8 +41,9 @@ using namespace NFile;
using namespace NDir;
using namespace NName;
#ifdef _WIN32
static CFSTR const kTempFolderPrefix = FTEXT("7zE");
#endif
void CUpdateErrorInfo::SetFromLastError(const char *message)
{
@@ -57,26 +58,12 @@ HRESULT CUpdateErrorInfo::SetFromLastError(const char *message, const FString &f
return Get_HRESULT_Error();
}
static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
HRESULT CUpdateErrorInfo::SetFromError_DWORD(const char *message, const FString &fileName, DWORD error)
{
NFind::CFileInfo fileInfo;
FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
{
NFind::CEnumerator enumerator;
enumerator.SetDirPrefix(pathPrefix);
while (enumerator.Next(fileInfo))
{
if (fileInfo.IsDir())
if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name))
return false;
}
}
/*
// we don't need clear read-only for folders
if (!MySetFileAttributes(path, 0))
return false;
*/
return RemoveDir(path);
Message = message;
FileNames.Add(fileName);
SystemError = error;
return Get_HRESULT_Error();
}
@@ -175,7 +162,7 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
altStream.StreamSpec = new COutFileStream;
altStream.Stream = altStream.StreamSpec;
if (!altStream.StreamSpec->Create(name, false))
return ::GetLastError();
return GetLastError_noZero_HRESULT();
{
// NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
TempFiles->Paths.Add(name);
@@ -204,14 +191,14 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
{
// CMyComPtr<IOutStream> outStream;
// RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream));
RINOK(altStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
RINOK(altStream.Stream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL));
altStream.Pos = _offsetPos;
}
UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos);
UInt32 realProcessed;
RINOK(altStream.Stream->Write(data, curSize, &realProcessed));
data = (void *)((Byte *)data + realProcessed);
data = (const void *)((const Byte *)data + realProcessed);
size -= realProcessed;
altStream.Pos += realProcessed;
_offsetPos += realProcessed;
@@ -240,9 +227,9 @@ STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *n
return STG_E_INVALIDFUNCTION;
switch (seekOrigin)
{
case STREAM_SEEK_SET: _absPos = offset; break;
case STREAM_SEEK_CUR: _absPos += offset; break;
case STREAM_SEEK_END: _absPos = _length + offset; break;
case STREAM_SEEK_SET: _absPos = (UInt64)offset; break;
case STREAM_SEEK_CUR: _absPos = (UInt64)((Int64)_absPos + offset); break;
case STREAM_SEEK_END: _absPos = (UInt64)((Int64)_length + offset); break;
}
_offsetPos = _absPos;
if (newPosition)
@@ -298,11 +285,11 @@ void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode)
Name.DeleteBack();
else
{
const UString ext = Name.Ptr(dotPos + 1);
const UString ext = Name.Ptr((unsigned)(dotPos + 1));
if (BaseExtension.IsEqualTo_NoCase(ext))
{
BaseExtension = ext;
Name.DeleteFrom(dotPos);
Name.DeleteFrom((unsigned)dotPos);
return;
}
}
@@ -392,7 +379,7 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
}
else
{
const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex];
if (!arcInfo.UpdateEnabled)
return false;
typeExt = arcInfo.GetMainExt();
@@ -417,8 +404,8 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
{
const CObjectVector<CArcItem> *_arcItems;
IUpdateCallbackUI *_callback;
CDirItemsStat *_stat;
IUpdateCallbackUI *_callback;
CUpdateProduceCallbackImp(
const CObjectVector<CArcItem> *a,
@@ -541,7 +528,7 @@ static HRESULT Compress(
}
else
{
RINOK(codecs->CreateOutArchive(formatIndex, outArchive));
RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive));
#ifdef EXTERNAL_CODECS
{
@@ -576,7 +563,7 @@ static HRESULT Compress(
}
{
const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex];
if (options.AltStreams.Val && !arcInfo.Flags_AltStreams())
return E_NOTIMPL;
if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure())
@@ -614,7 +601,7 @@ static HRESULT Compress(
int colonPos = FindAltStreamColon_in_Path(ai.Name);
if (colonPos >= 0)
{
UString mainName = ai.Name.Left(colonPos);
UString mainName = ai.Name.Left((unsigned)colonPos);
/*
actually we must improve that code to support cases
with folder renaming like: rn arc dir1\ dir2\
@@ -623,7 +610,7 @@ static HRESULT Compress(
{
needRename = true;
dest += ':';
dest += ai.Name.Ptr(colonPos + 1);
dest += ai.Name.Ptr((unsigned)(colonPos + 1));
break;
}
}
@@ -638,7 +625,7 @@ static HRESULT Compress(
{
up2.NewProps = true;
RINOK(arc->IsItemAnti(i, up2.IsAnti));
up2.NewNameIndex = newNames.Add(dest);
up2.NewNameIndex = (int)newNames.Add(dest);
}
updatePairs2.Add(up2);
}
@@ -664,7 +651,7 @@ static HRESULT Compress(
if (up.ExistOnDisk())
{
CDirItemsStat2 &stat = stat2.NewData;
const CDirItem &di = dirItems.Items[up.DirIndex];
const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex];
if (di.IsDir())
{
if (up.IsAnti)
@@ -697,7 +684,7 @@ static HRESULT Compress(
else if (up.ArcIndex >= 0)
{
CDirItemsStat2 &stat = *(up.NewData ? &stat2.NewData : &stat2.OldData);
const CArcItem &ai = arcItems[up.ArcIndex];
const CArcItem &ai = arcItems[(unsigned)up.ArcIndex];
if (ai.IsDir)
{
if (up.IsAnti)
@@ -733,6 +720,7 @@ static HRESULT Compress(
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
updateCallbackSpec->PreserveATime = options.PreserveATime;
updateCallbackSpec->ShareForWrite = options.OpenShareForWrite;
updateCallbackSpec->StopAfterOpenError = options.StopAfterOpenError;
updateCallbackSpec->StdInMode = options.StdInMode;
@@ -922,9 +910,9 @@ static HRESULT Compress(
CUpdatePair2 &pair2 = updatePairs2[i];
const FILETIME *ft2 = NULL;
if (pair2.NewProps && pair2.DirIndex >= 0)
ft2 = &dirItems.Items[pair2.DirIndex].MTime;
ft2 = &dirItems.Items[(unsigned)pair2.DirIndex].MTime;
else if (pair2.UseArcProps && pair2.ArcIndex >= 0)
ft2 = &arcItems[pair2.ArcIndex].MTime;
ft2 = &arcItems[(unsigned)pair2.ArcIndex].MTime;
if (ft2)
{
if (::CompareFileTime(&ft, ft2) < 0)
@@ -936,7 +924,7 @@ static HRESULT Compress(
if (outStreamSpec)
outStreamSpec->SetMTime(&ft);
else if (volStreamSpec)
volStreamSpec->SetMTime(&ft);;
volStreamSpec->SetMTime(&ft);
}
}
@@ -1041,7 +1029,7 @@ static HRESULT EnumerateInArchiveItems(
#if defined(_WIN32) && !defined(UNDER_CE)
#include <mapi.h>
#include <MAPI.h>
#endif
@@ -1074,7 +1062,7 @@ HRESULT UpdateArchive(
if (options.Commands.Size() != 1)
return E_NOTIMPL;
const CActionSet &as = options.Commands[0].ActionSet;
for (int i = 2; i < NPairState::kNumValues; i++)
for (unsigned i = 2; i < NPairState::kNumValues; i++)
if (as.StateActions[i] != NPairAction::kCompress)
return E_NOTIMPL;
}
@@ -1103,7 +1091,7 @@ HRESULT UpdateArchive(
if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0)
{
const FString fullName = NDLL::GetModuleDirPrefix() + options.SfxModule;
if (NFind::DoesFileExist(fullName))
if (NFind::DoesFileExist_FollowLink(fullName))
{
options.SfxModule = fullName;
found = true;
@@ -1111,7 +1099,7 @@ HRESULT UpdateArchive(
}
if (!found)
{
if (!NFind::DoesFileExist(options.SfxModule))
if (!NFind::DoesFileExist_FollowLink(options.SfxModule))
return errorInfo.SetFromLastError("cannot find specified SFX module", options.SfxModule);
}
}
@@ -1143,7 +1131,7 @@ HRESULT UpdateArchive(
else
{
NFind::CFileInfo fi;
if (!fi.Find(us2fs(arcPath)))
if (!fi.Find_FollowLink(us2fs(arcPath)))
{
if (renameMode)
throw "can't find archive";;
@@ -1156,24 +1144,35 @@ HRESULT UpdateArchive(
else
{
if (fi.IsDir())
throw "there is no such archive";
return errorInfo.SetFromError_DWORD("There is a folder with the name of archive",
us2fs(arcPath),
#ifdef _WIN32
ERROR_ACCESS_DENIED
#else
EISDIR
#endif
);
if (fi.IsDevice)
return E_NOTIMPL;
if (!options.StdOutMode && options.UpdateArchiveItself)
if (fi.IsReadOnly())
{
errorInfo.SystemError = ERROR_ACCESS_DENIED;
errorInfo.Message = "The file is read-only";
errorInfo.FileNames.Add(us2fs(arcPath));
return errorInfo.Get_HRESULT_Error();
return errorInfo.SetFromError_DWORD("The file is read-only",
us2fs(arcPath),
#ifdef _WIN32
ERROR_ACCESS_DENIED
#else
EACCES
#endif
);
}
if (options.VolumesSizes.Size() > 0)
{
errorInfo.FileNames.Add(us2fs(arcPath));
errorInfo.SystemError = (DWORD)E_NOTIMPL;
errorInfo.Message = kUpdateIsNotSupoorted_MultiVol;
// errorInfo.SystemError = (DWORD)E_NOTIMPL;
errorInfo.Message = kUpdateIsNotSupported_MultiVol;
return E_NOTIMPL;
}
CObjectVector<COpenType> types2;
@@ -1211,8 +1210,8 @@ HRESULT UpdateArchive(
if (arcLink.VolumePaths.Size() > 1)
{
errorInfo.SystemError = (DWORD)E_NOTIMPL;
errorInfo.Message = kUpdateIsNotSupoorted_MultiVol;
// errorInfo.SystemError = (DWORD)E_NOTIMPL;
errorInfo.Message = kUpdateIsNotSupported_MultiVol;
return E_NOTIMPL;
}
@@ -1222,7 +1221,7 @@ HRESULT UpdateArchive(
if (arc.ErrorInfo.ThereIsTail)
{
errorInfo.SystemError = (DWORD)E_NOTIMPL;
// errorInfo.SystemError = (DWORD)E_NOTIMPL;
errorInfo.Message = "There is some data block after the end of the archive";
return E_NOTIMPL;
}
@@ -1292,7 +1291,7 @@ HRESULT UpdateArchive(
HRESULT res = EnumerateItems(censor,
options.PathMode,
options.AddPathPrefix,
UString(), // options.AddPathPrefix,
dirItems);
if (res != S_OK)
@@ -1332,8 +1331,6 @@ HRESULT UpdateArchive(
dirItems.AddSecurityItem(prefix, secureIndex);
#endif
parentDirItem.SecureIndex = secureIndex;
parentDirItem_Ptr = &parentDirItem;
}
}
}
@@ -1565,7 +1562,7 @@ HRESULT UpdateArchive(
}
*/
LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)mapiLib.GetProc("MAPISendMail");
LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)(void *)mapiLib.GetProc("MAPISendMail");
if (sendMail == 0)
{
errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function");
@@ -1610,8 +1607,8 @@ HRESULT UpdateArchive(
MapiFileDesc &f = files[i];
memset(&f, 0, sizeof(f));
f.nPosition = 0xFFFFFFFF;
f.lpszPathName = (char *)(const char *)paths[i];
f.lpszFileName = (char *)(const char *)names[i];
f.lpszPathName = paths[i].Ptr_non_const();
f.lpszFileName = names[i].Ptr_non_const();
}
{
@@ -1626,7 +1623,7 @@ HRESULT UpdateArchive(
{
memset(&rec, 0, sizeof(rec));
rec.ulRecipClass = MAPI_TO;
rec.lpszAddress = (char *)(const char *)addr;
rec.lpszAddress = addr.Ptr_non_const();
m.nRecipCount = 1;
m.lpRecips = &rec;
}
@@ -1660,8 +1657,12 @@ HRESULT UpdateArchive(
if (processedItems[i] != 0 || dirItem.Size == 0)
{
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))
{
// FIXME: here we can check Find_FollowLink() also;
// maybe we must exclude also files with archive name: "a a.7z * -sdel"
if (fileInfo.Size == dirItem.Size
&& CompareFileTime(&fileInfo.MTime, &dirItem.MTime) == 0

View File

@@ -18,7 +18,7 @@ enum EArcNameMode
{
k_ArcNameMode_Smart,
k_ArcNameMode_Exact,
k_ArcNameMode_Add,
k_ArcNameMode_Add
};
struct CArchivePath
@@ -91,6 +91,7 @@ struct CUpdateOptions
bool SfxMode;
FString SfxModule;
bool PreserveATime;
bool OpenShareForWrite;
bool StopAfterOpenError;
@@ -104,7 +105,7 @@ struct CUpdateOptions
FString WorkingDir;
NWildcard::ECensorPathMode PathMode;
UString AddPathPrefix;
// UString AddPathPrefix;
CBoolPair NtSecurity;
CBoolPair AltStreams;
@@ -122,20 +123,26 @@ struct CUpdateOptions
CUpdateOptions():
UpdateArchiveItself(true),
ArcNameMode(k_ArcNameMode_Smart),
SfxMode(false),
StdInMode(false),
StdOutMode(false),
EMailMode(false),
EMailRemoveAfter(false),
PreserveATime(false),
OpenShareForWrite(false),
StopAfterOpenError(false),
ArcNameMode(k_ArcNameMode_Smart),
StdInMode(false),
StdOutMode(false),
EMailMode(false),
EMailRemoveAfter(false),
PathMode(NWildcard::k_RelatPath),
DeleteAfterCompressing(false),
SetArcMTime(false)
{};
{};
void SetActionCommand_Add()
{
@@ -150,7 +157,7 @@ struct CUpdateOptions
struct CUpdateErrorInfo
{
DWORD SystemError;
DWORD SystemError; // it's DWORD (WRes) only;
AString Message;
FStringVector FileNames;
@@ -158,6 +165,7 @@ struct CUpdateErrorInfo
HRESULT Get_HRESULT_Error() const { return SystemError == 0 ? E_FAIL : HRESULT_FROM_WIN32(SystemError); }
void SetFromLastError(const char *message);
HRESULT SetFromLastError(const char *message, const FString &fileName);
HRESULT SetFromError_DWORD(const char *message, const FString &fileName, DWORD error);
CUpdateErrorInfo(): SystemError(0) {};
};

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
// #include <stdio.h>
#ifndef _7ZIP_ST
#include "../../../Windows/Synchronization.h"
#endif
@@ -10,6 +12,7 @@
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/Wildcard.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
@@ -54,6 +57,7 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
CommentIndex(-1),
Comment(NULL),
PreserveATime(false),
ShareForWrite(false),
StopAfterOpenError(false),
StdInMode(false),
@@ -124,7 +128,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
{
*indexInArchive = (UInt32)(Int32)-1;
if (up.ExistInArchive())
*indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;
*indexInArchive = ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex;
}
return S_OK;
COM_TRY_END
@@ -188,7 +192,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID
{
if (ParentDirItem->SecureIndex < 0)
return S_OK;
const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[ParentDirItem->SecureIndex];
const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[(unsigned)ParentDirItem->SecureIndex];
*data = buf;
*dataSize = (UInt32)buf.Size();
*propType = NPropDataType::kRaw;
@@ -220,7 +224,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (up.UseArcProps && up.ExistInArchive() && Arc->GetRawProps)
return Arc->GetRawProps->GetRawProp(
ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex,
ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex,
propID, data, dataSize, propType);
{
/*
@@ -230,8 +234,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con
if (up.IsAnti)
return S_OK;
#ifndef UNDER_CE
const CDirItem &di = DirItems->Items[up.DirIndex];
#if defined(_WIN32) && !defined(UNDER_CE)
const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex];
#endif
#ifdef _USE_SECURITY_CODE
@@ -241,18 +245,19 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con
return S_OK;
if (di.SecureIndex < 0)
return S_OK;
const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[di.SecureIndex];
const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[(unsigned)di.SecureIndex];
*data = buf;
*dataSize = (UInt32)buf.Size();
*propType = NPropDataType::kRaw;
}
else
#endif
if (propID == kpidNtReparse)
{
// propID == kpidNtReparse
if (!StoreSymLinks)
return S_OK;
#ifndef UNDER_CE
#if defined(_WIN32) && !defined(UNDER_CE)
// we use ReparseData2 instead of ReparseData for WIM format
const CByteBuffer *buf = &di.ReparseData2;
if (buf->Size() == 0)
buf = &di.ReparseData;
@@ -272,7 +277,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con
return S_OK;
}
#ifndef UNDER_CE
#if defined(_WIN32) && !defined(UNDER_CE)
static UString GetRelativePath(const UString &to, const UString &from)
{
@@ -340,22 +345,25 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
prop.Detach(value);
return S_OK;
}
#if !defined(UNDER_CE)
if (up.DirIndex >= 0)
{
#ifndef UNDER_CE
const CDirItem &di = DirItems->Items[up.DirIndex];
const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex];
#ifdef _WIN32
// if (di.IsDir())
{
CReparseAttr attr;
DWORD errorCode = 0;
if (attr.Parse(di.ReparseData, di.ReparseData.Size(), errorCode))
if (attr.Parse(di.ReparseData, di.ReparseData.Size()))
{
UString simpleName = attr.GetPath();
if (attr.IsRelative())
if (!attr.IsSymLink_WSL() && attr.IsRelative_Win())
prop = simpleName;
else
{
const FString phyPath = DirItems->GetPhyPath(up.DirIndex);
const FString phyPath = DirItems->GetPhyPath((unsigned)up.DirIndex);
FString fullPath;
if (NDir::MyGetFullPathName(phyPath, fullPath))
{
@@ -366,8 +374,26 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
return S_OK;
}
}
#endif
#else // _WIN32
if (di.ReparseData.Size() != 0)
{
AString utf;
utf.SetFrom_CalcLen((const char *)(const Byte *)di.ReparseData, (unsigned)di.ReparseData.Size());
UString us;
if (ConvertUTF8ToUnicode(utf, us))
{
prop = us;
prop.Detach(value);
return S_OK;
}
}
#endif // _WIN32
}
#endif // !defined(UNDER_CE)
}
else if (propID == kpidHardLink)
{
@@ -375,7 +401,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
{
const CKeyKeyValPair &pair = _map[_hardIndex_To];
const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value];
prop = DirItems->GetLogPath(up2.DirIndex);
prop = DirItems->GetLogPath((unsigned)up2.DirIndex);
prop.Detach(value);
return S_OK;
}
@@ -399,7 +425,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
}
}
else if (propID == kpidPath && up.NewNameIndex >= 0)
prop = (*NewNames)[up.NewNameIndex];
prop = (*NewNames)[(unsigned)up.NewNameIndex];
else if (propID == kpidComment
&& CommentIndex >= 0
&& (unsigned)CommentIndex == index
@@ -411,13 +437,13 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
}
else if ((up.UseArcProps || (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream)))
&& up.ExistInArchive() && Archive)
return Archive->GetProperty(ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, propID, value);
return Archive->GetProperty(ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex, propID, value);
else if (up.ExistOnDisk())
{
const CDirItem &di = DirItems->Items[up.DirIndex];
const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex];
switch (propID)
{
case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break;
case kpidPath: prop = DirItems->GetLogPath((unsigned)up.DirIndex); break;
case kpidIsDir: prop = di.IsDir(); break;
case kpidSize: prop = di.IsDir() ? (UInt64)0 : di.Size; break;
case kpidAttrib: prop = di.Attrib; break;
@@ -428,6 +454,16 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
#if defined(_WIN32) && !defined(UNDER_CE)
// case kpidShortName: prop = di.ShortName; break;
#endif
case kpidPosixAttrib:
{
#ifdef _WIN32
prop = di.GetPosixAttrib();
#else
if (di.Attrib & FILE_ATTRIBUTE_UNIX_EXTENSION)
prop = (UInt32)(di.Attrib >> 16);
#endif
break;
}
}
}
prop.Detach(value);
@@ -456,9 +492,9 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
{
UString name;
if (up.ArcIndex >= 0)
name = (*ArcItems)[up.ArcIndex].Name;
name = (*ArcItems)[(unsigned)up.ArcIndex].Name;
else if (up.DirIndex >= 0)
name = DirItems->GetLogPath(up.DirIndex);
name = DirItems->GetLogPath((unsigned)up.DirIndex);
RINOK(Callback->GetStream(name, isDir, true, mode));
/* 9.33: fixed. Handlers expect real stream object for files, even for anti-file.
@@ -474,7 +510,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
return S_OK;
}
RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), isDir, false, mode));
RINOK(Callback->GetStream(DirItems->GetLogPath((unsigned)up.DirIndex), isDir, false, mode));
if (isDir)
return S_OK;
@@ -491,27 +527,42 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
}
else
{
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
inStreamSpec->SupportHardLinks = StoreHardLinks;
inStreamSpec->Callback = this;
inStreamSpec->CallbackRef = index;
const FString path = DirItems->GetPhyPath(up.DirIndex);
_openFiles_Indexes.Add(index);
_openFiles_Paths.Add(path);
#if defined(_WIN32) && !defined(UNDER_CE)
if (DirItems->Items[up.DirIndex].AreReparseData())
#if !defined(UNDER_CE)
const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex];
if (di.AreReparseData())
{
/*
// we still need DeviceIoControlOut() instead of Read
if (!inStreamSpec->File.OpenReparse(path))
{
return Callback->OpenFileError(path, ::GetLastError());
}
*/
// 20.03: we use Reparse Data instead of real data
CBufInStream *inStreamSpec = new CBufInStream();
CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
inStreamSpec->Init(di.ReparseData, di.ReparseData.Size());
*inStream = inStreamLoc.Detach();
return S_OK;
}
else
#endif
#endif // !defined(UNDER_CE)
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
inStreamSpec->SupportHardLinks = StoreHardLinks;
inStreamSpec->File.PreserveATime = PreserveATime;
const FString path = DirItems->GetPhyPath((unsigned)up.DirIndex);
_openFiles_Indexes.Add(index);
_openFiles_Paths.Add(path);
/* 21.02 : we set Callback/CallbackRef after _openFiles_Indexes adding
for correct working if exception was raised in GetPhyPath */
inStreamSpec->Callback = this;
inStreamSpec->CallbackRef = index;
if (!inStreamSpec->OpenShared(path, ShareForWrite))
{
DWORD error = ::GetLastError();
@@ -522,6 +573,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
return hres;
}
// #if defined(USE_WIN_FILE) || !defined(_WIN32)
if (StoreHardLinks)
{
CStreamFileProps props;
@@ -546,6 +598,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
}
}
}
// #endif
if (ProcessedItemsStatuses)
{
@@ -592,8 +645,8 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (up.ExistOnDisk())
{
name = DirItems->GetLogPath(up.DirIndex);
isDir = DirItems->Items[up.DirIndex].IsDir();
name = DirItems->GetLogPath((unsigned)up.DirIndex);
isDir = DirItems->Items[(unsigned)up.DirIndex].IsDir();
}
}
return Callback->ReportUpdateOpeartion(op, name.IsEmpty() ? NULL : name.Ptr(), isDir);
@@ -716,7 +769,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu
COutFileStream *streamSpec = new COutFileStream;
CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
if (!streamSpec->Create(fileName, false))
return ::GetLastError();
return GetLastError_noZero_HRESULT();
*volumeStream = streamLoc.Detach();
return S_OK;
COM_TRY_END
@@ -738,7 +791,10 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error)
{
if (error == ERROR_LOCK_VIOLATION)
#ifdef _WIN32 // FIX IT !!!
// why did we check only for ERROR_LOCK_VIOLATION ?
// if (error == ERROR_LOCK_VIOLATION)
#endif
{
MT_LOCK
UInt32 index = (UInt32)val;
@@ -756,6 +812,7 @@ HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error)
void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val)
{
{
MT_LOCK
UInt32 index = (UInt32)val;
FOR_VECTOR(i, _openFiles_Indexes)
@@ -767,5 +824,11 @@ void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val)
return;
}
}
throw 20141125;
}
/* 21.02 : this function can be called in destructor.
And destructor can be called after some exception.
If we don't want to throw exception in desctructors or after another exceptions,
we must disable the code below that raises new exception.
*/
// throw 20141125;
}

View File

@@ -135,6 +135,7 @@ public:
int CommentIndex;
const UString *Comment;
bool PreserveATime;
bool ShareForWrite;
bool StopAfterOpenError;
bool StdInMode;
@@ -152,9 +153,9 @@ public:
bool IsDir(const CUpdatePair2 &up) const
{
if (up.DirIndex >= 0)
return DirItems->Items[up.DirIndex].IsDir();
return DirItems->Items[(unsigned)up.DirIndex].IsDir();
else if (up.ArcIndex >= 0)
return (*ArcItems)[up.ArcIndex].IsDir;
return (*ArcItems)[(unsigned)up.ArcIndex].IsDir;
return false;
}
};

View File

@@ -42,7 +42,9 @@ static const char * const k_Duplicate_inArc_Message = "Duplicate filename in arc
static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:";
static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
static void ThrowError(const char *message, const UString &s1, const UString &s2)
MY_ATTR_NORETURN
static
void ThrowError(const char *message, const UString &s1, const UString &s2)
{
UString m (message);
m.Add_LF(); m += s1;
@@ -144,18 +146,18 @@ void GetUpdatePairInfoList(
if (dirIndex < numDirItems)
{
dirIndex2 = dirIndices[dirIndex];
di = &dirItems.Items[dirIndex2];
dirIndex2 = (int)dirIndices[dirIndex];
di = &dirItems.Items[(unsigned)dirIndex2];
}
if (arcIndex < numArcItems)
{
arcIndex2 = arcIndices[arcIndex];
ai = &arcItems[arcIndex2];
arcIndex2 = (int)arcIndices[arcIndex];
ai = &arcItems[(unsigned)arcIndex2];
compareResult = 1;
if (dirIndex < numDirItems)
{
compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name);
compareResult = CompareFileNames(dirNames[(unsigned)dirIndex2], ai->Name);
if (compareResult == 0)
{
if (di->IsDir() != ai->IsDir)
@@ -166,7 +168,7 @@ void GetUpdatePairInfoList(
if (compareResult < 0)
{
name = &dirNames[dirIndex2];
name = &dirNames[(unsigned)dirIndex2];
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
pair.DirIndex = dirIndex2;
dirIndex++;
@@ -184,9 +186,9 @@ void GetUpdatePairInfoList(
{
int dupl = duplicatedArcItem[arcIndex];
if (dupl != 0)
ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name);
ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[(unsigned)((int)arcIndex + dupl)]].Name);
name = &dirNames[dirIndex2];
name = &dirNames[(unsigned)dirIndex2];
if (!ai->Censored)
ThrowError(k_NotCensoredCollision_Message, *name, ai->Name);
@@ -222,7 +224,7 @@ void GetUpdatePairInfoList(
}
else
{
prevHostFile = updatePairs.Size();
prevHostFile = (int)updatePairs.Size();
prevHostName = name;
}

View File

@@ -28,7 +28,7 @@ void UpdateProduce(
{
case NPairAction::kIgnore:
if (pair.ArcIndex >= 0 && callback)
callback->ShowDeleteFile(pair.ArcIndex);
callback->ShowDeleteFile((unsigned)pair.ArcIndex);
continue;
case NPairAction::kCopy:
@@ -43,7 +43,7 @@ void UpdateProduce(
1) no such alt stream in Disk
2) there is Host file in disk
*/
if (updatePairs[pair.HostIndex].DirIndex >= 0)
if (updatePairs[(unsigned)pair.HostIndex].DirIndex >= 0)
continue;
}
}

View File

@@ -18,12 +18,12 @@ struct CUpdatePair2
bool IsMainRenameItem;
void SetAs_NoChangeArcItem(int arcIndex)
void SetAs_NoChangeArcItem(unsigned arcIndex) // int
{
NewData = NewProps = false;
UseArcProps = true;
IsAnti = false;
ArcIndex = arcIndex;
ArcIndex = (int)arcIndex;
}
bool ExistOnDisk() const { return DirIndex != -1; }

View File

@@ -5,6 +5,7 @@
#include "../../../Common/StringConvert.h"
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileName.h"
#include "WorkDir.h"
@@ -39,13 +40,13 @@ FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FStr
#endif
int pos = path.ReverseFind_PathSepar() + 1;
fileName = path.Ptr(pos);
fileName = path.Ptr((unsigned)pos);
switch (mode)
{
case NWorkDir::NMode::kCurrent:
{
return path.Left(pos);
return path.Left((unsigned)pos);
}
case NWorkDir::NMode::kSpecified:
{
@@ -75,8 +76,7 @@ HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath)
OutStream = _outStreamSpec;
if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File))
{
DWORD error = GetLastError();
return error ? error : E_FAIL;
return GetLastError_noZero_HRESULT();
}
_originalPath = originalPath;
return S_OK;
@@ -87,8 +87,7 @@ HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal)
OutStream.Release();
if (!_tempFile.MoveTo(_originalPath, deleteOriginal))
{
DWORD error = GetLastError();
return error ? error : E_FAIL;
return GetLastError_noZero_HRESULT();
}
return S_OK;
}