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   bool PreAllocateOutFile;
     61 
     62   CExtractNtOptions():
     63       ReplaceColonForAltStream(false),
     64       WriteToAltStreamIfColon(false)
     65   {
     66     SymLinks.Val = true;
     67     HardLinks.Val = true;
     68     AltStreams.Val = true;
     69 
     70     PreAllocateOutFile =
     71       #ifdef _WIN32
     72         true;
     73       #else
     74         false;
     75       #endif
     76   }
     77 };
     78 
     79 #ifndef _SFX
     80 
     81 class CGetProp:
     82   public IGetProp,
     83   public CMyUnknownImp
     84 {
     85 public:
     86   const CArc *Arc;
     87   UInt32 IndexInArc;
     88   // UString Name; // relative path
     89 
     90   MY_UNKNOWN_IMP1(IGetProp)
     91   INTERFACE_IGetProp(;)
     92 };
     93 
     94 #endif
     95 
     96 #ifndef _SFX
     97 #ifndef UNDER_CE
     98 
     99 #define SUPPORT_LINKS
    100 
    101 #endif
    102 #endif
    103 
    104 
    105 #ifdef SUPPORT_LINKS
    106 
    107 struct CHardLinkNode
    108 {
    109   UInt64 StreamId;
    110   UInt64 INode;
    111 
    112   int Compare(const CHardLinkNode &a) const;
    113 };
    114 
    115 class CHardLinks
    116 {
    117 public:
    118   CRecordVector<CHardLinkNode> IDs;
    119   CObjectVector<FString> Links;
    120 
    121   void Clear()
    122   {
    123     IDs.Clear();
    124     Links.Clear();
    125   }
    126 
    127   void PrepareLinks()
    128   {
    129     while (Links.Size() < IDs.Size())
    130       Links.AddNew();
    131   }
    132 };
    133 
    134 #endif
    135 
    136 #ifdef SUPPORT_ALT_STREAMS
    137 
    138 struct CIndexToPathPair
    139 {
    140   UInt32 Index;
    141   FString Path;
    142 
    143   CIndexToPathPair(UInt32 index): Index(index) {}
    144   CIndexToPathPair(UInt32 index, const FString &path): Index(index), Path(path) {}
    145 
    146   int Compare(const CIndexToPathPair &pair) const
    147   {
    148     return MyCompare(Index, pair.Index);
    149   }
    150 };
    151 
    152 #endif
    153 
    154 
    155 
    156 struct CDirPathTime
    157 {
    158   FILETIME CTime;
    159   FILETIME ATime;
    160   FILETIME MTime;
    161 
    162   bool CTimeDefined;
    163   bool ATimeDefined;
    164   bool MTimeDefined;
    165 
    166   FString Path;
    167 
    168   bool SetDirTime();
    169 };
    170 
    171 
    172 
    173 class CArchiveExtractCallback:
    174   public IArchiveExtractCallback,
    175   public IArchiveExtractCallbackMessage,
    176   public ICryptoGetTextPassword,
    177   public ICompressProgressInfo,
    178   public CMyUnknownImp
    179 {
    180   const CArc *_arc;
    181   CExtractNtOptions _ntOptions;
    182 
    183   const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
    184   CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
    185   CMyComPtr<ICompressProgressInfo> _compressProgress;
    186   CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
    187   CMyComPtr<IArchiveExtractCallbackMessage> _callbackMessage;
    188   CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2;
    189 
    190   FString _dirPathPrefix;
    191   FString _dirPathPrefix_Full;
    192   NExtract::NPathMode::EEnum _pathMode;
    193   NExtract::NOverwriteMode::EEnum _overwriteMode;
    194   bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_";
    195 
    196   #ifndef _SFX
    197 
    198   CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
    199   CGetProp *GetProp_Spec;
    200   CMyComPtr<IGetProp> GetProp;
    201 
    202   #endif
    203 
    204   CReadArcItem _item;
    205   FString _diskFilePath;
    206   UInt64 _position;
    207   bool _isSplit;
    208 
    209   bool _extractMode;
    210 
    211   bool WriteCTime;
    212   bool WriteATime;
    213   bool WriteMTime;
    214 
    215   bool _encrypted;
    216 
    217   struct CProcessedFileInfo
    218   {
    219     FILETIME CTime;
    220     FILETIME ATime;
    221     FILETIME MTime;
    222     UInt32 Attrib;
    223 
    224     bool CTimeDefined;
    225     bool ATimeDefined;
    226     bool MTimeDefined;
    227     bool AttribDefined;
    228   } _fi;
    229 
    230   UInt32 _index;
    231   UInt64 _curSize;
    232   bool _curSizeDefined;
    233   bool _fileLengthWasSet;
    234   COutFileStream *_outFileStreamSpec;
    235   CMyComPtr<ISequentialOutStream> _outFileStream;
    236 
    237   #ifndef _SFX
    238 
    239   COutStreamWithHash *_hashStreamSpec;
    240   CMyComPtr<ISequentialOutStream> _hashStream;
    241   bool _hashStreamWasUsed;
    242 
    243   #endif
    244 
    245   bool _removePartsForAltStreams;
    246   UStringVector _removePathParts;
    247 
    248   #ifndef _SFX
    249   bool _use_baseParentFolder_mode;
    250   UInt32 _baseParentFolder;
    251   #endif
    252 
    253   bool _stdOutMode;
    254   bool _testMode;
    255   bool _multiArchives;
    256 
    257   CMyComPtr<ICompressProgressInfo> _localProgress;
    258   UInt64 _packTotal;
    259 
    260   UInt64 _progressTotal;
    261   bool _progressTotal_Defined;
    262 
    263   CObjectVector<CDirPathTime> _extractedFolders;
    264 
    265   #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
    266   bool _saclEnabled;
    267   #endif
    268 
    269   void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
    270   HRESULT GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
    271   HRESULT GetUnpackSize();
    272 
    273   HRESULT SendMessageError(const char *message, const FString &path);
    274   HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
    275   HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
    276 
    277 public:
    278 
    279   CLocalProgress *LocalProgressSpec;
    280 
    281   UInt64 NumFolders;
    282   UInt64 NumFiles;
    283   UInt64 NumAltStreams;
    284   UInt64 UnpackSize;
    285   UInt64 AltStreams_UnpackSize;
    286 
    287   MY_UNKNOWN_IMP3(IArchiveExtractCallbackMessage, ICryptoGetTextPassword, ICompressProgressInfo)
    288 
    289   INTERFACE_IArchiveExtractCallback(;)
    290   INTERFACE_IArchiveExtractCallbackMessage(;)
    291 
    292   STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
    293 
    294   STDMETHOD(CryptoGetTextPassword)(BSTR *password);
    295 
    296   CArchiveExtractCallback();
    297 
    298   void InitForMulti(bool multiArchives,
    299       NExtract::NPathMode::EEnum pathMode,
    300       NExtract::NOverwriteMode::EEnum overwriteMode,
    301       bool keepAndReplaceEmptyDirPrefixes)
    302   {
    303     _multiArchives = multiArchives;
    304     _pathMode = pathMode;
    305     _overwriteMode = overwriteMode;
    306     _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes;
    307     NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
    308   }
    309 
    310   #ifndef _SFX
    311 
    312   void SetHashMethods(IHashCalc *hash)
    313   {
    314     if (!hash)
    315       return;
    316     _hashStreamSpec = new COutStreamWithHash;
    317     _hashStream = _hashStreamSpec;
    318     _hashStreamSpec->_hash = hash;
    319   }
    320 
    321   #endif
    322 
    323   void Init(
    324       const CExtractNtOptions &ntOptions,
    325       const NWildcard::CCensorNode *wildcardCensor,
    326       const CArc *arc,
    327       IFolderArchiveExtractCallback *extractCallback2,
    328       bool stdOutMode, bool testMode,
    329       const FString &directoryPath,
    330       const UStringVector &removePathParts, bool removePartsForAltStreams,
    331       UInt64 packSize);
    332 
    333 
    334   #ifdef SUPPORT_LINKS
    335 
    336 private:
    337   CHardLinks _hardLinks;
    338   UString linkPath;
    339 
    340   // FString _CopyFile_Path;
    341   // HRESULT MyCopyFile(ISequentialOutStream *outStream);
    342 
    343 public:
    344   // call PrepareHardLinks() after Init()
    345   HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices);  // NULL means all items
    346 
    347   #endif
    348 
    349 
    350   #ifdef SUPPORT_ALT_STREAMS
    351   CObjectVector<CIndexToPathPair> _renamedFiles;
    352   #endif
    353 
    354   // call it after Init()
    355 
    356   #ifndef _SFX
    357   void SetBaseParentFolderIndex(UInt32 indexInArc)
    358   {
    359     _baseParentFolder = indexInArc;
    360     _use_baseParentFolder_mode = true;
    361   }
    362   #endif
    363 
    364   HRESULT CloseArc();
    365 
    366 private:
    367   void ClearExtractedDirsInfo()
    368   {
    369     _extractedFolders.Clear();
    370   }
    371 
    372   HRESULT CloseFile();
    373   HRESULT SetDirsTimes();
    374 };
    375 
    376 
    377 struct CArchiveExtractCallback_Closer
    378 {
    379   CArchiveExtractCallback *_ref;
    380 
    381   CArchiveExtractCallback_Closer(CArchiveExtractCallback *ref): _ref(ref) {}
    382 
    383   HRESULT Close()
    384   {
    385     HRESULT res = S_OK;
    386     if (_ref)
    387     {
    388       res = _ref->CloseArc();
    389       _ref = NULL;
    390     }
    391     return res;
    392   }
    393 
    394   ~CArchiveExtractCallback_Closer()
    395   {
    396     Close();
    397   }
    398 };
    399 
    400 
    401 bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
    402 
    403 #endif
    404