mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 18:07:08 -06:00
Update to 7-Zip Version 21.02
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -79,11 +79,12 @@ static HRESULT Call7zGui(const UString ¶ms,
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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'~';
|
||||
|
||||
@@ -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;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,10 +53,10 @@ struct CExtractOptions: public CExtractOptionsBase
|
||||
#endif
|
||||
|
||||
CExtractOptions():
|
||||
TestMode(false),
|
||||
StdInMode(false),
|
||||
StdOutMode(false),
|
||||
YesToAll(false)
|
||||
YesToAll(false),
|
||||
TestMode(false)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {};
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user