mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 00:07:00 -06:00
21.02
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user