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 class CArchiveExtractCallback:
    128   public IArchiveExtractCallback,
    129   // public IArchiveVolumeExtractCallback,
    130   public ICryptoGetTextPassword,
    131   public ICompressProgressInfo,
    132   public CMyUnknownImp
    133 {
    134   const CArc *_arc;
    135   CExtractNtOptions _ntOptions;
    136 
    137   const NWildcard::CCensorNode *_wildcardCensor;
    138   CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
    139   CMyComPtr<ICompressProgressInfo> _compressProgress;
    140   CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
    141   FString _directoryPath;
    142   FString _directoryPathFull;
    143   NExtract::NPathMode::EEnum _pathMode;
    144   NExtract::NOverwriteMode::EEnum _overwriteMode;
    145 
    146   #ifndef _SFX
    147 
    148   CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
    149   CGetProp *GetProp_Spec;
    150   CMyComPtr<IGetProp> GetProp;
    151 
    152   #endif
    153 
    154   FString _diskFilePath;
    155   UString _filePath;
    156   UInt64 _position;
    157   bool _isSplit;
    158   bool _isAltStream;
    159 
    160   bool _extractMode;
    161 
    162   bool WriteCTime;
    163   bool WriteATime;
    164   bool WriteMTime;
    165 
    166   bool _encrypted;
    167 
    168   struct CProcessedFileInfo
    169   {
    170     FILETIME CTime;
    171     FILETIME ATime;
    172     FILETIME MTime;
    173     UInt32 Attrib;
    174 
    175     bool CTimeDefined;
    176     bool ATimeDefined;
    177     bool MTimeDefined;
    178     bool AttribDefined;
    179 
    180     bool IsDir;
    181   } _fi;
    182 
    183   UInt32 _index;
    184   UInt64 _curSize;
    185   bool _curSizeDefined;
    186   COutFileStream *_outFileStreamSpec;
    187   CMyComPtr<ISequentialOutStream> _outFileStream;
    188 
    189   #ifndef _SFX
    190 
    191   COutStreamWithHash *_hashStreamSpec;
    192   CMyComPtr<ISequentialOutStream> _hashStream;
    193   bool _hashStreamWasUsed;
    194 
    195   #endif
    196 
    197   UStringVector _removePathParts;
    198   bool _use_baseParentFolder_mode;
    199   UInt32 _baseParentFolder;
    200 
    201   bool _stdOutMode;
    202   bool _testMode;
    203   bool _multiArchives;
    204 
    205   CMyComPtr<ICompressProgressInfo> _localProgress;
    206   UInt64 _packTotal;
    207   UInt64 _unpTotal;
    208 
    209   FStringVector _extractedFolderPaths;
    210   CRecordVector<UInt32> _extractedFolderIndices;
    211 
    212   #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
    213   bool _saclEnabled;
    214   #endif
    215 
    216   void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
    217   HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
    218   HRESULT GetUnpackSize();
    219 
    220   HRESULT SendMessageError(const char *message, const FString &path);
    221   HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
    222 
    223 public:
    224 
    225   CLocalProgress *LocalProgressSpec;
    226 
    227   UInt64 NumFolders;
    228   UInt64 NumFiles;
    229   UInt64 NumAltStreams;
    230   UInt64 UnpackSize;
    231   UInt64 AltStreams_UnpackSize;
    232 
    233   MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
    234   // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
    235 
    236   INTERFACE_IArchiveExtractCallback(;)
    237 
    238   STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
    239 
    240   // IArchiveVolumeExtractCallback
    241   // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
    242 
    243   STDMETHOD(CryptoGetTextPassword)(BSTR *password);
    244 
    245   CArchiveExtractCallback();
    246 
    247   void InitForMulti(bool multiArchives,
    248       NExtract::NPathMode::EEnum pathMode,
    249       NExtract::NOverwriteMode::EEnum overwriteMode)
    250   {
    251     _multiArchives = multiArchives;
    252     _pathMode = pathMode;
    253     _overwriteMode = overwriteMode;
    254     NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
    255   }
    256 
    257   #ifndef _SFX
    258 
    259   void SetHashMethods(IHashCalc *hash)
    260   {
    261     if (!hash)
    262       return;
    263     _hashStreamSpec = new COutStreamWithHash;
    264     _hashStream = _hashStreamSpec;
    265     _hashStreamSpec->_hash = hash;
    266   }
    267 
    268   #endif
    269 
    270   void Init(
    271       const CExtractNtOptions &ntOptions,
    272       const NWildcard::CCensorNode *wildcardCensor,
    273       const CArc *arc,
    274       IFolderArchiveExtractCallback *extractCallback2,
    275       bool stdOutMode, bool testMode,
    276       const FString &directoryPath,
    277       const UStringVector &removePathParts,
    278       UInt64 packSize);
    279 
    280   #ifdef SUPPORT_LINKS
    281 private:
    282   CHardLinks _hardLinks;
    283 public:
    284   // call PrepareHardLinks() after Init()
    285   HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices);  // NULL means all items
    286   #endif
    287 
    288   // call it after Init()
    289 
    290   void SetBaseParentFolderIndex(UInt32 indexInArc)
    291   {
    292     _use_baseParentFolder_mode = true;
    293     _baseParentFolder = indexInArc;
    294   }
    295 
    296   HRESULT SetDirsTimes();
    297 };
    298 
    299 #endif
    300