This commit is contained in:
Igor Pavlov
2021-07-22 23:00:14 +01:00
committed by Kornel
parent 4a960640a3
commit 585698650f
619 changed files with 34904 additions and 10859 deletions

View File

@@ -27,8 +27,10 @@ CCodecs *g_CodecsObj;
#ifdef EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
CCodecs::CReleaser g_CodecsReleaser;
static CCodecs::CReleaser g_CodecsReleaser;
#else
extern
CMyComPtr<IUnknown> g_CodecsRef;
CMyComPtr<IUnknown> g_CodecsRef;
#endif
@@ -1245,7 +1247,7 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
// case kpidName: prop = dir.Name; break;
// case kpidPath: prop = _proxy2->GetFullPathPrefix(_proxyDirIndex); break;
case kpidType: prop = UString("7-Zip.") + _agentSpec->ArchiveType; break;
case kpidCRC: if (dir.CrcIsDefined) prop = dir.Crc; break;
case kpidCRC: if (dir.CrcIsDefined) { prop = dir.Crc; } break;
}
}
@@ -1533,8 +1535,8 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
CAgent::CAgent():
_proxy(NULL),
_proxy2(NULL),
_isDeviceFile(false),
_updatePathPrefix_is_AltFolder(false)
_updatePathPrefix_is_AltFolder(false),
_isDeviceFile(false)
{
}
@@ -1611,24 +1613,30 @@ STDMETHODIMP CAgent::Open(
options.filePath = _archiveFilePath;
options.callback = openArchiveCallback;
RINOK(_archiveLink.Open(options));
HRESULT res = _archiveLink.Open(options);
CArc &arc = _archiveLink.Arcs.Back();
if (!inStream)
if (!_archiveLink.Arcs.IsEmpty())
{
arc.MTimeDefined = !fi.IsDevice;
arc.MTime = fi.MTime;
CArc &arc = _archiveLink.Arcs.Back();
if (!inStream)
{
arc.MTimeDefined = !fi.IsDevice;
arc.MTime = fi.MTime;
}
ArchiveType = GetTypeOfArc(arc);
if (archiveType)
{
RINOK(StringToBstr(ArchiveType, archiveType));
}
}
ArchiveType = GetTypeOfArc(arc);
if (archiveType)
{
RINOK(StringToBstr(ArchiveType, archiveType));
}
return S_OK;
return res;
COM_TRY_END
}
STDMETHODIMP CAgent::ReOpen(IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
@@ -1717,7 +1725,10 @@ HRESULT CAgent::ReadItems()
STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder)
{
COM_TRY_BEGIN
RINOK(ReadItems());
if (!_archiveLink.Arcs.IsEmpty())
{
RINOK(ReadItems());
}
CAgentFolder *folderSpec = new CAgentFolder;
CMyComPtr<IFolderFolder> rootFolder = folderSpec;
folderSpec->Init(_proxy, _proxy2, k_Proxy_RootDirIndex, /* NULL, */ this);
@@ -1813,6 +1824,20 @@ STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)
if (_archiveLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
prop = g_CodecsObj->Formats[_archiveLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name;
break;
case kpidErrorFlags:
{
UInt32 flags = _archiveLink.NonOpen_ErrorInfo.GetErrorFlags();
if (flags != 0)
prop = flags;
break;
}
case kpidWarningFlags:
{
UInt32 flags = _archiveLink.NonOpen_ErrorInfo.GetWarningFlags();
if (flags != 0)
prop = flags;
break;
}
}
}
else
@@ -1822,7 +1847,10 @@ STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)
{
case kpidType: prop = GetTypeOfArc(arc); break;
case kpidPath: prop = arc.Path; break;
case kpidErrorType: if (arc.ErrorInfo.ErrorFormatIndex >= 0) prop = g_CodecsObj->Formats[arc.ErrorInfo.ErrorFormatIndex].Name; break;
case kpidErrorType:
if (arc.ErrorInfo.ErrorFormatIndex >= 0)
prop = g_CodecsObj->Formats[arc.ErrorInfo.ErrorFormatIndex].Name;
break;
case kpidErrorFlags:
{
UInt32 flags = arc.ErrorInfo.GetErrorFlags();

View File

@@ -292,7 +292,7 @@ public:
s2 += "Warning: The archive is open with offset";
else
{
s2 += "Can not open the file as [";
s2 += "Cannot open the file as [";
s2 += g_CodecsObj->GetFormatNamePtr(arc.ErrorInfo.ErrorFormatIndex);
s2 += "] archive";
}

View File

@@ -166,7 +166,7 @@ struct CDirItemsCallback_AgentOut: public IDirItemsCallback
IFolderArchiveUpdateCallback *FolderArchiveUpdateCallback;
HRESULT ErrorCode;
CDirItemsCallback_AgentOut(): ErrorCode(S_OK), FolderArchiveUpdateCallback(NULL) {}
CDirItemsCallback_AgentOut(): FolderArchiveUpdateCallback(NULL), ErrorCode(S_OK) {}
HRESULT ScanError(const FString &name, DWORD systemError)
{

View File

@@ -51,6 +51,18 @@ int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name) const
return FindSubDir(dirIndex, name, insertPos);
}
static const wchar_t *AllocStringAndCopy(const wchar_t *s, size_t len)
{
wchar_t *p = new wchar_t[len + 1];
MyStringCopy(p, s);
return p;
}
static const wchar_t *AllocStringAndCopy(const UString &s)
{
return AllocStringAndCopy(s, s.Len());
}
unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name)
{
unsigned insertPos;
@@ -70,8 +82,7 @@ unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name)
CProxyDir &item = Dirs.AddNew();
item.NameLen = name.Len();
item.Name = new wchar_t[item.NameLen + 1];
MyStringCopy((wchar_t *)item.Name, name);
item.Name = AllocStringAndCopy(name);
item.ArcIndex = arcIndex;
item.ParentDir = dirIndex;
@@ -248,6 +259,10 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
unsigned len = 0;
bool isPtrName = false;
#if WCHAR_PATH_SEPARATOR != L'/'
wchar_t replaceFromChar = 0;
#endif
#if defined(MY_CPU_LE) && defined(_WIN32)
// it works only if (sizeof(wchar_t) == 2)
if (arc.GetRawProps)
@@ -263,6 +278,9 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
len = size / 2 - 1;
s = (const wchar_t *)p;
isPtrName = true;
#if WCHAR_PATH_SEPARATOR != L'/'
replaceFromChar = L'\\';
#endif
}
}
if (!s)
@@ -309,9 +327,17 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
for (unsigned j = 0; j < len; j++)
{
wchar_t c = s[j];
const wchar_t c = s[j];
if (c == WCHAR_PATH_SEPARATOR || c == L'/')
{
#if WCHAR_PATH_SEPARATOR != L'/'
if (c == replaceFromChar)
{
// s.ReplaceOneCharAtPos(j, WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT);
continue;
}
#endif
const unsigned kLevelLimit = 1 << 10;
if (numLevels <= kLevelLimit)
{
@@ -351,9 +377,8 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
f.Name = s;
else
{
f.Name = new wchar_t[f.NameLen + 1];
f.Name = AllocStringAndCopy(s, f.NameLen);
f.NeedDeleteName = true;
MyStringCopy((wchar_t *)f.Name, s);
}
if (isDir)
@@ -382,15 +407,15 @@ void CProxyArc2::GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &i
isAltStreamDir = false;
if (dirIndex == k_Proxy2_RootDirIndex)
if (dirIndex == (int)k_Proxy2_RootDirIndex)
return;
if (dirIndex == k_Proxy2_AltRootDirIndex)
if (dirIndex == (int)k_Proxy2_AltRootDirIndex)
{
isAltStreamDir = true;
return;
}
while (dirIndex >= k_Proxy2_NumRootDirs)
while (dirIndex >= (int)k_Proxy2_NumRootDirs)
{
const CProxyDir2 &dir = Dirs[dirIndex];
const CProxyFile2 &file = Files[dir.ArcIndex];
@@ -608,9 +633,8 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
tempAString = (const char *)p;
ConvertUTF8ToUnicode(tempAString, tempUString);
file.NameLen = tempUString.Len();
file.Name = new wchar_t[file.NameLen + 1];
file.Name = AllocStringAndCopy(tempUString);
file.NeedDeleteName = true;
wmemcpy((wchar_t *)file.Name, tempUString.Ptr(), file.NameLen + 1);
}
else
{
@@ -624,9 +648,8 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
else
return E_FAIL;
file.NameLen = MyStringLen(s);
file.Name = new wchar_t[file.NameLen + 1];
file.Name = AllocStringAndCopy(s, file.NameLen);
file.NeedDeleteName = true;
wmemcpy((wchar_t *)file.Name, s, file.NameLen + 1);
}
UInt32 parent = (UInt32)(Int32)-1;

View File

@@ -12,7 +12,7 @@ struct CProxyFile
bool NeedDeleteName;
CProxyFile(): Name(NULL), NameLen(0), NeedDeleteName(false) {}
~CProxyFile() { if (NeedDeleteName) delete [](wchar_t *)Name; }
~CProxyFile() { if (NeedDeleteName) delete [](wchar_t *)(void *)Name; } // delete [](wchar_t *)Name;
};
const unsigned k_Proxy_RootDirIndex = 0;
@@ -35,7 +35,7 @@ struct CProxyDir
bool CrcIsDefined;
CProxyDir(): Name(NULL), NameLen(0), ParentDir(-1) {};
~CProxyDir() { delete [](wchar_t *)Name; }
~CProxyDir() { delete [](wchar_t *)(void *)Name; }
void Clear();
bool IsLeaf() const { return ArcIndex >= 0; }
@@ -93,7 +93,7 @@ struct CProxyFile2
~CProxyFile2()
{
if (NeedDeleteName)
delete [](wchar_t *)Name;
delete [](wchar_t *)(void *)Name;
}
};

View File

@@ -31,8 +31,21 @@ STDMETHODIMP CArchiveFolderManager::OpenFolderFile(IInStream *inStream,
}
CAgent *agent = new CAgent();
CMyComPtr<IInFolderArchive> archive = agent;
RINOK(agent->Open(inStream, filePath, arcFormat, NULL, openArchiveCallback));
return agent->BindToRootFolder(resultFolder);
HRESULT res = agent->Open(inStream, filePath, arcFormat, NULL, openArchiveCallback);
if (res != S_OK)
{
if (res != S_FALSE)
return res;
/* 20.01: we create folder even for Non-Open cases, if there is NonOpen_ErrorInfo information.
So we can get error information from that IFolderFolder later. */
if (!agent->_archiveLink.NonOpen_ErrorInfo.IsThereErrorOrWarning())
return res;
}
RINOK(agent->BindToRootFolder(resultFolder));
return res;
}
/*

View File

@@ -27,30 +27,41 @@ void CAgentFolder::GetPathParts(UStringVector &pathParts, bool &isAltStreamFolde
_proxy->GetDirPathParts(_proxyDirIndex, pathParts);
}
static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
static bool Delete_EmptyFolder_And_EmptySubFolders(const FString &path)
{
NFind::CFileInfo fileInfo;
FString pathPrefix = path;
pathPrefix.Add_PathSepar();
{
NFind::CEnumerator enumerator;
enumerator.SetDirPrefix(pathPrefix);
while (enumerator.Next(fileInfo))
const FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
CObjectVector<FString> names;
{
if (fileInfo.IsDir())
if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name))
NFind::CDirEntry fileInfo;
NFind::CEnumerator enumerator;
enumerator.SetDirPrefix(pathPrefix);
for (;;)
{
bool found;
if (!enumerator.Next(fileInfo, found))
return false;
if (!found)
break;
if (fileInfo.IsDir())
names.Add(fileInfo.Name);
}
}
bool res = true;
FOR_VECTOR (i, names)
{
if (!Delete_EmptyFolder_And_EmptySubFolders(pathPrefix + names[i]))
res = false;
}
if (!res)
return false;
}
/*
// we don't need clear readonly for folders
// we clear read-only attrib to remove read-only dir
if (!SetFileAttrib(path, 0))
return false;
*/
return RemoveDir(path);
}
HRESULT CAgentFolder::CommonUpdateOperation(
AGENT_OP operation,
bool moveMode,
@@ -123,7 +134,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
case AGENT_OP_Uni:
{
Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
for (unsigned i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
actionSetByte[i] = (Byte)actionSet->StateActions[i];
result = _agentSpec->DoOperation2(
moveMode ? &requestedPaths : NULL,
@@ -162,7 +173,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
{
const FString &fs = requestedPaths[i];
if (NFind::DoesDirExist(fs))
DeleteEmptyFolderAndEmptySubFolders(fs);
Delete_EmptyFolder_And_EmptySubFolders(fs);
}
}
}

View File

@@ -28,10 +28,12 @@
#include "../../../../C/7zVersion.h"
#ifdef _WIN32
extern
HINSTANCE g_hInstance;
HINSTANCE g_hInstance = 0;
#endif
// Tou can find the list of all GUIDs in Guid.txt file.
// You can find the list of all GUIDs in Guid.txt file.
// use another CLSIDs, if you want to support other formats (zip, rar, ...).
// {23170F69-40C1-278A-1000-000110070000}
@@ -47,7 +49,11 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
#ifdef _WIN32
#define kDllName "7z.dll"
#else
#define kDllName "7z.so"
#endif
static const char * const kCopyrightString =
"\n"
@@ -383,7 +389,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
{
if (!DeleteFileAlways(fullProcessedPath))
{
PrintError("Can not delete output file", fullProcessedPath);
PrintError("Cannot delete output file", fullProcessedPath);
return E_ABORT;
}
}
@@ -392,7 +398,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))
{
PrintError("Can not open output file", fullProcessedPath);
PrintError("Cannot open output file", fullProcessedPath);
return E_ABORT;
}
_outFileStream = outStreamLoc;
@@ -556,7 +562,11 @@ public:
FStringVector FailedFiles;
CRecordVector<HRESULT> FailedCodes;
CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};
CArchiveUpdateCallback():
DirItems(NULL),
PasswordIsDefined(false),
AskPassword(false)
{}
~CArchiveUpdateCallback() { Finilize(); }
HRESULT Finilize();
@@ -726,12 +736,18 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDef
// Main function
#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
#endif
int MY_CDECL main(int numArgs, const char *args[])
{
NT_CHECK
#ifdef ENV_HAVE_LOCALE
MY_SetLocale();
#endif
PrintStringLn(kCopyrightString);
if (numArgs < 2)
@@ -740,55 +756,96 @@ int MY_CDECL main(int numArgs, const char *args[])
return 0;
}
if (numArgs < 3)
{
PrintError(kIncorrectCommand);
return 1;
}
FString dllPrefix;
NDLL::CLibrary lib;
if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName)))
#ifdef _WIN32
dllPrefix = NDLL::GetModuleDirPrefix();
#else
{
PrintError("Can not load 7-zip library");
AString s (args[0]);
int sep = s.ReverseFind_PathSepar();
s.DeleteFrom(sep + 1);
dllPrefix = s;
}
#endif
NDLL::CLibrary lib;
if (!lib.Load(dllPrefix + FTEXT(kDllName)))
{
PrintError("Cannot load 7-zip library");
return 1;
}
Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject");
if (!createObjectFunc)
{
PrintError("Can not get CreateObject");
PrintError("Cannot get CreateObject");
return 1;
}
char c;
char c = 0;
UString password;
bool passwordIsDefined = false;
CObjectVector<FString> params;
for (int curCmd = 1; curCmd < numArgs; curCmd++)
{
AString command (args[1]);
if (command.Len() != 1)
AString a(args[curCmd]);
if (!a.IsEmpty())
{
if (a[0] == '-')
{
if (!passwordIsDefined && a[1] == 'p')
{
password = GetUnicodeString(a.Ptr(2));
passwordIsDefined = true;
continue;
}
}
else
{
if (c)
{
params.Add(CmdStringToFString(a));
continue;
}
if (a.Len() == 1)
{
c = (char)MyCharLower_Ascii(a[0]);
continue;
}
}
}
{
PrintError(kIncorrectCommand);
return 1;
}
c = (char)MyCharLower_Ascii(command[0]);
}
FString archiveName = CmdStringToFString(args[2]);
if (!c || params.Size() < 1)
{
PrintError(kIncorrectCommand);
return 1;
}
const FString &archiveName = params[0];
if (c == 'a')
{
// create archive command
if (numArgs < 4)
if (params.Size() < 2)
{
PrintError(kIncorrectCommand);
return 1;
}
CObjectVector<CDirItem> dirItems;
{
int i;
for (i = 3; i < numArgs; i++)
unsigned i;
for (i = 1; i < params.Size(); i++)
{
CDirItem di;
FString name = CmdStringToFString(args[i]);
const FString &name = params[i];
NFind::CFileInfo fi;
if (!fi.Find(name))
@@ -819,15 +876,15 @@ int MY_CDECL main(int numArgs, const char *args[])
CMyComPtr<IOutArchive> outArchive;
if (createObjectFunc(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK)
{
PrintError("Can not get class object");
PrintError("Cannot get class object");
return 1;
}
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
updateCallbackSpec->Init(&dirItems);
// updateCallbackSpec->PasswordIsDefined = true;
// updateCallbackSpec->Password = L"1";
updateCallbackSpec->PasswordIsDefined = passwordIsDefined;
updateCallbackSpec->Password = password;
/*
{
@@ -874,7 +931,7 @@ int MY_CDECL main(int numArgs, const char *args[])
}
else
{
if (numArgs != 3)
if (params.Size() != 1)
{
PrintError(kIncorrectCommand);
return 1;
@@ -895,7 +952,7 @@ int MY_CDECL main(int numArgs, const char *args[])
CMyComPtr<IInArchive> archive;
if (createObjectFunc(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK)
{
PrintError("Can not get class object");
PrintError("Cannot get class object");
return 1;
}
@@ -904,21 +961,20 @@ int MY_CDECL main(int numArgs, const char *args[])
if (!fileSpec->Open(archiveName))
{
PrintError("Can not open archive file", archiveName);
PrintError("Cannot open archive file", archiveName);
return 1;
}
{
CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;
CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
openCallbackSpec->PasswordIsDefined = false;
// openCallbackSpec->PasswordIsDefined = true;
// openCallbackSpec->Password = L"1";
openCallbackSpec->PasswordIsDefined = passwordIsDefined;
openCallbackSpec->Password = password;
const UInt64 scanSize = 1 << 23;
if (archive->Open(file, &scanSize, openCallback) != S_OK)
{
PrintError("Can not open file as archive", archiveName);
PrintError("Cannot open file as archive", archiveName);
return 1;
}
}
@@ -957,9 +1013,8 @@ int MY_CDECL main(int numArgs, const char *args[])
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
extractCallbackSpec->Init(archive, FString()); // second parameter is output folder path
extractCallbackSpec->PasswordIsDefined = false;
// extractCallbackSpec->PasswordIsDefined = true;
// extractCallbackSpec->Password = "1";
extractCallbackSpec->PasswordIsDefined = passwordIsDefined;
extractCallbackSpec->Password = password;
/*
const wchar_t *names[] =

View File

@@ -8,9 +8,9 @@ COMMON_OBJS = \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \
$O\MyVector.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\MyVector.obj \
$O\Wildcard.obj \
WIN_OBJS = \

View File

@@ -0,0 +1,59 @@
PROG = 7zcl
IS_NOT_STANDALONE = 1
# IS_X64 = 1
ifdef SystemDrive
SYS_OBJS = \
$O/resource.o \
else
SYS_OBJS = \
$O/MyWindows.o \
$O/TimeUtils.o \
endif
LOCAL_FLAGS = \
CURRENT_OBJS = \
$O/Client7z.o \
COMMON_OBJS = \
$O/IntToString.o \
$O/MyString.o \
$O/MyVector.o \
$O/NewHandler.o \
$O/StringConvert.o \
$O/StringToInt.o \
$O/UTFConvert.o \
$O/Wildcard.o \
WIN_OBJS = \
$O/DLL.o \
$O/FileDir.o \
$O/FileFind.o \
$O/FileIO.o \
$O/FileName.o \
$O/PropVariant.o \
$O/PropVariantConv.o \
7ZIP_COMMON_OBJS = \
$O/FileStreams.o \
OBJS = \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(SYS_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(CURRENT_OBJS) \
include ../../7zip_gcc.mak

View File

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

View File

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

View File

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -76,11 +76,12 @@ static HRESULT Call7zGui(const UString &params,
imageName += k7zGui;
CProcess process;
WRes res = process.Create(imageName, params, NULL); // curDir);
if (res != 0)
const WRes wres = process.Create(imageName, params, NULL); // curDir);
if (wres != 0)
{
ErrorMessageHRESULT(res, imageName);
return res;
HRESULT hres = HRESULT_FROM_WIN32(wres);
ErrorMessageHRESULT(hres, imageName);
return hres;
}
if (waitFinish)
process.Wait();
@@ -130,12 +131,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();
}
@@ -143,11 +143,11 @@ static HRESULT CreateMap(const UStringVector &names,
for (;;)
{
random.GenerateName(eventName, "7zEvent");
WRes res = event.CreateWithName(false, GetSystemString(eventName));
if (event.IsCreated() && res == 0)
const WRes wres = event.CreateWithName(false, GetSystemString(eventName));
if (event.IsCreated() && wres == 0)
break;
if (res != ERROR_ALREADY_EXISTS)
return res;
if (wres != ERROR_ALREADY_EXISTS)
return HRESULT_FROM_WIN32(wres);
event.Close();
}

View File

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

View File

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

View File

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

View File

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -14,6 +14,7 @@
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
@@ -32,11 +33,13 @@
#include "SetProperties.h"
#endif
#ifndef _SFX
#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#define PRF(x)
#endif
#endif
// increase it, if you need to support larger SFX stubs
static const UInt64 kMaxCheckStartPosition = 1 << 23;
@@ -64,7 +67,7 @@ Open:
- open FAIL:
Try to open with all other types from offset 0 only.
If some open type is OK and physical archive size is uequal or larger
than file size, then return that archive with warning that can not be open as [extension type].
than file size, then return that archive with warning that cannot be open as [extension type].
If extension was EXE, it will try to open as unknown_extension case
- file has unknown extension (like a.hhh)
It tries to open via parser code.
@@ -141,14 +144,14 @@ struct CParseItem
bool LenIsUnknown;
CParseItem():
LenIsUnknown(false),
// OkSize(0),
FileTime_Defined(false),
UnpackSize_Defined(false),
NumSubFiles_Defined(false),
NumSubDirs_Defined(false),
NumSubFiles_Defined(false),
IsSelfExe(false),
IsNotArcType(false)
// OkSize(0)
IsNotArcType(false),
LenIsUnknown(false)
{}
/*
@@ -214,15 +217,17 @@ int CHandler::FindInsertPos(const CParseItem &item) const
left = mid + 1;
else if (item.Size < midItem.Size)
right = mid;
/*
else if (item.Size > midItem.Size)
left = mid + 1;
*/
else
{
left = mid + 1;
// return -1;
}
}
return left;
return (int)left;
}
void CHandler::AddUnknownItem(UInt64 next)
@@ -260,7 +265,7 @@ void CHandler::AddItem(const CParseItem &item)
int pos = FindInsertPos(item);
if (pos >= 0)
{
_items.Insert(pos, item);
_items.Insert((unsigned)pos, item);
UInt64 next = item.Offset + item.Size;
if (_maxEndOffset < next)
_maxEndOffset = next;
@@ -401,7 +406,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i];
UInt32 index = allFilesMode ? i : indices[i];
const CParseItem &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -417,7 +422,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
outStreamSpec->Init(skipMode ? 0 : unpackSize, true);
Int32 opRes = NExtract::NOperationResult::kOK;
RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL));
RINOK(_stream->Seek((Int64)item.Offset, STREAM_SEEK_SET, NULL));
streamSpec->Init(unpackSize);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
@@ -496,13 +501,14 @@ static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &r
RINOK(arc->GetArchiveProperty(propid, &prop));
switch (prop.vt)
{
case VT_UI4: result = prop.ulVal; defined = true; break;
case VT_I4: result = (Int64)prop.lVal; defined = true; break;
case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break;
case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break;
case VT_EMPTY: break;
case VT_UI4: result = prop.ulVal; break;
case VT_I4: result = (UInt64)(Int64)prop.lVal; break;
case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; break;
case VT_I8: result = (UInt64)prop.hVal.QuadPart; break;
case VT_EMPTY: return S_OK;
default: return E_FAIL;
}
defined = true;
return S_OK;
}
@@ -513,13 +519,14 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res
RINOK(arc->GetArchiveProperty(propid, &prop));
switch (prop.vt)
{
case VT_UI4: result = prop.ulVal; defined = true; break;
case VT_I4: result = prop.lVal; defined = true; break;
case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break;
case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break;
case VT_EMPTY: break;
case VT_UI4: result = prop.ulVal; break;
case VT_I4: result = prop.lVal; break;
case VT_UI8: result = (Int64)prop.uhVal.QuadPart; break;
case VT_I8: result = (Int64)prop.hVal.QuadPart; break;
case VT_EMPTY: return S_OK;
default: return E_FAIL;
}
defined = true;
return S_OK;
}
@@ -607,6 +614,8 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
#endif
HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
{
#ifdef MY_CPU_LE
@@ -621,19 +630,42 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
propType == NPropDataType::kUtf16z)
{
unsigned len = size / 2 - 1;
// (len) doesn't include null terminator
/*
#if WCHAR_MAX > 0xffff
len = (unsigned)Utf16LE__Get_Num_WCHARs(p, len);
wchar_t *s = result.GetBuf(len);
wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, len, s);
if (s + len != sEnd) return E_FAIL;
*sEnd = 0;
#else
*/
wchar_t *s = result.GetBuf(len);
for (unsigned i = 0; i < len; i++)
{
wchar_t c = GetUi16(p);
p = (const void *)((const Byte *)p + 2);
#if WCHAR_PATH_SEPARATOR != L'/'
if (c == L'/')
c = WCHAR_PATH_SEPARATOR;
else if (c == L'\\')
c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
#endif
*s++ = c;
}
*s = 0;
// #endif
result.ReleaseBuf_SetLen(len);
Convert_UnicodeEsc16_To_UnicodeEscHigh(result);
if (len != 0)
return S_OK;
}
@@ -721,6 +753,8 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
if (result.IsEmpty())
return GetDefaultItemPath(index, result);
Convert_UnicodeEsc16_To_UnicodeEscHigh(result);
return S_OK;
}
@@ -772,7 +806,7 @@ int FindAltStreamColon_in_Path(const wchar_t *path)
if (c == ':')
{
if (colonPos < 0)
colonPos = i;
colonPos = (int)i;
continue;
}
if (c == WCHAR_PATH_SEPARATOR)
@@ -865,8 +899,8 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
int colon = FindAltStreamColon_in_Path(item.Path);
if (colon >= 0)
{
item.MainPath.DeleteFrom(colon);
item.AltStreamName = item.Path.Ptr(colon + 1);
item.MainPath.DeleteFrom((unsigned)colon);
item.AltStreamName = item.Path.Ptr((unsigned)(colon + 1));
item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1]));
item.IsAltStream = true;
}
@@ -877,7 +911,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
#ifndef _SFX
if (item._use_baseParentFolder_mode)
{
RINOK(GetItemPathToParent(mainIndex, item._baseParentFolder, item.PathParts));
RINOK(GetItemPathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts));
#ifdef SUPPORT_ALT_STREAMS
if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty())
@@ -888,10 +922,10 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
colon = FindAltStreamColon_in_Path(s);
if (colon >= 0)
{
item.AltStreamName = s.Ptr(colon + 1);
item.AltStreamName = s.Ptr((unsigned)(colon + 1));
item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1]));
item.IsAltStream = true;
s.DeleteFrom(colon);
s.DeleteFrom((unsigned)colon);
}
}
if (colon == 0)
@@ -1007,9 +1041,9 @@ static void MakeCheckOrder(CCodecs *codecs,
FOR_VECTOR (k, sigs)
{
const CByteBuffer &sig = sigs[k];
if (sig.Size() == 0 && dataSize == 0 ||
sig.Size() != 0 && sig.Size() <= dataSize &&
TestSignature(data, sig, sig.Size()))
if ((sig.Size() == 0 && dataSize == 0)
|| (sig.Size() != 0 && sig.Size() <= dataSize
&& TestSignature(data, sig, sig.Size())))
{
orderIndices2.Add(index);
orderIndices[i] = -1;
@@ -1019,8 +1053,6 @@ static void MakeCheckOrder(CCodecs *codecs,
}
}
#endif
#ifdef UNDER_CE
static const unsigned kNumHashBytes = 1;
#define HASH_VAL(buf) ((buf)[0])
@@ -1030,9 +1062,6 @@ static void MakeCheckOrder(CCodecs *codecs,
#define HASH_VAL(buf) GetUi16(buf)
#endif
#ifndef _SFX
static bool IsExeExt(const UString &ext)
{
return ext.IsEqualTo_Ascii_NoCase("exe");
@@ -1243,11 +1272,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;
@@ -1263,11 +1292,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);
}
*/
@@ -1286,7 +1316,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;
@@ -1437,7 +1467,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];
@@ -1463,6 +1493,8 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset)
}
}
#ifndef _SFX
class CExtractCallback_To_OpenCallback:
@@ -1510,7 +1542,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;
}
@@ -1524,6 +1556,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,
@@ -1547,22 +1580,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;
}
@@ -1590,7 +1633,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;
@@ -1615,13 +1658,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;
@@ -1658,10 +1706,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
isNumber = true;
}
if (isNumber)
{
if (c == 'z' || c == 'Z')
isZip = true;
else
isRar = true;
}
}
#endif
@@ -1673,7 +1723,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
@@ -1683,17 +1733,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);
}
}
@@ -1739,8 +1789,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++;
}
@@ -1785,10 +1835,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;
}
}
@@ -1842,12 +1892,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)
{
@@ -1871,7 +1923,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
CMyComPtr<IInArchive> archive;
RINOK(PrepareToOpen(op, FormatIndex, archive));
RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive));
if (!archive)
continue;
@@ -1948,7 +2000,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;
}
@@ -2063,16 +2115,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);
@@ -2118,12 +2176,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));
@@ -2131,7 +2189,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;
@@ -2144,7 +2202,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)
@@ -2166,7 +2227,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
NArchive::NParser::CParseItem pi;
pi.Offset = Offset;
pi.Offset = (UInt64)Offset;
pi.Size = AvailPhySize;
// bool needScan = false;
@@ -2203,7 +2264,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;
}
@@ -2299,6 +2360,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)
@@ -2329,7 +2392,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
if (isDifficult)
{
difficultFormats.Add(index);
difficultFormats.Add((unsigned)index);
difficultBools[(unsigned)index] = true;
}
}
@@ -2398,7 +2461,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)
@@ -2471,7 +2534,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 -
@@ -2502,7 +2565,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;
@@ -2599,13 +2662,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;
@@ -2615,14 +2674,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
{
@@ -2642,20 +2701,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;
@@ -2667,6 +2729,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 "));
@@ -2680,9 +2748,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;
@@ -2714,7 +2783,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;
@@ -2786,7 +2855,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;
}
@@ -2794,10 +2863,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (pi.Offset != 0)
{
if (!pi.IsNotArcType)
{
if (thereIsTail)
openCur = specFlags.CanReturnMid;
else
openCur = specFlags.CanReturnTail;
}
}
else
{
@@ -2805,11 +2876,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;
@@ -2836,7 +2907,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
{
InStream = op.stream;
Archive = archive;
FormatIndex = index;
FormatIndex = (int)index;
ArcStreamOffset = arcStreamOffset;
return S_OK;
}
@@ -2850,7 +2921,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
*/
pi.FormatIndex = index;
pi.FormatIndex = (int)index;
// printf("\nAdd offset = %d", (int)pi.Offset);
handlerSpec->AddItem(pi);
@@ -2905,6 +2976,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
return S_OK;
}
HRESULT CArc::OpenStream(const COpenOptions &op)
{
RINOK(OpenStream2(op));
@@ -2929,13 +3003,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
@@ -2943,7 +3017,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);
}
}
@@ -2981,9 +3055,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;
@@ -3288,7 +3360,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
{
@@ -3340,7 +3412,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());
}
@@ -3352,8 +3424,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;
}
@@ -3393,14 +3465,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];
@@ -3415,6 +3487,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;
@@ -3472,7 +3545,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':');
@@ -3481,11 +3554,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++;
}
@@ -3514,17 +3587,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;
@@ -3537,15 +3610,15 @@ bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType>
{
int pos2 = s.Find(L'.', pos);
if (pos2 < 0)
pos2 = s.Len();
UString name = s.Mid(pos, pos2 - pos);
pos2 = (int)s.Len();
UString name = s.Mid(pos, (unsigned)pos2 - pos);
if (name.IsEmpty())
return false;
COpenType type;
if (!ParseType(codecs, name, type))
return false;
types.Add(type);
pos = pos2 + 1;
pos = (unsigned)pos2 + 1;
}
return true;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -357,6 +357,14 @@ SOURCE=..\..\..\Windows\System.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\SystemInfo.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\SystemInfo.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Thread.h
# End Source File
# Begin Source File

View File

@@ -4,8 +4,13 @@
#include "ConsoleClose.h"
#if !defined(UNDER_CE) && defined(_WIN32)
#ifndef UNDER_CE
#ifdef _WIN32
#include "../../../Common/MyWindows.h"
#else
#include <stdlib.h>
#include <signal.h>
#endif
namespace NConsoleClose {
@@ -13,7 +18,8 @@ namespace NConsoleClose {
unsigned g_BreakCounter = 0;
static const unsigned kBreakAbortThreshold = 2;
#if !defined(UNDER_CE) && defined(_WIN32)
#ifdef _WIN32
static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
{
if (ctrlType == CTRL_LOGOFF_EVENT)
@@ -37,7 +43,49 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
return FALSE;
*/
}
#endif
CCtrlHandlerSetter::CCtrlHandlerSetter()
{
if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
throw "SetConsoleCtrlHandler fails";
}
CCtrlHandlerSetter::~CCtrlHandlerSetter()
{
if (!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
{
// warning for throw in destructor.
// throw "SetConsoleCtrlHandler fails";
}
}
#else // _WIN32
static void HandlerRoutine(int)
{
g_BreakCounter++;
if (g_BreakCounter < kBreakAbortThreshold)
return;
exit(EXIT_FAILURE);
}
CCtrlHandlerSetter::CCtrlHandlerSetter()
{
memo_sig_int = signal(SIGINT, HandlerRoutine); // CTRL-C
if (memo_sig_int == SIG_ERR)
throw "SetConsoleCtrlHandler fails (SIGINT)";
memo_sig_term = signal(SIGTERM, HandlerRoutine); // for kill -15 (before "kill -9")
if (memo_sig_term == SIG_ERR)
throw "SetConsoleCtrlHandler fails (SIGTERM)";
}
CCtrlHandlerSetter::~CCtrlHandlerSetter()
{
signal(SIGINT, memo_sig_int); // CTRL-C
signal(SIGTERM, memo_sig_term); // kill {pid}
}
#endif // _WIN32
/*
void CheckCtrlBreak()
@@ -47,23 +95,6 @@ void CheckCtrlBreak()
}
*/
CCtrlHandlerSetter::CCtrlHandlerSetter()
{
#if !defined(UNDER_CE) && defined(_WIN32)
if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
throw "SetConsoleCtrlHandler fails";
#endif
}
CCtrlHandlerSetter::~CCtrlHandlerSetter()
{
#if !defined(UNDER_CE) && defined(_WIN32)
if (!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
{
// warning for throw in destructor.
// throw "SetConsoleCtrlHandler fails";
}
#endif
}
}
#endif

View File

@@ -5,28 +5,34 @@
namespace NConsoleClose {
class CCtrlBreakException {};
#ifdef UNDER_CE
inline bool TestBreakSignal() { return false; }
struct CCtrlHandlerSetter {};
#else
extern unsigned g_BreakCounter;
inline bool TestBreakSignal()
{
#ifdef UNDER_CE
return false;
#else
return (g_BreakCounter != 0);
#endif
}
class CCtrlHandlerSetter
{
#ifndef _WIN32
void (*memo_sig_int)(int);
void (*memo_sig_term)(int);
#endif
public:
CCtrlHandlerSetter();
virtual ~CCtrlHandlerSetter();
};
class CCtrlBreakException
{};
// void CheckCtrlBreak();
#endif
}

View File

@@ -69,6 +69,7 @@ HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError)
}
void Print_UInt64_and_String(AString &s, UInt64 val, const char *name);
void Print_UInt64_and_String(AString &s, UInt64 val, const char *name)
{
char temp[32];
@@ -78,6 +79,7 @@ void Print_UInt64_and_String(AString &s, UInt64 val, const char *name)
s += name;
}
void PrintSize_bytes_Smart(AString &s, UInt64 val);
void PrintSize_bytes_Smart(AString &s, UInt64 val)
{
Print_UInt64_and_String(s, val, "bytes");
@@ -96,7 +98,7 @@ void PrintSize_bytes_Smart(AString &s, UInt64 val)
s += ')';
}
void PrintSize_bytes_Smart_comma(AString &s, UInt64 val)
static void PrintSize_bytes_Smart_comma(AString &s, UInt64 val)
{
if (val == (UInt64)(Int64)-1)
return;
@@ -106,6 +108,7 @@ void PrintSize_bytes_Smart_comma(AString &s, UInt64 val)
void Print_DirItemsStat(AString &s, const CDirItemsStat &st);
void Print_DirItemsStat(AString &s, const CDirItemsStat &st)
{
if (st.NumDirs != 0)
@@ -124,6 +127,7 @@ void Print_DirItemsStat(AString &s, const CDirItemsStat &st)
}
void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st);
void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st)
{
Print_DirItemsStat(s, (CDirItemsStat &)st);
@@ -184,9 +188,9 @@ static const char * const kTestString = "T";
static const char * const kExtractString = "-";
static const char * const kSkipString = ".";
// static const char * const kCantAutoRename = "can not create file with auto name\n";
// static const char * const kCantRenameFile = "can not rename existing file\n";
// static const char * const kCantDeleteOutputFile = "can not delete output file ";
// static const char * const kCantAutoRename = "cannot create file with auto name\n";
// static const char * const kCantRenameFile = "cannot rename existing file\n";
// static const char * const kCantDeleteOutputFile = "cannot delete output file ";
static const char * const kMemoryExceptionMessage = "Can't allocate required memory!";
@@ -394,6 +398,7 @@ STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
return CheckBreak2();
}
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest);
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest)
{
dest.Empty();
@@ -436,7 +441,7 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest)
else
{
dest += "Error #";
dest.Add_UInt32(opRes);
dest.Add_UInt32((UInt32)opRes);
}
}
@@ -566,6 +571,7 @@ static AString GetOpenArcErrorMessage(UInt32 errorFlags)
return s;
}
void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags);
void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags)
{
if (errorFlags == 0)
@@ -573,7 +579,7 @@ void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags)
so << s << endl << GetOpenArcErrorMessage(errorFlags) << endl;
}
void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType)
static void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType)
{
s.Add_LF();
s += pre;
@@ -582,6 +588,7 @@ void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcTyp
s += "] archive";
}
void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc);
void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc)
{
const CArcErrorInfo &er = arc.ErrorInfo;
@@ -596,7 +603,7 @@ void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, c
}
else
{
Add_Messsage_Pre_ArcType(s, "Can not open the file", codecs->GetFormatNamePtr(er.ErrorFormatIndex));
Add_Messsage_Pre_ArcType(s, "Cannot open the file", codecs->GetFormatNamePtr(er.ErrorFormatIndex));
Add_Messsage_Pre_ArcType(s, "The file is open", codecs->GetFormatNamePtr(arc.FormatIndex));
}
@@ -806,7 +813,9 @@ HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
else
{
NumArcsWithError++;
if (result == E_ABORT || result == ERROR_DISK_FULL)
if (result == E_ABORT
|| result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)
)
return result;
if (_se)

View File

@@ -32,6 +32,9 @@ class CExtractScanConsole: public IDirItemsCallback
}
public:
virtual ~CExtractScanConsole() {}
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
{
_so = outStream;

View File

@@ -222,7 +222,8 @@ void CHashCallbackConsole::PrintResultLine(UInt64 fileSize,
s[0] = 0;
if (showHash)
AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
SetSpacesAndNul(s + strlen(s), (int)GetColumnWidth(h.DigestSize) - (int)strlen(s));
const unsigned pos = (unsigned)strlen(s);
SetSpacesAndNul(s + pos, GetColumnWidth(h.DigestSize) - pos);
if (i != 0)
_s.Add_Space();
_s += s;
@@ -235,20 +236,15 @@ void CHashCallbackConsole::PrintResultLine(UInt64 fileSize,
char s[kSizeField_Len + 32];
char *p = s;
SetSpacesAndNul(s, kSizeField_Len);
if (showHash)
{
p = s + kSizeField_Len;
ConvertUInt64ToString(fileSize, p);
int numSpaces = kSizeField_Len - (int)strlen(p);
int numSpaces = (int)kSizeField_Len - (int)strlen(p);
if (numSpaces > 0)
{
p -= (unsigned)numSpaces;
for (unsigned i = 0; i < (unsigned)numSpaces; i++)
p[i] = ' ';
}
}
else
SetSpacesAndNul(s, kSizeField_Len);
_s += p;
}

View File

@@ -38,7 +38,7 @@ public:
PrintName(true)
{}
~CHashCallbackConsole() { }
virtual ~CHashCallbackConsole() {}
INTERFACE_IHashCallbackUI(;)
};

View File

@@ -351,7 +351,7 @@ struct CListStat2
AltStreams.Update(st.AltStreams);
NumDirs += st.NumDirs;
}
const UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; }
UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; }
CListStat &GetStat(bool altStreamsMode) { return altStreamsMode ? AltStreams : MainFiles; }
};
@@ -751,7 +751,7 @@ void CFieldPrinter::PrintSum(const CListStat2 &stat2)
PrintSum(stat2.MainFiles, stat2.NumDirs, kString_Files);
if (stat2.AltStreams.NumFiles != 0)
{
PrintSum(stat2.AltStreams, 0, kString_AltStreams);;
PrintSum(stat2.AltStreams, 0, kString_AltStreams);
CListStat st = stat2.MainFiles;
st.Update(stat2.AltStreams);
PrintSum(st, 0, kString_Streams);
@@ -905,7 +905,7 @@ static HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propI
static void PrintArcTypeError(CStdOutStream &so, const UString &type, bool isWarning)
{
so << "Open " << (isWarning ? "WARNING" : "ERROR")
<< ": Can not open the file as ["
<< ": Cannot open the file as ["
<< type
<< "] archive"
<< endl;
@@ -926,6 +926,7 @@ static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er)
PrintPropPair(so, "WARNING", er.WarningMessage, true);
}
HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
{
FOR_VECTOR (r, arcLink.Arcs)
@@ -990,11 +991,12 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const
return S_OK;
}
HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
{
#ifndef _NO_CRYPTO
if (arcLink.PasswordWasAsked)
so << "Can not open encrypted archive. Wrong password?";
so << "Cannot open encrypted archive. Wrong password?";
else
#endif
{
@@ -1002,10 +1004,10 @@ HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const
{
so.NormalizePrint_UString(arcLink.NonOpen_ArcPath);
so << endl;
PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
PrintArcTypeError(so, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
}
else
so << "Can not open the file as archive";
so << "Cannot open the file as archive";
}
so << endl;
@@ -1065,12 +1067,12 @@ HRESULT ListArchives(CCodecs *codecs,
if (!stdInMode)
{
NFile::NFind::CFileInfo fi;
if (!fi.Find(us2fs(arcPath)))
if (!fi.Find_FollowLink(us2fs(arcPath)))
{
DWORD errorCode = GetLastError();
if (errorCode == 0)
errorCode = ERROR_FILE_NOT_FOUND;
lastError = HRESULT_FROM_WIN32(lastError);;
lastError = HRESULT_FROM_WIN32(errorCode);
g_StdOut.Flush();
if (g_ErrStream)
{
@@ -1279,7 +1281,7 @@ HRESULT ListArchives(CCodecs *codecs,
}
else
{
SplitPathToParts(fp.FilePath, pathParts);;
SplitPathToParts(fp.FilePath, pathParts);
bool include;
if (!wildcardCensor.CheckPathVect(pathParts, !fp.IsDir, include))
continue;
@@ -1331,7 +1333,7 @@ HRESULT ListArchives(CCodecs *codecs,
{
g_StdOut << "----------\n";
PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath, false);
PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
PrintArcTypeError(g_StdOut, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
}
}

View File

@@ -6,6 +6,11 @@
#ifdef _WIN32
#include <Psapi.h>
#else
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/times.h>
#endif
#include "../../../../C/CpuArch.h"
@@ -15,12 +20,13 @@
#include "../../../Common/CommandLineParser.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/MyException.h"
#include "../../../Common/StdInStream.h"
#include "../../../Common/StdOutStream.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/TimeUtils.h"
#include "../Common/ArchiveCommandLine.h"
@@ -37,12 +43,11 @@
#include "BenchCon.h"
#include "ConsoleClose.h"
#include "ExtractCallbackConsole.h"
#include "HashCon.h"
#include "List.h"
#include "OpenCallbackConsole.h"
#include "UpdateCallbackConsole.h"
#include "HashCon.h"
#ifdef PROG_VARIANT_R
#include "../../../../C/7zVersion.h"
#else
@@ -66,27 +71,30 @@ extern const CCodecInfo *g_Codecs[];
extern unsigned g_NumHashers;
extern const CHasherInfo *g_Hashers[];
static const char * const kCopyrightString = "\n7-Zip"
#ifndef EXTERNAL_CODECS
#ifdef PROG_VARIANT_R
" (r)"
#else
" (a)"
#endif
#endif
#if defined(PROG_VARIANT_Z)
#define PROG_POSTFIX "z"
#define PROG_POSTFIX_2 " (z)"
#elif defined(PROG_VARIANT_R)
#define PROG_POSTFIX "r"
#define PROG_POSTFIX_2 " (r)"
#elif !defined(EXTERNAL_CODECS)
#define PROG_POSTFIX "a"
#define PROG_POSTFIX_2 " (a)"
#else
#define PROG_POSTFIX ""
#define PROG_POSTFIX_2 ""
#endif
static const char * const kCopyrightString = "\n7-Zip"
PROG_POSTFIX_2
" " MY_VERSION_CPU
" : " MY_COPYRIGHT_DATE "\n\n";
" : " MY_COPYRIGHT_DATE "\n";
static const char * const kHelpString =
"Usage: 7z"
#ifndef EXTERNAL_CODECS
#ifdef PROG_VARIANT_R
"r"
#else
"a"
#endif
#endif
PROG_POSTFIX
" <command> [<switches>...] <archive_name> [<file_names>...] [@listfile]\n"
"\n"
"<Commands>\n"
@@ -141,6 +149,7 @@ static const char * const kHelpString =
" -spf : use fully qualified file paths\n"
" -ssc[-] : set sensitive case mode\n"
" -sse : stop archive creating, if it can't open some input file\n"
" -ssp : do not change Last Access Time of source files while archiving\n"
" -ssw : compress shared files\n"
" -stl : set archive timestamp from the most recently modified file\n"
" -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n"
@@ -163,6 +172,7 @@ static const char * const kUnsupportedArcTypeMessage = "Unsupported archive type
#define kDefaultSfxModule "7zCon.sfx"
MY_ATTR_NORETURN
static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code)
{
if (g_ErrStream)
@@ -170,15 +180,109 @@ static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code)
throw code;
}
#ifndef _WIN32
static void GetArguments(int numArgs, const char *args[], UStringVector &parts)
#ifdef _WIN32
#define ShowProgInfo(so)
#else
static void ShowProgInfo(CStdOutStream *so)
{
parts.Clear();
for (int i = 0; i < numArgs; i++)
if (!so)
return;
*so
/*
#ifdef __DATE__
<< " " << __DATE__
#endif
#ifdef __TIME__
<< " " << __TIME__
#endif
*/
#ifdef __VERSION__
<< " compiler: " << __VERSION__
#endif
#ifdef __GNUC__
<< " GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__
#endif
#ifdef __clang__
<< " CLANG " << __clang_major__ << "." << __clang_minor__
#endif
#ifdef __xlC__
<< " XLC " << (__xlC__ >> 8) << "." << (__xlC__ & 0xFF)
#ifdef __xlC_ver__
<< "." << (__xlC_ver__ >> 8) << "." << (__xlC_ver__ & 0xFF)
#endif
#endif
#ifdef _MSC_VER
<< " MSC " << _MSC_VER
#endif
#ifdef __ARM_FEATURE_CRC32
<< " CRC32"
#endif
<< " " << (unsigned)(sizeof(void *)) * 8 << "-bit"
#ifdef __ILP32__
<< " ILP32"
#endif
#ifdef __ARM_ARCH
<< " arm_v:" << __ARM_ARCH
#ifdef __ARM_ARCH_ISA_THUMB
<< " thumb:" << __ARM_ARCH_ISA_THUMB
#endif
#endif
#ifdef ENV_HAVE_LOCALE
<< " locale=" << GetLocale()
#endif
#ifndef _WIN32
<< " UTF8=" << (IsNativeUTF8() ? "+" : "-")
<< " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-")
<< " wchar_t=" << (unsigned)(sizeof(wchar_t)) * 8 << "-bit"
<< " Files=" << (unsigned)(sizeof(off_t)) * 8 << "-bit"
#endif
;
{
UString s = MultiByteToUnicodeString(args[i]);
parts.Add(s);
const UInt32 numCpus = NWindows::NSystem::GetNumberOfProcessors();
*so << " Threads:" << numCpus;
}
{
AString s;
GetCpuName(s);
s.Trim();
*so << ", " << s;
}
#ifdef _7ZIP_ASM
*so << ",ASM";
#endif
#if (defined MY_CPU_X86_OR_AMD64 || defined(MY_CPU_ARM_OR_ARM64))
if (CPU_IsSupported_AES()) *so << ",AES";
#endif
#ifdef MY_CPU_ARM_OR_ARM64
if (CPU_IsSupported_CRC32()) *so << ",CRC32";
#if defined(_WIN32)
if (CPU_IsSupported_CRYPTO()) *so << ",CRYPTO";
#else
if (CPU_IsSupported_SHA1()) *so << ",SHA1";
if (CPU_IsSupported_SHA2()) *so << ",SHA2";
#endif
#endif
*so << endl;
}
#endif
@@ -188,6 +292,8 @@ static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp)
return;
*so << kCopyrightString;
// *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl;
ShowProgInfo(so);
*so << endl;
if (needHelp)
*so << kHelpString;
}
@@ -211,7 +317,7 @@ static void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size)
static void PrintLibIndex(CStdOutStream &so, int libIndex)
{
if (libIndex >= 0)
PrintUInt32(so, libIndex, 2);
PrintUInt32(so, (UInt32)libIndex, 2);
else
so << " ";
so << ' ';
@@ -329,7 +435,6 @@ static void ThrowException_if_Error(HRESULT res)
throw CSystemException(res);
}
static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ')
{
char temp[64];
@@ -341,6 +446,8 @@ static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ')
*g_StdStream << p;
}
#ifdef _WIN32
static void PrintTime(const char *s, UInt64 val, UInt64 total)
{
*g_StdStream << endl << s << " Time =";
@@ -427,19 +534,19 @@ static void PrintStat()
HMODULE kern = ::GetModuleHandleW(L"kernel32.dll");
Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)
::GetProcAddress(kern, "K32GetProcessMemoryInfo");
(void *)::GetProcAddress(kern, "K32GetProcessMemoryInfo");
if (!my_GetProcessMemoryInfo)
{
HMODULE lib = LoadLibraryW(L"Psapi.dll");
if (lib)
my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)::GetProcAddress(lib, "GetProcessMemoryInfo");
my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)(void *)::GetProcAddress(lib, "GetProcessMemoryInfo");
}
if (my_GetProcessMemoryInfo)
memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
// FreeLibrary(lib);
Func_QueryProcessCycleTime my_QueryProcessCycleTime = (Func_QueryProcessCycleTime)
::GetProcAddress(kern, "QueryProcessCycleTime");
(void *)::GetProcAddress(kern, "QueryProcessCycleTime");
if (my_QueryProcessCycleTime)
cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime);
}
@@ -455,18 +562,32 @@ static void PrintStat()
PrintTime("Kernel ", kernelTime, totalTime);
const UInt64 processTime = kernelTime + userTime;
#ifndef UNDER_CE
if (cycleDefined)
{
*g_StdStream << " ";
PrintNum(cycleTime / 1000000, 22);
*g_StdStream << " Cnt:";
PrintNum(cycleTime / 1000000, 15);
*g_StdStream << " MCycles";
}
#endif
PrintTime("User ", userTime, totalTime);
#ifndef UNDER_CE
if (cycleDefined)
{
*g_StdStream << " Freq (cnt/ptime):";
UInt64 us = processTime / 10;
if (us == 0)
us = 1;
PrintNum(cycleTime / us, 6);
*g_StdStream << " MHz";
}
#endif
PrintTime("Process", kernelTime + userTime, totalTime);
PrintTime("Process", processTime, totalTime);
#ifndef UNDER_CE
if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage);
#endif
@@ -475,10 +596,96 @@ static void PrintStat()
#ifndef UNDER_CE
if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize);
#endif
}
#else // ! _WIN32
static UInt64 Get_timeofday_us()
{
struct timeval now;
if (gettimeofday(&now, 0 ) == 0)
return (UInt64)now.tv_sec * 1000000 + (UInt64)now.tv_usec;
return 0;
}
static void PrintTime(const char *s, UInt64 val, UInt64 total_us, UInt64 kFreq)
{
*g_StdStream << endl << s << " Time =";
{
UInt64 sec, ms;
if (kFreq == 0)
{
sec = val / 1000000;
ms = val % 1000000 / 1000;
}
else
{
sec = val / kFreq;
ms = (UInt32)((val - (sec * kFreq)) * 1000 / kFreq);
}
PrintNum(sec, 6);
*g_StdStream << '.';
PrintNum(ms, 3, '0');
}
if (total_us == 0)
return;
UInt64 percent = 0;
if (kFreq == 0)
percent = val * 100 / total_us;
else
{
const UInt64 kMaxVal = (UInt64)(Int64)-1;
UInt32 m = 100000000;
for (;;)
{
if (m == 0 || kFreq == 0)
break;
if (kMaxVal / m > val &&
kMaxVal / kFreq > total_us)
break;
if (val > m)
val >>= 1;
else
m >>= 1;
if (kFreq > total_us)
kFreq >>= 1;
else
total_us >>= 1;
}
const UInt64 total = kFreq * total_us;
if (total != 0)
percent = val * m / total;
}
*g_StdStream << " =";
PrintNum(percent, 5);
*g_StdStream << '%';
}
static void PrintStat(UInt64 startTime)
{
tms t;
/* clock_t res = */ times(&t);
const UInt64 totalTime = Get_timeofday_us() - startTime;
const UInt64 kFreq = (UInt64)sysconf(_SC_CLK_TCK);
PrintTime("Kernel ", (UInt64)t.tms_stime, totalTime, kFreq);
PrintTime("User ", (UInt64)t.tms_utime, totalTime, kFreq);
PrintTime("Process", (UInt64)t.tms_utime + (UInt64)t.tms_stime, totalTime, kFreq);
PrintTime("Global ", totalTime, totalTime, 0);
*g_StdStream << endl;
}
#endif // ! _WIN32
static void PrintHexId(CStdOutStream &so, UInt64 id)
{
char s[32];
@@ -486,23 +693,62 @@ static void PrintHexId(CStdOutStream &so, UInt64 id)
PrintStringRight(so, s, 8);
}
#ifndef _WIN32
void Set_ModuleDirPrefix_From_ProgArg0(const char *s);
#endif
int Main2(
#ifndef _WIN32
int numArgs, char *args[]
#endif
);
int Main2(
#ifndef _WIN32
int numArgs, char *args[]
#endif
)
{
#if defined(MY_CPU_SIZEOF_POINTER)
{ unsigned k = sizeof(void *); if (k != MY_CPU_SIZEOF_POINTER) throw "incorrect MY_CPU_PTR_SIZE"; }
#endif
#if defined(_WIN32) && !defined(UNDER_CE)
SetFileApisToOEM();
#endif
#ifdef ENV_HAVE_LOCALE
// printf("\nBefore SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8");
MY_SetLocale();
// printf("\nAfter SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8");
#endif
#ifndef _WIN32
UInt64 startTime = Get_timeofday_us();
#endif
UStringVector commandStrings;
#ifdef _WIN32
NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
#else
GetArguments(numArgs, args, commandStrings);
{
if (numArgs > 0)
Set_ModuleDirPrefix_From_ProgArg0(args[0]);
for (int i = 0; i < numArgs; i++)
{
AString a (args[i]);
/*
printf("\n%d %s :", i, a.Ptr());
for (unsigned k = 0; k < a.Len(); k++)
printf(" %2x", (unsigned)(Byte)a[k]);
*/
const UString s = MultiByteToUnicodeString(a);
commandStrings.Add(s);
}
// printf("\n");
}
#endif
#ifndef UNDER_CE
@@ -542,10 +788,53 @@ int Main2(
}
if (options.EnableHeaders)
{
ShowCopyrightAndHelp(g_StdStream, false);
if (!parser.Parse1Log.IsEmpty())
*g_StdStream << parser.Parse1Log;
}
parser.Parse2(options);
{
int cp = options.ConsoleCodePage;
int stdout_cp = cp;
int stderr_cp = cp;
int stdin_cp = cp;
/*
// these cases are complicated.
// maybe we must use CRT functions instead of console WIN32.
// different Windows/CRT versions also can work different ways.
// so the following code was not enabled:
if (cp == -1)
{
// we set CodePage only if stream is attached to terminal
// maybe we should set CodePage even if is not terminal?
#ifdef _WIN32
{
UINT ccp = GetConsoleOutputCP();
if (ccp != 0)
{
if (options.IsStdOutTerminal) stdout_cp = ccp;
if (options.IsStdErrTerminal) stderr_cp = ccp;
}
}
if (options.IsInTerminal)
{
UINT ccp = GetConsoleCP();
if (ccp != 0) stdin_cp = ccp;
}
#endif
}
*/
if (stdout_cp != -1) g_StdOut.CodePage = stdout_cp;
if (stderr_cp != -1) g_StdErr.CodePage = stderr_cp;
if (stdin_cp != -1) g_StdIn.CodePage = stdin_cp;
}
unsigned percentsNameLevel = 1;
if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out)
percentsNameLevel = 2;
@@ -559,13 +848,13 @@ int Main2(
#if !defined(UNDER_CE)
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
consoleWidth = consoleInfo.dwSize.X;
consoleWidth = (unsigned)consoleInfo.dwSize.X;
#endif
#else
struct winsize w;
if (ioctl(0, TIOCGWINSZ, &w) == )
if (ioctl(0, TIOCGWINSZ, &w) == 0)
consoleWidth = w.ws_col;
#endif
@@ -577,6 +866,19 @@ int Main2(
codecs->CaseSensitive = options.CaseSensitive;
ThrowException_if_Error(codecs->Load());
#ifdef EXTERNAL_CODECS
{
UString s;
codecs->GetCodecsErrorMessage(s);
if (!s.IsEmpty())
{
CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
so << endl << s << endl;
}
}
#endif
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
if (codecs->Formats.Size() == 0 &&
@@ -640,14 +942,14 @@ int Main2(
so << endl << "Libs:" << endl;
for (i = 0; i < codecs->Libs.Size(); i++)
{
PrintLibIndex(so, i);
PrintLibIndex(so, (int)i);
so << ' ' << codecs->Libs[i].Path << endl;
}
#endif
so << endl << "Formats:" << endl;
const char * const kArcFlags = "KSNFMGOPBELH";
const char * const kArcFlags = "KSNFMGOPBELHX";
const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags);
for (i = 0; i < codecs->Formats.Size(); i++)
@@ -804,6 +1106,7 @@ int Main2(
options.Properties, options.NumIterations, (FILE *)so);
if (hresultMain == S_FALSE)
{
so << endl;
if (g_ErrStream)
*g_ErrStream << "\nDecoding ERROR\n";
retCode = NExitCode::kFatalError;
@@ -863,7 +1166,7 @@ int Main2(
}
}
if (hresultMain == S_OK)
if (hresultMain == S_OK) {
if (isExtractGroupCommand)
{
CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
@@ -992,7 +1295,7 @@ int Main2(
if (isError)
retCode = NExitCode::kFatalError;
if (so)
if (so) {
if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0)
{
// if (ecs->NumArchives > 1)
@@ -1023,8 +1326,9 @@ int Main2(
PrintHashStat(*so, hb);
}
}
} // if (so)
}
else
else // if_(!isExtractGroupCommand)
{
UInt64 numErrors = 0;
UInt64 numWarnings = 0;
@@ -1060,7 +1364,8 @@ int Main2(
g_StdOut << endl << "Errors: " << numErrors << endl;
retCode = NExitCode::kFatalError;
}
}
} // if_(isExtractGroupCommand)
} // if_(hresultMain == S_OK)
}
else if (options.Command.IsFromUpdateGroup())
{
@@ -1146,7 +1451,11 @@ int Main2(
ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);
if (options.ShowTime && g_StdStream)
PrintStat();
PrintStat(
#ifndef _WIN32
startTime
#endif
);
ThrowException_if_Error(hresultMain);

View File

@@ -19,7 +19,11 @@
using namespace NWindows;
extern
CStdOutStream *g_StdStream;
CStdOutStream *g_StdStream = NULL;
extern
CStdOutStream *g_ErrStream;
CStdOutStream *g_ErrStream = NULL;
extern int Main2(
@@ -48,7 +52,9 @@ static void PrintError(const char *message)
*g_ErrStream << "\n\n" << message << endl;
}
#if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION *g_StdStream << "Unsupported Windows version"; return NExitCode::kFatalError;
#endif
int MY_CDECL main
(

View File

@@ -46,6 +46,8 @@ public:
#endif
{}
virtual ~COpenCallbackConsole() {}
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
{

View File

@@ -143,7 +143,7 @@ void CPercentPrinter::Print()
_tempU = FileName;
_so->Normalize_UString(_tempU);
StdOut_Convert_UString_to_AString(_tempU, _temp);
_so->Convert_UString_to_AString(_tempU, _temp);
if (_s.Len() + _temp.Len() > MaxLen)
{
unsigned len = FileName.Len();
@@ -157,7 +157,7 @@ void CPercentPrinter::Print()
_tempU.Delete(len / 2, _tempU.Len() - len);
_tempU.Insert(len / 2, L" . ");
_so->Normalize_UString(_tempU);
StdOut_Convert_UString_to_AString(_tempU, _temp);
_so->Convert_UString_to_AString(_tempU, _temp);
if (_s.Len() + _temp.Len() <= MaxLen)
break;
}

View File

@@ -209,6 +209,7 @@ HRESULT CCallbackConsoleBase::OpenFileError_Base(const FString &path, DWORD syst
{
MT_LOCK
FailedFiles.AddError(path, systemError);
NumNonOpenFiles++;
/*
if (systemError == ERROR_SHARING_VIOLATION)
{
@@ -282,6 +283,12 @@ HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name)
HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
{
if (NeedPercents())
_percent.ClosePrint(true);
_percent.ClearCurState();
NumNonOpenFiles = 0;
if (_so)
{
*_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage);
@@ -302,7 +309,7 @@ HRESULT CUpdateCallbackConsole::FinishArchive(const CFinishArchiveStat &st)
{
AString s;
// Print_UInt64_and_String(s, _percent.Files == 1 ? "file" : "files", _percent.Files);
PrintPropPair(s, "Files read from disk", _percent.Files);
PrintPropPair(s, "Files read from disk", _percent.Files - NumNonOpenFiles);
s.Add_LF();
s += "Archive size: ";
PrintSize_bytes_Smart(s, st.OutArcFileSize);

View File

@@ -56,7 +56,8 @@ public:
StdOutMode(false),
NeedFlush(false),
PercentsNameLevel(1),
LogLevel(0)
LogLevel(0),
NumNonOpenFiles(0)
{}
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
@@ -82,9 +83,9 @@ public:
_percent.ClosePrint(false);
}
CErrorPathCodes FailedFiles;
CErrorPathCodes ScanErrors;
UInt64 NumNonOpenFiles;
HRESULT PrintProgress(const wchar_t *name, const char *command, bool showInLog);
@@ -95,21 +96,23 @@ class CUpdateCallbackConsole: public IUpdateCallbackUI2, public CCallbackConsole
// void PrintPropPair(const char *name, const wchar_t *val);
public:
bool DeleteMessageWasShown;
#ifndef _NO_CRYPTO
bool PasswordIsDefined;
UString Password;
bool AskPassword;
#endif
bool DeleteMessageWasShown;
CUpdateCallbackConsole()
: DeleteMessageWasShown(false)
CUpdateCallbackConsole():
DeleteMessageWasShown(false)
#ifndef _NO_CRYPTO
, PasswordIsDefined(false)
, AskPassword(false)
#endif
{}
virtual ~CUpdateCallbackConsole() {}
/*
void Init(CStdOutStream *outStream)

View File

@@ -78,7 +78,7 @@ static bool GetPassword(CStdOutStream *outStream, UString &psw)
DWORD mode = 0;
if (console != INVALID_HANDLE_VALUE && console != 0)
if (GetConsoleMode(console, &mode))
wasChanged = (SetConsoleMode(console, mode & ~ENABLE_ECHO_INPUT) != 0);
wasChanged = (SetConsoleMode(console, mode & ~(DWORD)ENABLE_ECHO_INPUT) != 0);
bool res = g_StdIn.ScanUStringUntilNewLine(psw);
if (wasChanged)
SetConsoleMode(console, mode);

View File

@@ -31,6 +31,7 @@ WIN_OBJS = \
$O\PropVariantConv.obj \
$O\Registry.obj \
$O\System.obj \
$O\SystemInfo.obj \
$O\TimeUtils.obj \
7ZIP_COMMON_OBJS = \

View File

@@ -0,0 +1,171 @@
PROG = 7z
IS_NOT_STANDALONE = 1
# IS_X64 = 1
# USE_ASM = 1
# ST_MODE = 1
LOCAL_FLAGS_ST =
MT_OBJS =
ifdef ST_MODE
LOCAL_FLAGS_ST = -D_7ZIP_ST
ifdef SystemDrive
MT_OBJS = \
$O/Threads.o \
endif
else
MT_OBJS = \
$O/Synchronization.o \
$O/Threads.o \
endif
LOCAL_FLAGS_WIN=
ifdef SystemDrive
LOCAL_FLAGS_WIN = \
-D_7ZIP_LARGE_PAGES \
-DWIN_LONG_PATH \
-DSUPPORT_DEVICE_FILE \
SYS_OBJS = \
$O/FileSystem.o \
$O/Registry.o \
$O/MemoryLock.o \
$O/DllSecur.o \
$O/resource.o \
else
SYS_OBJS = \
$O/MyWindows.o \
endif
LOCAL_FLAGS = \
$(LOCAL_FLAGS_WIN) \
$(LOCAL_FLAGS_ST) \
-DEXTERNAL_CODECS \
CONSOLE_OBJS = \
$O/BenchCon.o \
$O/ConsoleClose.o \
$O/ExtractCallbackConsole.o \
$O/HashCon.o \
$O/List.o \
$O/Main.o \
$O/MainAr.o \
$O/OpenCallbackConsole.o \
$O/PercentPrinter.o \
$O/UpdateCallbackConsole.o \
$O/UserInputUtils.o \
UI_COMMON_OBJS = \
$O/ArchiveCommandLine.o \
$O/ArchiveExtractCallback.o \
$O/ArchiveOpenCallback.o \
$O/Bench.o \
$O/DefaultName.o \
$O/EnumDirItems.o \
$O/Extract.o \
$O/ExtractingFilePath.o \
$O/HashCalc.o \
$O/LoadCodecs.o \
$O/OpenArchive.o \
$O/PropIDUtils.o \
$O/SetProperties.o \
$O/SortUtils.o \
$O/TempFiles.o \
$O/Update.o \
$O/UpdateAction.o \
$O/UpdateCallback.o \
$O/UpdatePair.o \
$O/UpdateProduce.o \
COMMON_OBJS = \
$O/CommandLineParser.o \
$O/CRC.o \
$O/CrcReg.o \
$O/IntToString.o \
$O/ListFileUtils.o \
$O/NewHandler.o \
$O/StdInStream.o \
$O/StdOutStream.o \
$O/MyString.o \
$O/StringConvert.o \
$O/StringToInt.o \
$O/UTFConvert.o \
$O/MyVector.o \
$O/Wildcard.o \
WIN_OBJS = \
$O/DLL.o \
$O/ErrorMsg.o \
$O/FileDir.o \
$O/FileFind.o \
$O/FileIO.o \
$O/FileLink.o \
$O/FileName.o \
$O/PropVariant.o \
$O/PropVariantConv.o \
$O/System.o \
$O/SystemInfo.o \
$O/TimeUtils.o \
7ZIP_COMMON_OBJS = \
$O/CreateCoder.o \
$O/CWrappers.o \
$O/FilePathAutoRename.o \
$O/FileStreams.o \
$O/InBuffer.o \
$O/InOutTempBuffer.o \
$O/FilterCoder.o \
$O/LimitedStreams.o \
$O/MethodId.o \
$O/MethodProps.o \
$O/OffsetStream.o \
$O/OutBuffer.o \
$O/ProgressUtils.o \
$O/PropId.o \
$O/StreamObjects.o \
$O/StreamUtils.o \
$O/UniqBlocks.o \
COMPRESS_OBJS = \
$O/CopyCoder.o \
C_OBJS = \
$O/Alloc.o \
$O/CpuArch.o \
$O/Sort.o \
$O/7zCrc.o \
$O/7zCrcOpt.o \
OBJS = \
$(C_OBJS) \
$(MT_OBJS) \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(SYS_OBJS) \
$(COMPRESS_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(UI_COMMON_OBJS) \
$(CONSOLE_OBJS) \
include ../../7zip_gcc.mak

View File

@@ -2,6 +2,7 @@
#include "StdAfx.h"
#include "../../../Common/ComTry.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/COM.h"
@@ -31,6 +32,12 @@
#include "resource.h"
// #define SHOW_DEBUG_CTX_MENU
#ifdef SHOW_DEBUG_CTX_MENU
#include <stdio.h>
#endif
using namespace NWindows;
using namespace NFile;
using namespace NDir;
@@ -63,8 +70,8 @@ CZipContextMenu::~CZipContextMenu()
HRESULT CZipContextMenu::GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames)
{
fileNames.Clear();
if (dataObject == NULL)
return E_FAIL;
if (!dataObject)
return E_INVALIDARG;
#ifndef UNDER_CE
@@ -146,76 +153,24 @@ struct CContextMenuCommand
UINT ResourceID;
};
#define CMD_REC(cns, verb, ids) { NContextMenuFlags::cns, CZipContextMenu::cns, verb, ids }
static const CContextMenuCommand g_Commands[] =
{
{
NContextMenuFlags::kOpen,
CZipContextMenu::kOpen,
"Open",
IDS_CONTEXT_OPEN
},
{
NContextMenuFlags::kExtract,
CZipContextMenu::kExtract,
"Extract",
IDS_CONTEXT_EXTRACT
},
{
NContextMenuFlags::kExtractHere,
CZipContextMenu::kExtractHere,
"ExtractHere",
IDS_CONTEXT_EXTRACT_HERE
},
{
NContextMenuFlags::kExtractTo,
CZipContextMenu::kExtractTo,
"ExtractTo",
IDS_CONTEXT_EXTRACT_TO
},
{
NContextMenuFlags::kTest,
CZipContextMenu::kTest,
"Test",
IDS_CONTEXT_TEST
},
{
NContextMenuFlags::kCompress,
CZipContextMenu::kCompress,
"Compress",
IDS_CONTEXT_COMPRESS
},
{
NContextMenuFlags::kCompressEmail,
CZipContextMenu::kCompressEmail,
"CompressEmail",
IDS_CONTEXT_COMPRESS_EMAIL
},
{
NContextMenuFlags::kCompressTo7z,
CZipContextMenu::kCompressTo7z,
"CompressTo7z",
IDS_CONTEXT_COMPRESS_TO
},
{
NContextMenuFlags::kCompressTo7zEmail,
CZipContextMenu::kCompressTo7zEmail,
"CompressTo7zEmail",
IDS_CONTEXT_COMPRESS_TO_EMAIL
},
{
NContextMenuFlags::kCompressToZip,
CZipContextMenu::kCompressToZip,
"CompressToZip",
IDS_CONTEXT_COMPRESS_TO
},
{
NContextMenuFlags::kCompressToZipEmail,
CZipContextMenu::kCompressToZipEmail,
"CompressToZipEmail",
IDS_CONTEXT_COMPRESS_TO_EMAIL
}
CMD_REC( kOpen, "Open", IDS_CONTEXT_OPEN),
CMD_REC( kExtract, "Extract", IDS_CONTEXT_EXTRACT),
CMD_REC( kExtractHere, "ExtractHere", IDS_CONTEXT_EXTRACT_HERE),
CMD_REC( kExtractTo, "ExtractTo", IDS_CONTEXT_EXTRACT_TO),
CMD_REC( kTest, "Test", IDS_CONTEXT_TEST),
CMD_REC( kCompress, "Compress", IDS_CONTEXT_COMPRESS),
CMD_REC( kCompressEmail, "CompressEmail", IDS_CONTEXT_COMPRESS_EMAIL),
CMD_REC( kCompressTo7z, "CompressTo7z", IDS_CONTEXT_COMPRESS_TO),
CMD_REC( kCompressTo7zEmail, "CompressTo7zEmail", IDS_CONTEXT_COMPRESS_TO_EMAIL),
CMD_REC( kCompressToZip, "CompressToZip", IDS_CONTEXT_COMPRESS_TO),
CMD_REC( kCompressToZipEmail, "CompressToZipEmail", IDS_CONTEXT_COMPRESS_TO_EMAIL)
};
struct CHashCommand
{
CZipContextMenu::ECommandInternalID CommandInternalID;
@@ -232,6 +187,7 @@ static const CHashCommand g_HashCommands[] =
{ CZipContextMenu::kHash_All, "*", "*" }
};
static int FindCommand(CZipContextMenu::ECommandInternalID &id)
{
for (unsigned i = 0; i < ARRAY_SIZE(g_Commands); i++)
@@ -240,22 +196,31 @@ static int FindCommand(CZipContextMenu::ECommandInternalID &id)
return -1;
}
bool CZipContextMenu::FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem)
void CZipContextMenu::FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi)
{
mainString.Empty();
int i = FindCommand(id);
if (i < 0)
return false;
const CContextMenuCommand &command = g_Commands[i];
commandMapItem.CommandInternalID = command.CommandInternalID;
commandMapItem.Verb = kMainVerb;
commandMapItem.Verb += command.Verb;
// LangString(command.ResourceHelpID, command.LangID + 1, commandMapItem.HelpString);
throw 201908;
const CContextMenuCommand &command = g_Commands[(unsigned)i];
cmi.CommandInternalID = command.CommandInternalID;
cmi.Verb = kMainVerb;
cmi.Verb += command.Verb;
// cmi.HelpString = cmi.Verb;
LangString(command.ResourceID, mainString);
return true;
// return true;
}
static bool MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s, HBITMAP bitmap)
void CZipContextMenu::AddCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi)
{
FillCommand(id, mainString, cmi);
_commandMap.Add(cmi);
}
static void MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s, HBITMAP bitmap)
{
CMenuItem mi;
mi.fType = MFT_STRING;
@@ -266,12 +231,40 @@ static bool MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s, HBITMA
mi.StringValue = s;
mi.hbmpUnchecked = bitmap;
// mi.hbmpChecked = bitmap; // do we need hbmpChecked ???
return menu.InsertItem(pos, true, mi);
if (!menu.InsertItem(pos, true, mi))
throw 20190816;
// SetMenuItemBitmaps also works
// ::SetMenuItemBitmaps(menu, pos, MF_BYPOSITION, bitmap, NULL);
}
static void MyAddSubMenu(
CObjectVector<CZipContextMenu::CCommandMapItem> &_commandMap,
const char *verb,
CMenu &menu, int pos, UINT id, const UString &s, HMENU hSubMenu, HBITMAP bitmap)
{
CZipContextMenu::CCommandMapItem cmi;
cmi.CommandInternalID = CZipContextMenu::kCommandNULL;
cmi.Verb = verb;
// cmi.HelpString = verb;
_commandMap.Add(cmi);
CMenuItem mi;
mi.fType = MFT_STRING;
mi.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
if (bitmap)
mi.fMask |= MIIM_CHECKMARKS;
mi.wID = id;
mi.hSubMenu = hSubMenu;
mi.hbmpUnchecked = bitmap;
mi.StringValue = s;
if (!menu.InsertItem(pos, true, mi))
throw 20190817;
}
static const char * const kArcExts[] =
{
"7z"
@@ -289,6 +282,7 @@ static bool IsItArcExt(const UString &ext)
return false;
}
UString GetSubFolderNameForExtract(const UString &arcName);
UString GetSubFolderNameForExtract(const UString &arcName)
{
int dotPos = arcName.ReverseFind_Dot();
@@ -302,11 +296,11 @@ UString GetSubFolderNameForExtract(const UString &arcName)
if (dotPos > 0)
{
const UString ext2 = res.Ptr(dotPos + 1);
if (ext.IsEqualTo_Ascii_NoCase("001") && IsItArcExt(ext2)
|| ext.IsEqualTo_Ascii_NoCase("rar") &&
if ((ext.IsEqualTo_Ascii_NoCase("001") && IsItArcExt(ext2))
|| (ext.IsEqualTo_Ascii_NoCase("rar") &&
( ext2.IsEqualTo_Ascii_NoCase("part001")
|| ext2.IsEqualTo_Ascii_NoCase("part01")
|| ext2.IsEqualTo_Ascii_NoCase("part1")))
|| ext2.IsEqualTo_Ascii_NoCase("part1"))))
res.DeleteFrom(dotPos);
res.TrimRight();
}
@@ -415,17 +409,44 @@ static bool DoNeedExtract(const FString &name)
// we must use diferent Verbs for Popup subMenu.
void CZipContextMenu::AddMapItem_ForSubMenu(const char *verb)
{
CCommandMapItem commandMapItem;
commandMapItem.CommandInternalID = kCommandNULL;
commandMapItem.Verb = verb;
_commandMap.Add(commandMapItem);
CCommandMapItem cmi;
cmi.CommandInternalID = kCommandNULL;
cmi.Verb = verb;
// cmi.HelpString = verb;
_commandMap.Add(cmi);
}
static HRESULT RETURN_WIN32_LastError_AS_HRESULT()
{
DWORD lastError = ::GetLastError();
if (lastError == 0)
return E_FAIL;
return HRESULT_FROM_WIN32(lastError);
}
/*
we add CCommandMapItem to _commandMap for each new Mene ID.
so then we use _commandMap[offset].
That way we can execute commands that have menu item.
Another non-implemented way:
We can return the number off all possible commnad in QueryContextMenu().
so the caller could call InvokeCommand() via string verb aven
without using menu items.
*/
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT commandIDFirst, UINT commandIDLast, UINT flags)
{
// OutputDebugStringA("QueryContextMenu");
COM_TRY_BEGIN
try {
#ifdef SHOW_DEBUG_CTX_MENU
{ char s[256]; sprintf(s, "QueryContextMenu: index=%d first=%d last=%d flags=%x _files=%d",
indexMenu, commandIDFirst, commandIDLast, flags, _fileNames.Size()); OutputDebugStringA(s); }
/*
for (UInt32 i = 0; i < _fileNames.Size(); i++)
@@ -433,15 +454,29 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
OutputDebugStringW(_fileNames[i]);
}
*/
#endif
LoadLangOneTime();
if (_fileNames.Size() == 0)
return E_FAIL;
{
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
// return E_INVALIDARG;
}
if (commandIDFirst > commandIDLast)
return E_INVALIDARG;
UINT currentCommandID = commandIDFirst;
if ((flags & 0x000F) != CMF_NORMAL &&
(flags & CMF_VERBSONLY) == 0 &&
(flags & CMF_EXPLORE) == 0)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID);
if ((flags & 0x000F) != CMF_NORMAL
&& (flags & CMF_VERBSONLY) == 0
&& (flags & CMF_EXPLORE) == 0)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst);
// return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID);
// 19.01 : we changed from (currentCommandID) to (currentCommandID - commandIDFirst)
// why it was so before?
_commandMap.Clear();
@@ -462,7 +497,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (ci.Cascaded.Val)
{
if (!popupMenu.CreatePopup())
return E_FAIL;
return RETURN_WIN32_LastError_AS_HRESULT();
menuDestroyer.Attach(popupMenu);
/* 9.31: we commented the following code. Probably we don't need.
@@ -508,7 +543,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
#endif
{
if (!fi0.Find(us2fs(fileName)))
return E_FAIL;
{
throw 20190820;
// return RETURN_WIN32_LastError_AS_HRESULT();
}
GetOnlyDirPrefix(us2fs(fileName), folderPrefix);
}
}
@@ -523,10 +561,9 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
bool thereIsMainOpenItem = ((contextMenuFlags & NContextMenuFlags::kOpen) != 0);
if (thereIsMainOpenItem)
{
CCommandMapItem commandMapItem;
FillCommand(kOpen, mainString, commandMapItem);
CCommandMapItem cmi;
AddCommand(kOpen, mainString, cmi);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap);
_commandMap.Add(commandMapItem);
}
if ((contextMenuFlags & NContextMenuFlags::kOpenAs) != 0
// && (!thereIsMainOpenItem || !FindExt(kNoOpenAsExtensions, fi0.Name))
@@ -535,37 +572,26 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
CMenu subMenu;
if (subMenu.CreatePopup())
{
CMenuItem mi;
mi.fType = MFT_STRING;
mi.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
if (bitmap)
mi.fMask |= MIIM_CHECKMARKS;
mi.wID = currentCommandID++;
mi.hSubMenu = subMenu;
mi.hbmpUnchecked = bitmap;
LangString(IDS_CONTEXT_OPEN, mi.StringValue);
popupMenu.InsertItem(subIndex++, true, mi);
AddMapItem_ForSubMenu(kOpenCascadedVerb);
MyAddSubMenu(_commandMap, kOpenCascadedVerb, popupMenu, subIndex++, currentCommandID++, LangString(IDS_CONTEXT_OPEN), subMenu, bitmap);
UINT subIndex2 = 0;
for (unsigned i = (thereIsMainOpenItem ? 1 : 0); i < ARRAY_SIZE(kOpenTypes); i++)
{
CCommandMapItem commandMapItem;
CCommandMapItem cmi;
if (i == 0)
FillCommand(kOpen, mainString, commandMapItem);
FillCommand(kOpen, mainString, cmi);
else
{
mainString = kOpenTypes[i];
commandMapItem.CommandInternalID = kOpen;
commandMapItem.Verb = kMainVerb;
commandMapItem.Verb += ".Open.";
commandMapItem.Verb += mainString;
commandMapItem.HelpString = mainString;
commandMapItem.ArcType = mainString;
cmi.CommandInternalID = kOpen;
cmi.Verb = kMainVerb;
cmi.Verb += ".Open.";
cmi.Verb += mainString;
// cmi.HelpString = cmi.Verb;
cmi.ArcType = mainString;
}
_commandMap.Add(cmi);
MyInsertMenu(subMenu, subIndex2++, currentCommandID++, mainString, bitmap);
_commandMap.Add(commandMapItem);
}
subMenu.Detach();
@@ -584,7 +610,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
{
NFind::CFileInfo fi;
if (!fi.Find(us2fs(_fileNames[i])))
return E_FAIL;
{
throw 20190821;
// return RETURN_WIN32_LastError_AS_HRESULT();
}
if (!fi.IsDir() && DoNeedExtract(fi.Name))
{
needExtract = true;
@@ -610,43 +639,39 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0)
{
// Extract
CCommandMapItem commandMapItem;
FillCommand(kExtract, mainString, commandMapItem);
commandMapItem.Folder = baseFolder + specFolder;
CCommandMapItem cmi;
cmi.Folder = baseFolder + specFolder;
AddCommand(kExtract, mainString, cmi);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap);
_commandMap.Add(commandMapItem);
}
if ((contextMenuFlags & NContextMenuFlags::kExtractHere) != 0)
{
// Extract Here
CCommandMapItem commandMapItem;
FillCommand(kExtractHere, mainString, commandMapItem);
commandMapItem.Folder = baseFolder;
CCommandMapItem cmi;
cmi.Folder = baseFolder;
AddCommand(kExtractHere, mainString, cmi);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap);
_commandMap.Add(commandMapItem);
}
if ((contextMenuFlags & NContextMenuFlags::kExtractTo) != 0)
{
// Extract To
CCommandMapItem commandMapItem;
CCommandMapItem cmi;
UString s;
FillCommand(kExtractTo, s, commandMapItem);
commandMapItem.Folder = baseFolder + specFolder;
cmi.Folder = baseFolder + specFolder;
AddCommand(kExtractTo, s, cmi);
MyFormatNew_ReducedName(s, specFolder);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
}
}
if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
{
// Test
CCommandMapItem commandMapItem;
FillCommand(kTest, mainString, commandMapItem);
CCommandMapItem cmi;
AddCommand(kTest, mainString, cmi);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap);
_commandMap.Add(commandMapItem);
}
}
@@ -660,26 +685,24 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
// Compress
if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0)
{
CCommandMapItem commandMapItem;
CCommandMapItem cmi;
if (_dropMode)
commandMapItem.Folder = _dropPath;
cmi.Folder = _dropPath;
else
commandMapItem.Folder = fs2us(folderPrefix);
commandMapItem.ArcName = arcName;
FillCommand(kCompress, mainString, commandMapItem);
cmi.Folder = fs2us(folderPrefix);
cmi.ArcName = arcName;
AddCommand(kCompress, mainString, cmi);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap);
_commandMap.Add(commandMapItem);
}
#ifdef EMAIL_SUPPORT
// CompressEmail
if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0 && !_dropMode)
{
CCommandMapItem commandMapItem;
commandMapItem.ArcName = arcName;
FillCommand(kCompressEmail, mainString, commandMapItem);
CCommandMapItem cmi;
cmi.ArcName = arcName;
AddCommand(kCompressEmail, mainString, cmi);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap);
_commandMap.Add(commandMapItem);
}
#endif
@@ -687,32 +710,30 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (contextMenuFlags & NContextMenuFlags::kCompressTo7z &&
!arcName7z.IsEqualTo_NoCase(fs2us(fi0.Name)))
{
CCommandMapItem commandMapItem;
CCommandMapItem cmi;
UString s;
FillCommand(kCompressTo7z, s, commandMapItem);
if (_dropMode)
commandMapItem.Folder = _dropPath;
cmi.Folder = _dropPath;
else
commandMapItem.Folder = fs2us(folderPrefix);
commandMapItem.ArcName = arcName7z;
commandMapItem.ArcType = "7z";
cmi.Folder = fs2us(folderPrefix);
cmi.ArcName = arcName7z;
cmi.ArcType = "7z";
AddCommand(kCompressTo7z, s, cmi);
MyFormatNew_ReducedName(s, arcName7z);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
}
#ifdef EMAIL_SUPPORT
// CompressTo7zEmail
if ((contextMenuFlags & NContextMenuFlags::kCompressTo7zEmail) != 0 && !_dropMode)
{
CCommandMapItem commandMapItem;
CCommandMapItem cmi;
UString s;
FillCommand(kCompressTo7zEmail, s, commandMapItem);
commandMapItem.ArcName = arcName7z;
commandMapItem.ArcType = "7z";
cmi.ArcName = arcName7z;
cmi.ArcType = "7z";
AddCommand(kCompressTo7zEmail, s, cmi);
MyFormatNew_ReducedName(s, arcName7z);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
}
#endif
@@ -720,32 +741,30 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (contextMenuFlags & NContextMenuFlags::kCompressToZip &&
!arcNameZip.IsEqualTo_NoCase(fs2us(fi0.Name)))
{
CCommandMapItem commandMapItem;
CCommandMapItem cmi;
UString s;
FillCommand(kCompressToZip, s, commandMapItem);
if (_dropMode)
commandMapItem.Folder = _dropPath;
cmi.Folder = _dropPath;
else
commandMapItem.Folder = fs2us(folderPrefix);
commandMapItem.ArcName = arcNameZip;
commandMapItem.ArcType = "zip";
cmi.Folder = fs2us(folderPrefix);
cmi.ArcName = arcNameZip;
cmi.ArcType = "zip";
AddCommand(kCompressToZip, s, cmi);
MyFormatNew_ReducedName(s, arcNameZip);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
}
#ifdef EMAIL_SUPPORT
// CompressToZipEmail
if ((contextMenuFlags & NContextMenuFlags::kCompressToZipEmail) != 0 && !_dropMode)
{
CCommandMapItem commandMapItem;
CCommandMapItem cmi;
UString s;
FillCommand(kCompressToZipEmail, s, commandMapItem);
commandMapItem.ArcName = arcNameZip;
commandMapItem.ArcType = "zip";
cmi.ArcName = arcNameZip;
cmi.ArcType = "zip";
AddCommand(kCompressToZipEmail, s, cmi);
MyFormatNew_ReducedName(s, arcNameZip);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
}
#endif
}
@@ -757,22 +776,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (ci.Cascaded.Val)
{
CMenuItem mi;
mi.fType = MFT_STRING;
mi.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
if (bitmap)
mi.fMask |= MIIM_CHECKMARKS;
mi.wID = currentCommandID++;
mi.hSubMenu = popupMenu.Detach();
mi.StringValue = "7-Zip"; // LangString(IDS_CONTEXT_POPUP_CAPTION);
mi.hbmpUnchecked = bitmap;
CMenu menu;
menu.Attach(hMenu);
menuDestroyer.Disable();
menu.InsertItem(indexMenu++, true, mi);
AddMapItem_ForSubMenu(kMainVerb);
MyAddSubMenu(_commandMap, kMainVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip", popupMenu.Detach(), bitmap);
}
else
{
@@ -783,7 +790,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (!_isMenuForFM &&
((contextMenuFlags & NContextMenuFlags::kCRC) != 0
&& currentCommandID + 6 <= commandIDLast))
&& currentCommandID + 1 < commandIDLast))
{
CMenu subMenu;
// CMenuDestroyer menuDestroyer_CRC;
@@ -793,40 +800,58 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (subMenu.CreatePopup())
{
// menuDestroyer_CRC.Attach(subMenu);
CMenuItem mi;
mi.fType = MFT_STRING;
mi.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
if (bitmap)
mi.fMask |= MIIM_CHECKMARKS;
mi.wID = currentCommandID++;
mi.hSubMenu = subMenu;
mi.StringValue = "CRC SHA";
mi.hbmpUnchecked = bitmap;
CMenu menu;
menu.Attach(hMenu);
// menuDestroyer_CRC.Disable();
menu.InsertItem(indexMenu++, true, mi);
AddMapItem_ForSubMenu(kCheckSumCascadedVerb);
MyAddSubMenu(_commandMap, kCheckSumCascadedVerb, menu, indexMenu++, currentCommandID++, (UString)"CRC SHA", subMenu, bitmap);
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
if (currentCommandID >= commandIDLast)
break;
const CHashCommand &hc = g_HashCommands[i];
CCommandMapItem commandMapItem;
commandMapItem.CommandInternalID = hc.CommandInternalID;
commandMapItem.Verb = kCheckSumCascadedVerb;
commandMapItem.Verb += hc.MethodName;
// commandMapItem.HelpString = hc.Name;
CCommandMapItem cmi;
cmi.CommandInternalID = hc.CommandInternalID;
cmi.Verb = kCheckSumCascadedVerb;
cmi.Verb += '.';
cmi.Verb += hc.MethodName;
// cmi.HelpString = cmi.Verb;
_commandMap.Add(cmi);
MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, (UString)hc.UserName, bitmap);
_commandMap.Add(commandMapItem);
}
subMenu.Detach();
}
}
#ifdef SHOW_DEBUG_CTX_MENU
{ char s[256]; sprintf(s, "Commands=%d currentCommandID - commandIDFirst = %d",
_commandMap.Size(), currentCommandID - commandIDFirst); OutputDebugStringA(s); }
#endif
if (_commandMap.Size() != currentCommandID - commandIDFirst)
throw 20190818;
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst);
}
catch(...)
{
/* we added some menu items already : num_added_menu_items,
So we MUST return (number_of_defined_ids), where (number_of_defined_ids >= num_added_menu_items)
This will prevent incorrect menu working, when same IDs can be
assigned in multiple menu items from different subhandlers.
And we must add items to _commandMap before adding to menu.
*/
#ifdef SHOW_DEBUG_CTX_MENU
{ char s[256]; sprintf(s, "catch() exception: Commands=%d",
_commandMap.Size()); OutputDebugStringA(s); }
#endif
// if (_commandMap.Size() != 0)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, _commandMap.Size());
// throw;
}
COM_TRY_END
}
@@ -843,35 +868,122 @@ static UString Get7zFmPath()
return fs2us(NWindows::NDLL::GetModuleDirPrefix()) + L"7zFM.exe";
}
#ifdef UNDER_CE
#define MY__IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16) == 0)
#else
#define MY__IS_INTRESOURCE(_r) IS_INTRESOURCE(_r)
#endif
#ifdef SHOW_DEBUG_CTX_MENU
static void PrintStringA(const char *name, LPCSTR ptr)
{
AString m;
m += name;
m += ": ";
char s[32];
sprintf(s, "%p", ptr);
m += s;
if (!MY__IS_INTRESOURCE(ptr))
{
m += ": \"";
m += ptr;
m += "\"";
}
OutputDebugStringA(m);
}
#if !defined(UNDER_CE)
static void PrintStringW(const char *name, LPCWSTR ptr)
{
UString m;
m += name;
m += ": ";
char s[32];
sprintf(s, "%p", ptr);
m += s;
if (!MY__IS_INTRESOURCE(ptr))
{
m += ": \"";
m += ptr;
m += "\"";
}
OutputDebugStringW(m);
}
#endif
#endif
STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
{
// ::OutputDebugStringA("1");
int commandOffset;
COM_TRY_BEGIN
// It's fix for bug: crashing in XP. See example in MSDN: "Creating Context Menu Handlers".
#ifdef SHOW_DEBUG_CTX_MENU
#if !defined(UNDER_CE) && defined(_MSC_VER)
{ char s[1280]; sprintf(s,
#ifdef _WIN64
"64"
#else
"32"
#endif
": InvokeCommand: cbSize=%d flags=%x "
, commandInfo->cbSize, commandInfo->fMask); OutputDebugStringA(s); }
PrintStringA("Verb", commandInfo->lpVerb);
PrintStringA("Parameters", commandInfo->lpParameters);
PrintStringA("Directory", commandInfo->lpDirectory);
#endif
int commandOffset = -1;
// xp64 / Win10 : explorer.exe sends 0 in lpVerbW
// MSDN: if (IS_INTRESOURCE(lpVerbW)), we must use LOWORD(lpVerb) as sommand offset
// FIXME: MINGW doesn't define CMINVOKECOMMANDINFOEX
#if !defined(UNDER_CE) /* && defined(_MSC_VER) */
bool unicodeVerb = false;
if (commandInfo->cbSize == sizeof(CMINVOKECOMMANDINFOEX) &&
(commandInfo->fMask & CMIC_MASK_UNICODE) != 0)
{
LPCMINVOKECOMMANDINFOEX commandInfoEx = (LPCMINVOKECOMMANDINFOEX)commandInfo;
if (HIWORD(commandInfoEx->lpVerbW) == 0)
commandOffset = LOWORD(commandInfo->lpVerb);
else
if (!MY__IS_INTRESOURCE(commandInfoEx->lpVerbW))
{
unicodeVerb = true;
commandOffset = FindVerb(commandInfoEx->lpVerbW);
}
#ifdef SHOW_DEBUG_CTX_MENU
PrintStringW("VerbW", commandInfoEx->lpVerbW);
PrintStringW("ParametersW", commandInfoEx->lpParametersW);
PrintStringW("DirectoryW", commandInfoEx->lpDirectoryW);
PrintStringW("TitleW", commandInfoEx->lpTitleW);
PrintStringA("Title", commandInfoEx->lpTitle);
#endif
}
else
if (!unicodeVerb)
#endif
if (HIWORD(commandInfo->lpVerb) == 0)
{
#ifdef SHOW_DEBUG_CTX_MENU
OutputDebugStringA("use non-UNICODE verb");
#endif
// if (HIWORD(commandInfo->lpVerb) == 0)
if (MY__IS_INTRESOURCE(commandInfo->lpVerb))
commandOffset = LOWORD(commandInfo->lpVerb);
else
commandOffset = FindVerb(GetUnicodeString(commandInfo->lpVerb));
}
#ifdef SHOW_DEBUG_CTX_MENU
{ char s[128]; sprintf(s, "commandOffset=%d",
commandOffset); OutputDebugStringA(s); }
#endif
if (commandOffset < 0 || (unsigned)commandOffset >= _commandMap.Size())
return E_FAIL;
return E_INVALIDARG;
const CCommandMapItem commandMapItem = _commandMap[commandOffset];
ECommandInternalID cmdID = commandMapItem.CommandInternalID;
const CCommandMapItem &cmi = _commandMap[(unsigned)commandOffset];
ECommandInternalID cmdID = cmi.CommandInternalID;
try
{
@@ -881,10 +993,10 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
{
UString params;
params = GetQuotedString(_fileNames[0]);
if (!commandMapItem.ArcType.IsEmpty())
if (!cmi.ArcType.IsEmpty())
{
params += " -t";
params += commandMapItem.ArcType;
params += cmi.ArcType;
}
MyCreateProcess(Get7zFmPath(), params);
break;
@@ -893,7 +1005,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
case kExtractHere:
case kExtractTo:
{
ExtractArchives(_fileNames, commandMapItem.Folder,
ExtractArchives(_fileNames, cmi.Folder,
(cmdID == kExtract), // showDialog
(cmdID == kExtractTo) && _elimDup.Val // elimDup
);
@@ -919,8 +1031,8 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
(cmdID == kCompress) ||
(cmdID == kCompressEmail);
bool addExtension = (cmdID == kCompress || cmdID == kCompressEmail);
CompressFiles(commandMapItem.Folder,
commandMapItem.ArcName, commandMapItem.ArcType,
CompressFiles(cmi.Folder,
cmi.ArcName, cmi.ArcType,
addExtension,
_fileNames, email, showDialog, false);
break;
@@ -943,6 +1055,8 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
}
break;
}
case kCommandNULL:
break;
}
}
catch(...)
@@ -950,66 +1064,75 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
::MessageBoxW(0, L"Error", L"7-Zip", MB_ICONERROR);
}
return S_OK;
COM_TRY_END
}
static void MyCopyString(void *dest, const wchar_t *src, bool writeInUnicode)
static void MyCopyString(void *dest, const UString &src, bool writeInUnicode, UINT size)
{
if (size != 0)
size--;
if (writeInUnicode)
{
MyStringCopy((wchar_t *)dest, src);
UString s = src;
s.DeleteFrom(size);
MyStringCopy((wchar_t *)dest, s);
}
else
MyStringCopy((char *)dest, (const char *)GetAnsiString(src));
{
AString s = GetAnsiString(src);
s.DeleteFrom(size);
MyStringCopy((char *)dest, s);
}
}
STDMETHODIMP CZipContextMenu::GetCommandString(UINT_PTR commandOffset, UINT uType,
UINT * /* pwReserved */ , LPSTR pszName, UINT /* cchMax */)
UINT * /* pwReserved */ , LPSTR pszName, UINT cchMax)
{
int cmdOffset = (int)commandOffset;
switch (uType)
COM_TRY_BEGIN
const int cmdOffset = (int)commandOffset;
#ifdef SHOW_DEBUG_CTX_MENU
{ char s[256]; sprintf(s, "GetCommandString: cmdOffset=%d uType=%d cchMax = %d",
cmdOffset, uType, cchMax); OutputDebugStringA(s); }
#endif
if (uType == GCS_VALIDATEA || uType == GCS_VALIDATEW)
{
#ifdef UNDER_CE
case GCS_VALIDATE:
#else
case GCS_VALIDATEA:
case GCS_VALIDATEW:
#endif
if (cmdOffset < 0 || (unsigned)cmdOffset >= _commandMap.Size())
return S_FALSE;
else
return S_OK;
if (cmdOffset < 0 || (unsigned)cmdOffset >= _commandMap.Size())
return S_FALSE;
else
return S_OK;
}
if (cmdOffset < 0 || (unsigned)cmdOffset >= _commandMap.Size())
return E_FAIL;
#ifdef UNDER_CE
if (uType == GCS_HELPTEXT)
#else
{
#ifdef SHOW_DEBUG_CTX_MENU
OutputDebugStringA("---------------- cmdOffset: E_INVALIDARG");
#endif
return E_INVALIDARG;
}
const CCommandMapItem &cmi = _commandMap[(unsigned)cmdOffset];
if (uType == GCS_HELPTEXTA || uType == GCS_HELPTEXTW)
#endif
{
MyCopyString(pszName, _commandMap[cmdOffset].HelpString,
#ifdef UNDER_CE
true
#else
uType == GCS_HELPTEXTW
#endif
);
return NO_ERROR;
// we can return "Verb" here for debug purposes.
// HelpString;
MyCopyString(pszName, cmi.Verb, uType == GCS_HELPTEXTW, cchMax);
return S_OK;
}
#ifdef UNDER_CE
if (uType == GCS_VERB)
#else
if (uType == GCS_VERBA || uType == GCS_VERBW)
#endif
{
MyCopyString(pszName, _commandMap[cmdOffset].Verb,
#ifdef UNDER_CE
true
#else
uType == GCS_VERBW
#endif
);
return NO_ERROR;
MyCopyString(pszName, cmi.Verb, uType == GCS_VERBW, cchMax);
return S_OK;
}
return E_FAIL;
return E_INVALIDARG;
COM_TRY_END
}

View File

@@ -54,18 +54,18 @@ public:
CZipContextMenu();
~CZipContextMenu();
private:
struct CCommandMapItem
{
ECommandInternalID CommandInternalID;
UString Verb;
UString HelpString;
// UString HelpString;
UString Folder;
UString ArcName;
UString ArcType;
};
private:
bool _isMenuForFM;
UStringVector _fileNames;
bool _dropMode;
@@ -78,7 +78,8 @@ private:
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
int FindVerb(const UString &verb);
bool FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem);
void FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi);
void AddCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi);
void AddMapItem_ForSubMenu(const char *ver);
};

View File

@@ -39,9 +39,16 @@ DEFINE_GUID(CLSID_CZipContextMenu,
using namespace NWindows;
extern
HINSTANCE g_hInstance;
HINSTANCE g_hInstance = 0;
extern
HWND g_HWND;
HWND g_HWND = 0;
extern
LONG g_DllRefCount;
LONG g_DllRefCount = 0; // Reference count of this DLL.
@@ -91,7 +98,18 @@ STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /* fLock */)
}
#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION return FALSE;
#endif
extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
HANDLE hInstance
#else
HINSTANCE hInstance
#endif
, DWORD dwReason, LPVOID);
extern "C"
BOOL WINAPI DllMain(

View File

@@ -26,7 +26,7 @@ void ShowErrorMessageRes(UINT resID)
ShowErrorMessageHwndRes(0, resID);
}
void ShowErrorMessageDWORD(HWND window, DWORD errorCode)
static void ShowErrorMessageDWORD(HWND window, DWORD errorCode)
{
ShowErrorMessage(window, NError::MyFormatMessage(errorCode));
}

View File

@@ -59,14 +59,16 @@ static const bool k_shellex_Statuses[2][4] =
#else
*/
typedef WINADVAPI LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
typedef
// WINADVAPI
LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
static Func_RegDeleteKeyExW func_RegDeleteKeyExW;
static void Init_RegDeleteKeyExW()
{
if (!func_RegDeleteKeyExW)
func_RegDeleteKeyExW = (Func_RegDeleteKeyExW)
GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW");
(void *)GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW");
}
#define INIT_REG_WOW if (wow != 0) Init_RegDeleteKeyExW();
@@ -80,12 +82,12 @@ static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCTSTR name, UInt32 wow)
/*
#ifdef _WIN64
return RegDeleteKeyExW
return RegDeleteKeyExW
#else
*/
if (!func_RegDeleteKeyExW)
return E_NOTIMPL;
return func_RegDeleteKeyExW
if (!func_RegDeleteKeyExW)
return E_NOTIMPL;
return func_RegDeleteKeyExW
// #endif
(parentKey, GetUnicodeString(name), wow, 0);
}

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp
#include "stdafx.h"
#include "StdAfx.h"

View File

@@ -167,6 +167,7 @@ STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message)
return CheckBreak2();
}
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s);
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s)
{
s.Empty();

View File

@@ -3,6 +3,10 @@
#include "StdAfx.h"
#ifdef __clang__
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#endif
#include "../../../Common/MyWindows.h"
#include "../../../Common/MyInitGuid.h"
@@ -39,7 +43,9 @@ const char *g_PluginName_for_Error = "7-Zip";
}
#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION return FALSE;
#endif
BOOL WINAPI DllMain(
#ifdef UNDER_CE

View File

@@ -53,7 +53,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\Far\Plugins\7-Zip\7-ZipFar.dll" /opt:NOWIN98
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Progs\Far\Plugins\7-Zip\7-ZipFar.dll" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Far - Win32 Debug"
@@ -80,7 +80,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Far\Plugins\7-Zip\7-ZipFar.dll" /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Progs\Far\Plugins\7-Zip\7-ZipFar.dll" /pdbtype:sept
!ENDIF

View File

@@ -26,7 +26,7 @@ struct CFileInfoStrings
AString Time;
};
void SetFileInfoStrings(const CFileInfo &fileInfo,
static void SetFileInfoStrings(const CFileInfo &fileInfo,
CFileInfoStrings &fileInfoStrings)
{
char buffer[256];

View File

@@ -197,10 +197,12 @@ void CPlugin::EnterToDirectory(const UString &dirName)
s = "..";
_folder->BindToFolder(s, &newFolder);
if (!newFolder)
{
if (dirName.IsEmpty())
return;
else
throw 40325;
}
_folder = newFolder;
}
@@ -457,7 +459,7 @@ static AString PropToString2(const NCOM::CPropVariant &prop, PROPID propID)
return s;
}
static void AddPropertyString(InfoPanelLine *lines, int &numItems, PROPID propID, const wchar_t *name,
static void AddPropertyString(InfoPanelLine *lines, unsigned &numItems, PROPID propID, const wchar_t *name,
const NCOM::CPropVariant &prop)
{
if (prop.vt != VT_EMPTY)
@@ -472,7 +474,7 @@ static void AddPropertyString(InfoPanelLine *lines, int &numItems, PROPID propID
}
}
static void InsertSeparator(InfoPanelLine *lines, int &numItems)
static void InsertSeparator(InfoPanelLine *lines, unsigned &numItems)
{
if (numItems < kNumInfoLinesMax)
{
@@ -528,7 +530,7 @@ void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
MyStringCopy(m_InfoLines[1].Text, g_StartupInfo.GetMsgString(NMessageID::kArchiveType));
MyStringCopy(m_InfoLines[1].Data, (const char *)UnicodeStringToMultiByte(_archiveTypeName, CP_OEMCP));
int numItems = 2;
unsigned numItems = 2;
{
CMyComPtr<IFolderProperties> folderProperties;

View File

@@ -4,6 +4,9 @@
#include <stdio.h>
#include "../../../Common/StringConvert.h"
#include "FarUtils.h"
#include "Messages.h"
#include "Plugin.h"
#include "UpdateCallbackFar.h"
@@ -28,16 +31,37 @@ int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, int opMode)
g_StartupInfo.GetMsgString(NMessageID::kDeleteDelete),
g_StartupInfo.GetMsgString(NMessageID::kDeleteCancel)
};
char msg[1024];
// char msg[1024];
AString str1;
if (numItems == 1)
{
sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteFile), panelItems[0].FindData.cFileName);
msgItems[1] = msg;
str1 = g_StartupInfo.GetMsgString(NMessageID::kDeleteFile);
AString name (panelItems[0].FindData.cFileName);
const unsigned kSizeLimit = 48;
if (name.Len() > kSizeLimit)
{
UString s = MultiByteToUnicodeString(name, CP_OEMCP);
ReduceString(s, kSizeLimit);
name = UnicodeStringToMultiByte(s, CP_OEMCP);
}
str1.Replace(AString ("%.40s"), name);
msgItems[1] = str1;
// sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteFile), panelItems[0].FindData.cFileName);
// msgItems[2] = msg;
}
else if (numItems > 1)
{
sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles), numItems);
msgItems[1] = msg;
str1 = g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles);
{
AString n;
n.Add_UInt32(numItems);
str1.Replace(AString ("%d"), n);
}
msgItems[1] = str1;
// sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles), numItems);
// msgItems[1] = msg;
}
if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems, ARRAY_SIZE(msgItems), 2) != 0)
return (FALSE);

View File

@@ -89,7 +89,7 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
}
*/
if (numItems == 0)
if (numItems <= 0)
return NFileOperationReturnCode::kError;
if (_agent->IsThereReadOnlyArc())
@@ -104,14 +104,18 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
NCompression::CInfo compressionInfo;
compressionInfo.Load();
int methodIndex = 0;
int i;
for (i = ARRAY_SIZE(g_MethodMap) - 1; i >= 0; i--)
unsigned methodIndex = 0;
unsigned i;
for (i = ARRAY_SIZE(g_MethodMap); i != 0;)
{
i--;
if (compressionInfo.Level >= g_MethodMap[i])
{
methodIndex = i;
break;
}
}
const int kMethodRadioIndex = 2;
const int kModeRadioIndex = kMethodRadioIndex + 7;
@@ -200,10 +204,10 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
UStringVector fileNames;
fileNames.ClearAndReserve(numItems);
for (i = 0; i < numItems; i++)
for (i = 0; i < (unsigned)numItems; i++)
fileNames.AddInReserved(MultiByteToUnicodeString(panelItems[i].FindData.cFileName, CP_OEMCP));
CObjArray<const wchar_t *> fileNamePointers(numItems);
for (i = 0; i < numItems; i++)
for (i = 0; i < (unsigned)numItems; i++)
fileNamePointers[i] = fileNames[i];
CMyComPtr<IOutFolderArchive> outArchive;
@@ -459,29 +463,36 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
const int kMethodRadioIndex = kArchiveNameIndex + 2;
const int kModeRadioIndex = kMethodRadioIndex + 7;
char updateAddToArchiveString[512];
// char updateAddToArchiveString[512];
AString str1;
{
const CArcInfoEx &arcInfo = codecs->Formats[archiverIndex];
const AString s (UnicodeStringToMultiByte(arcInfo.Name, CP_OEMCP));
str1 = g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive);
str1.Replace(AString ("%s"), s);
/*
sprintf(updateAddToArchiveString,
g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive), (const char *)s);
*/
}
int methodIndex = 0;
int i;
for (i = ARRAY_SIZE(g_MethodMap) - 1; i >= 0; i--)
unsigned methodIndex = 0;
unsigned i;
for (i = ARRAY_SIZE(g_MethodMap); i != 0;)
{
i--;
if (compressionInfo.Level >= g_MethodMap[i])
{
methodIndex = i;
break;
}
}
const struct CInitDialogItem initItems[]=
{
{ DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL },
{ DI_TEXT, 5, 2, 0, 0, false, false, 0, false, -1, updateAddToArchiveString, NULL },
{ DI_TEXT, 5, 2, 0, 0, false, false, 0, false, -1, str1, NULL },
{ DI_EDIT, 5, 3, 70, 3, true, false, DIF_HISTORY, false, -1, archiveNameA, kArchiveHistoryKeyName},
// { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, arcName, NULL},

View File

@@ -20,7 +20,6 @@ CURRENT_OBJS = \
$O\PluginWrite.obj \
$O\ProgressBox.obj \
$O\UpdateCallbackFar.obj \
$O\UTFConvert.obj \
COMMON_OBJS = \
$O\IntToString.obj \
@@ -29,6 +28,7 @@ COMMON_OBJS = \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\MyVector.obj \
$O\UTFConvert.obj \
$O\Wildcard.obj \
WIN_OBJS = \

View File

@@ -6,6 +6,8 @@
#include "../../MyVersion.h"
#include "../Common/LoadCodecs.h"
#include "AboutDialog.h"
#include "PropertyNameRes.h"
@@ -23,8 +25,20 @@ static const UInt32 kLangIDs[] =
#define LLL_(quote) L##quote
#define LLL(quote) LLL_(quote)
extern CCodecs *g_CodecsObj;
bool CAboutDialog::OnInit()
{
#ifdef EXTERNAL_CODECS
if (g_CodecsObj)
{
UString s;
g_CodecsObj->GetCodecsErrorMessage(s);
if (!s.IsEmpty())
MessageBoxW(GetParent(), s, L"7-Zip", MB_ICONERROR);
}
#endif
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
SetItemText(IDT_ABOUT_VERSION, UString("7-Zip " MY_VERSION_CPU));
SetItemText(IDT_ABOUT_DATE, LLL(MY_DATE));

View File

@@ -18,7 +18,7 @@ CAPTION "About 7-Zip"
{
DEFPUSHBUTTON "OK", IDOK, bx1, by, bxs, bys
PUSHBUTTON "www.7-zip.org", IDB_ABOUT_HOMEPAGE, bx2, by, bxs, bys
ICON IDI_LOGO, -1, m, m, 32, 32, SS_REALSIZEIMAGE,
ICON IDI_LOGO, -1, m, m, 32, 32, SS_REALSIZEIMAGE
LTEXT "", IDT_ABOUT_VERSION, m, 54, xc, 8
LTEXT "", IDT_ABOUT_DATE, m, 67, xc, 8
LTEXT MY_COPYRIGHT, -1, m, 80, xc, 8

View File

@@ -86,7 +86,7 @@ HRESULT CAltStreamsFolder::Init(const FString &path /* , IFolderFolder *parentFo
{
CFileInfo fi;
if (!fi.Find(_pathBaseFile))
return GetLastError();
return GetLastError_noZero_HRESULT();
}
unsigned prefixSize = GetFsParentPrefixSize(_pathBaseFile);
@@ -612,7 +612,7 @@ static HRESULT CopyStream(
FString destPath = destPathSpec;
if (CompareFileNames(destPath, srcPath) == 0)
{
RINOK(SendMessageError(callback, "can not copy file onto itself", destPath));
RINOK(SendMessageError(callback, "Cannot copy file onto itself", destPath));
return E_ABORT;
}
@@ -716,7 +716,7 @@ STDMETHODIMP CAltStreamsFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UI
if (destPath.IsEmpty() /* && !ExtractToStreamCallback */)
return E_INVALIDARG;
bool isAltDest = NName::IsAltPathPrefix(destPath);;
bool isAltDest = NName::IsAltPathPrefix(destPath);
bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
if (isDirectPath)
@@ -764,7 +764,7 @@ STDMETHODIMP CAltStreamsFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /
if (CompareFileNames(fromFolderPath, fs2us(_pathPrefix)) == 0)
{
RINOK(SendMessageError(callback, "can not copy file onto itself", _pathPrefix));
RINOK(SendMessageError(callback, "Cannot copy file onto itself", _pathPrefix));
return E_ABORT;
}

View File

@@ -117,7 +117,7 @@ void CApp::SetListSettings()
HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat,
bool needOpenArc,
bool &archiveIsOpened, bool &encrypted)
COpenResult &openRes)
{
if (Panels[panelIndex].PanelCreated)
return S_OK;
@@ -138,7 +138,7 @@ HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UStr
return Panels[panelIndex].Create(_window, _window,
id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState,
needOpenArc,
archiveIsOpened, encrypted);
openRes);
}
@@ -282,7 +282,7 @@ void CApp::SaveToolbarChanges()
}
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, bool &archiveIsOpened, bool &encrypted)
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes)
{
_window.Attach(hwnd);
@@ -334,21 +334,19 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
{
if (NumPanels == 1)
Panels[panelIndex]._xSize = xSizes[0] + xSizes[1];
bool archiveIsOpened2 = false;
bool encrypted2 = false;
COpenResult openRes2;
UString path;
if (isMainPanel)
path = mainPath;
RINOK(CreateOnePanel(panelIndex, path, arcFormat,
isMainPanel && needOpenArc,
archiveIsOpened2, encrypted2));
*(isMainPanel ? &openRes : &openRes2)));
if (isMainPanel)
{
archiveIsOpened = archiveIsOpened2;
encrypted = encrypted2;
if (needOpenArc && !archiveIsOpened2)
if (needOpenArc && !openRes.ArchiveIsOpened)
return S_OK;
}
}
@@ -365,10 +363,10 @@ HRESULT CApp::SwitchOnOffOnePanel()
if (NumPanels == 1)
{
NumPanels++;
bool archiveIsOpened, encrypted;
COpenResult openRes;
RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), UString(),
false, // needOpenArc
archiveIsOpened, encrypted));
openRes));
Panels[1 - LastFocusedPanel].Enable(true);
Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL);
}
@@ -414,13 +412,13 @@ void CApp::Release()
// reduces path to part that exists on disk (or root prefix of path)
// output path is normalized (with WCHAR_PATH_SEPARATOR)
static void ReducePathToRealFileSystemPath(UString &path)
static void Reduce_Path_To_RealFileSystemPath(UString &path)
{
unsigned prefixSize = GetRootPrefixSize(path);
while (!path.IsEmpty())
{
if (NFind::DoesDirExist(us2fs(path)))
if (NFind::DoesDirExist_FollowLink(us2fs(path)))
{
NName::NormalizeDirPathPrefix(path);
break;
@@ -431,10 +429,10 @@ static void ReducePathToRealFileSystemPath(UString &path)
path.Empty();
break;
}
path.DeleteFrom(pos + 1);
path.DeleteFrom((unsigned)(pos + 1));
if ((unsigned)pos + 1 == prefixSize)
break;
path.DeleteFrom(pos);
path.DeleteFrom((unsigned)pos);
}
}
@@ -443,7 +441,7 @@ static void ReducePathToRealFileSystemPath(UString &path)
static bool CheckFolderPath(const UString &path)
{
UString pathReduced = path;
ReducePathToRealFileSystemPath(pathReduced);
Reduce_Path_To_RealFileSystemPath(pathReduced);
return (pathReduced == path);
}
*/
@@ -463,6 +461,7 @@ static void AddValuePair1(UString &s, UINT resourceID, UInt64 size)
s.Add_LF();
}
void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size);
void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size)
{
if (num == 0)
@@ -601,7 +600,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
return;
destPath = destPanel.GetFsPath();
if (NumPanels == 1)
ReducePathToRealFileSystemPath(destPath);
Reduce_Path_To_RealFileSystemPath(destPath);
}
}
@@ -660,7 +659,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
{
if (NumPanels == 1 || CompareFileNames(destPath, srcPanel.GetFsPath()) == 0)
{
srcPanel.MessageBox_Error(L"Can not copy files onto itself");
srcPanel.MessageBox_Error(L"Cannot copy files onto itself");
return;
}
@@ -882,9 +881,11 @@ void CApp::OnSetSubFolder(int srcPanelIndex)
return;
if (!newFolder)
{
const UString parentPrefix = srcPanel.GetParentDirPrefix();
bool archiveIsOpened, encrypted;
destPanel.BindToPath(parentPrefix, UString(), archiveIsOpened, encrypted);
{
const UString parentPrefix = srcPanel.GetParentDirPrefix();
COpenResult openRes;
destPanel.BindToPath(parentPrefix, UString(), openRes);
}
destPanel.RefreshListCtrl();
return;
}
@@ -936,7 +937,7 @@ void CApp::OnNotify(int /* ctrlID */, LPNMHDR pnmh)
g_ToolTipBuffer.Empty();
SetButtonText((int)info->hdr.idFrom, g_ToolTipBuffer);
g_ToolTipBufferSys = GetSystemString(g_ToolTipBuffer);
info->lpszText = (LPTSTR)(LPCTSTR)g_ToolTipBufferSys;
info->lpszText = g_ToolTipBufferSys.Ptr_non_const();
return;
}
#ifndef _UNICODE
@@ -946,7 +947,7 @@ void CApp::OnNotify(int /* ctrlID */, LPNMHDR pnmh)
info->hinst = 0;
g_ToolTipBuffer.Empty();
SetButtonText((int)info->hdr.idFrom, g_ToolTipBuffer);
info->lpszText = (LPWSTR)(LPCWSTR)g_ToolTipBuffer;
info->lpszText = g_ToolTipBuffer.Ptr_non_const();
return;
}
#endif
@@ -971,7 +972,7 @@ void CApp::RefreshTitlePanel(unsigned panelIndex, bool always)
RefreshTitle(always);
}
void AddUniqueStringToHead(UStringVector &list, const UString &s)
static void AddUniqueStringToHead(UStringVector &list, const UString &s)
{
for (unsigned i = 0; i < list.Size();)
if (s.IsEqualTo_NoCase(list[i]))

View File

@@ -89,22 +89,24 @@ public:
STDMETHOD(Drop)(IDataObject * dataObject, DWORD keyState, POINTL pt, DWORD *effect);
CDropTarget():
TargetPanelIndex(-1),
SrcPanelIndex(-1),
m_IsAppTarget(false),
m_Panel(0),
App(0),
m_PanelDropIsAllowed(false),
m_DropIsAllowed(false),
m_SelectionIndex(-1),
m_DropIsAllowed(false),
m_PanelDropIsAllowed(false),
m_SubFolderIndex(-1),
m_SetPathIsOK(false) {}
m_Panel(NULL),
m_IsAppTarget(false),
m_SetPathIsOK(false),
App(NULL),
SrcPanelIndex(-1),
TargetPanelIndex(-1)
{}
CApp *App;
int SrcPanelIndex; // index of D&D source_panel
int TargetPanelIndex; // what panel to use as target_panel of Application
};
class CApp
{
public:
@@ -173,8 +175,8 @@ public:
void OnSetSameFolder(int srcPanelIndex);
void OnSetSubFolder(int srcPanelIndex);
HRESULT CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, bool needOpenArc, bool &archiveIsOpened, bool &encrypted);
HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, bool &archiveIsOpened, bool &encrypted);
HRESULT CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, bool needOpenArc, COpenResult &openRes);
HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes);
void Read();
void Save();
void Release();
@@ -196,7 +198,12 @@ public:
void Delete(bool toRecycleBin) { GetFocusedPanel().DeleteItems(toRecycleBin); }
HRESULT CalculateCrc2(const UString &methodName);
void CalculateCrc(const char *methodName);
void DiffFiles(const UString &path1, const UString &path2);
void DiffFiles();
void VerCtrl(unsigned id);
void Split();
void Combine();
void Properties() { GetFocusedPanel().Properties(); }

View File

@@ -4,7 +4,7 @@
#include "../../../Common/MyWindows.h"
#include <commctrl.h>
#include <CommCtrl.h>
#ifndef UNDER_CE
#include "../../../Windows/CommonDialog.h"
@@ -139,7 +139,7 @@ public:
UStringVector Filters;
UString FilterDescription;
CBrowseDialog(): FolderMode(false), _showDots(false), ShowAllFiles(true) {}
CBrowseDialog(): _showDots(false), FolderMode(false), ShowAllFiles(true) {}
void SetFilter(const UString &s);
INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_BROWSE, parent); }
int CompareItems(LPARAM lParam1, LPARAM lParam2);
@@ -235,7 +235,7 @@ bool CBrowseDialog::OnInit()
column.fmt = LVCFMT_RIGHT;
column.cx = 100;
const UString s = LangString(IDS_PROP_SIZE);
column.pszText = (wchar_t *)(const wchar_t *)s;
column.pszText = s.Ptr_non_const();
_list.InsertColumn(2, &column);
}
@@ -476,7 +476,7 @@ bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, US
return false;
int pos = s.ReverseFind_PathSepar();
parentPrefix.SetFrom(s, pos + 1);
name = s.Ptr(pos + 1);
name = s.Ptr((unsigned)(pos + 1));
return true;
}
@@ -604,7 +604,7 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
int subItem = 0;
item.iSubItem = subItem++;
item.lParam = kParentIndex;
item.pszText = (wchar_t *)(const wchar_t *)itemName;
item.pszText = itemName.Ptr_non_const();
item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix);
if (item.iImage < 0)
item.iImage = 0;
@@ -626,7 +626,7 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
int subItem = 0;
item.iSubItem = subItem++;
item.lParam = i;
item.pszText = (wchar_t *)(const wchar_t *)name;
item.pszText = name.Ptr_non_const();
const UString fullPath = DirPrefix + name;
#ifndef UNDER_CE
@@ -953,7 +953,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
if (path.Back() == WCHAR_PATH_SEPARATOR)
{
path.DeleteBack();
result.Insert(0, WCHAR_PATH_SEPARATOR);;
result.Insert(0, WCHAR_PATH_SEPARATOR);
}
int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR) + 1;
UString cur = path.Ptr(pos);

View File

@@ -58,7 +58,7 @@ CEnumFormatEtc::~CEnumFormatEtc()
for (ULONG i = 0; i < m_NumFormats; i++)
if (m_Formats[i].ptd)
CoTaskMemFree(m_Formats[i].ptd);
delete[]m_Formats;
delete []m_Formats;
}
}

View File

@@ -3,7 +3,7 @@
#ifndef __ENUMFORMATETC_H
#define __ENUMFORMATETC_H
#include <windows.h>
#include "../../../Common/MyWindows.h"
HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat);

View File

@@ -262,6 +262,7 @@ STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *s)
#endif
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s);
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s)
{
s.Empty();
@@ -449,6 +450,7 @@ static void AddNewLineString(UString &s, const UString &m)
s.Add_LF();
}
UString GetOpenArcErrorMessage(UInt32 errorFlags);
UString GetOpenArcErrorMessage(UInt32 errorFlags)
{
UString s;
@@ -523,6 +525,7 @@ static UString GetBracedType(const wchar_t *type)
return s;
}
void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result);
void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
{
FOR_VECTOR (level, arcLink.Arcs)
@@ -632,7 +635,9 @@ HRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
if (result == S_OK)
return result;
NumArchiveErrors++;
if (result == E_ABORT || result == ERROR_DISK_FULL)
if (result == E_ABORT
|| result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)
)
return result;
Add_ArchiveName_Error();
@@ -702,7 +707,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
{
if (!destFileInfo.IsDir())
{
RINOK(MessageError("can not replace file with folder with same name", destPathSys));
RINOK(MessageError("Cannot replace file with folder with same name", destPathSys));
return E_ABORT;
}
*writeAnswer = BoolToInt(false);
@@ -711,7 +716,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
if (destFileInfo.IsDir())
{
RINOK(MessageError("can not replace folder with file with same name", destPathSys));
RINOK(MessageError("Cannot replace folder with file with same name", destPathSys));
*writeAnswer = BoolToInt(false);
return S_OK;
}
@@ -725,7 +730,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
Int32 overwriteResult;
UString destPathSpec = destPath;
int slashPos = destPathSpec.ReverseFind_PathSepar();
destPathSpec.DeleteFrom(slashPos + 1);
destPathSpec.DeleteFrom((unsigned)(slashPos + 1));
destPathSpec += fs2us(destFileInfo.Name);
RINOK(AskOverwrite(
@@ -746,25 +751,28 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
default:
return E_FAIL;
}
break;
}
default:
break;
}
if (OverwriteMode == NExtract::NOverwriteMode::kRename)
{
if (!AutoRenamePath(destPathSys))
{
RINOK(MessageError("can not create name for file", destPathSys));
RINOK(MessageError("Cannot create name for file", destPathSys));
return E_ABORT;
}
destPathResultTemp = fs2us(destPathSys);
}
else
{
if (NFind::DoesFileExist(destPathSys))
if (NFind::DoesFileExist_Raw(destPathSys))
if (!NDir::DeleteFileAlways(destPathSys))
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
RINOK(MessageError("can not delete output file", destPathSys));
RINOK(MessageError("Cannot delete output file", destPathSys));
return E_ABORT;
}
}
@@ -950,9 +958,8 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypt
}
static const size_t k_SizeT_MAX = (size_t)((size_t)0 - 1);
static const UInt32 kBlockSize = ((UInt32)1 << 31);
// static const UInt32 kBlockSize = ((UInt32)1 << 31);
STDMETHODIMP CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
@@ -977,8 +984,9 @@ STDMETHODIMP CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *proce
if (b < a)
b = a;
useMem = false;
if (b <= k_SizeT_MAX && b <= MaxTotalAllocSize)
useMem = file.Data.ReAlloc_KeepData((size_t)b, (size_t)file.Size);
const size_t b_sizet = (size_t)b;
if (b == b_sizet && b <= MaxTotalAllocSize)
useMem = file.Data.ReAlloc_KeepData(b_sizet, (size_t)file.Size);
}
if (useMem)
{

View File

@@ -289,21 +289,19 @@ public:
bool MultiArcMode;
CExtractCallbackImp():
#ifndef _SFX
_hashCalc(NULL),
#endif
ProcessAltStreams(true),
StreamMode(false),
OverwriteMode(NExtract::NOverwriteMode::kAsk),
#ifndef _NO_CRYPTO
PasswordIsDefined(false),
PasswordWasAsked(false),
#endif
OverwriteMode(NExtract::NOverwriteMode::kAsk),
StreamMode(false),
ProcessAltStreams(true),
_totalFilesDefined(false),
_totalBytesDefined(false),
MultiArcMode(false)
#ifndef _SFX
, _hashCalc(NULL)
#endif
{}
~CExtractCallbackImp();

View File

@@ -4,7 +4,7 @@
#include "../../../Common/MyWindows.h"
#include <shlwapi.h>
#include <Shlwapi.h>
#include "../../../../C/Alloc.h"
#ifdef _WIN32
@@ -40,19 +40,24 @@ using namespace NWindows;
using namespace NFile;
using namespace NFind;
#define MAX_LOADSTRING 100
#define MENU_HEIGHT 26
// #define MAX_LOADSTRING 100
extern
bool g_RAM_Size_Defined;
bool g_LargePagesMode = false;
bool g_OpenArchive = false;
bool g_RAM_Size_Defined;
static bool g_LargePagesMode = false;
// static bool g_OpenArchive = false;
static bool g_Maximized = false;
extern
UInt64 g_RAM_Size;
UInt64 g_RAM_Size;
#ifdef _WIN32
extern
HINSTANCE g_hInstance;
HINSTANCE g_hInstance;
#endif
@@ -66,6 +71,8 @@ void FreeGlobalCodecs();
#ifndef UNDER_CE
extern
DWORD g_ComCtl32Version;
DWORD g_ComCtl32Version;
static DWORD GetDllVersion(LPCTSTR dllName)
@@ -74,7 +81,7 @@ static DWORD GetDllVersion(LPCTSTR dllName)
HINSTANCE hinstDll = LoadLibrary(dllName);
if (hinstDll)
{
DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)(void *)GetProcAddress(hinstDll, "DllGetVersion");
if (pDllGetVersion)
{
DLLVERSIONINFO dvi;
@@ -93,19 +100,19 @@ static DWORD GetDllVersion(LPCTSTR dllName)
bool g_IsSmallScreen = false;
extern
bool g_LVN_ITEMACTIVATE_Support;
bool g_LVN_ITEMACTIVATE_Support = true;
// LVN_ITEMACTIVATE replaces both NM_DBLCLK & NM_RETURN
// Windows 2000
// NT/98 + IE 3 (g_ComCtl32Version >= 4.70)
const int kNumDefaultPanels = 1;
static const int kNumDefaultPanels = 1;
static const int kSplitterWidth = 4;
static const int kSplitterRateMax = 1 << 16;
static const int kPanelSizeMin = 120;
const int kSplitterWidth = 4;
int kSplitterRateMax = 1 << 16;
int kPanelSizeMin = 120;
// bool OnMenuCommand(HWND hWnd, int id);
class CSplitterPos
{
@@ -343,7 +350,7 @@ typedef BOOL (WINAPI *Func_IsWow64Process)(HANDLE, PBOOL);
static void Set_Wow64()
{
g_Is_Wow64 = false;
Func_IsWow64Process fnIsWow64Process = (Func_IsWow64Process)GetProcAddress(
Func_IsWow64Process fnIsWow64Process = (Func_IsWow64Process)(void *)GetProcAddress(
GetModuleHandleA("kernel32.dll"), "IsWow64Process");
if (fnIsWow64Process)
{
@@ -356,6 +363,7 @@ static void Set_Wow64()
#endif
bool IsLargePageSupported();
bool IsLargePageSupported()
{
#ifdef _WIN64
@@ -383,7 +391,7 @@ static void SetMemoryLock()
if (!IsLargePageSupported())
return;
// if (ReadLockMemoryAdd())
NSecurity::AddLockMemoryPrivilege();
NSecurity::AddLockMemoryPrivilege();
if (ReadLockMemoryEnable())
if (NSecurity::Get_LargePages_RiskLevel() == 0)
@@ -393,6 +401,8 @@ static void SetMemoryLock()
}
}
extern
bool g_SymLink_Supported;
bool g_SymLink_Supported = false;
static void Set_SymLink_Supported()
@@ -443,7 +453,9 @@ static void ErrorMessage(const char *s)
}
#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION ErrorMessage("Unsupported Windows version"); return 1;
#endif
static int WINAPI WinMain2(int nCmdShow)
{
@@ -756,12 +768,12 @@ static void ExecuteCommand(UINT commandID)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
{
unsigned wmId = LOWORD(wParam);
unsigned wmEvent = HIWORD(wParam);
if ((HWND) lParam != NULL && wmEvent != 0)
break;
if (wmId >= kMenuCmdID_Toolbar_Start && wmId < kMenuCmdID_Toolbar_End)
@@ -772,6 +784,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (OnMenuCommand(hWnd, wmId))
return 0;
break;
}
case WM_INITMENUPOPUP:
OnMenuActivating(hWnd, HMENU(wParam), LOWORD(lParam));
break;
@@ -837,9 +850,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
g_App.CreateDragTarget();
bool archiveIsOpened;
bool encrypted;
bool needOpenFile = false;
COpenResult openRes;
bool needOpenArc = false;
UString fullPath = g_MainPath;
if (!fullPath.IsEmpty() /* && g_OpenArchive */)
@@ -850,29 +862,34 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (NFile::NName::GetFullPath(us2fs(fullPath), fullPathF))
fullPath = fs2us(fullPathF);
}
if (NFile::NFind::DoesFileExist(us2fs(fullPath)))
needOpenFile = true;
if (NFile::NFind::DoesFileExist_FollowLink(us2fs(fullPath)))
needOpenArc = true;
}
HRESULT res = g_App.Create(hWnd, fullPath, g_ArcFormat, xSizes,
needOpenFile,
archiveIsOpened, encrypted);
needOpenArc,
openRes);
if (res == E_ABORT)
return -1;
if (needOpenFile && !archiveIsOpened || res != S_OK)
if ((needOpenArc && !openRes.ArchiveIsOpened) || res != S_OK)
{
UString m ("Error");
if (res == S_FALSE || res == S_OK)
{
m = MyFormatNew(encrypted ?
m = MyFormatNew(openRes.Encrypted ?
IDS_CANT_OPEN_ENCRYPTED_ARCHIVE :
IDS_CANT_OPEN_ARCHIVE,
fullPath);
}
else if (res != S_OK)
m = HResultToMessage(res);
if (!openRes.ErrorMessage.IsEmpty())
{
m.Add_LF();
m += openRes.ErrorMessage;
}
ErrorMessage(m);
return -1;
}
@@ -954,7 +971,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
g_Panel[1]._listView.MoveWindow(xSize - xWidth, 0, xWidth, ySize);
*/
return 0;
break;
// break;
}
case WM_SETFOCUS:

View File

@@ -55,7 +55,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /opt:NOWIN98
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zFM.exe" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "FM - Win32 Debug"
@@ -82,7 +82,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zFM.exe" /pdbtype:sept
!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU"
@@ -109,7 +109,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /opt:NOWIN98
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zFM.exe" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "FM - Win32 DebugU"
@@ -137,7 +137,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zFM.exe" /pdbtype:sept
!ENDIF
@@ -393,6 +393,10 @@ SOURCE=.\PanelSort.cpp
SOURCE=.\PanelSplitFile.cpp
# End Source File
# Begin Source File
SOURCE=.\VerCtrl.cpp
# End Source File
# End Group
# Begin Group "Dialog"

View File

@@ -7,8 +7,8 @@ LIBS = $(LIBS) ceshell.lib Commctrl.lib
!ELSE
LIBS = $(LIBS) comctl32.lib htmlhelp.lib comdlg32.lib Mpr.lib Gdi32.lib
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -DSUPPORT_DEVICE_FILE
LFLAGS = $(LFLAGS) /DELAYLOAD:mpr.dll
LIBS = $(LIBS) delayimp.lib
LFLAGS = $(LFLAGS) /DELAYLOAD:mpr.dll
LIBS = $(LIBS) delayimp.lib
!ENDIF
FM_OBJS = \
@@ -70,6 +70,7 @@ FM_OBJS = \
$O\SettingsPage.obj \
$O\SplitDialog.obj \
$O\SystemPage.obj \
$O\VerCtrl.obj \
!IFNDEF UNDER_CE

View File

@@ -115,15 +115,15 @@ HRESULT CFsFolderStat::Enumerate()
const unsigned len = Path.Len();
CEnumerator enumerator;
enumerator.SetDirPrefix(Path);
CFileInfo fi;
CDirEntry fi;
while (enumerator.Next(fi))
{
if (fi.IsDir())
{
NumFolders++;
Path.DeleteFrom(len);
Path += fi.Name;
RINOK(Enumerate());
NumFolders++;
}
else
{
@@ -136,6 +136,7 @@ HRESULT CFsFolderStat::Enumerate()
#ifndef UNDER_CE
bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size);
bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
{
DWORD highPart;
@@ -171,7 +172,7 @@ bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix)
{
unsigned startIndex = Folders.Size();
const unsigned startIndex = Folders.Size();
{
CEnumerator enumerator;
enumerator.SetDirPrefix(_path + relPrefix);
@@ -261,7 +262,7 @@ HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix)
if (!_flatMode)
return S_OK;
unsigned endIndex = Folders.Size();
const unsigned endIndex = Folders.Size();
for (unsigned i = startIndex; i < endIndex; i++)
LoadSubItems(i, Folders[i]);
return S_OK;
@@ -293,8 +294,9 @@ bool CFSFolder::LoadComments()
return false;
AString s;
char *p = s.GetBuf((unsigned)(size_t)len);
UInt32 processedSize;
file.Read(p, (UInt32)len, processedSize);
size_t processedSize;
if (!file.ReadFull(p, (unsigned)(size_t)len, processedSize))
return false;
s.ReleaseBuf_CalcLen((unsigned)(size_t)len);
if (processedSize != len)
return false;
@@ -506,7 +508,7 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
{
int pos = comment.Find((wchar_t)4);
if (pos >= 0)
comment.DeleteFrom(pos);
comment.DeleteFrom((unsigned)pos);
prop = comment;
}
break;
@@ -784,7 +786,7 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
return E_FAIL;
FString parentPath = _path.Left(pos);
pos = parentPath.ReverseFind_PathSepar();
parentPath.DeleteFrom(pos + 1);
parentPath.DeleteFrom((unsigned)(pos + 1));
if (NName::IsDrivePath_SuperAllowed(parentPath))
{

View File

@@ -203,7 +203,7 @@ struct CCopyStateIO
int ErrorFileIndex;
UString ErrorMessage;
CCopyStateIO(): DeleteSrcFile(false), TotalSize(0), StartPos(0) {}
CCopyStateIO(): TotalSize(0), StartPos(0), DeleteSrcFile(false) {}
HRESULT MyCopyFile(CFSTR inPath, CFSTR outPath, DWORD attrib = INVALID_FILE_ATTRIBUTES);
};

View File

@@ -4,7 +4,7 @@
#include "../../../Common/MyWindows.h"
#include <Winbase.h>
#include <WinBase.h>
#include "../../../Common/Defs.h"
#include "../../../Common/StringConvert.h"
@@ -397,8 +397,8 @@ static HRESULT CopyFile_Ask(
{
RINOK(SendMessageError(state.Callback,
state.MoveMode ?
"can not move file onto itself" :
"can not copy file onto itself"
"Cannot move file onto itself" :
"Cannot copy file onto itself"
, destPath));
return E_ABORT;
}
@@ -497,8 +497,8 @@ static HRESULT CopyFolder(
{
RINOK(SendMessageError(state.Callback,
state.MoveMode ?
"can not copy folder onto itself" :
"can not move folder onto itself"
"Cannot copy folder onto itself" :
"Cannot move folder onto itself"
, destPath));
return E_ABORT;
}
@@ -513,7 +513,7 @@ static HRESULT CopyFolder(
if (!CreateComplexDir(destPath))
{
RINOK(SendMessageError(state.Callback, "can not create folder", destPath));
RINOK(SendMessageError(state.Callback, "Cannot create folder", destPath));
return E_ABORT;
}
@@ -547,7 +547,7 @@ static HRESULT CopyFolder(
{
if (!RemoveDir(srcPath))
{
RINOK(SendMessageError(state.Callback, "can not remove folder", srcPath));
RINOK(SendMessageError(state.Callback, "Cannot remove folder", srcPath));
return E_ABORT;
}
}
@@ -566,7 +566,7 @@ STDMETHODIMP CFSFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
if (destPath.IsEmpty())
return E_INVALIDARG;
bool isAltDest = NName::IsAltPathPrefix(destPath);;
bool isAltDest = NName::IsAltPathPrefix(destPath);
bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
if (isDirectPath)

View File

@@ -8,10 +8,14 @@
#include "../../../Windows/Thread.h"
#include "../Agent/Agent.h"
#include "../GUI/ExtractRes.h"
#include "FileFolderPluginOpen.h"
#include "FormatUtils.h"
#include "LangUtils.h"
#include "OpenCallback.h"
#include "PluginLoader.h"
#include "PropertyName.h"
#include "RegistryPlugins.h"
using namespace NWindows;
@@ -69,18 +73,165 @@ static void SplitNameToPureNameAndExtension(const FString &fullName,
{
pureName.SetFrom(fullName, index);
extensionDelimiter = '.';
extension = fullName.Ptr(index + 1);
extension = fullName.Ptr((unsigned)index + 1);
}
}
HRESULT OpenFileFolderPlugin(
IInStream *inStream,
const FString &path,
const UString &arcFormat,
HMODULE *module,
IFolderFolder **resultFolder,
HWND parentWindow,
bool &encrypted, UString &password)
struct CArcLevelInfo
{
UString Error;
UString Path;
UString Type;
UString ErrorType;
UString ErrorFlags;
};
struct CArcLevelsInfo
{
CObjectVector<CArcLevelInfo> Levels; // LastLevel Is NON-OPEN
};
UString GetOpenArcErrorMessage(UInt32 errorFlags);
static void GetFolderLevels(CMyComPtr<IFolderFolder> &folder, CArcLevelsInfo &levels)
{
levels.Levels.Clear();
CMyComPtr<IGetFolderArcProps> getFolderArcProps;
folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps);
if (!getFolderArcProps)
return;
CMyComPtr<IFolderArcProps> arcProps;
getFolderArcProps->GetFolderArcProps(&arcProps);
if (!arcProps)
return;
UInt32 numLevels;
if (arcProps->GetArcNumLevels(&numLevels) != S_OK)
numLevels = 0;
for (UInt32 level = 0; level <= numLevels; level++)
{
const PROPID propIDs[] = { kpidError, kpidPath, kpidType, kpidErrorType };
CArcLevelInfo lev;
for (Int32 i = 0; i < 4; i++)
{
CMyComBSTR name;
NCOM::CPropVariant prop;
if (arcProps->GetArcProp(level, propIDs[i], &prop) != S_OK)
continue;
if (prop.vt != VT_EMPTY)
{
UString *s = NULL;
switch (propIDs[i])
{
case kpidError: s = &lev.Error; break;
case kpidPath: s = &lev.Path; break;
case kpidType: s = &lev.Type; break;
case kpidErrorType: s = &lev.ErrorType; break;
}
*s = (prop.vt == VT_BSTR) ? prop.bstrVal : L"?";
}
}
{
NCOM::CPropVariant prop;
if (arcProps->GetArcProp(level, kpidErrorFlags, &prop) == S_OK)
{
UInt32 flags = GetOpenArcErrorFlags(prop);
if (flags != 0)
lev.ErrorFlags = GetOpenArcErrorMessage(flags);
}
}
levels.Levels.Add(lev);
}
}
static UString GetBracedType(const wchar_t *type)
{
UString s ('[');
s += type;
s += ']';
return s;
}
static void GetFolderError(CMyComPtr<IFolderFolder> &folder, UString &open_Errors, UString &nonOpen_Errors)
{
CArcLevelsInfo levs;
GetFolderLevels(folder, levs);
open_Errors.Empty();
nonOpen_Errors.Empty();
FOR_VECTOR (i, levs.Levels)
{
bool isNonOpenLevel = (i == 0);
const CArcLevelInfo &lev = levs.Levels[levs.Levels.Size() - 1 - i];
UString m;
if (!lev.ErrorType.IsEmpty())
{
m = MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(lev.ErrorType));
if (!isNonOpenLevel)
{
m.Add_LF();
m += MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(lev.Type));
}
}
if (!lev.Error.IsEmpty())
{
if (!m.IsEmpty())
m.Add_LF();
m += GetBracedType(lev.Type);
m += " : ";
m += GetNameOfProperty(kpidError, L"Error");
m += " : ";
m += lev.Error;
}
if (!lev.ErrorFlags.IsEmpty())
{
if (!m.IsEmpty())
m.Add_LF();
m += GetNameOfProperty(kpidErrorFlags, L"Errors");
m += ": ";
m += lev.ErrorFlags;
}
if (!m.IsEmpty())
{
if (isNonOpenLevel)
{
UString &s = nonOpen_Errors;
s += lev.Path;
s.Add_LF();
s += m;
}
else
{
UString &s = open_Errors;
if (!s.IsEmpty())
s += "--------------------\n";
s += lev.Path;
s.Add_LF();
s += m;
}
}
}
}
HRESULT CFfpOpen::OpenFileFolderPlugin(IInStream *inStream,
const FString &path, const UString &arcFormat, HWND parentWindow)
{
CObjectVector<CPluginInfo> plugins;
ReadFileFolderPluginInfoList(plugins);
@@ -92,8 +243,8 @@ HRESULT OpenFileFolderPlugin(
FString fileName;
if (slashPos >= 0)
{
dirPrefix.SetFrom(path, slashPos + 1);
fileName = path.Ptr(slashPos + 1);
dirPrefix.SetFrom(path, (unsigned)(slashPos + 1));
fileName = path.Ptr((unsigned)(slashPos + 1));
}
else
fileName = path;
@@ -120,6 +271,8 @@ HRESULT OpenFileFolderPlugin(
}
*/
ErrorMessage.Empty();
FOR_VECTOR (i, plugins)
{
const CPluginInfo &plugin = plugins[i];
@@ -136,24 +289,29 @@ HRESULT OpenFileFolderPlugin(
t.OpenCallbackSpec = new COpenArchiveCallback;
t.OpenCallback = t.OpenCallbackSpec;
t.OpenCallbackSpec->PasswordIsDefined = encrypted;
t.OpenCallbackSpec->Password = password;
t.OpenCallbackSpec->PasswordIsDefined = Encrypted;
t.OpenCallbackSpec->Password = Password;
t.OpenCallbackSpec->ParentWindow = parentWindow;
if (inStream)
t.OpenCallbackSpec->SetSubArchiveName(fs2us(fileName));
else
t.OpenCallbackSpec->LoadFileInfo(dirPrefix, fileName);
{
RINOK(t.OpenCallbackSpec->LoadFileInfo2(dirPrefix, fileName));
}
t.InStream = inStream;
t.Path = fs2us(path);
t.ArcFormat = arcFormat;
UString progressTitle = LangString(IDS_OPENNING);
t.OpenCallbackSpec->ProgressDialog.MainWindow = parentWindow;
t.OpenCallbackSpec->ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
t.OpenCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + L' ';
t.OpenCallbackSpec->ProgressDialog.WaitMode = true;
const UString progressTitle = LangString(IDS_OPENNING);
{
CProgressDialog &pd = t.OpenCallbackSpec->ProgressDialog;
pd.MainWindow = parentWindow;
pd.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
pd.MainAddTitle = progressTitle + L' ';
pd.WaitMode = true;
}
{
NWindows::CThread thread;
@@ -161,23 +319,39 @@ HRESULT OpenFileFolderPlugin(
t.OpenCallbackSpec->StartProgressDialog(progressTitle, thread);
}
if (t.Result == E_ABORT)
if (t.Result != S_FALSE && t.Result != S_OK)
return t.Result;
encrypted = t.OpenCallbackSpec->PasswordIsDefined;
if (t.Folder)
{
UString open_Errors, nonOpen_Errors;
GetFolderError(t.Folder, open_Errors, nonOpen_Errors);
if (!nonOpen_Errors.IsEmpty())
{
ErrorMessage = nonOpen_Errors;
// if (t.Result != S_OK) return t.Result;
/* if there are good open leves, and non0open level,
we could force error as critical error and return error here
but it's better to allow to open such rachives */
// return S_FALSE;
}
}
// if (openCallbackSpec->PasswordWasAsked)
{
Encrypted = t.OpenCallbackSpec->PasswordIsDefined;
Password = t.OpenCallbackSpec->Password;
}
if (t.Result == S_OK)
{
// if (openCallbackSpec->PasswordWasAsked)
{
password = t.OpenCallbackSpec->Password;
}
*module = library.Detach();
*resultFolder = t.Folder.Detach();
return S_OK;
Library.Attach(library.Detach());
// Folder.Attach(t.Folder.Detach());
Folder = t.Folder;
}
if (t.Result != S_FALSE)
return t.Result;
return t.Result;
}
return S_FALSE;
}

View File

@@ -3,7 +3,25 @@
#ifndef __FILE_FOLDER_PLUGIN_OPEN_H
#define __FILE_FOLDER_PLUGIN_OPEN_H
HRESULT OpenFileFolderPlugin(IInStream *inStream, const FString &path, const UString &arcFormat,
HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow, bool &encrypted, UString &password);
#include "../../../Windows/DLL.h"
struct CFfpOpen
{
CLASS_NO_COPY(CFfpOpen)
public:
// out:
bool Encrypted;
UString Password;
NWindows::NDLL::CLibrary Library;
CMyComPtr<IFolderFolder> Folder;
UString ErrorMessage;
CFfpOpen(): Encrypted (false) {}
HRESULT OpenFileFolderPlugin(IInStream *inStream,
const FString &path, const UString &arcFormat, HWND parentWindow);
};
#endif

View File

@@ -4,7 +4,7 @@
#include "HelpUtils.h"
#if defined(UNDER_CE) || !defined(_WIN32)
#if defined(UNDER_CE) || !defined(_WIN32) /* || !defined(_MSC_VER) */
void ShowHelpWindow(LPCSTR)
{

View File

@@ -23,6 +23,7 @@ static CLang g_Lang;
static bool g_Loaded = false;
static NSynchronization::CCriticalSection g_CriticalSection;
bool LangOpen(CLang &lang, CFSTR fileName);
bool LangOpen(CLang &lang, CFSTR fileName)
{
return lang.Open(fileName, "7-Zip");
@@ -145,7 +146,7 @@ static const char * const kLangs =
"it.ja.ko.nl.no.=nb.=nn.pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.sk.sq.sv.th.tr."
"ur.id.uk.be.sl.et.lv.lt.tg.fa.vi.hy.az.eu.hsb.mk."
"st.ts.tn.ve.xh.zu.af.ka.fo.hi.mt.se.ga.yi.ms.kk."
"ky.sw.tk.uz.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa."
"ky.sw.tk.uz.-latn.-cyrl.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa."
"mn.=mn.=mng.bo.cy.kh.lo.my.gl.kok..sd.syr.si..iu.am.tzm."
"ks.ne.fy.ps.tl.dv..ff.ha..yo.qu.st.ba.lb.kl."
"ig.kr.om.ti.gn..la.so.ii..arn..moh..br.."

View File

@@ -36,46 +36,50 @@ static const UInt32 kLangIDs[] =
IDR_LINK_TYPE_HARD,
IDR_LINK_TYPE_SYM_FILE,
IDR_LINK_TYPE_SYM_DIR,
IDR_LINK_TYPE_JUNCTION
IDR_LINK_TYPE_JUNCTION,
IDR_LINK_TYPE_WSL
};
#endif
static bool GetSymLink(CFSTR path, CReparseAttr &attr)
{
NIO::CInFile file;
if (!file.Open(path,
FILE_SHARE_READ,
OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS))
return false;
const unsigned kBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
CByteArr buf(kBufSize);
DWORD returnedSize;
if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize))
static bool GetSymLink(CFSTR path, CReparseAttr &attr, UString &errorMessage)
{
CByteBuffer buf;
if (!NIO::GetReparseData(path, buf, NULL))
return false;
DWORD errorCode = 0;
if (!attr.Parse(buf, returnedSize, errorCode))
if (!attr.Parse(buf, buf.Size()))
{
SetLastError(attr.ErrorCode);
return false;
}
CByteBuffer data2;
if (!FillLinkData(data2, attr.GetPath(), attr.IsSymLink()))
if (!FillLinkData(data2, attr.GetPath(),
!attr.IsMountPoint(), attr.IsSymLink_WSL()))
{
errorMessage = "Cannot reproduce reparse point";
return false;
}
if (data2.Size() != returnedSize ||
memcmp(data2, buf, returnedSize) != 0)
if (data2.Size() != buf.Size() ||
memcmp(data2, buf, buf.Size()) != 0)
{
errorMessage = "mismatch for reproduced reparse point";
return false;
}
return true;
}
static const int k_LinkType_Buttons[] =
{
IDR_LINK_TYPE_HARD,
IDR_LINK_TYPE_SYM_FILE,
IDR_LINK_TYPE_SYM_DIR,
IDR_LINK_TYPE_JUNCTION
IDR_LINK_TYPE_JUNCTION,
IDR_LINK_TYPE_WSL
};
void CLinkDialog::Set_LinkType_Radio(int idb)
@@ -104,16 +108,33 @@ bool CLinkDialog::OnInit()
if (fi.HasReparsePoint())
{
CReparseAttr attr;
bool res = GetSymLink(us2fs(FilePath), attr);
UString error;
bool res = GetSymLink(us2fs(FilePath), attr, error);
if (!res && error.IsEmpty())
{
DWORD lastError = GetLastError();
if (lastError != 0)
error = NError::MyFormatMessage(lastError);
}
UString s = attr.PrintName;
UString s = attr.GetPath();
if (!attr.IsSymLink_WSL())
if (!attr.IsOkNamePair())
{
s += " : ";
s += attr.SubsName;
s += attr.PrintName;
}
if (!res)
{
s.Insert(0, L"ERROR: ");
if (!error.IsEmpty())
{
s += " : ";
s += error;
}
}
SetItemText(IDT_LINK_PATH_TO_CUR, s);
@@ -121,11 +142,13 @@ bool CLinkDialog::OnInit()
_pathFromCombo.SetText(FilePath);
_pathToCombo.SetText(destPath);
if (res)
// if (res)
{
if (attr.IsMountPoint())
linkType = IDR_LINK_TYPE_JUNCTION;
if (attr.IsSymLink())
else if (attr.IsSymLink_WSL())
linkType = IDR_LINK_TYPE_WSL;
else if (attr.IsSymLink_Win())
{
linkType =
fi.IsDir() ?
@@ -140,6 +163,7 @@ bool CLinkDialog::OnInit()
}
else
{
// no ReparsePoint
_pathFromCombo.SetText(AnotherPath);
_pathToCombo.SetText(FilePath);
if (fi.IsDir())
@@ -258,15 +282,18 @@ void CLinkDialog::OnButton_Link()
}
NFind::CFileInfo info1, info2;
bool finded1 = info1.Find(us2fs(from));
bool finded2 = info2.Find(us2fs(to));
const bool finded1 = info1.Find(us2fs(from));
const bool finded2 = info2.Find(us2fs(to));
bool isDirLink = (
const bool isDirLink = (
idb == IDR_LINK_TYPE_SYM_DIR ||
idb == IDR_LINK_TYPE_JUNCTION);
if (finded1 && info1.IsDir() != isDirLink ||
finded2 && info2.IsDir() != isDirLink)
const bool isWSL = (idb == IDR_LINK_TYPE_WSL);
if (!isWSL)
if ((finded1 && info1.IsDir() != isDirLink) ||
(finded2 && info2.IsDir() != isDirLink))
{
ShowError(L"Incorrect link type");
return;
@@ -282,25 +309,41 @@ void CLinkDialog::OnButton_Link()
}
else
{
bool isSymLink = (idb != IDR_LINK_TYPE_JUNCTION);
if (finded1 && !info1.IsDir() && !info1.HasReparsePoint() && info1.Size != 0)
{
UString s ("WARNING: reparse point will hide the data of existing file");
s.Add_LF();
s += from;
ShowError(s);
return;
}
const bool isSymLink = (idb != IDR_LINK_TYPE_JUNCTION);
CByteBuffer data;
if (!FillLinkData(data, to, isSymLink))
if (!FillLinkData(data, to, isSymLink, isWSL))
{
ShowError(L"Incorrect link");
return;
}
CReparseAttr attr;
DWORD errorCode = 0;
if (!attr.Parse(data, data.Size(), errorCode))
if (!attr.Parse(data, data.Size()))
{
ShowError(L"Internal conversion error");
return;
}
if (!NIO::SetReparseData(us2fs(from), isDirLink, data, (DWORD)data.Size()))
bool res;
if (to.IsEmpty())
{
// res = NIO::SetReparseData(us2fs(from), isDirLink, NULL, 0);
res = NIO::DeleteReparseData(us2fs(from));
}
else
res = NIO::SetReparseData(us2fs(from), isDirLink, data, (DWORD)data.Size());
if (!res)
{
ShowLastErrorMessage();
return;
@@ -350,5 +393,7 @@ void CApp::Link()
if (dlg.Create(srcPanel.GetParent()) != IDOK)
return;
// fix it: we should refresh panel with changed link
RefreshTitleAlways();
}

View File

@@ -2,7 +2,7 @@
#include "../../GuiCommon.rc"
#define xc 288
#define yc 200
#define yc 214
#undef xRadioSize
#define xRadioSize xc - m - 2
@@ -20,7 +20,7 @@ BEGIN
LTEXT "", IDT_LINK_PATH_TO_CUR, m, 78, xc, 8
GROUPBOX "Link Type", IDG_LINK_TYPE, m, 104, xc, 76
GROUPBOX "Link Type", IDG_LINK_TYPE, m, 104, xc, 90
CONTROL "Hard Link", IDR_LINK_TYPE_HARD, "Button", BS_AUTORADIOBUTTON | WS_GROUP,
m + m, 120, xRadioSize, 10
@@ -30,6 +30,8 @@ BEGIN
m + m, 148, xRadioSize, 10
CONTROL "Directory Junction", IDR_LINK_TYPE_JUNCTION, "Button", BS_AUTORADIOBUTTON,
m + m, 162, xRadioSize, 10
CONTROL "WSL", IDR_LINK_TYPE_WSL, "Button", BS_AUTORADIOBUTTON,
m + m, 176, xRadioSize, 10
DEFPUSHBUTTON "Link", IDB_LINK_LINK, bx2, by, bxs, bys
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys

View File

@@ -10,6 +10,7 @@
#define IDR_LINK_TYPE_SYM_FILE 7712
#define IDR_LINK_TYPE_SYM_DIR 7713
#define IDR_LINK_TYPE_JUNCTION 7714
#define IDR_LINK_TYPE_WSL 7715
#define IDC_LINK_PATH_FROM 100

View File

@@ -152,7 +152,7 @@ bool CMenuPage::OnInit()
);
if (!NFile::NFind::DoesFileExist(path))
if (!NFile::NFind::DoesFileExist_Raw(path))
{
path.Empty();
EnableItem(dll.ctrl, false);

Some files were not shown because too many files have changed in this diff Show More