1370b324cSopenharmony_ci// 7zExtract.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "../../../../C/7zCrc.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "../../../Common/ComTry.h" 8370b324cSopenharmony_ci 9370b324cSopenharmony_ci#include "../../Common/ProgressUtils.h" 10370b324cSopenharmony_ci 11370b324cSopenharmony_ci#include "7zDecode.h" 12370b324cSopenharmony_ci#include "7zHandler.h" 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci// EXTERN_g_ExternalCodecs 15370b324cSopenharmony_ci 16370b324cSopenharmony_cinamespace NArchive { 17370b324cSopenharmony_cinamespace N7z { 18370b324cSopenharmony_ci 19370b324cSopenharmony_ciZ7_CLASS_IMP_COM_1( 20370b324cSopenharmony_ci CFolderOutStream 21370b324cSopenharmony_ci , ISequentialOutStream 22370b324cSopenharmony_ci /* , ICompressGetSubStreamSize */ 23370b324cSopenharmony_ci) 24370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> _stream; 25370b324cSopenharmony_cipublic: 26370b324cSopenharmony_ci bool TestMode; 27370b324cSopenharmony_ci bool CheckCrc; 28370b324cSopenharmony_ciprivate: 29370b324cSopenharmony_ci bool _fileIsOpen; 30370b324cSopenharmony_ci bool _calcCrc; 31370b324cSopenharmony_ci UInt32 _crc; 32370b324cSopenharmony_ci UInt64 _rem; 33370b324cSopenharmony_ci 34370b324cSopenharmony_ci const UInt32 *_indexes; 35370b324cSopenharmony_ci // unsigned _startIndex; 36370b324cSopenharmony_ci unsigned _numFiles; 37370b324cSopenharmony_ci unsigned _fileIndex; 38370b324cSopenharmony_ci 39370b324cSopenharmony_ci HRESULT OpenFile(bool isCorrupted = false); 40370b324cSopenharmony_ci HRESULT CloseFile_and_SetResult(Int32 res); 41370b324cSopenharmony_ci HRESULT CloseFile(); 42370b324cSopenharmony_ci HRESULT ProcessEmptyFiles(); 43370b324cSopenharmony_ci 44370b324cSopenharmony_cipublic: 45370b324cSopenharmony_ci const CDbEx *_db; 46370b324cSopenharmony_ci CMyComPtr<IArchiveExtractCallback> ExtractCallback; 47370b324cSopenharmony_ci 48370b324cSopenharmony_ci bool ExtraWriteWasCut; 49370b324cSopenharmony_ci 50370b324cSopenharmony_ci CFolderOutStream(): 51370b324cSopenharmony_ci TestMode(false), 52370b324cSopenharmony_ci CheckCrc(true) 53370b324cSopenharmony_ci {} 54370b324cSopenharmony_ci 55370b324cSopenharmony_ci HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles); 56370b324cSopenharmony_ci HRESULT FlushCorrupted(Int32 callbackOperationResult); 57370b324cSopenharmony_ci 58370b324cSopenharmony_ci bool WasWritingFinished() const { return _numFiles == 0; } 59370b324cSopenharmony_ci}; 60370b324cSopenharmony_ci 61370b324cSopenharmony_ci 62370b324cSopenharmony_ciHRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles) 63370b324cSopenharmony_ci{ 64370b324cSopenharmony_ci // _startIndex = startIndex; 65370b324cSopenharmony_ci _fileIndex = startIndex; 66370b324cSopenharmony_ci _indexes = indexes; 67370b324cSopenharmony_ci _numFiles = numFiles; 68370b324cSopenharmony_ci 69370b324cSopenharmony_ci _fileIsOpen = false; 70370b324cSopenharmony_ci ExtraWriteWasCut = false; 71370b324cSopenharmony_ci 72370b324cSopenharmony_ci return ProcessEmptyFiles(); 73370b324cSopenharmony_ci} 74370b324cSopenharmony_ci 75370b324cSopenharmony_ciHRESULT CFolderOutStream::OpenFile(bool isCorrupted) 76370b324cSopenharmony_ci{ 77370b324cSopenharmony_ci const CFileItem &fi = _db->Files[_fileIndex]; 78370b324cSopenharmony_ci const UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex); 79370b324cSopenharmony_ci Int32 askMode = (_fileIndex == nextFileIndex) ? TestMode ? 80370b324cSopenharmony_ci NExtract::NAskMode::kTest : 81370b324cSopenharmony_ci NExtract::NAskMode::kExtract : 82370b324cSopenharmony_ci NExtract::NAskMode::kSkip; 83370b324cSopenharmony_ci 84370b324cSopenharmony_ci if (isCorrupted 85370b324cSopenharmony_ci && askMode == NExtract::NAskMode::kExtract 86370b324cSopenharmony_ci && !_db->IsItemAnti(_fileIndex) 87370b324cSopenharmony_ci && !fi.IsDir) 88370b324cSopenharmony_ci askMode = NExtract::NAskMode::kTest; 89370b324cSopenharmony_ci 90370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> realOutStream; 91370b324cSopenharmony_ci RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode)) 92370b324cSopenharmony_ci 93370b324cSopenharmony_ci _stream = realOutStream; 94370b324cSopenharmony_ci _crc = CRC_INIT_VAL; 95370b324cSopenharmony_ci _calcCrc = (CheckCrc && fi.CrcDefined && !fi.IsDir); 96370b324cSopenharmony_ci 97370b324cSopenharmony_ci _fileIsOpen = true; 98370b324cSopenharmony_ci _rem = fi.Size; 99370b324cSopenharmony_ci 100370b324cSopenharmony_ci if (askMode == NExtract::NAskMode::kExtract 101370b324cSopenharmony_ci && !realOutStream 102370b324cSopenharmony_ci && !_db->IsItemAnti(_fileIndex) 103370b324cSopenharmony_ci && !fi.IsDir) 104370b324cSopenharmony_ci askMode = NExtract::NAskMode::kSkip; 105370b324cSopenharmony_ci return ExtractCallback->PrepareOperation(askMode); 106370b324cSopenharmony_ci} 107370b324cSopenharmony_ci 108370b324cSopenharmony_ciHRESULT CFolderOutStream::CloseFile_and_SetResult(Int32 res) 109370b324cSopenharmony_ci{ 110370b324cSopenharmony_ci _stream.Release(); 111370b324cSopenharmony_ci _fileIsOpen = false; 112370b324cSopenharmony_ci 113370b324cSopenharmony_ci if (!_indexes) 114370b324cSopenharmony_ci _numFiles--; 115370b324cSopenharmony_ci else if (*_indexes == _fileIndex) 116370b324cSopenharmony_ci { 117370b324cSopenharmony_ci _indexes++; 118370b324cSopenharmony_ci _numFiles--; 119370b324cSopenharmony_ci } 120370b324cSopenharmony_ci 121370b324cSopenharmony_ci _fileIndex++; 122370b324cSopenharmony_ci return ExtractCallback->SetOperationResult(res); 123370b324cSopenharmony_ci} 124370b324cSopenharmony_ci 125370b324cSopenharmony_ciHRESULT CFolderOutStream::CloseFile() 126370b324cSopenharmony_ci{ 127370b324cSopenharmony_ci const CFileItem &fi = _db->Files[_fileIndex]; 128370b324cSopenharmony_ci return CloseFile_and_SetResult((!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) ? 129370b324cSopenharmony_ci NExtract::NOperationResult::kOK : 130370b324cSopenharmony_ci NExtract::NOperationResult::kCRCError); 131370b324cSopenharmony_ci} 132370b324cSopenharmony_ci 133370b324cSopenharmony_ciHRESULT CFolderOutStream::ProcessEmptyFiles() 134370b324cSopenharmony_ci{ 135370b324cSopenharmony_ci while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0) 136370b324cSopenharmony_ci { 137370b324cSopenharmony_ci RINOK(OpenFile()) 138370b324cSopenharmony_ci RINOK(CloseFile()) 139370b324cSopenharmony_ci } 140370b324cSopenharmony_ci return S_OK; 141370b324cSopenharmony_ci} 142370b324cSopenharmony_ci 143370b324cSopenharmony_ciZ7_COM7F_IMF(CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) 144370b324cSopenharmony_ci{ 145370b324cSopenharmony_ci if (processedSize) 146370b324cSopenharmony_ci *processedSize = 0; 147370b324cSopenharmony_ci 148370b324cSopenharmony_ci while (size != 0) 149370b324cSopenharmony_ci { 150370b324cSopenharmony_ci if (_fileIsOpen) 151370b324cSopenharmony_ci { 152370b324cSopenharmony_ci UInt32 cur = (size < _rem ? size : (UInt32)_rem); 153370b324cSopenharmony_ci if (_calcCrc) 154370b324cSopenharmony_ci { 155370b324cSopenharmony_ci const UInt32 k_Step = (UInt32)1 << 20; 156370b324cSopenharmony_ci if (cur > k_Step) 157370b324cSopenharmony_ci cur = k_Step; 158370b324cSopenharmony_ci } 159370b324cSopenharmony_ci HRESULT result = S_OK; 160370b324cSopenharmony_ci if (_stream) 161370b324cSopenharmony_ci result = _stream->Write(data, cur, &cur); 162370b324cSopenharmony_ci if (_calcCrc) 163370b324cSopenharmony_ci _crc = CrcUpdate(_crc, data, cur); 164370b324cSopenharmony_ci if (processedSize) 165370b324cSopenharmony_ci *processedSize += cur; 166370b324cSopenharmony_ci data = (const Byte *)data + cur; 167370b324cSopenharmony_ci size -= cur; 168370b324cSopenharmony_ci _rem -= cur; 169370b324cSopenharmony_ci if (_rem == 0) 170370b324cSopenharmony_ci { 171370b324cSopenharmony_ci RINOK(CloseFile()) 172370b324cSopenharmony_ci RINOK(ProcessEmptyFiles()) 173370b324cSopenharmony_ci } 174370b324cSopenharmony_ci RINOK(result) 175370b324cSopenharmony_ci if (cur == 0) 176370b324cSopenharmony_ci break; 177370b324cSopenharmony_ci continue; 178370b324cSopenharmony_ci } 179370b324cSopenharmony_ci 180370b324cSopenharmony_ci RINOK(ProcessEmptyFiles()) 181370b324cSopenharmony_ci if (_numFiles == 0) 182370b324cSopenharmony_ci { 183370b324cSopenharmony_ci // we support partial extracting 184370b324cSopenharmony_ci /* 185370b324cSopenharmony_ci if (processedSize) 186370b324cSopenharmony_ci *processedSize += size; 187370b324cSopenharmony_ci break; 188370b324cSopenharmony_ci */ 189370b324cSopenharmony_ci ExtraWriteWasCut = true; 190370b324cSopenharmony_ci // return S_FALSE; 191370b324cSopenharmony_ci return k_My_HRESULT_WritingWasCut; 192370b324cSopenharmony_ci } 193370b324cSopenharmony_ci RINOK(OpenFile()) 194370b324cSopenharmony_ci } 195370b324cSopenharmony_ci 196370b324cSopenharmony_ci return S_OK; 197370b324cSopenharmony_ci} 198370b324cSopenharmony_ci 199370b324cSopenharmony_ciHRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult) 200370b324cSopenharmony_ci{ 201370b324cSopenharmony_ci while (_numFiles != 0) 202370b324cSopenharmony_ci { 203370b324cSopenharmony_ci if (_fileIsOpen) 204370b324cSopenharmony_ci { 205370b324cSopenharmony_ci RINOK(CloseFile_and_SetResult(callbackOperationResult)) 206370b324cSopenharmony_ci } 207370b324cSopenharmony_ci else 208370b324cSopenharmony_ci { 209370b324cSopenharmony_ci RINOK(OpenFile(true)) 210370b324cSopenharmony_ci } 211370b324cSopenharmony_ci } 212370b324cSopenharmony_ci return S_OK; 213370b324cSopenharmony_ci} 214370b324cSopenharmony_ci 215370b324cSopenharmony_ci/* 216370b324cSopenharmony_ciZ7_COM7F_IMF(CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)) 217370b324cSopenharmony_ci{ 218370b324cSopenharmony_ci *value = 0; 219370b324cSopenharmony_ci // const unsigned numFiles_Original = _numFiles + _fileIndex - _startIndex; 220370b324cSopenharmony_ci const unsigned numFiles_Original = _numFiles; 221370b324cSopenharmony_ci if (subStream >= numFiles_Original) 222370b324cSopenharmony_ci return S_FALSE; // E_FAIL; 223370b324cSopenharmony_ci *value = _db->Files[_startIndex + (unsigned)subStream].Size; 224370b324cSopenharmony_ci return S_OK; 225370b324cSopenharmony_ci} 226370b324cSopenharmony_ci*/ 227370b324cSopenharmony_ci 228370b324cSopenharmony_ci 229370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, 230370b324cSopenharmony_ci Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)) 231370b324cSopenharmony_ci{ 232370b324cSopenharmony_ci // for GCC 233370b324cSopenharmony_ci // CFolderOutStream *folderOutStream = new CFolderOutStream; 234370b324cSopenharmony_ci // CMyComPtr<ISequentialOutStream> outStream(folderOutStream); 235370b324cSopenharmony_ci 236370b324cSopenharmony_ci COM_TRY_BEGIN 237370b324cSopenharmony_ci 238370b324cSopenharmony_ci CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; 239370b324cSopenharmony_ci 240370b324cSopenharmony_ci UInt64 importantTotalUnpacked = 0; 241370b324cSopenharmony_ci 242370b324cSopenharmony_ci // numItems = (UInt32)(Int32)-1; 243370b324cSopenharmony_ci 244370b324cSopenharmony_ci const bool allFilesMode = (numItems == (UInt32)(Int32)-1); 245370b324cSopenharmony_ci if (allFilesMode) 246370b324cSopenharmony_ci numItems = _db.Files.Size(); 247370b324cSopenharmony_ci 248370b324cSopenharmony_ci if (numItems == 0) 249370b324cSopenharmony_ci return S_OK; 250370b324cSopenharmony_ci 251370b324cSopenharmony_ci { 252370b324cSopenharmony_ci CNum prevFolder = kNumNoIndex; 253370b324cSopenharmony_ci UInt32 nextFile = 0; 254370b324cSopenharmony_ci 255370b324cSopenharmony_ci UInt32 i; 256370b324cSopenharmony_ci 257370b324cSopenharmony_ci for (i = 0; i < numItems; i++) 258370b324cSopenharmony_ci { 259370b324cSopenharmony_ci const UInt32 fileIndex = allFilesMode ? i : indices[i]; 260370b324cSopenharmony_ci const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; 261370b324cSopenharmony_ci if (folderIndex == kNumNoIndex) 262370b324cSopenharmony_ci continue; 263370b324cSopenharmony_ci if (folderIndex != prevFolder || fileIndex < nextFile) 264370b324cSopenharmony_ci nextFile = _db.FolderStartFileIndex[folderIndex]; 265370b324cSopenharmony_ci for (CNum index = nextFile; index <= fileIndex; index++) 266370b324cSopenharmony_ci importantTotalUnpacked += _db.Files[index].Size; 267370b324cSopenharmony_ci nextFile = fileIndex + 1; 268370b324cSopenharmony_ci prevFolder = folderIndex; 269370b324cSopenharmony_ci } 270370b324cSopenharmony_ci } 271370b324cSopenharmony_ci 272370b324cSopenharmony_ci RINOK(extractCallback->SetTotal(importantTotalUnpacked)) 273370b324cSopenharmony_ci 274370b324cSopenharmony_ci CLocalProgress *lps = new CLocalProgress; 275370b324cSopenharmony_ci CMyComPtr<ICompressProgressInfo> progress = lps; 276370b324cSopenharmony_ci lps->Init(extractCallback, false); 277370b324cSopenharmony_ci 278370b324cSopenharmony_ci CDecoder decoder( 279370b324cSopenharmony_ci #if !defined(USE_MIXER_MT) 280370b324cSopenharmony_ci false 281370b324cSopenharmony_ci #elif !defined(USE_MIXER_ST) 282370b324cSopenharmony_ci true 283370b324cSopenharmony_ci #elif !defined(Z7_7Z_SET_PROPERTIES) 284370b324cSopenharmony_ci #ifdef Z7_ST 285370b324cSopenharmony_ci false 286370b324cSopenharmony_ci #else 287370b324cSopenharmony_ci true 288370b324cSopenharmony_ci #endif 289370b324cSopenharmony_ci #else 290370b324cSopenharmony_ci _useMultiThreadMixer 291370b324cSopenharmony_ci #endif 292370b324cSopenharmony_ci ); 293370b324cSopenharmony_ci 294370b324cSopenharmony_ci UInt64 curPacked, curUnpacked; 295370b324cSopenharmony_ci 296370b324cSopenharmony_ci CMyComPtr<IArchiveExtractCallbackMessage2> callbackMessage; 297370b324cSopenharmony_ci extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage2, &callbackMessage); 298370b324cSopenharmony_ci 299370b324cSopenharmony_ci CFolderOutStream *folderOutStream = new CFolderOutStream; 300370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> outStream(folderOutStream); 301370b324cSopenharmony_ci 302370b324cSopenharmony_ci folderOutStream->_db = &_db; 303370b324cSopenharmony_ci folderOutStream->ExtractCallback = extractCallback; 304370b324cSopenharmony_ci folderOutStream->TestMode = (testModeSpec != 0); 305370b324cSopenharmony_ci folderOutStream->CheckCrc = (_crcSize != 0); 306370b324cSopenharmony_ci 307370b324cSopenharmony_ci for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked) 308370b324cSopenharmony_ci { 309370b324cSopenharmony_ci RINOK(lps->SetCur()) 310370b324cSopenharmony_ci 311370b324cSopenharmony_ci if (i >= numItems) 312370b324cSopenharmony_ci break; 313370b324cSopenharmony_ci 314370b324cSopenharmony_ci curUnpacked = 0; 315370b324cSopenharmony_ci curPacked = 0; 316370b324cSopenharmony_ci 317370b324cSopenharmony_ci UInt32 fileIndex = allFilesMode ? i : indices[i]; 318370b324cSopenharmony_ci const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; 319370b324cSopenharmony_ci 320370b324cSopenharmony_ci UInt32 numSolidFiles = 1; 321370b324cSopenharmony_ci 322370b324cSopenharmony_ci if (folderIndex != kNumNoIndex) 323370b324cSopenharmony_ci { 324370b324cSopenharmony_ci curPacked = _db.GetFolderFullPackSize(folderIndex); 325370b324cSopenharmony_ci UInt32 nextFile = fileIndex + 1; 326370b324cSopenharmony_ci fileIndex = _db.FolderStartFileIndex[folderIndex]; 327370b324cSopenharmony_ci UInt32 k; 328370b324cSopenharmony_ci 329370b324cSopenharmony_ci for (k = i + 1; k < numItems; k++) 330370b324cSopenharmony_ci { 331370b324cSopenharmony_ci const UInt32 fileIndex2 = allFilesMode ? k : indices[k]; 332370b324cSopenharmony_ci if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex 333370b324cSopenharmony_ci || fileIndex2 < nextFile) 334370b324cSopenharmony_ci break; 335370b324cSopenharmony_ci nextFile = fileIndex2 + 1; 336370b324cSopenharmony_ci } 337370b324cSopenharmony_ci 338370b324cSopenharmony_ci numSolidFiles = k - i; 339370b324cSopenharmony_ci 340370b324cSopenharmony_ci for (k = fileIndex; k < nextFile; k++) 341370b324cSopenharmony_ci curUnpacked += _db.Files[k].Size; 342370b324cSopenharmony_ci } 343370b324cSopenharmony_ci 344370b324cSopenharmony_ci { 345370b324cSopenharmony_ci const HRESULT result = folderOutStream->Init(fileIndex, 346370b324cSopenharmony_ci allFilesMode ? NULL : indices + i, 347370b324cSopenharmony_ci numSolidFiles); 348370b324cSopenharmony_ci 349370b324cSopenharmony_ci i += numSolidFiles; 350370b324cSopenharmony_ci 351370b324cSopenharmony_ci RINOK(result) 352370b324cSopenharmony_ci } 353370b324cSopenharmony_ci 354370b324cSopenharmony_ci if (folderOutStream->WasWritingFinished()) 355370b324cSopenharmony_ci { 356370b324cSopenharmony_ci // for debug: to test zero size stream unpacking 357370b324cSopenharmony_ci // if (folderIndex == kNumNoIndex) // enable this check for debug 358370b324cSopenharmony_ci continue; 359370b324cSopenharmony_ci } 360370b324cSopenharmony_ci 361370b324cSopenharmony_ci if (folderIndex == kNumNoIndex) 362370b324cSopenharmony_ci return E_FAIL; 363370b324cSopenharmony_ci 364370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 365370b324cSopenharmony_ci CMyComPtr<ICryptoGetTextPassword> getTextPassword; 366370b324cSopenharmony_ci if (extractCallback) 367370b324cSopenharmony_ci extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); 368370b324cSopenharmony_ci #endif 369370b324cSopenharmony_ci 370370b324cSopenharmony_ci try 371370b324cSopenharmony_ci { 372370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 373370b324cSopenharmony_ci bool isEncrypted = false; 374370b324cSopenharmony_ci bool passwordIsDefined = false; 375370b324cSopenharmony_ci UString_Wipe password; 376370b324cSopenharmony_ci #endif 377370b324cSopenharmony_ci 378370b324cSopenharmony_ci bool dataAfterEnd_Error = false; 379370b324cSopenharmony_ci 380370b324cSopenharmony_ci const HRESULT result = decoder.Decode( 381370b324cSopenharmony_ci EXTERNAL_CODECS_VARS 382370b324cSopenharmony_ci _inStream, 383370b324cSopenharmony_ci _db.ArcInfo.DataStartPosition, 384370b324cSopenharmony_ci _db, folderIndex, 385370b324cSopenharmony_ci &curUnpacked, 386370b324cSopenharmony_ci 387370b324cSopenharmony_ci outStream, 388370b324cSopenharmony_ci progress, 389370b324cSopenharmony_ci NULL // *inStreamMainRes 390370b324cSopenharmony_ci , dataAfterEnd_Error 391370b324cSopenharmony_ci 392370b324cSopenharmony_ci Z7_7Z_DECODER_CRYPRO_VARS 393370b324cSopenharmony_ci #if !defined(Z7_ST) 394370b324cSopenharmony_ci , true, _numThreads, _memUsage_Decompress 395370b324cSopenharmony_ci #endif 396370b324cSopenharmony_ci ); 397370b324cSopenharmony_ci 398370b324cSopenharmony_ci if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error) 399370b324cSopenharmony_ci { 400370b324cSopenharmony_ci const bool wasFinished = folderOutStream->WasWritingFinished(); 401370b324cSopenharmony_ci 402370b324cSopenharmony_ci int resOp = NExtract::NOperationResult::kDataError; 403370b324cSopenharmony_ci 404370b324cSopenharmony_ci if (result != S_FALSE) 405370b324cSopenharmony_ci { 406370b324cSopenharmony_ci if (result == E_NOTIMPL) 407370b324cSopenharmony_ci resOp = NExtract::NOperationResult::kUnsupportedMethod; 408370b324cSopenharmony_ci else if (wasFinished && dataAfterEnd_Error) 409370b324cSopenharmony_ci resOp = NExtract::NOperationResult::kDataAfterEnd; 410370b324cSopenharmony_ci } 411370b324cSopenharmony_ci 412370b324cSopenharmony_ci RINOK(folderOutStream->FlushCorrupted(resOp)) 413370b324cSopenharmony_ci 414370b324cSopenharmony_ci if (wasFinished) 415370b324cSopenharmony_ci { 416370b324cSopenharmony_ci // we don't show error, if it's after required files 417370b324cSopenharmony_ci if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage) 418370b324cSopenharmony_ci { 419370b324cSopenharmony_ci RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp)) 420370b324cSopenharmony_ci } 421370b324cSopenharmony_ci } 422370b324cSopenharmony_ci continue; 423370b324cSopenharmony_ci } 424370b324cSopenharmony_ci 425370b324cSopenharmony_ci if (result != S_OK) 426370b324cSopenharmony_ci return result; 427370b324cSopenharmony_ci 428370b324cSopenharmony_ci RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)) 429370b324cSopenharmony_ci continue; 430370b324cSopenharmony_ci } 431370b324cSopenharmony_ci catch(...) 432370b324cSopenharmony_ci { 433370b324cSopenharmony_ci RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)) 434370b324cSopenharmony_ci // continue; 435370b324cSopenharmony_ci // return E_FAIL; 436370b324cSopenharmony_ci throw; 437370b324cSopenharmony_ci } 438370b324cSopenharmony_ci } 439370b324cSopenharmony_ci 440370b324cSopenharmony_ci return S_OK; 441370b324cSopenharmony_ci 442370b324cSopenharmony_ci COM_TRY_END 443370b324cSopenharmony_ci} 444370b324cSopenharmony_ci 445370b324cSopenharmony_ci}} 446