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