1 // ExtractCallback.h 2 3 #ifndef ZIP7_INC_EXTRACT_CALLBACK_H 4 #define ZIP7_INC_EXTRACT_CALLBACK_H 5 6 #include "../../../../C/Alloc.h" 7 8 #include "../../../Common/MyCom.h" 9 #include "../../../Common/StringConvert.h" 10 11 #ifndef Z7_SFX 12 #include "../Agent/IFolderArchive.h" 13 #endif 14 15 #include "../Common/ArchiveExtractCallback.h" 16 #include "../Common/ArchiveOpenCallback.h" 17 18 #ifndef Z7_NO_CRYPTO 19 #include "../../IPassword.h" 20 #endif 21 22 #ifndef Z7_SFX 23 #include "IFolder.h" 24 #endif 25 26 #include "ProgressDialog2.h" 27 28 #ifdef Z7_LANG 29 // #include "LangUtils.h" 30 #endif 31 32 #ifndef Z7_SFX 33 34 class CGrowBuf 35 { 36 Byte *_items; 37 size_t _size; 38 Z7_CLASS_NO_COPY(CGrowBuf)39 Z7_CLASS_NO_COPY(CGrowBuf) 40 41 public: 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(NULL), _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 96 Z7_CLASS_IMP_NOQIB_1( 97 CVirtFileSystem, 98 ISequentialOutStream 99 ) 100 UInt64 _totalAllocSize; 101 102 size_t _pos; 103 unsigned _numFlushed; 104 bool _fileIsOpen; 105 bool _fileMode; 106 COutFileStream *_outFileStreamSpec; 107 CMyComPtr<ISequentialOutStream> _outFileStream; 108 public: 109 CObjectVector<CVirtFile> Files; 110 UInt64 MaxTotalAllocSize; 111 FString DirPrefix; 112 AddNewFile()113 CVirtFile &AddNewFile() 114 { 115 if (!Files.IsEmpty()) 116 { 117 MaxTotalAllocSize -= Files.Back().Data.Size(); 118 } 119 return Files.AddNew(); 120 } CloseMemFile()121 HRESULT CloseMemFile() 122 { 123 if (_fileMode) 124 { 125 return FlushToDisk(true); 126 } 127 CVirtFile &file = Files.Back(); 128 if (file.Data.Size() != file.Size) 129 { 130 file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size); 131 } 132 return S_OK; 133 } 134 IsStreamInMem()135 bool IsStreamInMem() const 136 { 137 if (_fileMode) 138 return false; 139 if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir) 140 return false; 141 return true; 142 } 143 GetMemStreamWrittenSize()144 size_t GetMemStreamWrittenSize() const { return _pos; } 145 CVirtFileSystem()146 CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {} 147 Init()148 void Init() 149 { 150 _totalAllocSize = 0; 151 _fileMode = false; 152 _pos = 0; 153 _numFlushed = 0; 154 _fileIsOpen = false; 155 } 156 157 HRESULT CloseFile(const FString &path); 158 HRESULT FlushToDisk(bool closeLast); GetPos()159 size_t GetPos() const { return _pos; } 160 }; 161 162 #endif 163 164 class CExtractCallbackImp Z7_final: 165 public IFolderArchiveExtractCallback, 166 /* IExtractCallbackUI: 167 before v23.00 : it included IFolderArchiveExtractCallback 168 since v23.00 : it doesn't include IFolderArchiveExtractCallback 169 */ 170 public IExtractCallbackUI, // NON-COM interface since 23.00 171 public IOpenCallbackUI, // NON-COM interface 172 public IFolderArchiveExtractCallback2, 173 #ifndef Z7_SFX 174 public IFolderOperationsExtractCallback, 175 public IFolderExtractToStreamCallback, 176 public ICompressProgressInfo, 177 #endif 178 #ifndef Z7_NO_CRYPTO 179 public ICryptoGetTextPassword, 180 #endif 181 public CMyUnknownImp 182 { 183 Z7_COM_QI_BEGIN2(IFolderArchiveExtractCallback) 184 Z7_COM_QI_ENTRY(IFolderArchiveExtractCallback2) 185 #ifndef Z7_SFX 186 Z7_COM_QI_ENTRY(IFolderOperationsExtractCallback) 187 Z7_COM_QI_ENTRY(IFolderExtractToStreamCallback) 188 Z7_COM_QI_ENTRY(ICompressProgressInfo) 189 #endif 190 #ifndef Z7_NO_CRYPTO 191 Z7_COM_QI_ENTRY(ICryptoGetTextPassword) 192 #endif 193 Z7_COM_QI_END 194 Z7_COM_ADDREF_RELEASE 195 196 Z7_IFACE_IMP(IExtractCallbackUI) 197 Z7_IFACE_IMP(IOpenCallbackUI) 198 Z7_IFACE_COM7_IMP(IProgress) 199 Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback) 200 Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback2) 201 #ifndef Z7_SFX 202 Z7_IFACE_COM7_IMP(IFolderOperationsExtractCallback) 203 Z7_IFACE_COM7_IMP(IFolderExtractToStreamCallback) 204 Z7_IFACE_COM7_IMP(ICompressProgressInfo) 205 #endif 206 #ifndef Z7_NO_CRYPTO 207 Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) 208 #endif 209 210 211 UString _currentArchivePath; 212 bool _needWriteArchivePath; 213 214 bool _isFolder; 215 UString _currentFilePath; 216 UString _filePath; 217 218 #ifndef Z7_SFX 219 bool _needUpdateStat; 220 bool _newVirtFileWasAdded; 221 bool _isAltStream; 222 bool _curSize_Defined; 223 UInt64 _curSize; 224 // bool _extractMode; 225 // bool _testMode; 226 bool _hashStreamWasUsed; 227 COutStreamWithHash *_hashStreamSpec; 228 CMyComPtr<ISequentialOutStream> _hashStream; 229 IHashCalc *_hashCalc; // it's for stat in Test operation 230 #endif 231 232 HRESULT SetCurrentFilePath2(const wchar_t *filePath); 233 void AddError_Message(LPCWSTR message); 234 HRESULT MessageError(const char *message, const FString &path); 235 void Add_ArchiveName_Error(); 236 237 public: 238 239 #ifndef Z7_SFX 240 CVirtFileSystem *VirtFileSystemSpec; 241 CMyComPtr<ISequentialOutStream> VirtFileSystem; 242 #endif 243 244 bool ProcessAltStreams; 245 246 bool StreamMode; 247 248 CProgressDialog *ProgressDialog; 249 #ifndef Z7_SFX 250 UInt64 NumFolders; 251 UInt64 NumFiles; 252 bool NeedAddFile; 253 #endif 254 UInt32 NumArchiveErrors; 255 bool ThereAreMessageErrors; 256 NExtract::NOverwriteMode::EEnum OverwriteMode; 257 258 #ifndef Z7_NO_CRYPTO 259 bool PasswordIsDefined; 260 bool PasswordWasAsked; 261 UString Password; 262 #endif 263 264 265 UString _lang_Extracting; 266 UString _lang_Testing; 267 UString _lang_Skipping; 268 UString _lang_Reading; 269 UString _lang_Empty; 270 271 bool _totalFilesDefined; 272 bool _totalBytesDefined; 273 bool MultiArcMode; 274 275 CExtractCallbackImp(): 276 #ifndef Z7_SFX 277 _hashCalc(NULL), 278 #endif 279 ProcessAltStreams(true), 280 StreamMode(false), 281 OverwriteMode(NExtract::NOverwriteMode::kAsk), 282 #ifndef Z7_NO_CRYPTO 283 PasswordIsDefined(false), 284 PasswordWasAsked(false), 285 #endif 286 _totalFilesDefined(false), 287 _totalBytesDefined(false), 288 MultiArcMode(false) 289 {} 290 291 ~CExtractCallbackImp(); 292 void Init(); 293 294 #ifndef Z7_SFX 295 void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; } 296 297 void SetHashMethods(IHashCalc *hash) 298 { 299 if (!hash) 300 return; 301 _hashStreamSpec = new COutStreamWithHash; 302 _hashStream = _hashStreamSpec; 303 _hashStreamSpec->_hash = hash; 304 } 305 #endif 306 307 bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; } 308 }; 309 310 #endif 311