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