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); SetStream(ISequentialOutStream * stream)36 void SetStream(ISequentialOutStream *stream) { _stream = stream; } ReleaseStream()37 void ReleaseStream() { _stream.Release(); } 38 void Init(bool calculate = true) 39 { 40 InitCRC(); 41 _size = 0; 42 _calculate = calculate; 43 } EnableCalc(bool calculate)44 void EnableCalc(bool calculate) { _calculate = calculate; } InitCRC()45 void InitCRC() { _hash->InitForNewFile(); } GetSize()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 CExtractNtOptionsCExtractNtOptions60 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 Clear()112 void Clear() 113 { 114 IDs.Clear(); 115 Links.Clear(); 116 } 117 PrepareLinks()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 CIndexToPathPairCIndexToPathPair134 CIndexToPathPair(UInt32 index): Index(index) {} CIndexToPathPairCIndexToPathPair135 CIndexToPathPair(UInt32 index, const FString &path): Index(index), Path(path) {} 136 CompareCIndexToPathPair137 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 InitForMulti(bool multiArchives,NExtract::NPathMode::EEnum pathMode,NExtract::NOverwriteMode::EEnum overwriteMode)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 SetHashMethods(IHashCalc * hash)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 SetBaseParentFolderIndex(UInt32 indexInArc)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