Files
Aaru.Compression.Native/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h

585 lines
12 KiB
C
Raw Permalink Normal View History

2021-10-19 21:27:23 +01:00
// ArchiveExtractCallback.h
2023-09-24 03:13:03 +01:00
#ifndef ZIP7_INC_ARCHIVE_EXTRACT_CALLBACK_H
#define ZIP7_INC_ARCHIVE_EXTRACT_CALLBACK_H
2021-10-19 21:27:23 +01:00
#include "../../../Common/MyCom.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/Wildcard.h"
#include "../../IPassword.h"
#include "../../Common/FileStreams.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h"
#include "../../Archive/IArchive.h"
#include "ExtractMode.h"
#include "IFileExtractCallback.h"
#include "OpenArchive.h"
#include "HashCalc.h"
2023-09-24 03:13:03 +01:00
#ifndef Z7_SFX
2021-10-19 21:27:23 +01:00
2023-09-24 03:13:03 +01:00
Z7_CLASS_IMP_NOQIB_1(
COutStreamWithHash
, ISequentialOutStream
)
2021-10-19 21:27:23 +01:00
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
bool _calculate;
public:
IHashCalc *_hash;
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init(bool calculate = true)
{
InitCRC();
_size = 0;
_calculate = calculate;
}
void EnableCalc(bool calculate) { _calculate = calculate; }
void InitCRC() { _hash->InitForNewFile(); }
UInt64 GetSize() const { return _size; }
};
#endif
struct CExtractNtOptions
{
CBoolPair NtSecurity;
CBoolPair SymLinks;
CBoolPair SymLinks_AllowDangerous;
CBoolPair HardLinks;
CBoolPair AltStreams;
bool ReplaceColonForAltStream;
bool WriteToAltStreamIfColon;
2023-09-24 03:13:03 +01:00
bool ExtractOwner;
2021-10-19 21:27:23 +01:00
bool PreAllocateOutFile;
2023-09-24 03:13:03 +01:00
// used for hash arcs only, when we open external files
bool PreserveATime;
bool OpenShareForWrite;
2021-10-19 21:27:23 +01:00
CExtractNtOptions():
ReplaceColonForAltStream(false),
2023-09-24 03:13:03 +01:00
WriteToAltStreamIfColon(false),
ExtractOwner(false),
PreserveATime(false),
OpenShareForWrite(false)
2021-10-19 21:27:23 +01:00
{
SymLinks.Val = true;
SymLinks_AllowDangerous.Val = false;
HardLinks.Val = true;
AltStreams.Val = true;
PreAllocateOutFile =
#ifdef _WIN32
true;
#else
false;
#endif
}
};
2023-09-24 03:13:03 +01:00
#ifndef Z7_SFX
2021-10-19 21:27:23 +01:00
2023-09-24 03:13:03 +01:00
Z7_CLASS_IMP_COM_1(
CGetProp
, IGetProp
)
2021-10-19 21:27:23 +01:00
public:
UInt32 IndexInArc;
2023-09-24 03:13:03 +01:00
const CArc *Arc;
2021-10-19 21:27:23 +01:00
// UString Name; // relative path
};
#endif
2023-09-24 03:13:03 +01:00
#ifndef Z7_SFX
2021-10-19 21:27:23 +01:00
#ifndef UNDER_CE
#define SUPPORT_LINKS
#endif
#endif
#ifdef SUPPORT_LINKS
struct CHardLinkNode
{
UInt64 StreamId;
UInt64 INode;
int Compare(const CHardLinkNode &a) const;
};
class CHardLinks
{
public:
CRecordVector<CHardLinkNode> IDs;
CObjectVector<FString> Links;
void Clear()
{
IDs.Clear();
Links.Clear();
}
void PrepareLinks()
{
while (Links.Size() < IDs.Size())
Links.AddNew();
}
};
#endif
#ifdef SUPPORT_ALT_STREAMS
struct CIndexToPathPair
{
UInt32 Index;
FString Path;
CIndexToPathPair(UInt32 index): Index(index) {}
CIndexToPathPair(UInt32 index, const FString &path): Index(index), Path(path) {}
int Compare(const CIndexToPathPair &pair) const
{
return MyCompare(Index, pair.Index);
}
};
#endif
2023-09-24 03:13:03 +01:00
struct CFiTimesCAM
2021-10-19 21:27:23 +01:00
{
2023-09-24 03:13:03 +01:00
CFiTime CTime;
CFiTime ATime;
CFiTime MTime;
2021-10-19 21:27:23 +01:00
2023-09-24 03:13:03 +01:00
bool CTime_Defined;
bool ATime_Defined;
bool MTime_Defined;
bool IsSomeTimeDefined() const
{
return
CTime_Defined |
ATime_Defined |
MTime_Defined;
}
};
2021-10-19 21:27:23 +01:00
2023-09-24 03:13:03 +01:00
struct CDirPathTime: public CFiTimesCAM
{
2021-10-19 21:27:23 +01:00
FString Path;
bool SetDirTime() const;
};
#ifdef SUPPORT_LINKS
struct CLinkInfo
{
// bool isCopyLink;
bool isHardLink;
bool isJunction;
bool isRelative;
bool isWSL;
UString linkPath;
2023-09-24 03:13:03 +01:00
bool IsSymLink() const { return !isHardLink; }
CLinkInfo():
// IsCopyLink(false),
isHardLink(false),
isJunction(false),
isRelative(false),
isWSL(false)
{}
2021-10-19 21:27:23 +01:00
void Clear()
{
// IsCopyLink = false;
isHardLink = false;
isJunction = false;
isRelative = false;
isWSL = false;
linkPath.Empty();
}
bool Parse(const Byte *data, size_t dataSize, bool isLinuxData);
};
#endif // SUPPORT_LINKS
2023-09-24 03:13:03 +01:00
#ifndef _WIN32
struct COwnerInfo
{
bool Id_Defined;
UInt32 Id;
AString Name;
void Clear()
{
Id_Defined = false;
Id = 0;
Name.Empty();
}
};
#endif
class CArchiveExtractCallback Z7_final:
2021-10-19 21:27:23 +01:00
public IArchiveExtractCallback,
2023-09-24 03:13:03 +01:00
public IArchiveExtractCallbackMessage2,
2021-10-19 21:27:23 +01:00
public ICryptoGetTextPassword,
public ICompressProgressInfo,
2023-09-24 03:13:03 +01:00
public IArchiveUpdateCallbackFile,
public IArchiveGetDiskProperty,
2021-10-19 21:27:23 +01:00
public CMyUnknownImp
{
2023-09-24 03:13:03 +01:00
Z7_COM_UNKNOWN_IMP_5(
/* IArchiveExtractCallback, */
IArchiveExtractCallbackMessage2,
ICryptoGetTextPassword,
ICompressProgressInfo,
IArchiveUpdateCallbackFile,
IArchiveGetDiskProperty)
Z7_IFACE_COM7_IMP(IProgress)
Z7_IFACE_COM7_IMP(IArchiveExtractCallback)
Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage2)
Z7_IFACE_COM7_IMP(ICryptoGetTextPassword)
Z7_IFACE_COM7_IMP(ICompressProgressInfo)
Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackFile)
Z7_IFACE_COM7_IMP(IArchiveGetDiskProperty)
2021-10-19 21:27:23 +01:00
const CArc *_arc;
CExtractNtOptions _ntOptions;
2023-09-24 03:13:03 +01:00
bool _isSplit;
bool _extractMode;
bool Write_CTime;
bool Write_ATime;
bool Write_MTime;
bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_";
bool _encrypted;
// bool _is_SymLink_in_Data;
bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX
bool _needSetAttrib;
bool _isSymLinkCreated;
bool _itemFailure;
bool _curSize_Defined;
bool _fileLength_WasSet;
bool _removePartsForAltStreams;
bool _stdOutMode;
bool _testMode;
bool _multiArchives;
NExtract::NPathMode::EEnum _pathMode;
NExtract::NOverwriteMode::EEnum _overwriteMode;
2021-10-19 21:27:23 +01:00
const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
2023-09-24 03:13:03 +01:00
// CMyComPtr<ICompressProgressInfo> _compressProgress;
// CMyComPtr<IArchiveExtractCallbackMessage2> _callbackMessage;
2021-10-19 21:27:23 +01:00
CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2;
2023-09-24 03:13:03 +01:00
CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
2021-10-19 21:27:23 +01:00
FString _dirPathPrefix;
FString _dirPathPrefix_Full;
2023-09-24 03:13:03 +01:00
#ifndef Z7_SFX
2021-10-19 21:27:23 +01:00
CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
CGetProp *GetProp_Spec;
CMyComPtr<IGetProp> GetProp;
#endif
CReadArcItem _item;
FString _diskFilePath;
UInt64 _position;
struct CProcessedFileInfo
{
2023-09-24 03:13:03 +01:00
CArcTime CTime;
CArcTime ATime;
CArcTime MTime;
2021-10-19 21:27:23 +01:00
UInt32 Attrib;
2023-09-24 03:13:03 +01:00
bool Attrib_Defined;
#ifndef _WIN32
COwnerInfo Owner;
COwnerInfo Group;
#endif
2021-10-19 21:27:23 +01:00
bool IsReparse() const
{
2023-09-24 03:13:03 +01:00
return (Attrib_Defined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
2021-10-19 21:27:23 +01:00
}
bool IsLinuxSymLink() const
{
2023-09-24 03:13:03 +01:00
return (Attrib_Defined && MY_LIN_S_ISLNK(Attrib >> 16));
2021-10-19 21:27:23 +01:00
}
void SetFromPosixAttrib(UInt32 a)
{
// here we set only part of combined attribute required by SetFileAttrib() call
#ifdef _WIN32
// Windows sets FILE_ATTRIBUTE_NORMAL, if we try to set 0 as attribute.
Attrib = MY_LIN_S_ISDIR(a) ?
FILE_ATTRIBUTE_DIRECTORY :
FILE_ATTRIBUTE_ARCHIVE;
if ((a & 0222) == 0) // (& S_IWUSR) in p7zip
Attrib |= FILE_ATTRIBUTE_READONLY;
2023-09-24 03:13:03 +01:00
// 22.00 : we need type bits for (MY_LIN_S_IFLNK) for IsLinuxSymLink()
a &= MY_LIN_S_IFMT;
if (a == MY_LIN_S_IFLNK)
Attrib |= (a << 16);
2021-10-19 21:27:23 +01:00
#else
Attrib = (a << 16) | FILE_ATTRIBUTE_UNIX_EXTENSION;
#endif
2023-09-24 03:13:03 +01:00
Attrib_Defined = true;
2021-10-19 21:27:23 +01:00
}
} _fi;
UInt32 _index;
UInt64 _curSize;
UInt64 _fileLength_that_WasSet;
COutFileStream *_outFileStreamSpec;
CMyComPtr<ISequentialOutStream> _outFileStream;
CByteBuffer _outMemBuf;
CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec;
CMyComPtr<ISequentialOutStream> _bufPtrSeqOutStream;
2023-09-24 03:13:03 +01:00
#ifndef Z7_SFX
2021-10-19 21:27:23 +01:00
COutStreamWithHash *_hashStreamSpec;
CMyComPtr<ISequentialOutStream> _hashStream;
bool _hashStreamWasUsed;
bool _use_baseParentFolder_mode;
UInt32 _baseParentFolder;
2023-09-24 03:13:03 +01:00
#endif
2021-10-19 21:27:23 +01:00
2023-09-24 03:13:03 +01:00
UStringVector _removePathParts;
2021-10-19 21:27:23 +01:00
CMyComPtr<ICompressProgressInfo> _localProgress;
UInt64 _packTotal;
UInt64 _progressTotal;
bool _progressTotal_Defined;
CObjectVector<CDirPathTime> _extractedFolders;
#ifndef _WIN32
// CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks;
#endif
2023-09-24 03:13:03 +01:00
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
2021-10-19 21:27:23 +01:00
bool _saclEnabled;
#endif
void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
2023-09-24 03:13:03 +01:00
HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft);
2021-10-19 21:27:23 +01:00
HRESULT GetUnpackSize();
2023-09-24 03:13:03 +01:00
FString Hash_GetFullFilePath();
void SetAttrib();
public:
2021-10-19 21:27:23 +01:00
HRESULT SendMessageError(const char *message, const FString &path);
HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2);
public:
2023-09-24 03:13:03 +01:00
#if defined(_WIN32) && !defined(UNDER_CE)
NExtract::NZoneIdMode::EEnum ZoneMode;
CByteBuffer ZoneBuf;
#endif
2021-10-19 21:27:23 +01:00
CLocalProgress *LocalProgressSpec;
UInt64 NumFolders;
UInt64 NumFiles;
UInt64 NumAltStreams;
UInt64 UnpackSize;
UInt64 AltStreams_UnpackSize;
2023-09-24 03:13:03 +01:00
FString DirPathPrefix_for_HashFiles;
2021-10-19 21:27:23 +01:00
CArchiveExtractCallback();
void InitForMulti(bool multiArchives,
NExtract::NPathMode::EEnum pathMode,
NExtract::NOverwriteMode::EEnum overwriteMode,
2023-09-24 03:13:03 +01:00
NExtract::NZoneIdMode::EEnum zoneMode,
2021-10-19 21:27:23 +01:00
bool keepAndReplaceEmptyDirPrefixes)
{
_multiArchives = multiArchives;
_pathMode = pathMode;
_overwriteMode = overwriteMode;
2023-09-24 03:13:03 +01:00
#if defined(_WIN32) && !defined(UNDER_CE)
ZoneMode = zoneMode;
#else
UNUSED_VAR(zoneMode)
#endif
2021-10-19 21:27:23 +01:00
_keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes;
NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
}
2023-09-24 03:13:03 +01:00
#ifndef Z7_SFX
2021-10-19 21:27:23 +01:00
void SetHashMethods(IHashCalc *hash)
{
if (!hash)
return;
_hashStreamSpec = new COutStreamWithHash;
_hashStream = _hashStreamSpec;
_hashStreamSpec->_hash = hash;
}
#endif
2023-09-24 03:13:03 +01:00
void InitBeforeNewArchive();
2021-10-19 21:27:23 +01:00
void Init(
const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
bool stdOutMode, bool testMode,
const FString &directoryPath,
const UStringVector &removePathParts, bool removePartsForAltStreams,
UInt64 packSize);
#ifdef SUPPORT_LINKS
private:
CHardLinks _hardLinks;
CLinkInfo _link;
2023-09-24 03:13:03 +01:00
// FString _copyFile_Path;
2021-10-19 21:27:23 +01:00
// HRESULT MyCopyFile(ISequentialOutStream *outStream);
HRESULT Link(const FString &fullProcessedPath);
HRESULT ReadLink();
public:
// call PrepareHardLinks() after Init()
HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices); // NULL means all items
#endif
#ifdef SUPPORT_ALT_STREAMS
CObjectVector<CIndexToPathPair> _renamedFiles;
#endif
// call it after Init()
2023-09-24 03:13:03 +01:00
#ifndef Z7_SFX
2021-10-19 21:27:23 +01:00
void SetBaseParentFolderIndex(UInt32 indexInArc)
{
_baseParentFolder = indexInArc;
_use_baseParentFolder_mode = true;
}
#endif
HRESULT CloseArc();
private:
void ClearExtractedDirsInfo()
{
_extractedFolders.Clear();
#ifndef _WIN32
// _delayedSymLinks.Clear();
#endif
}
HRESULT Read_fi_Props();
void CorrectPathParts();
2023-09-24 03:13:03 +01:00
void GetFiTimesCAM(CFiTimesCAM &pt);
2021-10-19 21:27:23 +01:00
void CreateFolders();
bool _isRenamed;
HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit);
HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit);
2023-09-24 03:13:03 +01:00
HRESULT GetItem(UInt32 index);
2021-10-19 21:27:23 +01:00
HRESULT CloseFile();
HRESULT CloseReparseAndFile();
HRESULT CloseReparseAndFile2();
HRESULT SetDirsTimes();
const void *NtReparse_Data;
UInt32 NtReparse_Size;
#ifdef SUPPORT_LINKS
HRESULT SetFromLinkPath(
const FString &fullProcessedPath,
const CLinkInfo &linkInfo,
bool &linkWasSet);
#endif
};
struct CArchiveExtractCallback_Closer
{
CArchiveExtractCallback *_ref;
CArchiveExtractCallback_Closer(CArchiveExtractCallback *ref): _ref(ref) {}
HRESULT Close()
{
HRESULT res = S_OK;
if (_ref)
{
res = _ref->CloseArc();
_ref = NULL;
}
return res;
}
~CArchiveExtractCallback_Closer()
{
Close();
}
};
bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
2023-09-24 03:13:03 +01:00
void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf);
2021-10-19 21:27:23 +01:00
#endif