Home | History | Annotate | Download | only in Common
      1 // ArchiveExtractCallback.h
      2 
      3 #ifndef __ARCHIVE_EXTRACT_CALLBACK_H
      4 #define __ARCHIVE_EXTRACT_CALLBACK_H
      5 
      6 #include "../../../Common/MyCom.h"
      7 #include "../../../Common/Wildcard.h"
      8 
      9 #include "../../IPassword.h"
     10 
     11 #include "../../Common/FileStreams.h"
     12 #include "../../Common/ProgressUtils.h"
     13 
     14 #include "../../Archive/IArchive.h"
     15 
     16 #include "ExtractMode.h"
     17 #include "IFileExtractCallback.h"
     18 #include "OpenArchive.h"
     19 
     20 #include "HashCalc.h"
     21 
     22 #ifndef _SFX
     23 
     24 class COutStreamWithHash:
     25   public ISequentialOutStream,
     26   public CMyUnknownImp
     27 {
     28   CMyComPtr<ISequentialOutStream> _stream;
     29   UInt64 _size;
     30   bool _calculate;
     31 public:
     32   IHashCalc *_hash;
     33 
     34   MY_UNKNOWN_IMP
     35   STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
     36   void SetStream(ISequentialOutStream *stream) { _stream = stream; }
     37   void ReleaseStream() { _stream.Release(); }
     38   void Init(bool calculate = true)
     39   {
     40     InitCRC();
     41     _size = 0;
     42     _calculate = calculate;
     43   }
     44   void EnableCalc(bool calculate) { _calculate = calculate; }
     45   void InitCRC() { _hash->InitForNewFile(); }
     46   UInt64 GetSize() const { return _size; }
     47 };
     48 
     49 #endif
     50 
     51 struct CExtractNtOptions
     52 {
     53   CBoolPair NtSecurity;
     54   CBoolPair SymLinks;
     55   CBoolPair HardLinks;
     56   CBoolPair AltStreams;
     57   bool ReplaceColonForAltStream;
     58   bool WriteToAltStreamIfColon;
     59 
     60   CExtractNtOptions():
     61       ReplaceColonForAltStream(false),
     62       WriteToAltStreamIfColon(false)
     63   {
     64     SymLinks.Val = true;
     65     HardLinks.Val = true;
     66     AltStreams.Val = true;
     67   }
     68 };
     69 
     70 #ifndef _SFX
     71 
     72 class CGetProp:
     73   public IGetProp,
     74   public CMyUnknownImp
     75 {
     76 public:
     77   const CArc *Arc;
     78   UInt32 IndexInArc;
     79   // UString Name; // relative path
     80 
     81   MY_UNKNOWN_IMP1(IGetProp)
     82   INTERFACE_IGetProp(;)
     83 };
     84 
     85 #endif
     86 
     87 #ifndef _SFX
     88 #ifndef UNDER_CE
     89 
     90 #define SUPPORT_LINKS
     91 
     92 #endif
     93 #endif
     94 
     95 
     96 #ifdef SUPPORT_LINKS
     97 
     98 struct CHardLinkNode
     99 {
    100   UInt64 StreamId;
    101   UInt64 INode;
    102 
    103   int Compare(const CHardLinkNode &a) const;
    104 };
    105 
    106 class CHardLinks
    107 {
    108 public:
    109   CRecordVector<CHardLinkNode> IDs;
    110   CObjectVector<FString> Links;
    111 
    112   void Clear()
    113   {
    114     IDs.Clear();
    115     Links.Clear();
    116   }
    117 
    118   void PrepareLinks()
    119   {
    120     while (Links.Size() < IDs.Size())
    121       Links.AddNew();
    122   }
    123 };
    124 
    125 #endif
    126 
    127 #ifdef SUPPORT_ALT_STREAMS
    128 
    129 struct CIndexToPathPair
    130 {
    131   UInt32 Index;
    132   FString Path;
    133 
    134   CIndexToPathPair(UInt32 index): Index(index) {}
    135   CIndexToPathPair(UInt32 index, const FString &path): Index(index), Path(path) {}
    136 
    137   int Compare(const CIndexToPathPair &pair) const
    138   {
    139     return MyCompare(Index, pair.Index);
    140   }
    141 };
    142 
    143 #endif
    144 
    145 class CArchiveExtractCallback:
    146   public IArchiveExtractCallback,
    147   public IArchiveExtractCallbackMessage,
    148   public ICryptoGetTextPassword,
    149   public ICompressProgressInfo,
    150   public CMyUnknownImp
    151 {
    152   const CArc *_arc;
    153   CExtractNtOptions _ntOptions;
    154 
    155   const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
    156   CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
    157   CMyComPtr<ICompressProgressInfo> _compressProgress;
    158   CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
    159   CMyComPtr<IArchiveExtractCallbackMessage> _callbackMessage;
    160   CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2;
    161 
    162   FString _dirPathPrefix;
    163   FString _dirPathPrefix_Full;
    164   NExtract::NPathMode::EEnum _pathMode;
    165   NExtract::NOverwriteMode::EEnum _overwriteMode;
    166 
    167   #ifndef _SFX
    168 
    169   CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
    170   CGetProp *GetProp_Spec;
    171   CMyComPtr<IGetProp> GetProp;
    172 
    173   #endif
    174 
    175   CReadArcItem _item;
    176   FString _diskFilePath;
    177   UInt64 _position;
    178   bool _isSplit;
    179 
    180   bool _extractMode;
    181 
    182   bool WriteCTime;
    183   bool WriteATime;
    184   bool WriteMTime;
    185 
    186   bool _encrypted;
    187 
    188   struct CProcessedFileInfo
    189   {
    190     FILETIME CTime;
    191     FILETIME ATime;
    192     FILETIME MTime;
    193     UInt32 Attrib;
    194 
    195     bool CTimeDefined;
    196     bool ATimeDefined;
    197     bool MTimeDefined;
    198     bool AttribDefined;
    199   } _fi;
    200 
    201   UInt32 _index;
    202   UInt64 _curSize;
    203   bool _curSizeDefined;
    204   COutFileStream *_outFileStreamSpec;
    205   CMyComPtr<ISequentialOutStream> _outFileStream;
    206 
    207   #ifndef _SFX
    208 
    209   COutStreamWithHash *_hashStreamSpec;
    210   CMyComPtr<ISequentialOutStream> _hashStream;
    211   bool _hashStreamWasUsed;
    212 
    213   #endif
    214 
    215   bool _removePartsForAltStreams;
    216   UStringVector _removePathParts;
    217 
    218   #ifndef _SFX
    219   bool _use_baseParentFolder_mode;
    220   UInt32 _baseParentFolder;
    221   #endif
    222 
    223   bool _stdOutMode;
    224   bool _testMode;
    225   bool _multiArchives;
    226 
    227   CMyComPtr<ICompressProgressInfo> _localProgress;
    228   UInt64 _packTotal;
    229 
    230   UInt64 _progressTotal;
    231   bool _progressTotal_Defined;
    232 
    233   FStringVector _extractedFolderPaths;
    234   CRecordVector<UInt32> _extractedFolderIndices;
    235 
    236   #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
    237   bool _saclEnabled;
    238   #endif
    239 
    240   void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
    241   HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
    242   HRESULT GetUnpackSize();
    243 
    244   HRESULT SendMessageError(const char *message, const FString &path);
    245   HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
    246   HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
    247 
    248 public:
    249 
    250   CLocalProgress *LocalProgressSpec;
    251 
    252   UInt64 NumFolders;
    253   UInt64 NumFiles;
    254   UInt64 NumAltStreams;
    255   UInt64 UnpackSize;
    256   UInt64 AltStreams_UnpackSize;
    257 
    258   MY_UNKNOWN_IMP3(IArchiveExtractCallbackMessage, ICryptoGetTextPassword, ICompressProgressInfo)
    259 
    260   INTERFACE_IArchiveExtractCallback(;)
    261   INTERFACE_IArchiveExtractCallbackMessage(;)
    262 
    263   STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
    264 
    265   STDMETHOD(CryptoGetTextPassword)(BSTR *password);
    266 
    267   CArchiveExtractCallback();
    268 
    269   void InitForMulti(bool multiArchives,
    270       NExtract::NPathMode::EEnum pathMode,
    271       NExtract::NOverwriteMode::EEnum overwriteMode)
    272   {
    273     _multiArchives = multiArchives;
    274     _pathMode = pathMode;
    275     _overwriteMode = overwriteMode;
    276     NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
    277   }
    278 
    279   #ifndef _SFX
    280 
    281   void SetHashMethods(IHashCalc *hash)
    282   {
    283     if (!hash)
    284       return;
    285     _hashStreamSpec = new COutStreamWithHash;
    286     _hashStream = _hashStreamSpec;
    287     _hashStreamSpec->_hash = hash;
    288   }
    289 
    290   #endif
    291 
    292   void Init(
    293       const CExtractNtOptions &ntOptions,
    294       const NWildcard::CCensorNode *wildcardCensor,
    295       const CArc *arc,
    296       IFolderArchiveExtractCallback *extractCallback2,
    297       bool stdOutMode, bool testMode,
    298       const FString &directoryPath,
    299       const UStringVector &removePathParts, bool removePartsForAltStreams,
    300       UInt64 packSize);
    301 
    302 
    303   #ifdef SUPPORT_LINKS
    304 
    305 private:
    306   CHardLinks _hardLinks;
    307   UString linkPath;
    308 
    309   // FString _CopyFile_Path;
    310   // HRESULT MyCopyFile(ISequentialOutStream *outStream);
    311 
    312 public:
    313   // call PrepareHardLinks() after Init()
    314   HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices);  // NULL means all items
    315 
    316   #endif
    317 
    318 
    319   #ifdef SUPPORT_ALT_STREAMS
    320   CObjectVector<CIndexToPathPair> _renamedFiles;
    321   #endif
    322 
    323   // call it after Init()
    324 
    325   #ifndef _SFX
    326   void SetBaseParentFolderIndex(UInt32 indexInArc)
    327   {
    328     _baseParentFolder = indexInArc;
    329     _use_baseParentFolder_mode = true;
    330   }
    331   #endif
    332 
    333   HRESULT SetDirsTimes();
    334 };
    335 
    336 bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
    337 
    338 #endif
    339