1 // ExtractCallback.h 2 3 #ifndef __EXTRACT_CALLBACK_H 4 #define __EXTRACT_CALLBACK_H 5 6 #include "../../../../C/Alloc.h" 7 8 #include "../../../Common/MyCom.h" 9 #include "../../../Common/StringConvert.h" 10 11 #ifndef _SFX 12 #include "../Agent/IFolderArchive.h" 13 #endif 14 15 #include "../Common/ArchiveExtractCallback.h" 16 #include "../Common/ArchiveOpenCallback.h" 17 18 #ifndef _NO_CRYPTO 19 #include "../../IPassword.h" 20 #endif 21 22 #ifndef _SFX 23 #include "IFolder.h" 24 #endif 25 26 #include "ProgressDialog2.h" 27 28 #ifdef LANG 29 #include "LangUtils.h" 30 #endif 31 32 #ifndef _SFX 33 34 class CGrowBuf 35 { 36 Byte *_items; 37 size_t _size; 38 39 CLASS_NO_COPY(CGrowBuf); 40 41 public: ReAlloc_KeepData(size_t newSize,size_t keepSize)42 bool ReAlloc_KeepData(size_t newSize, size_t keepSize) 43 { 44 void *buf = MyAlloc(newSize); 45 if (!buf) 46 return false; 47 if (keepSize != 0) 48 memcpy(buf, _items, keepSize); 49 MyFree(_items); 50 _items = (Byte *)buf; 51 _size = newSize; 52 return true; 53 } 54 CGrowBuf()55 CGrowBuf(): _items(0), _size(0) {} ~CGrowBuf()56 ~CGrowBuf() { MyFree(_items); } 57 58 operator Byte *() { return _items; } 59 operator const Byte *() const { return _items; } Size()60 size_t Size() const { return _size; } 61 }; 62 63 struct CVirtFile 64 { 65 CGrowBuf Data; 66 67 UInt64 Size; // real size 68 UInt64 ExpectedSize; // the size from props request. 0 if unknown 69 70 UString Name; 71 72 bool CTimeDefined; 73 bool ATimeDefined; 74 bool MTimeDefined; 75 bool AttribDefined; 76 77 bool IsDir; 78 bool IsAltStream; 79 80 DWORD Attrib; 81 82 FILETIME CTime; 83 FILETIME ATime; 84 FILETIME MTime; 85 CVirtFileCVirtFile86 CVirtFile(): 87 CTimeDefined(false), 88 ATimeDefined(false), 89 MTimeDefined(false), 90 AttribDefined(false), 91 IsDir(false), 92 IsAltStream(false) {} 93 }; 94 95 class CVirtFileSystem: 96 public ISequentialOutStream, 97 public CMyUnknownImp 98 { 99 UInt64 _totalAllocSize; 100 101 size_t _pos; 102 unsigned _numFlushed; 103 bool _fileIsOpen; 104 bool _fileMode; 105 COutFileStream *_outFileStreamSpec; 106 CMyComPtr<ISequentialOutStream> _outFileStream; 107 public: 108 CObjectVector<CVirtFile> Files; 109 UInt64 MaxTotalAllocSize; 110 FString DirPrefix; 111 AddNewFile()112 CVirtFile &AddNewFile() 113 { 114 if (!Files.IsEmpty()) 115 { 116 MaxTotalAllocSize -= Files.Back().Data.Size(); 117 } 118 return Files.AddNew(); 119 } CloseMemFile()120 HRESULT CloseMemFile() 121 { 122 if (_fileMode) 123 { 124 return FlushToDisk(true); 125 } 126 CVirtFile &file = Files.Back(); 127 if (file.Data.Size() != file.Size) 128 { 129 file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size); 130 } 131 return S_OK; 132 } 133 IsStreamInMem()134 bool IsStreamInMem() const 135 { 136 if (_fileMode) 137 return false; 138 if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir) 139 return false; 140 return true; 141 } 142 GetMemStreamWrittenSize()143 size_t GetMemStreamWrittenSize() const { return _pos; } 144 CVirtFileSystem()145 CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {} 146 Init()147 void Init() 148 { 149 _totalAllocSize = 0; 150 _fileMode = false; 151 _pos = 0; 152 _numFlushed = 0; 153 _fileIsOpen = false; 154 } 155 156 HRESULT CloseFile(const FString &path); 157 HRESULT FlushToDisk(bool closeLast); GetPos()158 size_t GetPos() const { return _pos; } 159 160 MY_UNKNOWN_IMP 161 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 162 }; 163 164 #endif 165 166 class CExtractCallbackImp: 167 public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback 168 public IOpenCallbackUI, 169 public IFolderArchiveExtractCallback2, 170 #ifndef _SFX 171 public IFolderOperationsExtractCallback, 172 public IFolderExtractToStreamCallback, 173 public ICompressProgressInfo, 174 #endif 175 #ifndef _NO_CRYPTO 176 public ICryptoGetTextPassword, 177 #endif 178 public CMyUnknownImp 179 { 180 HRESULT MessageError(const char *message, const FString &path); 181 void Add_ArchiveName_Error(); 182 public: 183 MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) 184 MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2) 185 #ifndef _SFX 186 MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback) 187 MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback) 188 MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) 189 #endif 190 #ifndef _NO_CRYPTO 191 MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) 192 #endif 193 MY_QUERYINTERFACE_END 194 MY_ADDREF_RELEASE 195 196 INTERFACE_IProgress(;) 197 INTERFACE_IOpenCallbackUI(;) 198 INTERFACE_IFolderArchiveExtractCallback(;) 199 INTERFACE_IFolderArchiveExtractCallback2(;) 200 // STDMETHOD(SetTotalFiles)(UInt64 total); 201 // STDMETHOD(SetCompletedFiles)(const UInt64 *value); 202 203 INTERFACE_IExtractCallbackUI(;) 204 205 #ifndef _SFX 206 // IFolderOperationsExtractCallback 207 STDMETHOD(AskWrite)( 208 const wchar_t *srcPath, 209 Int32 srcIsFolder, 210 const FILETIME *srcTime, 211 const UInt64 *srcSize, 212 const wchar_t *destPathRequest, 213 BSTR *destPathResult, 214 Int32 *writeAnswer); 215 STDMETHOD(ShowMessage)(const wchar_t *message); 216 STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath); 217 STDMETHOD(SetNumFiles)(UInt64 numFiles); 218 INTERFACE_IFolderExtractToStreamCallback(;) 219 STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); 220 #endif 221 222 // ICryptoGetTextPassword 223 #ifndef _NO_CRYPTO 224 STDMETHOD(CryptoGetTextPassword)(BSTR *password); 225 #endif 226 227 private: 228 UString _currentArchivePath; 229 bool _needWriteArchivePath; 230 231 UString _currentFilePath; 232 bool _isFolder; 233 234 bool _isAltStream; 235 UInt64 _curSize; 236 bool _curSizeDefined; 237 UString _filePath; 238 // bool _extractMode; 239 // bool _testMode; 240 bool _newVirtFileWasAdded; 241 bool _needUpdateStat; 242 243 244 HRESULT SetCurrentFilePath2(const wchar_t *filePath); 245 void AddError_Message(LPCWSTR message); 246 247 #ifndef _SFX 248 bool _hashStreamWasUsed; 249 COutStreamWithHash *_hashStreamSpec; 250 CMyComPtr<ISequentialOutStream> _hashStream; 251 IHashCalc *_hashCalc; // it's for stat in Test operation 252 #endif 253 254 public: 255 256 #ifndef _SFX 257 CVirtFileSystem *VirtFileSystemSpec; 258 CMyComPtr<ISequentialOutStream> VirtFileSystem; 259 #endif 260 261 bool ProcessAltStreams; 262 263 bool StreamMode; 264 265 CProgressDialog *ProgressDialog; 266 #ifndef _SFX 267 UInt64 NumFolders; 268 UInt64 NumFiles; 269 bool NeedAddFile; 270 #endif 271 UInt32 NumArchiveErrors; 272 bool ThereAreMessageErrors; 273 NExtract::NOverwriteMode::EEnum OverwriteMode; 274 275 #ifndef _NO_CRYPTO 276 bool PasswordIsDefined; 277 bool PasswordWasAsked; 278 UString Password; 279 #endif 280 281 282 UString _lang_Extracting; 283 UString _lang_Testing; 284 UString _lang_Skipping; 285 UString _lang_Reading; 286 UString _lang_Empty; 287 288 bool _totalFilesDefined; 289 bool _totalBytesDefined; 290 bool MultiArcMode; 291 CExtractCallbackImp()292 CExtractCallbackImp(): 293 #ifndef _SFX 294 _hashCalc(NULL), 295 #endif 296 ProcessAltStreams(true), 297 StreamMode(false), 298 OverwriteMode(NExtract::NOverwriteMode::kAsk), 299 #ifndef _NO_CRYPTO 300 PasswordIsDefined(false), 301 PasswordWasAsked(false), 302 #endif 303 _totalFilesDefined(false), 304 _totalBytesDefined(false), 305 MultiArcMode(false) 306 {} 307 308 ~CExtractCallbackImp(); 309 void Init(); 310 311 #ifndef _SFX SetHashCalc(IHashCalc * hashCalc)312 void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; } 313 SetHashMethods(IHashCalc * hash)314 void SetHashMethods(IHashCalc *hash) 315 { 316 if (!hash) 317 return; 318 _hashStreamSpec = new COutStreamWithHash; 319 _hashStream = _hashStreamSpec; 320 _hashStreamSpec->_hash = hash; 321 } 322 #endif 323 IsOK()324 bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; } 325 }; 326 327 #endif 328