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);
}
}
}