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 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 InitForMulti(bool multiArchives,NExtract::NPathMode::EEnum pathMode,NExtract::NOverwriteMode::EEnum overwriteMode)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 SetHashMethods(IHashCalc * hash)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 SetBaseParentFolderIndex(UInt32 indexInArc)290 void SetBaseParentFolderIndex(UInt32 indexInArc) 291 { 292 _use_baseParentFolder_mode = true; 293 _baseParentFolder = indexInArc; 294 } 295 296 HRESULT SetDirsTimes(); 297 }; 298 299 #endif 300