mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 21:14:58 -06:00
15.05
This commit is contained in:
committed by
Kornel Lesiński
parent
0713a3ab80
commit
54490d51d5
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,10 @@
|
||||
#include "AgentProxy.h"
|
||||
#include "IFolderArchive.h"
|
||||
|
||||
extern CCodecs *g_CodecsObj;
|
||||
HRESULT LoadGlobalCodecs();
|
||||
void FreeGlobalCodecs();
|
||||
|
||||
class CAgentFolder;
|
||||
|
||||
DECL_INTERFACE(IArchiveFolderInternal, 0x01, 0xC)
|
||||
@@ -27,7 +31,7 @@ DECL_INTERFACE(IArchiveFolderInternal, 0x01, 0xC)
|
||||
|
||||
struct CProxyItem
|
||||
{
|
||||
unsigned ProxyFolderIndex;
|
||||
unsigned DirIndex;
|
||||
unsigned Index;
|
||||
};
|
||||
|
||||
@@ -44,6 +48,7 @@ enum AGENT_OP
|
||||
|
||||
class CAgentFolder:
|
||||
public IFolderFolder,
|
||||
public IFolderAltStreams,
|
||||
public IFolderProperties,
|
||||
public IArchiveGetRawProps,
|
||||
public IGetFolderArcProps,
|
||||
@@ -59,10 +64,11 @@ class CAgentFolder:
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
void LoadFolder(unsigned proxyFolderIndex);
|
||||
void LoadFolder(unsigned proxyDirIndex);
|
||||
public:
|
||||
|
||||
MY_QUERYINTERFACE_BEGIN2(IFolderFolder)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderAltStreams)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderProperties)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
|
||||
MY_QUERYINTERFACE_ENTRY(IGetFolderArcProps)
|
||||
@@ -79,7 +85,8 @@ public:
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
HRESULT BindToFolder_Internal(unsigned proxyFolderIndex, IFolderFolder **resultFolder);
|
||||
HRESULT BindToFolder_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder);
|
||||
HRESULT BindToAltStreams_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder);
|
||||
int GetRealIndex(unsigned index) const;
|
||||
void GetRealIndices(const UInt32 *indices, UInt32 numItems,
|
||||
bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const;
|
||||
@@ -87,6 +94,7 @@ public:
|
||||
// INTERFACE_FolderSetReplaceAltStreamCharsMode(;)
|
||||
|
||||
INTERFACE_FolderFolder(;)
|
||||
INTERFACE_FolderAltStreams(;)
|
||||
INTERFACE_FolderProperties(;)
|
||||
INTERFACE_IArchiveGetRawProps(;)
|
||||
INTERFACE_IFolderGetItemName(;)
|
||||
@@ -108,48 +116,57 @@ public:
|
||||
STDMETHOD(SetFlatMode)(Int32 flatMode);
|
||||
#endif
|
||||
|
||||
CAgentFolder(): _proxyFolderItem(0), _flatMode(0) /* , _replaceAltStreamCharsMode(0) */ {}
|
||||
CAgentFolder():
|
||||
_proxyDirIndex(0),
|
||||
_isAltStreamFolder(false),
|
||||
_flatMode(false),
|
||||
_loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now
|
||||
/* , _replaceAltStreamCharsMode(0) */
|
||||
{}
|
||||
|
||||
void Init(const CProxyArchive *proxyArc, const CProxyArchive2 *proxyArc2,
|
||||
unsigned proxyFolderItem,
|
||||
IFolderFolder *parentFolder,
|
||||
void Init(const CProxyArc *proxy, const CProxyArc2 *proxy2,
|
||||
unsigned proxyDirIndex,
|
||||
/* IFolderFolder *parentFolder, */
|
||||
CAgent *agent)
|
||||
{
|
||||
_proxyArchive = proxyArc;
|
||||
_proxyArchive2 = proxyArc2;
|
||||
_proxyFolderItem = proxyFolderItem;
|
||||
_parentFolder = parentFolder;
|
||||
_proxy = proxy;
|
||||
_proxy2 = proxy2;
|
||||
_proxyDirIndex = proxyDirIndex;
|
||||
_isAltStreamFolder = false;
|
||||
if (_proxy2)
|
||||
_isAltStreamFolder = _proxy2->IsAltDir(proxyDirIndex);
|
||||
// _parentFolder = parentFolder;
|
||||
_agent = (IInFolderArchive *)agent;
|
||||
_agentSpec = agent;
|
||||
}
|
||||
|
||||
void GetPathParts(UStringVector &pathParts);
|
||||
void GetPathParts(UStringVector &pathParts, bool &isAltStreamFolder);
|
||||
HRESULT CommonUpdateOperation(
|
||||
AGENT_OP operation,
|
||||
bool moveMode,
|
||||
const wchar_t *newItemName,
|
||||
const NUpdateArchive::CActionSet *actionSet,
|
||||
const UInt32 *indices, UInt32 numItems,
|
||||
IFolderArchiveUpdateCallback *updateCallback100);
|
||||
IProgress *progress);
|
||||
|
||||
|
||||
void GetPrefix(UInt32 index, UString &prefix) const;
|
||||
UString GetName(UInt32 index) const;
|
||||
UString GetFullPathPrefixPlusPrefix(UInt32 index) const;
|
||||
UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive
|
||||
|
||||
public:
|
||||
const CProxyArchive *_proxyArchive;
|
||||
const CProxyArchive2 *_proxyArchive2;
|
||||
// const CProxyFolder *_proxyFolderItem;
|
||||
unsigned _proxyFolderItem;
|
||||
CMyComPtr<IFolderFolder> _parentFolder;
|
||||
const CProxyArc *_proxy;
|
||||
const CProxyArc2 *_proxy2;
|
||||
unsigned _proxyDirIndex;
|
||||
bool _isAltStreamFolder;
|
||||
// CMyComPtr<IFolderFolder> _parentFolder;
|
||||
CMyComPtr<IInFolderArchive> _agent;
|
||||
CAgent *_agentSpec;
|
||||
|
||||
CRecordVector<CProxyItem> _items;
|
||||
bool _flatMode;
|
||||
bool _loadAltStreams; // in Flat mode
|
||||
// Int32 _replaceAltStreamCharsMode;
|
||||
private:
|
||||
};
|
||||
|
||||
class CAgent:
|
||||
@@ -193,29 +210,28 @@ public:
|
||||
IFolderArchiveUpdateCallback *updateCallback100);
|
||||
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps);
|
||||
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
|
||||
#endif
|
||||
|
||||
CCodecs *_codecs;
|
||||
CMyComPtr<ICompressCodecsInfo> _compressCodecsInfo;
|
||||
|
||||
CAgent();
|
||||
~CAgent();
|
||||
private:
|
||||
HRESULT ReadItems();
|
||||
public:
|
||||
CProxyArchive *_proxyArchive;
|
||||
CProxyArchive2 *_proxyArchive2;
|
||||
CProxyArc *_proxy;
|
||||
CProxyArc2 *_proxy2;
|
||||
CArchiveLink _archiveLink;
|
||||
|
||||
bool ThereIsPathProp;
|
||||
// bool ThereIsAltStreamProp;
|
||||
|
||||
UString ArchiveType;
|
||||
|
||||
FStringVector _names;
|
||||
FString _folderPrefix;
|
||||
|
||||
UString _archiveNamePrefix;
|
||||
bool _updatePathPrefix_is_AltFolder;
|
||||
UString _updatePathPrefix;
|
||||
CAgentFolder *_agentFolder;
|
||||
|
||||
UString _archiveFilePath;
|
||||
@@ -230,11 +246,22 @@ public:
|
||||
IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
|
||||
bool CanUpdate() const;
|
||||
|
||||
bool IsThereReadOnlyArc() const
|
||||
{
|
||||
FOR_VECTOR (i, _archiveLink.Arcs)
|
||||
{
|
||||
const CArc &arc = _archiveLink.Arcs[i];
|
||||
if (!g_CodecsObj->Formats[arc.FormatIndex].UpdateEnabled || arc.IsReadOnly)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
UString GetTypeOfArc(const CArc &arc) const
|
||||
{
|
||||
if (arc.FormatIndex < 0)
|
||||
return L"Parser";
|
||||
return _codecs->GetFormatNamePtr(arc.FormatIndex);
|
||||
return g_CodecsObj->GetFormatNamePtr(arc.FormatIndex);
|
||||
}
|
||||
|
||||
UString GetErrorMessage() const
|
||||
@@ -246,25 +273,29 @@ public:
|
||||
|
||||
UString s2;
|
||||
if (arc.ErrorInfo.ErrorFormatIndex >= 0)
|
||||
s2 = L"Can not open the file as [" + _codecs->Formats[arc.ErrorInfo.ErrorFormatIndex].Name + L"] archive";
|
||||
{
|
||||
s2.AddAscii("Can not open the file as [");
|
||||
s2 += g_CodecsObj->Formats[arc.ErrorInfo.ErrorFormatIndex].Name;
|
||||
s2.AddAscii("] archive");
|
||||
}
|
||||
|
||||
if (!arc.ErrorInfo.ErrorMessage.IsEmpty())
|
||||
{
|
||||
if (!s2.IsEmpty())
|
||||
s2 += L"\n";
|
||||
s2 += L"\n[";
|
||||
s2.Add_LF();
|
||||
s2.AddAscii("\n[");
|
||||
s2 += GetTypeOfArc(arc);
|
||||
s2 += L"]: ";
|
||||
s2.AddAscii("]: ");
|
||||
s2 += arc.ErrorInfo.ErrorMessage;
|
||||
}
|
||||
if (!s2.IsEmpty())
|
||||
{
|
||||
if (!s.IsEmpty())
|
||||
s += L"--------------------\n";
|
||||
s.AddAscii("--------------------\n");
|
||||
s += arc.Path;
|
||||
s += L"\n";
|
||||
s.Add_LF();
|
||||
s += s2;
|
||||
s += L"\n";
|
||||
s.Add_LF();
|
||||
}
|
||||
}
|
||||
return s;
|
||||
@@ -274,23 +305,20 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
|
||||
class CArchiveFolderManager:
|
||||
public IFolderManager,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(IFolderManager)
|
||||
|
||||
INTERFACE_IFolderManager(;)
|
||||
|
||||
CArchiveFolderManager(): _codecs(0) {}
|
||||
private:
|
||||
void LoadFormats();
|
||||
int FindFormat(const UString &type);
|
||||
CCodecs *_codecs;
|
||||
CMyComPtr<ICompressCodecsInfo> _compressCodecsInfo;
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(IFolderManager)
|
||||
INTERFACE_IFolderManager(;)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/TimeUtils.h"
|
||||
@@ -18,29 +20,33 @@ using namespace NCOM;
|
||||
|
||||
STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder)
|
||||
{
|
||||
_archiveNamePrefix.Empty();
|
||||
if (folder == NULL)
|
||||
{
|
||||
_agentFolder = NULL;
|
||||
_updatePathPrefix.Empty();
|
||||
_updatePathPrefix_is_AltFolder = false;
|
||||
_agentFolder = NULL;
|
||||
|
||||
if (!folder)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
{
|
||||
CMyComPtr<IFolderFolder> archiveFolder = folder;
|
||||
CMyComPtr<IArchiveFolderInternal> archiveFolderInternal;
|
||||
RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal));
|
||||
RINOK(archiveFolderInternal->GetAgentFolder(&_agentFolder));
|
||||
CMyComPtr<IArchiveFolderInternal> afi;
|
||||
RINOK(folder->QueryInterface(IID_IArchiveFolderInternal, (void **)&afi));
|
||||
if (afi)
|
||||
{
|
||||
RINOK(afi->GetAgentFolder(&_agentFolder));
|
||||
}
|
||||
if (!_agentFolder)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (_proxyArchive2)
|
||||
_archiveNamePrefix = _proxyArchive2->GetFullPathPrefix(_agentFolder->_proxyFolderItem);
|
||||
if (_proxy2)
|
||||
_updatePathPrefix = _proxy2->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex, _updatePathPrefix_is_AltFolder);
|
||||
else
|
||||
_archiveNamePrefix = _proxyArchive->GetFullPathPrefix(_agentFolder->_proxyFolderItem);
|
||||
_updatePathPrefix = _proxy->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix,
|
||||
const wchar_t **names, UInt32 numNames)
|
||||
const wchar_t * const *names, UInt32 numNames)
|
||||
{
|
||||
_folderPrefix = us2fs(folderPrefix);
|
||||
_names.ClearAndReserve(numNames);
|
||||
@@ -50,54 +56,57 @@ STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix,
|
||||
}
|
||||
|
||||
static HRESULT EnumerateArchiveItems(CAgent *agent,
|
||||
const CProxyFolder &item,
|
||||
const CProxyDir &item,
|
||||
const UString &prefix,
|
||||
CObjectVector<CArcItem> &arcItems)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < item.Files.Size(); i++)
|
||||
|
||||
for (i = 0; i < item.SubFiles.Size(); i++)
|
||||
{
|
||||
const CProxyFile &fileItem = item.Files[i];
|
||||
unsigned arcIndex = item.SubFiles[i];
|
||||
const CProxyFile &fileItem = agent->_proxy->Files[arcIndex];
|
||||
CArcItem ai;
|
||||
RINOK(agent->GetArc().GetItemMTime(fileItem.Index, ai.MTime, ai.MTimeDefined));
|
||||
RINOK(agent->GetArc().GetItemSize(fileItem.Index, ai.Size, ai.SizeDefined));
|
||||
RINOK(agent->GetArc().GetItemMTime(arcIndex, ai.MTime, ai.MTimeDefined));
|
||||
RINOK(agent->GetArc().GetItemSize(arcIndex, ai.Size, ai.SizeDefined));
|
||||
ai.IsDir = false;
|
||||
ai.Name = prefix + fileItem.Name;
|
||||
ai.Censored = true; // test it
|
||||
ai.IndexInServer = fileItem.Index;
|
||||
ai.IndexInServer = arcIndex;
|
||||
arcItems.Add(ai);
|
||||
}
|
||||
for (i = 0; i < item.Folders.Size(); i++)
|
||||
|
||||
for (i = 0; i < item.SubDirs.Size(); i++)
|
||||
{
|
||||
const CProxyFolder &dirItem = agent->_proxyArchive->Folders[item.Folders[i]];
|
||||
const CProxyDir &dirItem = agent->_proxy->Dirs[item.SubDirs[i]];
|
||||
UString fullName = prefix + dirItem.Name;
|
||||
if (dirItem.IsLeaf)
|
||||
if (dirItem.IsLeaf())
|
||||
{
|
||||
CArcItem ai;
|
||||
RINOK(agent->GetArc().GetItemMTime(dirItem.Index, ai.MTime, ai.MTimeDefined));
|
||||
RINOK(agent->GetArc().GetItemMTime(dirItem.ArcIndex, ai.MTime, ai.MTimeDefined));
|
||||
ai.IsDir = true;
|
||||
ai.SizeDefined = false;
|
||||
ai.Name = fullName;
|
||||
ai.Censored = true; // test it
|
||||
ai.IndexInServer = dirItem.Index;
|
||||
ai.IndexInServer = dirItem.ArcIndex;
|
||||
arcItems.Add(ai);
|
||||
}
|
||||
RINOK(EnumerateArchiveItems(agent, dirItem, fullName + UString(WCHAR_PATH_SEPARATOR), arcItems));
|
||||
RINOK(EnumerateArchiveItems(agent, dirItem, fullName + WCHAR_PATH_SEPARATOR, arcItems));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT EnumerateArchiveItems2(const CAgent *agent,
|
||||
const CProxyArchive2 *proxyArchive2,
|
||||
unsigned folderIndex,
|
||||
unsigned dirIndex,
|
||||
const UString &prefix,
|
||||
CObjectVector<CArcItem> &arcItems)
|
||||
{
|
||||
const CProxyFolder2 &folder = proxyArchive2->Folders[folderIndex];
|
||||
FOR_VECTOR (i, folder.SubFiles)
|
||||
const CProxyDir2 &dir = agent->_proxy2->Dirs[dirIndex];
|
||||
FOR_VECTOR (i, dir.Items)
|
||||
{
|
||||
unsigned arcIndex = folder.SubFiles[i];
|
||||
const CProxyFile2 &file = proxyArchive2->Files[arcIndex];
|
||||
unsigned arcIndex = dir.Items[i];
|
||||
const CProxyFile2 &file = agent->_proxy2->Files[arcIndex];
|
||||
CArcItem ai;
|
||||
ai.IndexInServer = arcIndex;
|
||||
ai.Name = prefix + file.Name;
|
||||
@@ -105,15 +114,22 @@ static HRESULT EnumerateArchiveItems2(const CAgent *agent,
|
||||
RINOK(agent->GetArc().GetItemMTime(arcIndex, ai.MTime, ai.MTimeDefined));
|
||||
ai.IsDir = file.IsDir();
|
||||
ai.SizeDefined = false;
|
||||
ai.IsAltStream = file.IsAltStream;
|
||||
if (!ai.IsDir)
|
||||
{
|
||||
RINOK(agent->GetArc().GetItemSize(arcIndex, ai.Size, ai.SizeDefined));
|
||||
ai.IsDir = false;
|
||||
}
|
||||
arcItems.Add(ai);
|
||||
|
||||
if (file.AltDirIndex >= 0)
|
||||
{
|
||||
RINOK(EnumerateArchiveItems2(agent, file.AltDirIndex, ai.Name + L':', arcItems));
|
||||
}
|
||||
|
||||
if (ai.IsDir)
|
||||
{
|
||||
RINOK(EnumerateArchiveItems2(agent, proxyArchive2, file.FolderIndex, ai.Name + UString(WCHAR_PATH_SEPARATOR), arcItems));
|
||||
RINOK(EnumerateArchiveItems2(agent, file.DirIndex, ai.Name + WCHAR_PATH_SEPARATOR, arcItems));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
@@ -126,10 +142,10 @@ struct CAgUpCallbackImp: public IUpdateProduceCallback
|
||||
|
||||
CAgUpCallbackImp(const CObjectVector<CArcItem> *a,
|
||||
IFolderArchiveUpdateCallback *callback): _arcItems(a), _callback(callback) {}
|
||||
HRESULT ShowDeleteFile(int arcIndex);
|
||||
HRESULT ShowDeleteFile(unsigned arcIndex);
|
||||
};
|
||||
|
||||
HRESULT CAgUpCallbackImp::ShowDeleteFile(int arcIndex)
|
||||
HRESULT CAgUpCallbackImp::ShowDeleteFile(unsigned arcIndex)
|
||||
{
|
||||
return _callback->DeleteOperation((*_arcItems)[arcIndex].Name);
|
||||
}
|
||||
@@ -140,11 +156,40 @@ static void SetInArchiveInterfaces(CAgent *agent, CArchiveUpdateCallback *upd)
|
||||
if (agent->_archiveLink.Arcs.IsEmpty())
|
||||
return;
|
||||
const CArc &arc = agent->GetArc();
|
||||
upd->Arc = &arc;
|
||||
upd->Archive = arc.Archive;
|
||||
upd->GetRawProps = arc.GetRawProps;
|
||||
upd->GetRootProps = arc.GetRootProps;
|
||||
}
|
||||
|
||||
struct CDirItemsCallback_AgentOut: public IDirItemsCallback
|
||||
{
|
||||
CMyComPtr<IFolderScanProgress> FolderScanProgress;
|
||||
IFolderArchiveUpdateCallback *FolderArchiveUpdateCallback;
|
||||
HRESULT ErrorCode;
|
||||
|
||||
CDirItemsCallback_AgentOut(): ErrorCode(S_OK), FolderArchiveUpdateCallback(NULL) {}
|
||||
|
||||
HRESULT ScanError(const FString &name, DWORD systemError)
|
||||
{
|
||||
HRESULT hres = HRESULT_FROM_WIN32(systemError);
|
||||
if (FolderArchiveUpdateCallback)
|
||||
return FolderScanProgress->ScanError(fs2us(name), hres);
|
||||
ErrorCode = hres;
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir)
|
||||
{
|
||||
if (FolderScanProgress)
|
||||
return FolderScanProgress->ScanProgress(st.NumDirs, st.NumFiles + st.NumAltStreams,
|
||||
st.GetTotalBytes(), fs2us(path), BoolToInt(isDir));
|
||||
|
||||
if (FolderArchiveUpdateCallback)
|
||||
return FolderArchiveUpdateCallback->SetNumFiles(st.NumFiles);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
STDMETHODIMP CAgent::DoOperation(
|
||||
FStringVector *requestedPaths,
|
||||
FStringVector *processedPaths,
|
||||
@@ -157,22 +202,43 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
|
||||
NUpdateArchive::CActionSet actionSet;
|
||||
unsigned i;
|
||||
for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];
|
||||
{
|
||||
for (unsigned i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];
|
||||
}
|
||||
|
||||
CDirItemsCallback_AgentOut enumCallback;
|
||||
if (updateCallback100)
|
||||
{
|
||||
enumCallback.FolderArchiveUpdateCallback = updateCallback100;
|
||||
updateCallback100->QueryInterface(IID_IFolderScanProgress, (void **)&enumCallback.FolderScanProgress);
|
||||
}
|
||||
|
||||
CDirItems dirItems;
|
||||
dirItems.Callback = &enumCallback;
|
||||
|
||||
{
|
||||
FString folderPrefix = _folderPrefix;
|
||||
NFile::NName::NormalizeDirPathPrefix(folderPrefix);
|
||||
dirItems.EnumerateItems2(folderPrefix, _archiveNamePrefix, _names, requestedPaths);
|
||||
if (dirItems.ErrorCodes.Size() > 0)
|
||||
return dirItems.ErrorCodes.Front();
|
||||
|
||||
RINOK(dirItems.EnumerateItems2(folderPrefix, _updatePathPrefix, _names, requestedPaths));
|
||||
|
||||
if (_updatePathPrefix_is_AltFolder)
|
||||
{
|
||||
FOR_VECTOR(i, dirItems.Items)
|
||||
{
|
||||
CDirItem &item = dirItems.Items[i];
|
||||
if (item.IsDir())
|
||||
return E_NOTIMPL;
|
||||
item.IsAltStream = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CMyComPtr<IOutArchive> outArchive;
|
||||
|
||||
if (GetArchive())
|
||||
{
|
||||
RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
|
||||
@@ -182,6 +248,7 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
if (formatIndex < 0)
|
||||
return E_FAIL;
|
||||
RINOK(codecs->CreateOutArchive(formatIndex, outArchive));
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
{
|
||||
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
|
||||
@@ -192,7 +259,6 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
NFileTimeType::EEnum fileTimeType;
|
||||
@@ -215,13 +281,14 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
if (GetArchive())
|
||||
{
|
||||
RINOK(ReadItems());
|
||||
if (_proxyArchive2)
|
||||
if (_proxy2)
|
||||
{
|
||||
RINOK(EnumerateArchiveItems2(this, _proxyArchive2, 0, L"", arcItems));
|
||||
RINOK(EnumerateArchiveItems2(this, k_Proxy2_RootDirIndex, L"", arcItems));
|
||||
RINOK(EnumerateArchiveItems2(this, k_Proxy2_AltRootDirIndex, L":", arcItems));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(EnumerateArchiveItems(this, _proxyArchive->Folders[0], L"", arcItems));
|
||||
RINOK(EnumerateArchiveItems(this, _proxy->Dirs[0], L"", arcItems));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,9 +302,11 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
}
|
||||
|
||||
UInt32 numFiles = 0;
|
||||
for (i = 0; i < updatePairs2.Size(); i++)
|
||||
if (updatePairs2[i].NewData)
|
||||
numFiles++;
|
||||
{
|
||||
FOR_VECTOR (i, updatePairs2)
|
||||
if (updatePairs2[i].NewData)
|
||||
numFiles++;
|
||||
}
|
||||
|
||||
if (updateCallback100)
|
||||
{
|
||||
@@ -262,7 +331,7 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
{
|
||||
unsigned num = dirItems.Items.Size();
|
||||
processedItems.Alloc(num);
|
||||
for (i = 0; i < num; i++)
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
processedItems[i] = 0;
|
||||
updateCallbackSpec->ProcessedItemsStatuses = processedItems;
|
||||
}
|
||||
@@ -277,7 +346,7 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
else
|
||||
{
|
||||
CRecordVector<const wchar_t *> names;
|
||||
for(i = 0; i < m_PropNames.Size(); i++)
|
||||
FOR_VECTOR (i, m_PropNames)
|
||||
names.Add((const wchar_t *)m_PropNames[i]);
|
||||
|
||||
CPropVariant *propValues = new CPropVariant[m_PropValues.Size()];
|
||||
@@ -311,9 +380,9 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
HRESULT res = outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(), updateCallback);
|
||||
if (res == S_OK && processedPaths)
|
||||
{
|
||||
for (i = 0; i < dirItems.Items.Size(); i++)
|
||||
FOR_VECTOR (i, dirItems.Items)
|
||||
if (processedItems[i] != 0)
|
||||
processedPaths->Add(us2fs(dirItems.GetPhyPath(i)));
|
||||
processedPaths->Add(dirItems.GetPhyPath(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -324,7 +393,7 @@ STDMETHODIMP CAgent::DoOperation2(
|
||||
ISequentialOutStream *outArchiveStream,
|
||||
const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
return DoOperation(requestedPaths, processedPaths, _codecs, -1, outArchiveStream, stateActions, sfxModule, updateCallback100);
|
||||
return DoOperation(requestedPaths, processedPaths, g_CodecsObj, -1, outArchiveStream, stateActions, sfxModule, updateCallback100);
|
||||
}
|
||||
|
||||
HRESULT CAgent::CommonUpdate(ISequentialOutStream *outArchiveStream,
|
||||
@@ -357,11 +426,17 @@ STDMETHODIMP CAgent::DeleteItems(ISequentialOutStream *outArchiveStream,
|
||||
unsigned curIndex = 0;
|
||||
UInt32 numItemsInArchive;
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
|
||||
UString deletePath;
|
||||
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
if (curIndex < realIndices.Size())
|
||||
if (realIndices[curIndex] == i)
|
||||
{
|
||||
RINOK(GetArc().GetItemPath2(i, deletePath));
|
||||
RINOK(updateCallback100->DeleteOperation(deletePath));
|
||||
|
||||
curIndex++;
|
||||
continue;
|
||||
}
|
||||
@@ -410,10 +485,12 @@ HRESULT CAgent::CreateFolder(ISequentialOutStream *outArchiveStream,
|
||||
|
||||
di.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
di.Size = 0;
|
||||
if (_proxyArchive2)
|
||||
di.Name = _proxyArchive2->GetFullPathPrefix(_agentFolder->_proxyFolderItem) + folderName;
|
||||
bool isAltStreamFolder = false;
|
||||
if (_proxy2)
|
||||
di.Name = _proxy2->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex, isAltStreamFolder);
|
||||
else
|
||||
di.Name = _proxyArchive->GetFullPathPrefix(_agentFolder->_proxyFolderItem) + folderName;
|
||||
di.Name = _proxy->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex);
|
||||
di.Name += folderName;
|
||||
|
||||
FILETIME ft;
|
||||
NTime::GetCurUtcFileTime(ft);
|
||||
@@ -455,7 +532,7 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
|
||||
|
||||
int mainRealIndex = _agentFolder->GetRealIndex(indices[0]);
|
||||
|
||||
UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]);
|
||||
UString fullPrefix = _agentFolder->GetFullPrefix(indices[0]);
|
||||
UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]);
|
||||
UString newItemPath = fullPrefix + newItemName;
|
||||
|
||||
@@ -464,6 +541,7 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
|
||||
unsigned curIndex = 0;
|
||||
UInt32 numItemsInArchive;
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
CUpdatePair2 up2;
|
||||
@@ -477,7 +555,7 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
|
||||
UString oldFullPath;
|
||||
RINOK(GetArc().GetItemPath2(i, oldFullPath));
|
||||
|
||||
if (MyStringCompareNoCase_N(oldFullPath, oldItemPath, oldItemPath.Len()) != 0)
|
||||
if (!IsPath1PrefixedByPath2(oldFullPath, oldItemPath))
|
||||
return E_INVALIDARG;
|
||||
|
||||
up2.NewNameIndex = newNames.Add(newItemPath + oldFullPath.Ptr(oldItemPath.Len()));
|
||||
@@ -486,6 +564,7 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
|
||||
}
|
||||
updatePairs.Add(up2);
|
||||
}
|
||||
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->NewNames = &newNames;
|
||||
@@ -553,7 +632,7 @@ HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream,
|
||||
return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
|
||||
STDMETHODIMP CAgent::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
|
||||
{
|
||||
m_PropNames.Clear();
|
||||
m_PropValues.Clear();
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
#include "../../../../C/Sort.h"
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
@@ -14,10 +16,10 @@
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
int CProxyArchive::FindDirSubItemIndex(unsigned folderIndex, const UString &name, unsigned &insertPos) const
|
||||
int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &insertPos) const
|
||||
{
|
||||
const CRecordVector<unsigned> &subFolders = Folders[folderIndex].Folders;
|
||||
unsigned left = 0, right = subFolders.Size();
|
||||
const CRecordVector<unsigned> &subDirs = Dirs[dirIndex].SubDirs;
|
||||
unsigned left = 0, right = subDirs.Size();
|
||||
for (;;)
|
||||
{
|
||||
if (left == right)
|
||||
@@ -26,10 +28,10 @@ int CProxyArchive::FindDirSubItemIndex(unsigned folderIndex, const UString &name
|
||||
return -1;
|
||||
}
|
||||
unsigned mid = (left + right) / 2;
|
||||
unsigned folderIndex = subFolders[mid];
|
||||
int compare = CompareFileNames(name, Folders[folderIndex].Name);
|
||||
unsigned dirIndex = subDirs[mid];
|
||||
int compare = CompareFileNames(name, Dirs[dirIndex].Name);
|
||||
if (compare == 0)
|
||||
return folderIndex;
|
||||
return dirIndex;
|
||||
if (compare < 0)
|
||||
right = mid;
|
||||
else
|
||||
@@ -37,120 +39,117 @@ int CProxyArchive::FindDirSubItemIndex(unsigned folderIndex, const UString &name
|
||||
}
|
||||
}
|
||||
|
||||
int CProxyArchive::FindDirSubItemIndex(unsigned folderIndex, const UString &name) const
|
||||
int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name) const
|
||||
{
|
||||
unsigned insertPos;
|
||||
return FindDirSubItemIndex(folderIndex, name, insertPos);
|
||||
return FindSubDir(dirIndex, name, insertPos);
|
||||
}
|
||||
|
||||
void CProxyFolder::AddFileSubItem(UInt32 index, const UString &name)
|
||||
{
|
||||
CProxyFile &f = Files.AddNew();
|
||||
f.Index = index;
|
||||
f.Name = name;
|
||||
}
|
||||
|
||||
unsigned CProxyArchive::AddDirSubItem(unsigned folderIndex, UInt32 index, bool leaf, const UString &name)
|
||||
unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name)
|
||||
{
|
||||
unsigned insertPos;
|
||||
int subFolderIndex = FindDirSubItemIndex(folderIndex, name, insertPos);
|
||||
if (subFolderIndex >= 0)
|
||||
int subDirIndex = FindSubDir(dirIndex, name, insertPos);
|
||||
if (subDirIndex >= 0)
|
||||
{
|
||||
CProxyFolder &item = Folders[subFolderIndex];
|
||||
if (leaf)
|
||||
if (arcIndex >= 0)
|
||||
{
|
||||
item.Index = index;
|
||||
item.IsLeaf = true;
|
||||
CProxyDir &item = Dirs[subDirIndex];
|
||||
if (item.ArcIndex < 0)
|
||||
item.ArcIndex = arcIndex;
|
||||
}
|
||||
return subFolderIndex;
|
||||
return subDirIndex;
|
||||
}
|
||||
subFolderIndex = Folders.Size();
|
||||
Folders[folderIndex].Folders.Insert(insertPos, subFolderIndex);
|
||||
CProxyFolder &item = Folders.AddNew();
|
||||
item.Name = name;
|
||||
item.Index = index;
|
||||
item.Parent = folderIndex;
|
||||
item.IsLeaf = leaf;
|
||||
return subFolderIndex;
|
||||
subDirIndex = Dirs.Size();
|
||||
Dirs[dirIndex].SubDirs.Insert(insertPos, subDirIndex);
|
||||
CProxyDir &item = Dirs.AddNew();
|
||||
|
||||
item.NameLen = name.Len();
|
||||
item.Name = new wchar_t[item.NameLen + 1];
|
||||
MyStringCopy((wchar_t *)item.Name, name);
|
||||
|
||||
item.ArcIndex = arcIndex;
|
||||
item.ParentDir = dirIndex;
|
||||
return subDirIndex;
|
||||
}
|
||||
|
||||
void CProxyFolder::Clear()
|
||||
void CProxyDir::Clear()
|
||||
{
|
||||
Folders.Clear();
|
||||
Files.Clear();
|
||||
SubDirs.Clear();
|
||||
SubFiles.Clear();
|
||||
}
|
||||
|
||||
void CProxyArchive::GetPathParts(int folderIndex, UStringVector &pathParts) const
|
||||
void CProxyArc::GetDirPathParts(int dirIndex, UStringVector &pathParts) const
|
||||
{
|
||||
pathParts.Clear();
|
||||
while (folderIndex >= 0)
|
||||
while (dirIndex >= 0)
|
||||
{
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
folderIndex = folder.Parent;
|
||||
if (folderIndex < 0)
|
||||
const CProxyDir &dir = Dirs[dirIndex];
|
||||
dirIndex = dir.ParentDir;
|
||||
if (dirIndex < 0)
|
||||
break;
|
||||
pathParts.Insert(0, folder.Name);
|
||||
pathParts.Insert(0, dir.Name);
|
||||
}
|
||||
}
|
||||
|
||||
UString CProxyArchive::GetFullPathPrefix(int folderIndex) const
|
||||
UString CProxyArc::GetDirPath_as_Prefix(int dirIndex) const
|
||||
{
|
||||
UString result;
|
||||
while (folderIndex >= 0)
|
||||
UString s;
|
||||
while (dirIndex >= 0)
|
||||
{
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
folderIndex = folder.Parent;
|
||||
if (folderIndex < 0)
|
||||
const CProxyDir &dir = Dirs[dirIndex];
|
||||
dirIndex = dir.ParentDir;
|
||||
if (dirIndex < 0)
|
||||
break;
|
||||
result = folder.Name + UString(WCHAR_PATH_SEPARATOR) + result;
|
||||
s.InsertAtFront(WCHAR_PATH_SEPARATOR);
|
||||
s.Insert(0, dir.Name);
|
||||
}
|
||||
return result;
|
||||
return s;
|
||||
}
|
||||
|
||||
void CProxyArchive::AddRealIndices(unsigned folderIndex, CUIntVector &realIndices) const
|
||||
void CProxyArc::AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const
|
||||
{
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
if (folder.IsLeaf)
|
||||
realIndices.Add(folder.Index);
|
||||
const CProxyDir &dir = Dirs[dirIndex];
|
||||
if (dir.IsLeaf())
|
||||
realIndices.Add(dir.ArcIndex);
|
||||
unsigned i;
|
||||
for (i = 0; i < folder.Folders.Size(); i++)
|
||||
AddRealIndices(folder.Folders[i], realIndices);
|
||||
for (i = 0; i < folder.Files.Size(); i++)
|
||||
realIndices.Add(folder.Files[i].Index);
|
||||
for (i = 0; i < dir.SubDirs.Size(); i++)
|
||||
AddRealIndices(dir.SubDirs[i], realIndices);
|
||||
for (i = 0; i < dir.SubFiles.Size(); i++)
|
||||
realIndices.Add(dir.SubFiles[i]);
|
||||
}
|
||||
|
||||
int CProxyArchive::GetRealIndex(unsigned folderIndex, unsigned index) const
|
||||
int CProxyArc::GetRealIndex(unsigned dirIndex, unsigned index) const
|
||||
{
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
unsigned numDirItems = folder.Folders.Size();
|
||||
const CProxyDir &dir = Dirs[dirIndex];
|
||||
unsigned numDirItems = dir.SubDirs.Size();
|
||||
if (index < numDirItems)
|
||||
{
|
||||
const CProxyFolder &f = Folders[folder.Folders[index]];
|
||||
if (f.IsLeaf)
|
||||
return f.Index;
|
||||
const CProxyDir &f = Dirs[dir.SubDirs[index]];
|
||||
if (f.IsLeaf())
|
||||
return f.ArcIndex;
|
||||
return -1;
|
||||
}
|
||||
return folder.Files[index - numDirItems].Index;
|
||||
return dir.SubFiles[index - numDirItems];
|
||||
}
|
||||
|
||||
void CProxyArchive::GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
|
||||
void CProxyArc::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
|
||||
{
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
const CProxyDir &dir = Dirs[dirIndex];
|
||||
realIndices.Clear();
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 index = indices[i];
|
||||
unsigned numDirItems = folder.Folders.Size();
|
||||
unsigned numDirItems = dir.SubDirs.Size();
|
||||
if (index < numDirItems)
|
||||
AddRealIndices(folder.Folders[index], realIndices);
|
||||
AddRealIndices(dir.SubDirs[index], realIndices);
|
||||
else
|
||||
realIndices.Add(folder.Files[index - numDirItems].Index);
|
||||
realIndices.Add(dir.SubFiles[index - numDirItems]);
|
||||
}
|
||||
HeapSort(&realIndices.Front(), realIndices.Size());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// CProxyArchive
|
||||
// CProxyArc
|
||||
|
||||
static bool GetSize(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &size)
|
||||
{
|
||||
@@ -161,79 +160,131 @@ static bool GetSize(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &si
|
||||
return ConvertPropVariantToUInt64(prop, size);
|
||||
}
|
||||
|
||||
void CProxyArchive::CalculateSizes(unsigned folderIndex, IInArchive *archive)
|
||||
void CProxyArc::CalculateSizes(unsigned dirIndex, IInArchive *archive)
|
||||
{
|
||||
CProxyFolder &folder = Folders[folderIndex];
|
||||
folder.Size = folder.PackSize = 0;
|
||||
folder.NumSubFolders = folder.Folders.Size();
|
||||
folder.NumSubFiles = folder.Files.Size();
|
||||
folder.CrcIsDefined = true;
|
||||
folder.Crc = 0;
|
||||
CProxyDir &dir = Dirs[dirIndex];
|
||||
dir.Size = dir.PackSize = 0;
|
||||
dir.NumSubDirs = dir.SubDirs.Size();
|
||||
dir.NumSubFiles = dir.SubFiles.Size();
|
||||
dir.CrcIsDefined = true;
|
||||
dir.Crc = 0;
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < folder.Files.Size(); i++)
|
||||
|
||||
for (i = 0; i < dir.SubFiles.Size(); i++)
|
||||
{
|
||||
UInt32 index = folder.Files[i].Index;
|
||||
UInt32 index = (UInt32)dir.SubFiles[i];
|
||||
UInt64 size, packSize;
|
||||
bool sizeDefined = GetSize(archive, index, kpidSize, size);
|
||||
folder.Size += size;
|
||||
dir.Size += size;
|
||||
GetSize(archive, index, kpidPackSize, packSize);
|
||||
folder.PackSize += packSize;
|
||||
dir.PackSize += packSize;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
folder.Crc += prop.ulVal;
|
||||
dir.Crc += prop.ulVal;
|
||||
else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
dir.CrcIsDefined = false;
|
||||
}
|
||||
else
|
||||
folder.CrcIsDefined = false;
|
||||
dir.CrcIsDefined = false;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < folder.Folders.Size(); i++)
|
||||
|
||||
for (i = 0; i < dir.SubDirs.Size(); i++)
|
||||
{
|
||||
unsigned subFolderIndex = folder.Folders[i];
|
||||
CProxyFolder &f = Folders[subFolderIndex];
|
||||
CalculateSizes(subFolderIndex, archive);
|
||||
folder.Size += f.Size;
|
||||
folder.PackSize += f.PackSize;
|
||||
folder.NumSubFiles += f.NumSubFiles;
|
||||
folder.NumSubFolders += f.NumSubFolders;
|
||||
folder.Crc += f.Crc;
|
||||
unsigned subDirIndex = dir.SubDirs[i];
|
||||
CalculateSizes(subDirIndex, archive);
|
||||
CProxyDir &f = Dirs[subDirIndex];
|
||||
dir.Size += f.Size;
|
||||
dir.PackSize += f.PackSize;
|
||||
dir.NumSubFiles += f.NumSubFiles;
|
||||
dir.NumSubDirs += f.NumSubDirs;
|
||||
dir.Crc += f.Crc;
|
||||
if (!f.CrcIsDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
dir.CrcIsDefined = false;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress)
|
||||
HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
|
||||
{
|
||||
/*
|
||||
DWORD tickCount = GetTickCount();
|
||||
for (int ttt = 0; ttt < 1000; ttt++) {
|
||||
*/
|
||||
// DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) {
|
||||
|
||||
Folders.Clear();
|
||||
Folders.AddNew();
|
||||
Files.Free();
|
||||
Dirs.Clear();
|
||||
|
||||
Dirs.AddNew();
|
||||
IInArchive *archive = arc.Archive;
|
||||
|
||||
UInt32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
|
||||
if (progress)
|
||||
RINOK(progress->SetTotal(numItems));
|
||||
UString filePath;
|
||||
UString fileName;
|
||||
|
||||
Files.Alloc(numItems);
|
||||
|
||||
UString path;
|
||||
UString name;
|
||||
NCOM::CPropVariant prop;
|
||||
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (progress && (i & 0xFFFFF) == 0)
|
||||
if (progress && (i & 0xFFFF) == 0)
|
||||
{
|
||||
UInt64 currentItemIndex = i;
|
||||
RINOK(progress->SetCompleted(¤tItemIndex));
|
||||
}
|
||||
RINOK(arc.GetItemPath(i, filePath));
|
||||
|
||||
const wchar_t *s = NULL;
|
||||
unsigned len = 0;
|
||||
bool isPtrName = false;
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
if (arc.GetRawProps)
|
||||
{
|
||||
const void *p;
|
||||
UInt32 size;
|
||||
UInt32 propType;
|
||||
if (arc.GetRawProps->GetRawProp(i, kpidPath, &p, &size, &propType) == S_OK
|
||||
&& propType == NPropDataType::kUtf16z
|
||||
&& size > 2)
|
||||
{
|
||||
// is (size <= 2), it's empty name, and we call default arc.GetItemPath();
|
||||
len = size / 2 - 1;
|
||||
s = (const wchar_t *)p;
|
||||
isPtrName = true;
|
||||
}
|
||||
}
|
||||
if (!s)
|
||||
#endif
|
||||
{
|
||||
prop.Clear();
|
||||
RINOK(arc.Archive->GetProperty(i, kpidPath, &prop));
|
||||
if (prop.vt == VT_BSTR)
|
||||
{
|
||||
s = prop.bstrVal;
|
||||
len = ::SysStringLen(prop.bstrVal);
|
||||
}
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
return E_FAIL;
|
||||
if (len == 0)
|
||||
{
|
||||
RINOK(arc.GetDefaultItemPath(i, path));
|
||||
len = path.Len();
|
||||
s = path;
|
||||
}
|
||||
|
||||
/*
|
||||
RINOK(arc.GetItemPath(i, path));
|
||||
len = path.Len();
|
||||
s = path;
|
||||
*/
|
||||
}
|
||||
|
||||
unsigned curItem = 0;
|
||||
unsigned len = filePath.Len();
|
||||
fileName.Empty();
|
||||
|
||||
/*
|
||||
if (arc.Ask_Deleted)
|
||||
@@ -245,16 +296,16 @@ HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress)
|
||||
}
|
||||
*/
|
||||
|
||||
unsigned namePos = 0;
|
||||
for (unsigned j = 0; j < len; j++)
|
||||
{
|
||||
wchar_t c = filePath[j];
|
||||
wchar_t c = s[j];
|
||||
if (c == WCHAR_PATH_SEPARATOR || c == L'/')
|
||||
{
|
||||
curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, fileName);
|
||||
fileName.Empty();
|
||||
name.SetFrom(s + namePos, j - namePos);
|
||||
curItem = AddDir(curItem, -1, name);
|
||||
namePos = j + 1;
|
||||
}
|
||||
else
|
||||
fileName += c;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -270,21 +321,35 @@ HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress)
|
||||
}
|
||||
*/
|
||||
|
||||
bool isFolder;
|
||||
RINOK(Archive_IsItem_Folder(archive, i, isFolder));
|
||||
if (isFolder)
|
||||
AddDirSubItem(curItem, i, true, fileName);
|
||||
bool isDir;
|
||||
RINOK(Archive_IsItem_Dir(archive, i, isDir));
|
||||
|
||||
CProxyFile &f = Files[i];
|
||||
|
||||
f.NameLen = len - namePos;
|
||||
s += namePos;
|
||||
|
||||
if (isPtrName)
|
||||
f.Name = s;
|
||||
else
|
||||
Folders[curItem].AddFileSubItem(i, fileName);
|
||||
{
|
||||
f.Name = new wchar_t[f.NameLen + 1];
|
||||
f.NeedDeleteName = true;
|
||||
MyStringCopy((wchar_t *)f.Name, s);
|
||||
}
|
||||
|
||||
if (isDir)
|
||||
{
|
||||
name = s;
|
||||
AddDir(curItem, (int)i, name);
|
||||
}
|
||||
else
|
||||
Dirs[curItem].SubFiles.Add(i);
|
||||
}
|
||||
|
||||
CalculateSizes(0, archive);
|
||||
|
||||
/*
|
||||
}
|
||||
char s[128];
|
||||
sprintf(s, "load archive %7d ms", GetTickCount() - tickCount);
|
||||
OutputDebugStringA(s);
|
||||
*/
|
||||
// } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -293,151 +358,162 @@ HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress)
|
||||
|
||||
// ---------- for Tree-mode archive ----------
|
||||
|
||||
void CProxyArchive2::GetPathParts(int folderIndex, UStringVector &pathParts) const
|
||||
void CProxyArc2::GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const
|
||||
{
|
||||
pathParts.Clear();
|
||||
while (folderIndex > 0)
|
||||
|
||||
isAltStreamDir = false;
|
||||
|
||||
if (dirIndex == k_Proxy2_RootDirIndex)
|
||||
return;
|
||||
if (dirIndex == k_Proxy2_AltRootDirIndex)
|
||||
{
|
||||
const CProxyFolder2 &folder = Folders[folderIndex];
|
||||
const CProxyFile2 &file = Files[folder.ArcIndex];
|
||||
isAltStreamDir = true;
|
||||
return;
|
||||
}
|
||||
|
||||
while (dirIndex >= k_Proxy2_NumRootDirs)
|
||||
{
|
||||
const CProxyDir2 &dir = Dirs[dirIndex];
|
||||
const CProxyFile2 &file = Files[dir.ArcIndex];
|
||||
if (pathParts.IsEmpty() && dirIndex == file.AltDirIndex)
|
||||
isAltStreamDir = true;
|
||||
pathParts.Insert(0, file.Name);
|
||||
int par = file.Parent;
|
||||
if (par < 0)
|
||||
break;
|
||||
folderIndex = Files[par].FolderIndex;
|
||||
dirIndex = Files[par].DirIndex;
|
||||
}
|
||||
}
|
||||
|
||||
UString CProxyArchive2::GetFullPathPrefix(unsigned folderIndex) const
|
||||
bool CProxyArc2::IsAltDir(unsigned dirIndex) const
|
||||
{
|
||||
return Folders[folderIndex].PathPrefix;
|
||||
/*
|
||||
UString result;
|
||||
while (folderIndex > 0)
|
||||
{
|
||||
const CProxyFile2 &file = Files[Folders[folderIndex].ArcIndex];
|
||||
result = (UString)(file.Name) + (UString)WCHAR_PATH_SEPARATOR + result;
|
||||
if (file.Parent < 0)
|
||||
break;
|
||||
folderIndex = Files[file.Parent].FolderIndex;
|
||||
}
|
||||
return result;
|
||||
*/
|
||||
if (dirIndex == k_Proxy2_RootDirIndex)
|
||||
return false;
|
||||
if (dirIndex == k_Proxy2_AltRootDirIndex)
|
||||
return true;
|
||||
const CProxyDir2 &dir = Dirs[dirIndex];
|
||||
const CProxyFile2 &file = Files[dir.ArcIndex];
|
||||
return ((int)dirIndex == file.AltDirIndex);
|
||||
}
|
||||
|
||||
void CProxyArchive2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
UString CProxyArc2::GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const
|
||||
{
|
||||
isAltStreamDir = false;
|
||||
const CProxyDir2 &dir = Dirs[dirIndex];
|
||||
if (dirIndex == k_Proxy2_AltRootDirIndex)
|
||||
isAltStreamDir = true;
|
||||
else if (dirIndex >= k_Proxy2_NumRootDirs)
|
||||
{
|
||||
const CProxyFile2 &file = Files[dir.ArcIndex];
|
||||
isAltStreamDir = ((int)dirIndex == file.AltDirIndex);
|
||||
}
|
||||
return dir.PathPrefix;
|
||||
}
|
||||
|
||||
void CProxyArc2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
{
|
||||
realIndices.Add(arcIndex);
|
||||
const CProxyFile2 &file = Files[arcIndex];
|
||||
if (file.FolderIndex >= 0)
|
||||
AddRealIndices_of_Folder(file.FolderIndex, includeAltStreams, realIndices);
|
||||
if (includeAltStreams && file.AltStreamsFolderIndex >= 0)
|
||||
AddRealIndices_of_Folder(file.AltStreamsFolderIndex, includeAltStreams, realIndices);
|
||||
if (file.DirIndex >= 0)
|
||||
AddRealIndices_of_Dir(file.DirIndex, includeAltStreams, realIndices);
|
||||
if (includeAltStreams && file.AltDirIndex >= 0)
|
||||
AddRealIndices_of_Dir(file.AltDirIndex, includeAltStreams, realIndices);
|
||||
}
|
||||
|
||||
void CProxyArchive2::AddRealIndices_of_Folder(unsigned folderIndex, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
void CProxyArc2::AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
{
|
||||
const CRecordVector<unsigned> &subFiles = Folders[folderIndex].SubFiles;
|
||||
const CRecordVector<unsigned> &subFiles = Dirs[dirIndex].Items;
|
||||
FOR_VECTOR (i, subFiles)
|
||||
{
|
||||
AddRealIndices_of_ArcItem(subFiles[i], includeAltStreams, realIndices);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned CProxyArchive2::GetRealIndex(unsigned folderIndex, unsigned index) const
|
||||
unsigned CProxyArc2::GetRealIndex(unsigned dirIndex, unsigned index) const
|
||||
{
|
||||
return Folders[folderIndex].SubFiles[index];
|
||||
return Dirs[dirIndex].Items[index];
|
||||
}
|
||||
|
||||
void CProxyArchive2::GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
void CProxyArc2::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
{
|
||||
const CProxyFolder2 &folder = Folders[folderIndex];
|
||||
const CProxyDir2 &dir = Dirs[dirIndex];
|
||||
realIndices.Clear();
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
AddRealIndices_of_ArcItem(folder.SubFiles[indices[i]], includeAltStreams, realIndices);
|
||||
AddRealIndices_of_ArcItem(dir.Items[indices[i]], includeAltStreams, realIndices);
|
||||
}
|
||||
HeapSort(&realIndices.Front(), realIndices.Size());
|
||||
}
|
||||
|
||||
void CProxyArchive2::CalculateSizes(unsigned folderIndex, IInArchive *archive)
|
||||
void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive)
|
||||
{
|
||||
CProxyFolder2 &folder = Folders[folderIndex];
|
||||
folder.Size = folder.PackSize = 0;
|
||||
folder.NumSubFolders = 0; // folder.Folders.Size();
|
||||
folder.NumSubFiles = 0; // folder.Files.Size();
|
||||
folder.CrcIsDefined = true;
|
||||
folder.Crc = 0;
|
||||
FOR_VECTOR (i, folder.SubFiles)
|
||||
CProxyDir2 &dir = Dirs[dirIndex];
|
||||
dir.Size = dir.PackSize = 0;
|
||||
dir.NumSubDirs = 0; // dir.SubDirs.Size();
|
||||
dir.NumSubFiles = 0; // dir.Files.Size();
|
||||
dir.CrcIsDefined = true;
|
||||
dir.Crc = 0;
|
||||
|
||||
FOR_VECTOR (i, dir.Items)
|
||||
{
|
||||
UInt32 index = folder.SubFiles[i];
|
||||
UInt32 index = dir.Items[i];
|
||||
UInt64 size, packSize;
|
||||
bool sizeDefined = GetSize(archive, index, kpidSize, size);
|
||||
folder.Size += size;
|
||||
dir.Size += size;
|
||||
GetSize(archive, index, kpidPackSize, packSize);
|
||||
folder.PackSize += packSize;
|
||||
dir.PackSize += packSize;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
folder.Crc += prop.ulVal;
|
||||
dir.Crc += prop.ulVal;
|
||||
else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
dir.CrcIsDefined = false;
|
||||
}
|
||||
else
|
||||
folder.CrcIsDefined = false;
|
||||
dir.CrcIsDefined = false;
|
||||
}
|
||||
|
||||
const CProxyFile2 &subFile = Files[index];
|
||||
if (subFile.FolderIndex < 0)
|
||||
if (subFile.DirIndex < 0)
|
||||
{
|
||||
folder.NumSubFiles++;
|
||||
dir.NumSubFiles++;
|
||||
}
|
||||
else
|
||||
{
|
||||
folder.NumSubFolders++;
|
||||
CProxyFolder2 &f = Folders[subFile.FolderIndex];
|
||||
f.PathPrefix = folder.PathPrefix + subFile.Name + WCHAR_PATH_SEPARATOR;
|
||||
CalculateSizes(subFile.FolderIndex, archive);
|
||||
folder.Size += f.Size;
|
||||
folder.PackSize += f.PackSize;
|
||||
folder.NumSubFiles += f.NumSubFiles;
|
||||
folder.NumSubFolders += f.NumSubFolders;
|
||||
folder.Crc += f.Crc;
|
||||
dir.NumSubDirs++;
|
||||
CProxyDir2 &f = Dirs[subFile.DirIndex];
|
||||
f.PathPrefix = dir.PathPrefix + subFile.Name + WCHAR_PATH_SEPARATOR;
|
||||
CalculateSizes(subFile.DirIndex, archive);
|
||||
dir.Size += f.Size;
|
||||
dir.PackSize += f.PackSize;
|
||||
dir.NumSubFiles += f.NumSubFiles;
|
||||
dir.NumSubDirs += f.NumSubDirs;
|
||||
dir.Crc += f.Crc;
|
||||
if (!f.CrcIsDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
dir.CrcIsDefined = false;
|
||||
}
|
||||
|
||||
if (subFile.AltStreamsFolderIndex < 0)
|
||||
if (subFile.AltDirIndex < 0)
|
||||
{
|
||||
// folder.NumSubFiles++;
|
||||
// dir.NumSubFiles++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// folder.NumSubFolders++;
|
||||
CProxyFolder2 &f = Folders[subFile.AltStreamsFolderIndex];
|
||||
f.PathPrefix = folder.PathPrefix + subFile.Name + L":";
|
||||
CalculateSizes(subFile.AltStreamsFolderIndex, archive);
|
||||
/*
|
||||
folder.Size += f.Size;
|
||||
folder.PackSize += f.PackSize;
|
||||
folder.NumSubFiles += f.NumSubFiles;
|
||||
folder.NumSubFolders += f.NumSubFolders;
|
||||
folder.Crc += f.Crc;
|
||||
if (!f.CrcIsDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
*/
|
||||
// dir.NumSubDirs++;
|
||||
CProxyDir2 &f = Dirs[subFile.AltDirIndex];
|
||||
f.PathPrefix = dir.PathPrefix + subFile.Name + L':';
|
||||
CalculateSizes(subFile.AltDirIndex, archive);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CProxyArchive2::IsThere_SubDir(unsigned folderIndex, const UString &name) const
|
||||
bool CProxyArc2::IsThere_SubDir(unsigned dirIndex, const UString &name) const
|
||||
{
|
||||
const CRecordVector<unsigned> &subFiles = Folders[folderIndex].SubFiles;
|
||||
const CRecordVector<unsigned> &subFiles = Dirs[dirIndex].Items;
|
||||
FOR_VECTOR (i, subFiles)
|
||||
{
|
||||
const CProxyFile2 &file = Files[subFiles[i]];
|
||||
@@ -448,14 +524,15 @@ bool CProxyArchive2::IsThere_SubDir(unsigned folderIndex, const UString &name) c
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT CProxyArchive2::Load(const CArc &arc, IProgress *progress)
|
||||
HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
|
||||
{
|
||||
if (!arc.GetRawProps)
|
||||
return E_FAIL;
|
||||
|
||||
// DWORD tickCount = GetTickCount();
|
||||
// DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) {
|
||||
|
||||
Folders.Clear();
|
||||
Dirs.Clear();
|
||||
Files.Free();
|
||||
|
||||
IInArchive *archive = arc.Archive;
|
||||
|
||||
@@ -464,9 +541,17 @@ HRESULT CProxyArchive2::Load(const CArc &arc, IProgress *progress)
|
||||
if (progress)
|
||||
RINOK(progress->SetTotal(numItems));
|
||||
UString fileName;
|
||||
|
||||
|
||||
{
|
||||
CProxyFolder2 &folder = Folders.AddNew();
|
||||
folder.ArcIndex = -1;
|
||||
// Dirs[0] - root dir
|
||||
/* CProxyDir2 &dir = */ Dirs.AddNew();
|
||||
}
|
||||
|
||||
{
|
||||
// Dirs[1] - for alt streams of root dir
|
||||
CProxyDir2 &dir = Dirs.AddNew();
|
||||
dir.PathPrefix = L':';
|
||||
}
|
||||
|
||||
Files.Alloc(numItems);
|
||||
@@ -491,9 +576,9 @@ HRESULT CProxyArchive2::Load(const CArc &arc, IProgress *progress)
|
||||
if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE)
|
||||
{
|
||||
file.Name = (const wchar_t *)p;
|
||||
file.NameSize = 0;
|
||||
file.NameLen = 0;
|
||||
if (size >= sizeof(wchar_t))
|
||||
file.NameSize = size / sizeof(wchar_t) - 1;
|
||||
file.NameLen = size / sizeof(wchar_t) - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -507,11 +592,12 @@ HRESULT CProxyArchive2::Load(const CArc &arc, IProgress *progress)
|
||||
s = L"[Content]";
|
||||
else
|
||||
return E_FAIL;
|
||||
file.NameSize = MyStringLen(s);
|
||||
file.Name = new wchar_t[file.NameSize + 1];
|
||||
file.NameLen = MyStringLen(s);
|
||||
file.Name = new wchar_t[file.NameLen + 1];
|
||||
file.NeedDeleteName = true;
|
||||
MyStringCopy((wchar_t *)file.Name, s);
|
||||
}
|
||||
|
||||
UInt32 parent = (UInt32)(Int32)-1;
|
||||
UInt32 parentType = 0;
|
||||
RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType));
|
||||
@@ -528,14 +614,14 @@ HRESULT CProxyArchive2::Load(const CArc &arc, IProgress *progress)
|
||||
}
|
||||
}
|
||||
|
||||
bool isFolder;
|
||||
RINOK(Archive_IsItem_Folder(archive, i, isFolder));
|
||||
bool isDir;
|
||||
RINOK(Archive_IsItem_Dir(archive, i, isDir));
|
||||
|
||||
if (isFolder)
|
||||
if (isDir)
|
||||
{
|
||||
file.FolderIndex = Folders.Size();
|
||||
CProxyFolder2 &folder = Folders.AddNew();
|
||||
folder.ArcIndex = i;
|
||||
file.DirIndex = Dirs.Size();
|
||||
CProxyDir2 &dir = Dirs.AddNew();
|
||||
dir.ArcIndex = i;
|
||||
}
|
||||
if (arc.Ask_AltStream)
|
||||
RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream));
|
||||
@@ -544,34 +630,57 @@ HRESULT CProxyArchive2::Load(const CArc &arc, IProgress *progress)
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
CProxyFile2 &file = Files[i];
|
||||
int dirIndex;
|
||||
|
||||
if (file.IsAltStream)
|
||||
{
|
||||
if (file.Parent >= 0)
|
||||
if (file.Parent < 0)
|
||||
dirIndex = k_Proxy2_AltRootDirIndex;
|
||||
else
|
||||
{
|
||||
int &folderIndex = Files[file.Parent].AltStreamsFolderIndex;
|
||||
if (folderIndex < 0)
|
||||
int &folderIndex2 = Files[file.Parent].AltDirIndex;
|
||||
if (folderIndex2 < 0)
|
||||
{
|
||||
folderIndex = Folders.Size();
|
||||
CProxyFolder2 &folder = Folders.AddNew();
|
||||
folder.ArcIndex = file.Parent; // do we need it ???
|
||||
folderIndex2 = Dirs.Size();
|
||||
CProxyDir2 &dir = Dirs.AddNew();
|
||||
dir.ArcIndex = file.Parent;
|
||||
}
|
||||
Folders[folderIndex].SubFiles.Add(i);
|
||||
dirIndex = folderIndex2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int folderIndex = GetParentFolderOfFile(i);
|
||||
if (folderIndex < 0)
|
||||
return E_FAIL;
|
||||
Folders[folderIndex].SubFiles.Add(i);
|
||||
if (file.Parent < 0)
|
||||
dirIndex = k_Proxy2_RootDirIndex;
|
||||
else
|
||||
{
|
||||
dirIndex = Files[file.Parent].DirIndex;
|
||||
if (dirIndex < 0)
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
Dirs[dirIndex].Items.Add(i);
|
||||
}
|
||||
CalculateSizes(0, archive);
|
||||
|
||||
for (i = 0; i < k_Proxy2_NumRootDirs; i++)
|
||||
CalculateSizes(i, archive);
|
||||
|
||||
// } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s);
|
||||
|
||||
/*
|
||||
char s[128];
|
||||
sprintf(s, "load archive %7d ms", GetTickCount() - tickCount);
|
||||
OutputDebugStringA(s);
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int CProxyArc2::FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnly) const
|
||||
{
|
||||
const CProxyDir2 &dir = Dirs[dirIndex];
|
||||
FOR_VECTOR (i, dir.Items)
|
||||
{
|
||||
const CProxyFile2 &file = Files[dir.Items[i]];
|
||||
if (foldersOnly && file.DirIndex < 0)
|
||||
continue;
|
||||
if (CompareFileNames(file.Name, name) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -7,46 +7,61 @@
|
||||
|
||||
struct CProxyFile
|
||||
{
|
||||
UInt32 Index;
|
||||
UString Name;
|
||||
const wchar_t *Name;
|
||||
unsigned NameLen;
|
||||
bool NeedDeleteName;
|
||||
|
||||
CProxyFile(): Name(NULL), NameLen(0), NeedDeleteName(false) {}
|
||||
~CProxyFile() { if (NeedDeleteName) delete [](wchar_t *)Name; }
|
||||
};
|
||||
|
||||
class CProxyFolder: public CProxyFile
|
||||
const unsigned k_Proxy_RootDirIndex = 0;
|
||||
|
||||
struct CProxyDir
|
||||
{
|
||||
public:
|
||||
int Parent;
|
||||
CRecordVector<unsigned> Folders;
|
||||
CObjectVector<CProxyFile> Files;
|
||||
const wchar_t *Name;
|
||||
unsigned NameLen;
|
||||
|
||||
int ArcIndex; // index in proxy->Files[] ; -1 if there is no item for that folder
|
||||
int ParentDir; // index in proxy->Dirs[] ; -1 for root folder; ;
|
||||
CRecordVector<unsigned> SubDirs;
|
||||
CRecordVector<unsigned> SubFiles;
|
||||
|
||||
UInt64 Size;
|
||||
UInt64 PackSize;
|
||||
UInt32 Crc;
|
||||
UInt32 NumSubFolders;
|
||||
UInt32 NumSubDirs;
|
||||
UInt32 NumSubFiles;
|
||||
bool IsLeaf;
|
||||
bool CrcIsDefined;
|
||||
|
||||
CProxyFolder(): Parent(-1) {};
|
||||
void AddFileSubItem(UInt32 index, const UString &name);
|
||||
CProxyDir(): Name(NULL), NameLen(0), ParentDir(-1) {};
|
||||
~CProxyDir() { delete [](wchar_t *)Name; }
|
||||
|
||||
void Clear();
|
||||
bool IsLeaf() const { return ArcIndex >= 0; }
|
||||
};
|
||||
|
||||
class CProxyArchive
|
||||
class CProxyArc
|
||||
{
|
||||
int FindDirSubItemIndex(unsigned folderIndex, const UString &name, unsigned &insertPos) const;
|
||||
int FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &insertPos) const;
|
||||
|
||||
void CalculateSizes(unsigned folderIndex, IInArchive *archive);
|
||||
unsigned AddDirSubItem(unsigned folderIndex, UInt32 index, bool leaf, const UString &name);
|
||||
void CalculateSizes(unsigned dirIndex, IInArchive *archive);
|
||||
unsigned AddDir(unsigned dirIndex, int arcIndex, const UString &name);
|
||||
public:
|
||||
CObjectVector<CProxyFolder> Folders; // Folders[0] - isRoot
|
||||
CObjectVector<CProxyDir> Dirs; // Dirs[0] - root
|
||||
CObjArray<CProxyFile> Files; // all items from archive in same order
|
||||
|
||||
int FindDirSubItemIndex(unsigned folderIndex, const UString &name) const;
|
||||
void GetPathParts(int folderIndex, UStringVector &pathParts) const;
|
||||
UString GetFullPathPrefix(int folderIndex) const;
|
||||
// returns index in Dirs[], or -1,
|
||||
int FindSubDir(unsigned dirIndex, const wchar_t *name) const;
|
||||
|
||||
void GetDirPathParts(int dirIndex, UStringVector &pathParts) const;
|
||||
// returns full path of Dirs[dirIndex], including back slash
|
||||
UString GetDirPath_as_Prefix(int dirIndex) const;
|
||||
|
||||
// AddRealIndices DOES ADD also item represented by folderIndex (if it's Leaf)
|
||||
void AddRealIndices(unsigned folderIndex, CUIntVector &realIndices) const;
|
||||
int GetRealIndex(unsigned folderIndex, unsigned index) const;
|
||||
void GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const;
|
||||
// AddRealIndices DOES ADD also item represented by dirIndex (if it's Leaf)
|
||||
void AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const;
|
||||
int GetRealIndex(unsigned dirIndex, unsigned index) const;
|
||||
void GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const;
|
||||
|
||||
HRESULT Load(const CArc &arc, IProgress *progress);
|
||||
};
|
||||
@@ -56,19 +71,25 @@ public:
|
||||
|
||||
struct CProxyFile2
|
||||
{
|
||||
int FolderIndex; // >= 0 for dir. (index in ProxyArchive2->Folders)
|
||||
int AltStreamsFolderIndex; // >= 0 if there are alt streams. (index in ProxyArchive2->Folders)
|
||||
int Parent; // >= 0 if there is parent. (index in archive and in ProxyArchive2->Files)
|
||||
int DirIndex; // >= 0 for dir. (index in ProxyArchive2->Dirs)
|
||||
int AltDirIndex; // >= 0 if there are alt streams. (index in ProxyArchive2->Dirs)
|
||||
int Parent; // >= 0 if there is parent. (index in archive and in ProxyArchive2->Files)
|
||||
const wchar_t *Name;
|
||||
unsigned NameSize;
|
||||
unsigned NameLen;
|
||||
bool NeedDeleteName;
|
||||
bool Ignore;
|
||||
bool IsAltStream;
|
||||
bool NeedDeleteName;
|
||||
|
||||
int GetFolderIndex(bool forAltStreams) const { return forAltStreams ? AltStreamsFolderIndex : FolderIndex; }
|
||||
int GetDirIndex(bool forAltStreams) const { return forAltStreams ? AltDirIndex : DirIndex; }
|
||||
|
||||
bool IsDir() const { return FolderIndex >= 0; }
|
||||
CProxyFile2(): FolderIndex(-1), AltStreamsFolderIndex(-1), Name(NULL), Ignore(false), IsAltStream(false), NeedDeleteName(false) {}
|
||||
bool IsDir() const { return DirIndex >= 0; }
|
||||
CProxyFile2():
|
||||
DirIndex(-1), AltDirIndex(-1), Parent(-1),
|
||||
Name(NULL), NameLen(0),
|
||||
NeedDeleteName(false),
|
||||
Ignore(false),
|
||||
IsAltStream(false)
|
||||
{}
|
||||
~CProxyFile2()
|
||||
{
|
||||
if (NeedDeleteName)
|
||||
@@ -76,53 +97,66 @@ struct CProxyFile2
|
||||
}
|
||||
};
|
||||
|
||||
class CProxyFolder2
|
||||
struct CProxyDir2
|
||||
{
|
||||
public:
|
||||
Int32 ArcIndex; // = -1 for Root folder
|
||||
CRecordVector<unsigned> SubFiles;
|
||||
int ArcIndex; // = -1 for root folders, index in proxy->Files[]
|
||||
CRecordVector<unsigned> Items;
|
||||
UString PathPrefix;
|
||||
UInt64 Size;
|
||||
UInt64 PackSize;
|
||||
bool CrcIsDefined;
|
||||
UInt32 Crc;
|
||||
UInt32 NumSubFolders;
|
||||
UInt32 NumSubDirs;
|
||||
UInt32 NumSubFiles;
|
||||
|
||||
CProxyFolder2(): ArcIndex(-1) {};
|
||||
CProxyDir2(): ArcIndex(-1) {};
|
||||
void AddFileSubItem(UInt32 index, const UString &name);
|
||||
void Clear();
|
||||
|
||||
};
|
||||
|
||||
class CProxyArchive2
|
||||
const unsigned k_Proxy2_RootDirIndex = k_Proxy_RootDirIndex;
|
||||
const unsigned k_Proxy2_AltRootDirIndex = 1;
|
||||
const unsigned k_Proxy2_NumRootDirs = 2;
|
||||
|
||||
class CProxyArc2
|
||||
{
|
||||
void CalculateSizes(unsigned folderIndex, IInArchive *archive);
|
||||
// AddRealIndices_of_Folder DOES NOT ADD item itself represented by folderIndex
|
||||
void AddRealIndices_of_Folder(unsigned folderIndex, bool includeAltStreams, CUIntVector &realIndices) const;
|
||||
void CalculateSizes(unsigned dirIndex, IInArchive *archive);
|
||||
// AddRealIndices_of_Dir DOES NOT ADD item itself represented by dirIndex
|
||||
void AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const;
|
||||
public:
|
||||
CObjectVector<CProxyFolder2> Folders; // Folders[0] - is root folder
|
||||
CObjArray<CProxyFile2> Files; // all aitems from archive in same order
|
||||
CObjectVector<CProxyDir2> Dirs; // Dirs[0] - root folder
|
||||
// Dirs[1] - for alt streams of root dir
|
||||
CObjArray<CProxyFile2> Files; // all items from archive in same order
|
||||
|
||||
bool IsThere_SubDir(unsigned folderIndex, const UString &name) const;
|
||||
bool IsThere_SubDir(unsigned dirIndex, const UString &name) const;
|
||||
|
||||
void GetPathParts(int folderIndex, UStringVector &pathParts) const;
|
||||
UString GetFullPathPrefix(unsigned folderIndex) const;
|
||||
void GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const;
|
||||
UString GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const;
|
||||
bool IsAltDir(unsigned dirIndex) const;
|
||||
|
||||
// AddRealIndices_of_ArcItem DOES ADD item and subItems
|
||||
void AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const;
|
||||
unsigned GetRealIndex(unsigned folderIndex, unsigned index) const;
|
||||
void GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const;
|
||||
unsigned GetRealIndex(unsigned dirIndex, unsigned index) const;
|
||||
void GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const;
|
||||
|
||||
HRESULT Load(const CArc &arc, IProgress *progress);
|
||||
|
||||
int GetParentFolderOfFile(UInt32 indexInArc) const
|
||||
int GetParentDirOfFile(UInt32 arcIndex) const
|
||||
{
|
||||
const CProxyFile2 &file = Files[indexInArc];
|
||||
const CProxyFile2 &file = Files[arcIndex];
|
||||
|
||||
if (file.Parent < 0)
|
||||
return 0;
|
||||
return Files[file.Parent].FolderIndex;
|
||||
return file.IsAltStream ?
|
||||
k_Proxy2_AltRootDirIndex :
|
||||
k_Proxy2_RootDirIndex;
|
||||
|
||||
const CProxyFile2 &parentFile = Files[file.Parent];
|
||||
return file.IsAltStream ?
|
||||
parentFile.AltDirIndex :
|
||||
parentFile.DirIndex;
|
||||
}
|
||||
|
||||
int FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnly) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,9 +28,14 @@ STDMETHODIMP CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32
|
||||
CMyComPtr<IFolderOperationsExtractCallback> callbackWrap = callback;
|
||||
RINOK(callbackWrap.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2));
|
||||
}
|
||||
NExtract::NPathMode::EEnum pathMode = _flatMode ?
|
||||
NExtract::NPathMode::kNoPaths :
|
||||
NExtract::NPathMode::kCurPaths;
|
||||
NExtract::NPathMode::EEnum pathMode;
|
||||
if (!_flatMode)
|
||||
pathMode = NExtract::NPathMode::kCurPaths;
|
||||
else
|
||||
pathMode = (_proxy2 && _loadAltStreams) ?
|
||||
NExtract::NPathMode::kNoPathsAlt :
|
||||
NExtract::NPathMode::kNoPaths;
|
||||
|
||||
return Extract(indices, numItems,
|
||||
includeAltStreams, replaceAltStreamCharsMode,
|
||||
pathMode, NExtract::NOverwriteMode::kAsk,
|
||||
|
||||
@@ -2,21 +2,19 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Windows/DLL.h"
|
||||
|
||||
#include "Agent.h"
|
||||
|
||||
void CArchiveFolderManager::LoadFormats()
|
||||
{
|
||||
if (!_codecs)
|
||||
{
|
||||
_compressCodecsInfo = _codecs = new CCodecs;
|
||||
_codecs->Load();
|
||||
}
|
||||
LoadGlobalCodecs();
|
||||
}
|
||||
|
||||
int CArchiveFolderManager::FindFormat(const UString &type)
|
||||
{
|
||||
FOR_VECTOR (i, _codecs->Formats)
|
||||
if (type.IsEqualToNoCase(_codecs->Formats[i].Name))
|
||||
FOR_VECTOR (i, g_CodecsObj->Formats)
|
||||
if (type.IsEqualTo_NoCase(g_CodecsObj->Formats[i].Name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
@@ -54,7 +52,7 @@ STDMETHODIMP CArchiveFolderManager::GetExtensions(const wchar_t *type, BSTR *ext
|
||||
if (formatIndex < 0)
|
||||
return E_INVALIDARG;
|
||||
// Exts[0].Ext;
|
||||
return StringToBstr(_codecs.Formats[formatIndex].GetAllExtensions(), extensions);
|
||||
return StringToBstr(g_CodecsObj.Formats[formatIndex].GetAllExtensions(), extensions);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -62,8 +60,7 @@ static void AddIconExt(const CCodecIcons &lib, UString &dest)
|
||||
{
|
||||
FOR_VECTOR (i, lib.IconPairs)
|
||||
{
|
||||
if (!dest.IsEmpty())
|
||||
dest += L' ';
|
||||
dest.Add_Space_if_NotEmpty();
|
||||
dest += lib.IconPairs[i].Ext;
|
||||
}
|
||||
}
|
||||
@@ -73,20 +70,30 @@ STDMETHODIMP CArchiveFolderManager::GetExtensions(BSTR *extensions)
|
||||
LoadFormats();
|
||||
*extensions = 0;
|
||||
UString res;
|
||||
FOR_VECTOR (i, _codecs->Libs)
|
||||
AddIconExt(_codecs->Libs[i], res);
|
||||
AddIconExt(_codecs->InternalIcons, res);
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
|
||||
FOR_VECTOR (i, g_CodecsObj->Libs)
|
||||
AddIconExt(g_CodecsObj->Libs[i], res);
|
||||
|
||||
#endif
|
||||
|
||||
AddIconExt(g_CodecsObj->InternalIcons, res);
|
||||
return StringToBstr(res, extensions);
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex)
|
||||
{
|
||||
LoadFormats();
|
||||
*iconPath = 0;
|
||||
*iconIndex = 0;
|
||||
FOR_VECTOR (i, _codecs->Libs)
|
||||
|
||||
LoadFormats();
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
|
||||
FOR_VECTOR (i, g_CodecsObj->Libs)
|
||||
{
|
||||
const CCodecLib &lib = _codecs->Libs[i];
|
||||
const CCodecLib &lib = g_CodecsObj->Libs[i];
|
||||
int ii;
|
||||
if (lib.FindIconIndex(ext, ii))
|
||||
{
|
||||
@@ -94,8 +101,11 @@ STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPa
|
||||
return StringToBstr(fs2us(lib.Path), iconPath);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int ii;
|
||||
if (_codecs->InternalIcons.FindIconIndex(ext, ii))
|
||||
if (g_CodecsObj->InternalIcons.FindIconIndex(ext, ii))
|
||||
{
|
||||
FString path;
|
||||
if (NWindows::NDLL::MyGetModuleFileName(path))
|
||||
@@ -112,13 +122,13 @@ STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types)
|
||||
{
|
||||
LoadFormats();
|
||||
UString typesStrings;
|
||||
FOR_VECTOR(i, _codecs.Formats)
|
||||
FOR_VECTOR(i, g_CodecsObj.Formats)
|
||||
{
|
||||
const CArcInfoEx &ai = _codecs.Formats[i];
|
||||
const CArcInfoEx &ai = g_CodecsObj.Formats[i];
|
||||
if (ai.AssociateExts.Size() == 0)
|
||||
continue;
|
||||
if (i != 0)
|
||||
typesStrings += L' ';
|
||||
typesStrings.Add_Space();
|
||||
typesStrings += ai.Name;
|
||||
}
|
||||
return StringToBstr(typesStrings, types);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// FolderOut.cpp
|
||||
// ArchiveFolderOut.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -19,12 +19,12 @@ using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
void CAgentFolder::GetPathParts(UStringVector &pathParts)
|
||||
void CAgentFolder::GetPathParts(UStringVector &pathParts, bool &isAltStreamFolder)
|
||||
{
|
||||
if (_proxyArchive2)
|
||||
_proxyArchive2->GetPathParts(_proxyFolderItem, pathParts);
|
||||
if (_proxy2)
|
||||
_proxy2->GetDirPathParts(_proxyDirIndex, pathParts, isAltStreamFolder);
|
||||
else
|
||||
_proxyArchive->GetPathParts(_proxyFolderItem, pathParts);
|
||||
_proxy->GetDirPathParts(_proxyDirIndex, pathParts);
|
||||
}
|
||||
|
||||
static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
|
||||
@@ -55,16 +55,25 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
const wchar_t *newItemName,
|
||||
const NUpdateArchive::CActionSet *actionSet,
|
||||
const UInt32 *indices, UInt32 numItems,
|
||||
IFolderArchiveUpdateCallback *updateCallback100)
|
||||
IProgress *progress)
|
||||
{
|
||||
if (!_agentSpec->CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
|
||||
////////////////////////////
|
||||
// Save FolderItem;
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress)
|
||||
progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
|
||||
// ---------- Save FolderItem ----------
|
||||
|
||||
UStringVector pathParts;
|
||||
GetPathParts(pathParts);
|
||||
bool isAltStreamFolder = false;
|
||||
GetPathParts(pathParts, isAltStreamFolder);
|
||||
|
||||
FStringVector requestedPaths;
|
||||
FStringVector processedPaths;
|
||||
@@ -153,25 +162,96 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> openCallback;
|
||||
if (updateCallback100)
|
||||
{
|
||||
RINOK(updateCallback100->QueryInterface(IID_IArchiveOpenCallback, (void **)&openCallback));
|
||||
}
|
||||
updateCallback100->QueryInterface(IID_IArchiveOpenCallback, (void **)&openCallback);
|
||||
RINOK(_agentSpec->ReOpen(openCallback));
|
||||
}
|
||||
|
||||
// Restore FolderItem;
|
||||
// CAgent::ReOpen() deletes _proxy and _proxy2
|
||||
_items.Clear();
|
||||
_proxy = NULL;
|
||||
_proxy2 = NULL;
|
||||
_proxyDirIndex = k_Proxy_RootDirIndex;
|
||||
_isAltStreamFolder = false;
|
||||
|
||||
|
||||
// ---------- Restore FolderItem ----------
|
||||
|
||||
CMyComPtr<IFolderFolder> archiveFolder;
|
||||
RINOK(_agentSpec->BindToRootFolder(&archiveFolder));
|
||||
|
||||
// CAgent::BindToRootFolder() changes _proxy and _proxy2
|
||||
_proxy = _agentSpec->_proxy;
|
||||
_proxy2 = _agentSpec->_proxy2;
|
||||
|
||||
if (_proxy)
|
||||
{
|
||||
FOR_VECTOR (i, pathParts)
|
||||
{
|
||||
int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]);
|
||||
if (next < 0)
|
||||
break;
|
||||
_proxyDirIndex = next;
|
||||
}
|
||||
}
|
||||
|
||||
if (_proxy2)
|
||||
{
|
||||
if (pathParts.IsEmpty() && isAltStreamFolder)
|
||||
{
|
||||
_proxyDirIndex = k_Proxy2_AltRootDirIndex;
|
||||
}
|
||||
else FOR_VECTOR (i, pathParts)
|
||||
{
|
||||
bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder);
|
||||
int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly);
|
||||
if (index < 0)
|
||||
break;
|
||||
|
||||
const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]];
|
||||
|
||||
if (dirOnly)
|
||||
_proxyDirIndex = file.DirIndex;
|
||||
else
|
||||
{
|
||||
if (file.AltDirIndex >= 0)
|
||||
_proxyDirIndex = file.AltDirIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (pathParts.IsEmpty() && isAltStreamFolder)
|
||||
{
|
||||
CMyComPtr<IFolderAltStreams> folderAltStreams;
|
||||
archiveFolder.QueryInterface(IID_IFolderAltStreams, &folderAltStreams);
|
||||
if (folderAltStreams)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
folderAltStreams->BindToAltStreams((UInt32)(Int32)-1, &newFolder);
|
||||
if (newFolder)
|
||||
archiveFolder = newFolder;
|
||||
}
|
||||
}
|
||||
|
||||
FOR_VECTOR (i, pathParts)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
archiveFolder->BindToFolder(pathParts[i], &newFolder);
|
||||
if(!newFolder)
|
||||
|
||||
if (isAltStreamFolder && i == pathParts.Size() - 1)
|
||||
{
|
||||
CMyComPtr<IFolderAltStreams> folderAltStreams;
|
||||
archiveFolder.QueryInterface(IID_IFolderAltStreams, &folderAltStreams);
|
||||
if (folderAltStreams)
|
||||
folderAltStreams->BindToAltStreams(pathParts[i], &newFolder);
|
||||
}
|
||||
else
|
||||
archiveFolder->BindToFolder(pathParts[i], &newFolder);
|
||||
|
||||
if (!newFolder)
|
||||
break;
|
||||
archiveFolder = newFolder;
|
||||
}
|
||||
@@ -180,63 +260,56 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal));
|
||||
CAgentFolder *agentFolder;
|
||||
RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder));
|
||||
_proxyFolderItem = agentFolder->_proxyFolderItem;
|
||||
_proxyArchive = agentFolder->_proxyArchive;
|
||||
_proxyArchive2 = agentFolder->_proxyArchive2;
|
||||
_parentFolder = agentFolder->_parentFolder;
|
||||
_proxyDirIndex = agentFolder->_proxyDirIndex;
|
||||
// _parentFolder = agentFolder->_parentFolder;
|
||||
*/
|
||||
|
||||
if (_proxy2)
|
||||
_isAltStreamFolder = _proxy2->IsAltDir(_proxyDirIndex);
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
catch(const UString &s)
|
||||
{
|
||||
if (updateCallback100)
|
||||
{
|
||||
UString s2 = L"Error: ";
|
||||
s2 += s;
|
||||
RINOK(updateCallback100->UpdateErrorMessage(s2));
|
||||
return E_FAIL;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CAgentFolder::CopyFrom(Int32 moveMode,
|
||||
const wchar_t *fromFolderPath, // test it
|
||||
const wchar_t **itemsPaths,
|
||||
const wchar_t * const *itemsPaths,
|
||||
UInt32 numItems,
|
||||
IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress)
|
||||
{
|
||||
RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100));
|
||||
}
|
||||
try
|
||||
{
|
||||
RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems));
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
return CommonUpdateOperation(AGENT_OP_Uni, (moveMode != 0), NULL,
|
||||
&NUpdateArchive::k_ActionSet_Add,
|
||||
0, 0, updateCallback100);
|
||||
}
|
||||
catch(const UString &s)
|
||||
{
|
||||
RINOK(updateCallback100->UpdateErrorMessage(UString(L"Error: ") + s));
|
||||
return E_FAIL;
|
||||
NULL, 0, progress);
|
||||
}
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress * progress)
|
||||
STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CUIntVector indices;
|
||||
indices.Add(destIndex);
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress)
|
||||
{
|
||||
RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100));
|
||||
}
|
||||
try
|
||||
{
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
return CommonUpdateOperation(AGENT_OP_CopyFromFile, false, itemPath,
|
||||
&NUpdateArchive::k_ActionSet_Add,
|
||||
&indices.Front(), indices.Size(), updateCallback100);
|
||||
}
|
||||
catch(const UString &s)
|
||||
{
|
||||
RINOK(updateCallback100->UpdateErrorMessage(UString(L"Error: ") + s));
|
||||
return E_FAIL;
|
||||
&indices.Front(), indices.Size(), progress);
|
||||
}
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -244,40 +317,30 @@ STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPat
|
||||
STDMETHODIMP CAgentFolder::Delete(const UInt32 *indices, UInt32 numItems, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress)
|
||||
{
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(
|
||||
IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(AGENT_OP_Delete, false, NULL,
|
||||
&NUpdateArchive::k_ActionSet_Delete, indices, numItems, updateCallback100);
|
||||
&NUpdateArchive::k_ActionSet_Delete, indices, numItems, progress);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
if (_proxyArchive2)
|
||||
|
||||
if (_isAltStreamFolder)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (_proxy2)
|
||||
{
|
||||
if (_proxyArchive2->IsThere_SubDir(_proxyFolderItem, name))
|
||||
if (_proxy2->IsThere_SubDir(_proxyDirIndex, name))
|
||||
return ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_proxyArchive->FindDirSubItemIndex(_proxyFolderItem, name) >= 0)
|
||||
if (_proxy->FindSubDir(_proxyDirIndex, name) >= 0)
|
||||
return ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress)
|
||||
{
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(AGENT_OP_CreateFolder, false, name, NULL, NULL, 0, updateCallback100);
|
||||
|
||||
return CommonUpdateOperation(AGENT_OP_CreateFolder, false, name, NULL, NULL, 0, progress);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -286,15 +349,8 @@ STDMETHODIMP CAgentFolder::Rename(UInt32 index, const wchar_t *newName, IProgres
|
||||
COM_TRY_BEGIN
|
||||
CUIntVector indices;
|
||||
indices.Add(index);
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress)
|
||||
{
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(AGENT_OP_Rename, false, newName, NULL, &indices.Front(),
|
||||
indices.Size(), updateCallback100);
|
||||
return CommonUpdateOperation(AGENT_OP_Rename, false, newName, NULL,
|
||||
&indices.Front(), indices.Size(), progress);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,15 @@
|
||||
#define FOLDER_ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 0x01, x)
|
||||
#define FOLDER_ARCHIVE_INTERFACE(i, x) FOLDER_ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
|
||||
|
||||
/* ---------- IArchiveFolder ----------
|
||||
IArchiveFolder is implemented by CAgentFolder (Agent/Agent.h)
|
||||
IArchiveFolder is used by:
|
||||
- FileManager/PanelCopy.cpp
|
||||
CPanel::CopyTo(), if (options->testMode)
|
||||
- FAR/PluginRead.cpp
|
||||
CPlugin::ExtractFiles
|
||||
*/
|
||||
|
||||
#define INTERFACE_IArchiveFolder(x) \
|
||||
STDMETHOD(Extract)(const UInt32 *indices, UInt32 numItems, \
|
||||
Int32 includeAltStreams, \
|
||||
@@ -29,6 +38,12 @@ FOLDER_ARCHIVE_INTERFACE(IArchiveFolder, 0x0D)
|
||||
INTERFACE_IArchiveFolder(PURE)
|
||||
};
|
||||
|
||||
|
||||
/* ---------- IInFolderArchive ----------
|
||||
IInFolderArchive is implemented by CAgent (Agent/Agent.h)
|
||||
IInFolderArchive Is used by FAR/Plugin
|
||||
*/
|
||||
|
||||
#define INTERFACE_IInFolderArchive(x) \
|
||||
STDMETHOD(Open)(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveTypeRes, IArchiveOpenCallback *openArchiveCallback) x; \
|
||||
STDMETHOD(ReOpen)(IArchiveOpenCallback *openArchiveCallback) x; \
|
||||
@@ -48,7 +63,7 @@ FOLDER_ARCHIVE_INTERFACE(IInFolderArchive, 0x0E)
|
||||
#define INTERFACE_IFolderArchiveUpdateCallback(x) \
|
||||
STDMETHOD(CompressOperation)(const wchar_t *name) x; \
|
||||
STDMETHOD(DeleteOperation)(const wchar_t *name) x; \
|
||||
STDMETHOD(OperationResult)(Int32 operationResult) x; \
|
||||
STDMETHOD(OperationResult)(Int32 opRes) x; \
|
||||
STDMETHOD(UpdateErrorMessage)(const wchar_t *message) x; \
|
||||
STDMETHOD(SetNumFiles)(UInt64 numFiles) x; \
|
||||
|
||||
@@ -59,7 +74,7 @@ FOLDER_ARCHIVE_INTERFACE_SUB(IFolderArchiveUpdateCallback, IProgress, 0x0B)
|
||||
|
||||
#define INTERFACE_IOutFolderArchive(x) \
|
||||
STDMETHOD(SetFolder)(IFolderFolder *folder) x; \
|
||||
STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UInt32 numNames) x; \
|
||||
STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t * const *names, UInt32 numNames) x; \
|
||||
STDMETHOD(DeleteItems)(ISequentialOutStream *outArchiveStream, \
|
||||
const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback) x; \
|
||||
STDMETHOD(DoOperation)( \
|
||||
@@ -79,4 +94,26 @@ FOLDER_ARCHIVE_INTERFACE(IOutFolderArchive, 0x0F)
|
||||
INTERFACE_IOutFolderArchive(PURE)
|
||||
};
|
||||
|
||||
|
||||
#define INTERFACE_IFolderArchiveUpdateCallback2(x) \
|
||||
STDMETHOD(OpenFileError)(const wchar_t *path, HRESULT errorCode) x; \
|
||||
STDMETHOD(ReadingFileError)(const wchar_t *path, HRESULT errorCode) x; \
|
||||
STDMETHOD(ReportExtractResult)(Int32 opRes, Int32 isEncrypted, const wchar_t *path) x; \
|
||||
STDMETHOD(ReportUpdateOperation)(UInt32 notifyOp, const wchar_t *path, Int32 isDir) x; \
|
||||
|
||||
FOLDER_ARCHIVE_INTERFACE(IFolderArchiveUpdateCallback2, 0x10)
|
||||
{
|
||||
INTERFACE_IFolderArchiveUpdateCallback2(PURE)
|
||||
};
|
||||
|
||||
|
||||
#define INTERFACE_IFolderScanProgress(x) \
|
||||
STDMETHOD(ScanError)(const wchar_t *path, HRESULT errorCode) x; \
|
||||
STDMETHOD(ScanProgress)(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 isDir) x; \
|
||||
|
||||
FOLDER_ARCHIVE_INTERFACE(IFolderScanProgress, 0x11)
|
||||
{
|
||||
INTERFACE_IFolderScanProgress(PURE)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,14 +14,24 @@ void CUpdateCallbackAgent::SetCallback(IFolderArchiveUpdateCallback *callback)
|
||||
{
|
||||
Callback = callback;
|
||||
_compressProgress.Release();
|
||||
Callback2.Release();
|
||||
if (Callback)
|
||||
{
|
||||
Callback.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
|
||||
Callback.QueryInterface(IID_IFolderArchiveUpdateCallback2, &Callback2);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::SetNumFiles(UInt64 numFiles)
|
||||
HRESULT CUpdateCallbackAgent::SetNumItems(UInt64 numItems)
|
||||
{
|
||||
if (Callback)
|
||||
return Callback->SetNumFiles(numFiles);
|
||||
return Callback->SetNumFiles(numItems);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CUpdateCallbackAgent::WriteSfx(const wchar_t * /* name */, UInt64 /* size */)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -52,31 +62,65 @@ HRESULT CUpdateCallbackAgent::CheckBreak()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::Finilize()
|
||||
/*
|
||||
HRESULT CUpdateCallbackAgent::Finalize()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
HRESULT CUpdateCallbackAgent::OpenFileError(const wchar_t *name, DWORD systemError)
|
||||
HRESULT CUpdateCallbackAgent::OpenFileError(const FString &path, DWORD systemError)
|
||||
{
|
||||
HRESULT hres = HRESULT_FROM_WIN32(systemError);
|
||||
// if (systemError == ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
if (Callback2)
|
||||
{
|
||||
RINOK(Callback2->OpenFileError(fs2us(path), hres));
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if (Callback)
|
||||
{
|
||||
UString s = L"WARNING: ";
|
||||
s += NError::MyFormatMessage(systemError);
|
||||
s += L": ";
|
||||
s += name;
|
||||
s += fs2us(path);
|
||||
RINOK(Callback->UpdateErrorMessage(s));
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
// FailedFiles.Add(name);
|
||||
return systemError;
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool /* isAnti */)
|
||||
HRESULT CUpdateCallbackAgent::ReadingFileError(const FString &path, DWORD systemError)
|
||||
{
|
||||
HRESULT hres = HRESULT_FROM_WIN32(systemError);
|
||||
|
||||
// if (systemError == ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
if (Callback2)
|
||||
{
|
||||
RINOK(Callback2->ReadingFileError(fs2us(path), hres));
|
||||
}
|
||||
else if (Callback)
|
||||
{
|
||||
UString s = L"ERROR: ";
|
||||
s += NError::MyFormatMessage(systemError);
|
||||
s += L": ";
|
||||
s += fs2us(path);
|
||||
RINOK(Callback->UpdateErrorMessage(s));
|
||||
}
|
||||
}
|
||||
// FailedFiles.Add(name);
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool isDir, bool /* isAnti */, UInt32 mode)
|
||||
{
|
||||
if (Callback2)
|
||||
return Callback2->ReportUpdateOperation(mode, name, BoolToInt(isDir));
|
||||
if (Callback)
|
||||
return Callback->CompressOperation(name);
|
||||
return S_OK;
|
||||
@@ -89,6 +133,50 @@ HRESULT CUpdateCallbackAgent::SetOperationResult(Int32 operationResult)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s);
|
||||
|
||||
HRESULT CUpdateCallbackAgent::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)
|
||||
{
|
||||
if (Callback2)
|
||||
{
|
||||
return Callback2->ReportExtractResult(opRes, isEncrypted, name);
|
||||
}
|
||||
/*
|
||||
if (mode != NArchive::NExtract::NOperationResult::kOK)
|
||||
{
|
||||
Int32 encrypted = 0;
|
||||
UString s;
|
||||
SetExtractErrorMessage(mode, encrypted, name, s);
|
||||
// ProgressDialog->Sync.AddError_Message(s);
|
||||
}
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir)
|
||||
{
|
||||
if (Callback2)
|
||||
{
|
||||
return Callback2->ReportUpdateOperation(op, name, BoolToInt(isDir));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
HRESULT CUpdateCallbackAgent::SetPassword(const UString &
|
||||
#ifndef _NO_CRYPTO
|
||||
password
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifndef _NO_CRYPTO
|
||||
PasswordIsDefined = true;
|
||||
Password = password;
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
HRESULT CUpdateCallbackAgent::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
|
||||
{
|
||||
*password = NULL;
|
||||
@@ -114,9 +202,7 @@ HRESULT CUpdateCallbackAgent::CryptoGetTextPassword(BSTR *password)
|
||||
return getTextPassword->CryptoGetTextPassword(password);
|
||||
}
|
||||
|
||||
/*
|
||||
HRESULT CUpdateCallbackAgent::ShowDeleteFile(const wchar_t *name)
|
||||
HRESULT CUpdateCallbackAgent::ShowDeleteFile(const wchar_t *name, bool /* isDir */)
|
||||
{
|
||||
return Callback->DeleteOperation(name);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
class CUpdateCallbackAgent: public IUpdateCallbackUI
|
||||
{
|
||||
INTERFACE_IUpdateCallbackUI(;)
|
||||
|
||||
CMyComPtr<ICryptoGetTextPassword2> _cryptoGetTextPassword;
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> Callback;
|
||||
CMyComPtr<IFolderArchiveUpdateCallback2> Callback2;
|
||||
CMyComPtr<ICompressProgressInfo> _compressProgress;
|
||||
public:
|
||||
void SetCallback(IFolderArchiveUpdateCallback *callback);
|
||||
|
||||
Reference in New Issue
Block a user