Files
easy7zip/CPP/7zip/UI/Agent/Agent.h
Igor Pavlov a36c48cece 23.01
2023-12-22 17:17:05 +00:00

354 lines
9.0 KiB
C++
Executable File

// Agent/Agent.h
#ifndef ZIP7_INC_AGENT_AGENT_H
#define ZIP7_INC_AGENT_AGENT_H
#include "../../../Common/MyCom.h"
#include "../../../Windows/PropVariant.h"
#include "../Common/LoadCodecs.h"
#include "../Common/OpenArchive.h"
#include "../Common/UpdateAction.h"
#include "../FileManager/IFolder.h"
#include "AgentProxy.h"
#include "IFolderArchive.h"
extern CCodecs *g_CodecsObj;
HRESULT LoadGlobalCodecs();
void FreeGlobalCodecs();
class CAgentFolder;
Z7_PURE_INTERFACES_BEGIN
#define Z7_IFACEM_IArchiveFolderInternal(x) \
x(GetAgentFolder(CAgentFolder **agentFolder))
Z7_IFACE_CONSTR_FOLDERARC(IArchiveFolderInternal, 0xC)
Z7_PURE_INTERFACES_END
struct CProxyItem
{
unsigned DirIndex;
unsigned Index;
};
class CAgent;
enum AGENT_OP
{
AGENT_OP_Uni,
AGENT_OP_Delete,
AGENT_OP_CreateFolder,
AGENT_OP_Rename,
AGENT_OP_CopyFromFile,
AGENT_OP_Comment
};
class CAgentFolder Z7_final:
public IFolderFolder,
public IFolderAltStreams,
public IFolderProperties,
public IArchiveGetRawProps,
public IGetFolderArcProps,
public IFolderCompare,
public IFolderGetItemName,
public IArchiveFolder,
public IArchiveFolderInternal,
public IInArchiveGetStream,
public IFolderSetZoneIdMode,
public IFolderOperations,
public IFolderSetFlatMode,
public CMyUnknownImp
{
Z7_COM_QI_BEGIN2(IFolderFolder)
Z7_COM_QI_ENTRY(IFolderAltStreams)
Z7_COM_QI_ENTRY(IFolderProperties)
Z7_COM_QI_ENTRY(IArchiveGetRawProps)
Z7_COM_QI_ENTRY(IGetFolderArcProps)
Z7_COM_QI_ENTRY(IFolderCompare)
Z7_COM_QI_ENTRY(IFolderGetItemName)
Z7_COM_QI_ENTRY(IArchiveFolder)
Z7_COM_QI_ENTRY(IArchiveFolderInternal)
Z7_COM_QI_ENTRY(IInArchiveGetStream)
Z7_COM_QI_ENTRY(IFolderSetZoneIdMode)
Z7_COM_QI_ENTRY(IFolderOperations)
Z7_COM_QI_ENTRY(IFolderSetFlatMode)
Z7_COM_QI_END
Z7_COM_ADDREF_RELEASE
Z7_IFACE_COM7_IMP(IFolderFolder)
Z7_IFACE_COM7_IMP(IFolderAltStreams)
Z7_IFACE_COM7_IMP(IFolderProperties)
Z7_IFACE_COM7_IMP(IArchiveGetRawProps)
Z7_IFACE_COM7_IMP(IGetFolderArcProps)
Z7_IFACE_COM7_IMP(IFolderCompare)
Z7_IFACE_COM7_IMP(IFolderGetItemName)
Z7_IFACE_COM7_IMP(IArchiveFolder)
Z7_IFACE_COM7_IMP(IArchiveFolderInternal)
Z7_IFACE_COM7_IMP(IInArchiveGetStream)
Z7_IFACE_COM7_IMP(IFolderSetZoneIdMode)
Z7_IFACE_COM7_IMP(IFolderOperations)
Z7_IFACE_COM7_IMP(IFolderSetFlatMode)
void LoadFolder(unsigned proxyDirIndex);
public:
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;
int CompareItems3(UInt32 index1, UInt32 index2, PROPID propID);
int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
CAgentFolder():
_proxyDirIndex(0),
_isAltStreamFolder(false),
_flatMode(false),
_loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now
, _zoneMode(NExtract::NZoneIdMode::kNone)
/* , _replaceAltStreamCharsMode(0) */
{}
void Init(const CProxyArc *proxy, const CProxyArc2 *proxy2,
unsigned proxyDirIndex,
/* IFolderFolder *parentFolder, */
CAgent *agent)
{
_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, bool &isAltStreamFolder);
HRESULT CommonUpdateOperation(
AGENT_OP operation,
bool moveMode,
const wchar_t *newItemName,
const NUpdateArchive::CActionSet *actionSet,
const UInt32 *indices, UInt32 numItems,
IProgress *progress);
void GetPrefix(UInt32 index, UString &prefix) const;
UString GetName(UInt32 index) const;
UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive
public:
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;
NExtract::NZoneIdMode::EEnum _zoneMode;
};
class CAgent Z7_final:
public IInFolderArchive,
public IFolderArcProps,
#ifndef Z7_EXTRACT_ONLY
public IOutFolderArchive,
public ISetProperties,
#endif
public CMyUnknownImp
{
Z7_COM_QI_BEGIN2(IInFolderArchive)
Z7_COM_QI_ENTRY(IFolderArcProps)
#ifndef Z7_EXTRACT_ONLY
Z7_COM_QI_ENTRY(IOutFolderArchive)
Z7_COM_QI_ENTRY(ISetProperties)
#endif
Z7_COM_QI_END
Z7_COM_ADDREF_RELEASE
Z7_IFACE_COM7_IMP(IInFolderArchive)
Z7_IFACE_COM7_IMP(IFolderArcProps)
#ifndef Z7_EXTRACT_ONLY
Z7_IFACE_COM7_IMP(ISetProperties)
public:
Z7_IFACE_COM7_IMP(IOutFolderArchive)
HRESULT CommonUpdate(ISequentialOutStream *outArchiveStream,
unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback);
HRESULT CreateFolder(ISequentialOutStream *outArchiveStream,
const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100);
HRESULT RenameItem(ISequentialOutStream *outArchiveStream,
const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
IFolderArchiveUpdateCallback *updateCallback100);
HRESULT CommentItem(ISequentialOutStream *outArchiveStream,
const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
IFolderArchiveUpdateCallback *updateCallback100);
HRESULT UpdateOneFile(ISequentialOutStream *outArchiveStream,
const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath,
IFolderArchiveUpdateCallback *updateCallback100);
#endif
private:
HRESULT ReadItems();
public:
CProxyArc *_proxy;
CProxyArc2 *_proxy2;
CArchiveLink _archiveLink;
bool ThereIsPathProp;
// bool ThereIsAltStreamProp;
UString ArchiveType;
FStringVector _names;
FString _folderPrefix; // for new files from disk
bool _updatePathPrefix_is_AltFolder;
UString _updatePathPrefix;
CAgentFolder *_agentFolder;
UString _archiveFilePath;
DWORD _attrib;
bool _isDeviceFile;
bool _isHashHandler;
FString _hashBaseFolderPrefix;
#ifndef Z7_EXTRACT_ONLY
CObjectVector<UString> m_PropNames;
CObjectVector<NWindows::NCOM::CPropVariant> m_PropValues;
#endif
CAgent();
~CAgent();
const CArc &GetArc() const { return _archiveLink.Arcs.Back(); }
IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return NULL; return GetArc().Archive; }
bool CanUpdate() const;
bool Is_Attrib_ReadOnly() const
{
return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY);
}
bool IsThere_ReadOnlyArc() const
{
FOR_VECTOR (i, _archiveLink.Arcs)
{
const CArc &arc = _archiveLink.Arcs[i];
if (arc.FormatIndex < 0
|| arc.IsReadOnly
|| !g_CodecsObj->Formats[arc.FormatIndex].UpdateEnabled)
return true;
}
return false;
}
UString GetTypeOfArc(const CArc &arc) const
{
if (arc.FormatIndex < 0)
return UString("Parser");
return g_CodecsObj->GetFormatNamePtr(arc.FormatIndex);
}
UString GetErrorMessage() const
{
UString s;
for (int i = (int)_archiveLink.Arcs.Size() - 1; i >= 0; i--)
{
const CArc &arc = _archiveLink.Arcs[i];
UString s2;
if (arc.ErrorInfo.ErrorFormatIndex >= 0)
{
if (arc.ErrorInfo.ErrorFormatIndex == arc.FormatIndex)
s2 += "Warning: The archive is open with offset";
else
{
s2 += "Cannot open the file as [";
s2 += g_CodecsObj->GetFormatNamePtr(arc.ErrorInfo.ErrorFormatIndex);
s2 += "] archive";
}
}
if (!arc.ErrorInfo.ErrorMessage.IsEmpty())
{
if (!s2.IsEmpty())
s2.Add_LF();
s2 += "\n[";
s2 += GetTypeOfArc(arc);
s2 += "]: ";
s2 += arc.ErrorInfo.ErrorMessage;
}
if (!s2.IsEmpty())
{
if (!s.IsEmpty())
s += "--------------------\n";
s += arc.Path;
s.Add_LF();
s += s2;
s.Add_LF();
}
}
return s;
}
void KeepModeForNextOpen() { _archiveLink.KeepModeForNextOpen(); }
};
// #ifdef NEW_FOLDER_INTERFACE
struct CCodecIcons
{
struct CIconPair
{
UString Ext;
int IconIndex;
};
CObjectVector<CIconPair> IconPairs;
// void Clear() { IconPairs.Clear(); }
void LoadIcons(HMODULE m);
bool FindIconIndex(const UString &ext, int &iconIndex) const;
};
Z7_CLASS_IMP_COM_1(
CArchiveFolderManager
, IFolderManager
)
CObjectVector<CCodecIcons> CodecIconsVector;
CCodecIcons InternalIcons;
bool WasLoaded;
void LoadFormats();
// int FindFormat(const UString &type);
public:
CArchiveFolderManager():
WasLoaded(false)
{}
};
// #endif
#endif