1370b324cSopenharmony_ci// ExtractCallback.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci
6370b324cSopenharmony_ci#include "../../../Common/ComTry.h"
7370b324cSopenharmony_ci#include "../../../Common/IntToString.h"
8370b324cSopenharmony_ci#include "../../../Common/Lang.h"
9370b324cSopenharmony_ci#include "../../../Common/StringConvert.h"
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci#include "../../../Windows/ErrorMsg.h"
12370b324cSopenharmony_ci#include "../../../Windows/FileDir.h"
13370b324cSopenharmony_ci#include "../../../Windows/FileFind.h"
14370b324cSopenharmony_ci#include "../../../Windows/PropVariantConv.h"
15370b324cSopenharmony_ci
16370b324cSopenharmony_ci#include "../../Common/FilePathAutoRename.h"
17370b324cSopenharmony_ci#include "../../Common/StreamUtils.h"
18370b324cSopenharmony_ci#include "../Common/ExtractingFilePath.h"
19370b324cSopenharmony_ci
20370b324cSopenharmony_ci#ifndef Z7_SFX
21370b324cSopenharmony_ci#include "../Common/ZipRegistry.h"
22370b324cSopenharmony_ci#endif
23370b324cSopenharmony_ci
24370b324cSopenharmony_ci#include "../GUI/ExtractRes.h"
25370b324cSopenharmony_ci#include "resourceGui.h"
26370b324cSopenharmony_ci
27370b324cSopenharmony_ci#include "ExtractCallback.h"
28370b324cSopenharmony_ci#include "FormatUtils.h"
29370b324cSopenharmony_ci#include "LangUtils.h"
30370b324cSopenharmony_ci#include "OverwriteDialog.h"
31370b324cSopenharmony_ci#ifndef Z7_NO_CRYPTO
32370b324cSopenharmony_ci#include "PasswordDialog.h"
33370b324cSopenharmony_ci#endif
34370b324cSopenharmony_ci#include "PropertyName.h"
35370b324cSopenharmony_ci
36370b324cSopenharmony_ciusing namespace NWindows;
37370b324cSopenharmony_ciusing namespace NFile;
38370b324cSopenharmony_ciusing namespace NFind;
39370b324cSopenharmony_ci
40370b324cSopenharmony_ciCExtractCallbackImp::~CExtractCallbackImp() {}
41370b324cSopenharmony_ci
42370b324cSopenharmony_civoid CExtractCallbackImp::Init()
43370b324cSopenharmony_ci{
44370b324cSopenharmony_ci  _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING);
45370b324cSopenharmony_ci  _lang_Testing = LangString(IDS_PROGRESS_TESTING);
46370b324cSopenharmony_ci  _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING);
47370b324cSopenharmony_ci  _lang_Reading = "Reading";
48370b324cSopenharmony_ci
49370b324cSopenharmony_ci  NumArchiveErrors = 0;
50370b324cSopenharmony_ci  ThereAreMessageErrors = false;
51370b324cSopenharmony_ci  #ifndef Z7_SFX
52370b324cSopenharmony_ci  NumFolders = NumFiles = 0;
53370b324cSopenharmony_ci  NeedAddFile = false;
54370b324cSopenharmony_ci  #endif
55370b324cSopenharmony_ci}
56370b324cSopenharmony_ci
57370b324cSopenharmony_civoid CExtractCallbackImp::AddError_Message(LPCWSTR s)
58370b324cSopenharmony_ci{
59370b324cSopenharmony_ci  ThereAreMessageErrors = true;
60370b324cSopenharmony_ci  ProgressDialog->Sync.AddError_Message(s);
61370b324cSopenharmony_ci}
62370b324cSopenharmony_ci
63370b324cSopenharmony_ci#ifndef Z7_SFX
64370b324cSopenharmony_ci
65370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetNumFiles(UInt64 numFiles))
66370b324cSopenharmony_ci{
67370b324cSopenharmony_ci #ifdef Z7_SFX
68370b324cSopenharmony_ci  UNUSED_VAR(numFiles)
69370b324cSopenharmony_ci #else
70370b324cSopenharmony_ci  ProgressDialog->Sync.Set_NumFilesTotal(numFiles);
71370b324cSopenharmony_ci #endif
72370b324cSopenharmony_ci  return S_OK;
73370b324cSopenharmony_ci}
74370b324cSopenharmony_ci
75370b324cSopenharmony_ci#endif
76370b324cSopenharmony_ci
77370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 total))
78370b324cSopenharmony_ci{
79370b324cSopenharmony_ci  ProgressDialog->Sync.Set_NumBytesTotal(total);
80370b324cSopenharmony_ci  return S_OK;
81370b324cSopenharmony_ci}
82370b324cSopenharmony_ci
83370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *value))
84370b324cSopenharmony_ci{
85370b324cSopenharmony_ci  return ProgressDialog->Sync.Set_NumBytesCur(value);
86370b324cSopenharmony_ci}
87370b324cSopenharmony_ci
88370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_CheckBreak()
89370b324cSopenharmony_ci{
90370b324cSopenharmony_ci  return ProgressDialog->Sync.CheckStop();
91370b324cSopenharmony_ci}
92370b324cSopenharmony_ci
93370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *bytes)
94370b324cSopenharmony_ci{
95370b324cSopenharmony_ci  HRESULT res = S_OK;
96370b324cSopenharmony_ci  if (!MultiArcMode)
97370b324cSopenharmony_ci  {
98370b324cSopenharmony_ci    if (files)
99370b324cSopenharmony_ci    {
100370b324cSopenharmony_ci      _totalFilesDefined = true;
101370b324cSopenharmony_ci      // res = ProgressDialog->Sync.Set_NumFilesTotal(*files);
102370b324cSopenharmony_ci    }
103370b324cSopenharmony_ci    else
104370b324cSopenharmony_ci      _totalFilesDefined = false;
105370b324cSopenharmony_ci
106370b324cSopenharmony_ci    if (bytes)
107370b324cSopenharmony_ci    {
108370b324cSopenharmony_ci      _totalBytesDefined = true;
109370b324cSopenharmony_ci      ProgressDialog->Sync.Set_NumBytesTotal(*bytes);
110370b324cSopenharmony_ci    }
111370b324cSopenharmony_ci    else
112370b324cSopenharmony_ci      _totalBytesDefined = false;
113370b324cSopenharmony_ci  }
114370b324cSopenharmony_ci
115370b324cSopenharmony_ci  return res;
116370b324cSopenharmony_ci}
117370b324cSopenharmony_ci
118370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes)
119370b324cSopenharmony_ci{
120370b324cSopenharmony_ci  if (!MultiArcMode)
121370b324cSopenharmony_ci  {
122370b324cSopenharmony_ci    if (files)
123370b324cSopenharmony_ci    {
124370b324cSopenharmony_ci      ProgressDialog->Sync.Set_NumFilesCur(*files);
125370b324cSopenharmony_ci    }
126370b324cSopenharmony_ci
127370b324cSopenharmony_ci    if (bytes)
128370b324cSopenharmony_ci    {
129370b324cSopenharmony_ci    }
130370b324cSopenharmony_ci  }
131370b324cSopenharmony_ci
132370b324cSopenharmony_ci  return ProgressDialog->Sync.CheckStop();
133370b324cSopenharmony_ci}
134370b324cSopenharmony_ci
135370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_Finished()
136370b324cSopenharmony_ci{
137370b324cSopenharmony_ci  return ProgressDialog->Sync.CheckStop();
138370b324cSopenharmony_ci}
139370b324cSopenharmony_ci
140370b324cSopenharmony_ci#ifndef Z7_NO_CRYPTO
141370b324cSopenharmony_ci
142370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password)
143370b324cSopenharmony_ci{
144370b324cSopenharmony_ci  return CryptoGetTextPassword(password);
145370b324cSopenharmony_ci}
146370b324cSopenharmony_ci
147370b324cSopenharmony_ci/*
148370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password)
149370b324cSopenharmony_ci{
150370b324cSopenharmony_ci  passwordIsDefined = PasswordIsDefined;
151370b324cSopenharmony_ci  password = Password;
152370b324cSopenharmony_ci  return S_OK;
153370b324cSopenharmony_ci}
154370b324cSopenharmony_ci
155370b324cSopenharmony_cibool CExtractCallbackImp::Open_WasPasswordAsked()
156370b324cSopenharmony_ci{
157370b324cSopenharmony_ci  return PasswordWasAsked;
158370b324cSopenharmony_ci}
159370b324cSopenharmony_ci
160370b324cSopenharmony_civoid CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag()
161370b324cSopenharmony_ci{
162370b324cSopenharmony_ci  PasswordWasAsked = false;
163370b324cSopenharmony_ci}
164370b324cSopenharmony_ci*/
165370b324cSopenharmony_ci
166370b324cSopenharmony_ci#endif
167370b324cSopenharmony_ci
168370b324cSopenharmony_ci
169370b324cSopenharmony_ci#ifndef Z7_SFX
170370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
171370b324cSopenharmony_ci{
172370b324cSopenharmony_ci  ProgressDialog->Sync.Set_Ratio(inSize, outSize);
173370b324cSopenharmony_ci  return S_OK;
174370b324cSopenharmony_ci}
175370b324cSopenharmony_ci#endif
176370b324cSopenharmony_ci
177370b324cSopenharmony_ci/*
178370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetTotalFiles(UInt64 total)
179370b324cSopenharmony_ci{
180370b324cSopenharmony_ci  ProgressDialog->Sync.SetNumFilesTotal(total);
181370b324cSopenharmony_ci  return S_OK;
182370b324cSopenharmony_ci}
183370b324cSopenharmony_ci
184370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetCompletedFiles(const UInt64 *value)
185370b324cSopenharmony_ci{
186370b324cSopenharmony_ci  if (value != NULL)
187370b324cSopenharmony_ci    ProgressDialog->Sync.SetNumFilesCur(*value);
188370b324cSopenharmony_ci  return S_OK;
189370b324cSopenharmony_ci}
190370b324cSopenharmony_ci*/
191370b324cSopenharmony_ci
192370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::AskOverwrite(
193370b324cSopenharmony_ci    const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
194370b324cSopenharmony_ci    const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
195370b324cSopenharmony_ci    Int32 *answer))
196370b324cSopenharmony_ci{
197370b324cSopenharmony_ci  COverwriteDialog dialog;
198370b324cSopenharmony_ci
199370b324cSopenharmony_ci  dialog.OldFileInfo.SetTime(existTime);
200370b324cSopenharmony_ci  dialog.OldFileInfo.SetSize(existSize);
201370b324cSopenharmony_ci  dialog.OldFileInfo.Name = existName;
202370b324cSopenharmony_ci
203370b324cSopenharmony_ci  dialog.NewFileInfo.SetTime(newTime);
204370b324cSopenharmony_ci  dialog.NewFileInfo.SetSize(newSize);
205370b324cSopenharmony_ci  dialog.NewFileInfo.Name = newName;
206370b324cSopenharmony_ci
207370b324cSopenharmony_ci  ProgressDialog->WaitCreating();
208370b324cSopenharmony_ci  INT_PTR writeAnswer = dialog.Create(*ProgressDialog);
209370b324cSopenharmony_ci
210370b324cSopenharmony_ci  switch (writeAnswer)
211370b324cSopenharmony_ci  {
212370b324cSopenharmony_ci    case IDCANCEL:        *answer = NOverwriteAnswer::kCancel; return E_ABORT;
213370b324cSopenharmony_ci    case IDYES:           *answer = NOverwriteAnswer::kYes; break;
214370b324cSopenharmony_ci    case IDNO:            *answer = NOverwriteAnswer::kNo; break;
215370b324cSopenharmony_ci    case IDB_YES_TO_ALL:  *answer = NOverwriteAnswer::kYesToAll; break;
216370b324cSopenharmony_ci    case IDB_NO_TO_ALL:   *answer = NOverwriteAnswer::kNoToAll; break;
217370b324cSopenharmony_ci    case IDB_AUTO_RENAME: *answer = NOverwriteAnswer::kAutoRename; break;
218370b324cSopenharmony_ci    default: return E_FAIL;
219370b324cSopenharmony_ci  }
220370b324cSopenharmony_ci  return S_OK;
221370b324cSopenharmony_ci}
222370b324cSopenharmony_ci
223370b324cSopenharmony_ci
224370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */))
225370b324cSopenharmony_ci{
226370b324cSopenharmony_ci  _isFolder = IntToBool(isFolder);
227370b324cSopenharmony_ci  _currentFilePath = name;
228370b324cSopenharmony_ci
229370b324cSopenharmony_ci  const UString *msg = &_lang_Empty;
230370b324cSopenharmony_ci  switch (askExtractMode)
231370b324cSopenharmony_ci  {
232370b324cSopenharmony_ci    case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break;
233370b324cSopenharmony_ci    case NArchive::NExtract::NAskMode::kTest:    msg = &_lang_Testing; break;
234370b324cSopenharmony_ci    case NArchive::NExtract::NAskMode::kSkip:    msg = &_lang_Skipping; break;
235370b324cSopenharmony_ci    case NArchive::NExtract::NAskMode::kReadExternal: msg = &_lang_Reading; break;
236370b324cSopenharmony_ci    // default: s = "Unknown operation";
237370b324cSopenharmony_ci  }
238370b324cSopenharmony_ci
239370b324cSopenharmony_ci  return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder));
240370b324cSopenharmony_ci}
241370b324cSopenharmony_ci
242370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::MessageError(const wchar_t *s))
243370b324cSopenharmony_ci{
244370b324cSopenharmony_ci  AddError_Message(s);
245370b324cSopenharmony_ci  return S_OK;
246370b324cSopenharmony_ci}
247370b324cSopenharmony_ci
248370b324cSopenharmony_ciHRESULT CExtractCallbackImp::MessageError(const char *message, const FString &path)
249370b324cSopenharmony_ci{
250370b324cSopenharmony_ci  ThereAreMessageErrors = true;
251370b324cSopenharmony_ci  ProgressDialog->Sync.AddError_Message_Name(GetUnicodeString(message), fs2us(path));
252370b324cSopenharmony_ci  return S_OK;
253370b324cSopenharmony_ci}
254370b324cSopenharmony_ci
255370b324cSopenharmony_ci#ifndef Z7_SFX
256370b324cSopenharmony_ci
257370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::ShowMessage(const wchar_t *s))
258370b324cSopenharmony_ci{
259370b324cSopenharmony_ci  AddError_Message(s);
260370b324cSopenharmony_ci  return S_OK;
261370b324cSopenharmony_ci}
262370b324cSopenharmony_ci
263370b324cSopenharmony_ci#endif
264370b324cSopenharmony_ci
265370b324cSopenharmony_civoid SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s);
266370b324cSopenharmony_civoid SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s)
267370b324cSopenharmony_ci{
268370b324cSopenharmony_ci  s.Empty();
269370b324cSopenharmony_ci
270370b324cSopenharmony_ci  if (opRes == NArchive::NExtract::NOperationResult::kOK)
271370b324cSopenharmony_ci    return;
272370b324cSopenharmony_ci
273370b324cSopenharmony_ci #ifndef Z7_SFX
274370b324cSopenharmony_ci  UINT messageID = 0;
275370b324cSopenharmony_ci #endif
276370b324cSopenharmony_ci  UINT id = 0;
277370b324cSopenharmony_ci
278370b324cSopenharmony_ci  switch (opRes)
279370b324cSopenharmony_ci  {
280370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
281370b324cSopenharmony_ci     #ifndef Z7_SFX
282370b324cSopenharmony_ci      messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
283370b324cSopenharmony_ci     #endif
284370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD;
285370b324cSopenharmony_ci      break;
286370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kDataError:
287370b324cSopenharmony_ci     #ifndef Z7_SFX
288370b324cSopenharmony_ci      messageID = encrypted ?
289370b324cSopenharmony_ci          IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED:
290370b324cSopenharmony_ci          IDS_EXTRACT_MESSAGE_DATA_ERROR;
291370b324cSopenharmony_ci     #endif
292370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_DATA_ERROR;
293370b324cSopenharmony_ci      break;
294370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kCRCError:
295370b324cSopenharmony_ci     #ifndef Z7_SFX
296370b324cSopenharmony_ci      messageID = encrypted ?
297370b324cSopenharmony_ci          IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED:
298370b324cSopenharmony_ci          IDS_EXTRACT_MESSAGE_CRC_ERROR;
299370b324cSopenharmony_ci     #endif
300370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_CRC_ERROR;
301370b324cSopenharmony_ci      break;
302370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kUnavailable:
303370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA;
304370b324cSopenharmony_ci      break;
305370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
306370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_UEXPECTED_END;
307370b324cSopenharmony_ci      break;
308370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kDataAfterEnd:
309370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_DATA_AFTER_END;
310370b324cSopenharmony_ci      break;
311370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kIsNotArc:
312370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_IS_NOT_ARC;
313370b324cSopenharmony_ci      break;
314370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kHeadersError:
315370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_HEADERS_ERROR;
316370b324cSopenharmony_ci      break;
317370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kWrongPassword:
318370b324cSopenharmony_ci      id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM;
319370b324cSopenharmony_ci      break;
320370b324cSopenharmony_ci    /*
321370b324cSopenharmony_ci    default:
322370b324cSopenharmony_ci      messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR;
323370b324cSopenharmony_ci      break;
324370b324cSopenharmony_ci    */
325370b324cSopenharmony_ci  }
326370b324cSopenharmony_ci
327370b324cSopenharmony_ci  UString msg;
328370b324cSopenharmony_ci
329370b324cSopenharmony_ci #ifndef Z7_SFX
330370b324cSopenharmony_ci  UString msgOld;
331370b324cSopenharmony_ci #ifdef Z7_LANG
332370b324cSopenharmony_ci  if (id != 0)
333370b324cSopenharmony_ci    LangString_OnlyFromLangFile(id, msg);
334370b324cSopenharmony_ci  if (messageID != 0 && msg.IsEmpty())
335370b324cSopenharmony_ci    LangString_OnlyFromLangFile(messageID, msgOld);
336370b324cSopenharmony_ci #endif
337370b324cSopenharmony_ci  if (msg.IsEmpty() && !msgOld.IsEmpty())
338370b324cSopenharmony_ci    s = MyFormatNew(msgOld, fileName);
339370b324cSopenharmony_ci  else
340370b324cSopenharmony_ci #endif
341370b324cSopenharmony_ci  {
342370b324cSopenharmony_ci    if (msg.IsEmpty() && id != 0)
343370b324cSopenharmony_ci      LangString(id, msg);
344370b324cSopenharmony_ci    if (!msg.IsEmpty())
345370b324cSopenharmony_ci      s += msg;
346370b324cSopenharmony_ci    else
347370b324cSopenharmony_ci    {
348370b324cSopenharmony_ci      s += "Error #";
349370b324cSopenharmony_ci      s.Add_UInt32((UInt32)opRes);
350370b324cSopenharmony_ci    }
351370b324cSopenharmony_ci
352370b324cSopenharmony_ci    if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword)
353370b324cSopenharmony_ci    {
354370b324cSopenharmony_ci      // s += " : ";
355370b324cSopenharmony_ci      // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED);
356370b324cSopenharmony_ci      s += " : ";
357370b324cSopenharmony_ci      AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
358370b324cSopenharmony_ci    }
359370b324cSopenharmony_ci    s += " : ";
360370b324cSopenharmony_ci    s += fileName;
361370b324cSopenharmony_ci  }
362370b324cSopenharmony_ci}
363370b324cSopenharmony_ci
364370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted))
365370b324cSopenharmony_ci{
366370b324cSopenharmony_ci  switch (opRes)
367370b324cSopenharmony_ci  {
368370b324cSopenharmony_ci    case NArchive::NExtract::NOperationResult::kOK:
369370b324cSopenharmony_ci      break;
370370b324cSopenharmony_ci    default:
371370b324cSopenharmony_ci    {
372370b324cSopenharmony_ci      UString s;
373370b324cSopenharmony_ci      SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s);
374370b324cSopenharmony_ci      Add_ArchiveName_Error();
375370b324cSopenharmony_ci      AddError_Message(s);
376370b324cSopenharmony_ci    }
377370b324cSopenharmony_ci  }
378370b324cSopenharmony_ci
379370b324cSopenharmony_ci  #ifndef Z7_SFX
380370b324cSopenharmony_ci  if (_isFolder)
381370b324cSopenharmony_ci    NumFolders++;
382370b324cSopenharmony_ci  else
383370b324cSopenharmony_ci    NumFiles++;
384370b324cSopenharmony_ci  ProgressDialog->Sync.Set_NumFilesCur(NumFiles);
385370b324cSopenharmony_ci  #endif
386370b324cSopenharmony_ci
387370b324cSopenharmony_ci  return S_OK;
388370b324cSopenharmony_ci}
389370b324cSopenharmony_ci
390370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name))
391370b324cSopenharmony_ci{
392370b324cSopenharmony_ci  if (opRes != NArchive::NExtract::NOperationResult::kOK)
393370b324cSopenharmony_ci  {
394370b324cSopenharmony_ci    UString s;
395370b324cSopenharmony_ci    SetExtractErrorMessage(opRes, encrypted, name, s);
396370b324cSopenharmony_ci    Add_ArchiveName_Error();
397370b324cSopenharmony_ci    AddError_Message(s);
398370b324cSopenharmony_ci  }
399370b324cSopenharmony_ci  return S_OK;
400370b324cSopenharmony_ci}
401370b324cSopenharmony_ci
402370b324cSopenharmony_ci////////////////////////////////////////
403370b324cSopenharmony_ci// IExtractCallbackUI
404370b324cSopenharmony_ci
405370b324cSopenharmony_ciHRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */)
406370b324cSopenharmony_ci{
407370b324cSopenharmony_ci  #ifndef Z7_SFX
408370b324cSopenharmony_ci  RINOK(ProgressDialog->Sync.CheckStop())
409370b324cSopenharmony_ci  ProgressDialog->Sync.Set_TitleFileName(name);
410370b324cSopenharmony_ci  #endif
411370b324cSopenharmony_ci  _currentArchivePath = name;
412370b324cSopenharmony_ci  return S_OK;
413370b324cSopenharmony_ci}
414370b324cSopenharmony_ci
415370b324cSopenharmony_ciHRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path)
416370b324cSopenharmony_ci{
417370b324cSopenharmony_ci  _currentFilePath = path;
418370b324cSopenharmony_ci  #ifndef Z7_SFX
419370b324cSopenharmony_ci  ProgressDialog->Sync.Set_FilePath(path);
420370b324cSopenharmony_ci  #endif
421370b324cSopenharmony_ci  return S_OK;
422370b324cSopenharmony_ci}
423370b324cSopenharmony_ci
424370b324cSopenharmony_ci#ifndef Z7_SFX
425370b324cSopenharmony_ci
426370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path))
427370b324cSopenharmony_ci{
428370b324cSopenharmony_ci  #ifndef Z7_SFX
429370b324cSopenharmony_ci  if (NeedAddFile)
430370b324cSopenharmony_ci    NumFiles++;
431370b324cSopenharmony_ci  NeedAddFile = true;
432370b324cSopenharmony_ci  ProgressDialog->Sync.Set_NumFilesCur(NumFiles);
433370b324cSopenharmony_ci  #endif
434370b324cSopenharmony_ci  return SetCurrentFilePath2(path);
435370b324cSopenharmony_ci}
436370b324cSopenharmony_ci
437370b324cSopenharmony_ci#endif
438370b324cSopenharmony_ci
439370b324cSopenharmony_ciUString HResultToMessage(HRESULT errorCode);
440370b324cSopenharmony_ci
441370b324cSopenharmony_cistatic const UInt32 k_ErrorFlagsIds[] =
442370b324cSopenharmony_ci{
443370b324cSopenharmony_ci  IDS_EXTRACT_MSG_IS_NOT_ARC,
444370b324cSopenharmony_ci  IDS_EXTRACT_MSG_HEADERS_ERROR,
445370b324cSopenharmony_ci  IDS_EXTRACT_MSG_HEADERS_ERROR,
446370b324cSopenharmony_ci  IDS_OPEN_MSG_UNAVAILABLE_START,
447370b324cSopenharmony_ci  IDS_OPEN_MSG_UNCONFIRMED_START,
448370b324cSopenharmony_ci  IDS_EXTRACT_MSG_UEXPECTED_END,
449370b324cSopenharmony_ci  IDS_EXTRACT_MSG_DATA_AFTER_END,
450370b324cSopenharmony_ci  IDS_EXTRACT_MSG_UNSUPPORTED_METHOD,
451370b324cSopenharmony_ci  IDS_OPEN_MSG_UNSUPPORTED_FEATURE,
452370b324cSopenharmony_ci  IDS_EXTRACT_MSG_DATA_ERROR,
453370b324cSopenharmony_ci  IDS_EXTRACT_MSG_CRC_ERROR
454370b324cSopenharmony_ci};
455370b324cSopenharmony_ci
456370b324cSopenharmony_cistatic void AddNewLineString(UString &s, const UString &m)
457370b324cSopenharmony_ci{
458370b324cSopenharmony_ci  s += m;
459370b324cSopenharmony_ci  s.Add_LF();
460370b324cSopenharmony_ci}
461370b324cSopenharmony_ci
462370b324cSopenharmony_ciUString GetOpenArcErrorMessage(UInt32 errorFlags);
463370b324cSopenharmony_ciUString GetOpenArcErrorMessage(UInt32 errorFlags)
464370b324cSopenharmony_ci{
465370b324cSopenharmony_ci  UString s;
466370b324cSopenharmony_ci
467370b324cSopenharmony_ci  for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsIds); i++)
468370b324cSopenharmony_ci  {
469370b324cSopenharmony_ci    UInt32 f = ((UInt32)1 << i);
470370b324cSopenharmony_ci    if ((errorFlags & f) == 0)
471370b324cSopenharmony_ci      continue;
472370b324cSopenharmony_ci    UInt32 id = k_ErrorFlagsIds[i];
473370b324cSopenharmony_ci    UString m = LangString(id);
474370b324cSopenharmony_ci    if (m.IsEmpty())
475370b324cSopenharmony_ci      continue;
476370b324cSopenharmony_ci    if (f == kpv_ErrorFlags_EncryptedHeadersError)
477370b324cSopenharmony_ci    {
478370b324cSopenharmony_ci      m += " : ";
479370b324cSopenharmony_ci      AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
480370b324cSopenharmony_ci    }
481370b324cSopenharmony_ci    if (!s.IsEmpty())
482370b324cSopenharmony_ci      s.Add_LF();
483370b324cSopenharmony_ci    s += m;
484370b324cSopenharmony_ci    errorFlags &= ~f;
485370b324cSopenharmony_ci  }
486370b324cSopenharmony_ci
487370b324cSopenharmony_ci  if (errorFlags != 0)
488370b324cSopenharmony_ci  {
489370b324cSopenharmony_ci    char sz[16];
490370b324cSopenharmony_ci    sz[0] = '0';
491370b324cSopenharmony_ci    sz[1] = 'x';
492370b324cSopenharmony_ci    ConvertUInt32ToHex(errorFlags, sz + 2);
493370b324cSopenharmony_ci    if (!s.IsEmpty())
494370b324cSopenharmony_ci      s.Add_LF();
495370b324cSopenharmony_ci    s += sz;
496370b324cSopenharmony_ci  }
497370b324cSopenharmony_ci
498370b324cSopenharmony_ci  return s;
499370b324cSopenharmony_ci}
500370b324cSopenharmony_ci
501370b324cSopenharmony_cistatic void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
502370b324cSopenharmony_ci{
503370b324cSopenharmony_ci  UInt32 errorFlags = er.GetErrorFlags();
504370b324cSopenharmony_ci  UInt32 warningFlags = er.GetWarningFlags();
505370b324cSopenharmony_ci
506370b324cSopenharmony_ci  if (errorFlags != 0)
507370b324cSopenharmony_ci    AddNewLineString(s, GetOpenArcErrorMessage(errorFlags));
508370b324cSopenharmony_ci
509370b324cSopenharmony_ci  if (!er.ErrorMessage.IsEmpty())
510370b324cSopenharmony_ci    AddNewLineString(s, er.ErrorMessage);
511370b324cSopenharmony_ci
512370b324cSopenharmony_ci  if (warningFlags != 0)
513370b324cSopenharmony_ci  {
514370b324cSopenharmony_ci    s += GetNameOfProperty(kpidWarningFlags, L"Warnings");
515370b324cSopenharmony_ci    s += ":";
516370b324cSopenharmony_ci    s.Add_LF();
517370b324cSopenharmony_ci    AddNewLineString(s, GetOpenArcErrorMessage(warningFlags));
518370b324cSopenharmony_ci  }
519370b324cSopenharmony_ci
520370b324cSopenharmony_ci  if (!er.WarningMessage.IsEmpty())
521370b324cSopenharmony_ci  {
522370b324cSopenharmony_ci    s += GetNameOfProperty(kpidWarning, L"Warning");
523370b324cSopenharmony_ci    s += ": ";
524370b324cSopenharmony_ci    s += er.WarningMessage;
525370b324cSopenharmony_ci    s.Add_LF();
526370b324cSopenharmony_ci  }
527370b324cSopenharmony_ci}
528370b324cSopenharmony_ci
529370b324cSopenharmony_cistatic UString GetBracedType(const wchar_t *type)
530370b324cSopenharmony_ci{
531370b324cSopenharmony_ci  UString s ('[');
532370b324cSopenharmony_ci  s += type;
533370b324cSopenharmony_ci  s += ']';
534370b324cSopenharmony_ci  return s;
535370b324cSopenharmony_ci}
536370b324cSopenharmony_ci
537370b324cSopenharmony_civoid OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result);
538370b324cSopenharmony_civoid OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
539370b324cSopenharmony_ci{
540370b324cSopenharmony_ci  FOR_VECTOR (level, arcLink.Arcs)
541370b324cSopenharmony_ci  {
542370b324cSopenharmony_ci    const CArc &arc = arcLink.Arcs[level];
543370b324cSopenharmony_ci    const CArcErrorInfo &er = arc.ErrorInfo;
544370b324cSopenharmony_ci
545370b324cSopenharmony_ci    if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0)
546370b324cSopenharmony_ci      continue;
547370b324cSopenharmony_ci
548370b324cSopenharmony_ci    if (s.IsEmpty())
549370b324cSopenharmony_ci    {
550370b324cSopenharmony_ci      s += name;
551370b324cSopenharmony_ci      s.Add_LF();
552370b324cSopenharmony_ci    }
553370b324cSopenharmony_ci
554370b324cSopenharmony_ci    if (level != 0)
555370b324cSopenharmony_ci    {
556370b324cSopenharmony_ci      AddNewLineString(s, arc.Path);
557370b324cSopenharmony_ci    }
558370b324cSopenharmony_ci
559370b324cSopenharmony_ci    ErrorInfo_Print(s, er);
560370b324cSopenharmony_ci
561370b324cSopenharmony_ci    if (er.ErrorFormatIndex >= 0)
562370b324cSopenharmony_ci    {
563370b324cSopenharmony_ci      AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning"));
564370b324cSopenharmony_ci      if (arc.FormatIndex == er.ErrorFormatIndex)
565370b324cSopenharmony_ci      {
566370b324cSopenharmony_ci        AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET));
567370b324cSopenharmony_ci      }
568370b324cSopenharmony_ci      else
569370b324cSopenharmony_ci      {
570370b324cSopenharmony_ci        AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex))));
571370b324cSopenharmony_ci        AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex))));
572370b324cSopenharmony_ci      }
573370b324cSopenharmony_ci    }
574370b324cSopenharmony_ci  }
575370b324cSopenharmony_ci
576370b324cSopenharmony_ci  if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK)
577370b324cSopenharmony_ci  {
578370b324cSopenharmony_ci    s += name;
579370b324cSopenharmony_ci    s.Add_LF();
580370b324cSopenharmony_ci    if (!arcLink.Arcs.IsEmpty())
581370b324cSopenharmony_ci      AddNewLineString(s, arcLink.NonOpen_ArcPath);
582370b324cSopenharmony_ci
583370b324cSopenharmony_ci    if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE)
584370b324cSopenharmony_ci    {
585370b324cSopenharmony_ci      UINT id = IDS_CANT_OPEN_ARCHIVE;
586370b324cSopenharmony_ci      UString param;
587370b324cSopenharmony_ci      if (arcLink.PasswordWasAsked)
588370b324cSopenharmony_ci        id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE;
589370b324cSopenharmony_ci      else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
590370b324cSopenharmony_ci      {
591370b324cSopenharmony_ci        id = IDS_CANT_OPEN_AS_TYPE;
592370b324cSopenharmony_ci        param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex));
593370b324cSopenharmony_ci      }
594370b324cSopenharmony_ci      UString s2 = MyFormatNew(id, param);
595370b324cSopenharmony_ci      s2.Replace(L" ''", L"");
596370b324cSopenharmony_ci      s2.Replace(L"''", L"");
597370b324cSopenharmony_ci      s += s2;
598370b324cSopenharmony_ci    }
599370b324cSopenharmony_ci    else
600370b324cSopenharmony_ci      s += HResultToMessage(result);
601370b324cSopenharmony_ci
602370b324cSopenharmony_ci    s.Add_LF();
603370b324cSopenharmony_ci    ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo);
604370b324cSopenharmony_ci  }
605370b324cSopenharmony_ci
606370b324cSopenharmony_ci  if (!s.IsEmpty() && s.Back() == '\n')
607370b324cSopenharmony_ci    s.DeleteBack();
608370b324cSopenharmony_ci}
609370b324cSopenharmony_ci
610370b324cSopenharmony_ciHRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
611370b324cSopenharmony_ci{
612370b324cSopenharmony_ci  _currentArchivePath = name;
613370b324cSopenharmony_ci  _needWriteArchivePath = true;
614370b324cSopenharmony_ci
615370b324cSopenharmony_ci  UString s;
616370b324cSopenharmony_ci  OpenResult_GUI(s, codecs, arcLink, name, result);
617370b324cSopenharmony_ci  if (!s.IsEmpty())
618370b324cSopenharmony_ci  {
619370b324cSopenharmony_ci    NumArchiveErrors++;
620370b324cSopenharmony_ci    AddError_Message(s);
621370b324cSopenharmony_ci    _needWriteArchivePath = false;
622370b324cSopenharmony_ci  }
623370b324cSopenharmony_ci
624370b324cSopenharmony_ci  return S_OK;
625370b324cSopenharmony_ci}
626370b324cSopenharmony_ci
627370b324cSopenharmony_ciHRESULT CExtractCallbackImp::ThereAreNoFiles()
628370b324cSopenharmony_ci{
629370b324cSopenharmony_ci  return S_OK;
630370b324cSopenharmony_ci}
631370b324cSopenharmony_ci
632370b324cSopenharmony_civoid CExtractCallbackImp::Add_ArchiveName_Error()
633370b324cSopenharmony_ci{
634370b324cSopenharmony_ci  if (_needWriteArchivePath)
635370b324cSopenharmony_ci  {
636370b324cSopenharmony_ci    if (!_currentArchivePath.IsEmpty())
637370b324cSopenharmony_ci      AddError_Message(_currentArchivePath);
638370b324cSopenharmony_ci    _needWriteArchivePath = false;
639370b324cSopenharmony_ci  }
640370b324cSopenharmony_ci}
641370b324cSopenharmony_ci
642370b324cSopenharmony_ciHRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
643370b324cSopenharmony_ci{
644370b324cSopenharmony_ci  if (result == S_OK)
645370b324cSopenharmony_ci    return result;
646370b324cSopenharmony_ci  NumArchiveErrors++;
647370b324cSopenharmony_ci  if (result == E_ABORT
648370b324cSopenharmony_ci      || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)
649370b324cSopenharmony_ci      )
650370b324cSopenharmony_ci    return result;
651370b324cSopenharmony_ci
652370b324cSopenharmony_ci  Add_ArchiveName_Error();
653370b324cSopenharmony_ci  if (!_currentFilePath.IsEmpty())
654370b324cSopenharmony_ci    MessageError(_currentFilePath);
655370b324cSopenharmony_ci  MessageError(NError::MyFormatMessage(result));
656370b324cSopenharmony_ci  return S_OK;
657370b324cSopenharmony_ci}
658370b324cSopenharmony_ci
659370b324cSopenharmony_ci#ifndef Z7_NO_CRYPTO
660370b324cSopenharmony_ci
661370b324cSopenharmony_ciHRESULT CExtractCallbackImp::SetPassword(const UString &password)
662370b324cSopenharmony_ci{
663370b324cSopenharmony_ci  PasswordIsDefined = true;
664370b324cSopenharmony_ci  Password = password;
665370b324cSopenharmony_ci  return S_OK;
666370b324cSopenharmony_ci}
667370b324cSopenharmony_ci
668370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword(BSTR *password))
669370b324cSopenharmony_ci{
670370b324cSopenharmony_ci  PasswordWasAsked = true;
671370b324cSopenharmony_ci  if (!PasswordIsDefined)
672370b324cSopenharmony_ci  {
673370b324cSopenharmony_ci    CPasswordDialog dialog;
674370b324cSopenharmony_ci    #ifndef Z7_SFX
675370b324cSopenharmony_ci    const bool showPassword = NExtract::Read_ShowPassword();
676370b324cSopenharmony_ci    dialog.ShowPassword = showPassword;
677370b324cSopenharmony_ci    #endif
678370b324cSopenharmony_ci    ProgressDialog->WaitCreating();
679370b324cSopenharmony_ci    if (dialog.Create(*ProgressDialog) != IDOK)
680370b324cSopenharmony_ci      return E_ABORT;
681370b324cSopenharmony_ci    Password = dialog.Password;
682370b324cSopenharmony_ci    PasswordIsDefined = true;
683370b324cSopenharmony_ci    #ifndef Z7_SFX
684370b324cSopenharmony_ci    if (dialog.ShowPassword != showPassword)
685370b324cSopenharmony_ci      NExtract::Save_ShowPassword(dialog.ShowPassword);
686370b324cSopenharmony_ci    #endif
687370b324cSopenharmony_ci  }
688370b324cSopenharmony_ci  return StringToBstr(Password, password);
689370b324cSopenharmony_ci}
690370b324cSopenharmony_ci
691370b324cSopenharmony_ci#endif
692370b324cSopenharmony_ci
693370b324cSopenharmony_ci#ifndef Z7_SFX
694370b324cSopenharmony_ci
695370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::AskWrite(
696370b324cSopenharmony_ci    const wchar_t *srcPath, Int32 srcIsFolder,
697370b324cSopenharmony_ci    const FILETIME *srcTime, const UInt64 *srcSize,
698370b324cSopenharmony_ci    const wchar_t *destPath,
699370b324cSopenharmony_ci    BSTR *destPathResult,
700370b324cSopenharmony_ci    Int32 *writeAnswer))
701370b324cSopenharmony_ci{
702370b324cSopenharmony_ci  UString destPathResultTemp = destPath;
703370b324cSopenharmony_ci
704370b324cSopenharmony_ci  // RINOK(StringToBstr(destPath, destPathResult));
705370b324cSopenharmony_ci
706370b324cSopenharmony_ci  *destPathResult = NULL;
707370b324cSopenharmony_ci  *writeAnswer = BoolToInt(false);
708370b324cSopenharmony_ci
709370b324cSopenharmony_ci  FString destPathSys = us2fs(destPath);
710370b324cSopenharmony_ci  const bool srcIsFolderSpec = IntToBool(srcIsFolder);
711370b324cSopenharmony_ci  CFileInfo destFileInfo;
712370b324cSopenharmony_ci
713370b324cSopenharmony_ci  if (destFileInfo.Find(destPathSys))
714370b324cSopenharmony_ci  {
715370b324cSopenharmony_ci    if (srcIsFolderSpec)
716370b324cSopenharmony_ci    {
717370b324cSopenharmony_ci      if (!destFileInfo.IsDir())
718370b324cSopenharmony_ci      {
719370b324cSopenharmony_ci        RINOK(MessageError("Cannot replace file with folder with same name", destPathSys))
720370b324cSopenharmony_ci        return E_ABORT;
721370b324cSopenharmony_ci      }
722370b324cSopenharmony_ci      *writeAnswer = BoolToInt(false);
723370b324cSopenharmony_ci      return S_OK;
724370b324cSopenharmony_ci    }
725370b324cSopenharmony_ci
726370b324cSopenharmony_ci    if (destFileInfo.IsDir())
727370b324cSopenharmony_ci    {
728370b324cSopenharmony_ci      RINOK(MessageError("Cannot replace folder with file with same name", destPathSys))
729370b324cSopenharmony_ci      *writeAnswer = BoolToInt(false);
730370b324cSopenharmony_ci      return S_OK;
731370b324cSopenharmony_ci    }
732370b324cSopenharmony_ci
733370b324cSopenharmony_ci    switch ((int)OverwriteMode)
734370b324cSopenharmony_ci    {
735370b324cSopenharmony_ci      case NExtract::NOverwriteMode::kSkip:
736370b324cSopenharmony_ci        return S_OK;
737370b324cSopenharmony_ci      case NExtract::NOverwriteMode::kAsk:
738370b324cSopenharmony_ci      {
739370b324cSopenharmony_ci        Int32 overwriteResult;
740370b324cSopenharmony_ci        UString destPathSpec = destPath;
741370b324cSopenharmony_ci        const int slashPos = destPathSpec.ReverseFind_PathSepar();
742370b324cSopenharmony_ci        destPathSpec.DeleteFrom((unsigned)(slashPos + 1));
743370b324cSopenharmony_ci        destPathSpec += fs2us(destFileInfo.Name);
744370b324cSopenharmony_ci
745370b324cSopenharmony_ci        RINOK(AskOverwrite(
746370b324cSopenharmony_ci            destPathSpec,
747370b324cSopenharmony_ci            &destFileInfo.MTime, &destFileInfo.Size,
748370b324cSopenharmony_ci            srcPath,
749370b324cSopenharmony_ci            srcTime, srcSize,
750370b324cSopenharmony_ci            &overwriteResult))
751370b324cSopenharmony_ci
752370b324cSopenharmony_ci        switch (overwriteResult)
753370b324cSopenharmony_ci        {
754370b324cSopenharmony_ci          case NOverwriteAnswer::kCancel: return E_ABORT;
755370b324cSopenharmony_ci          case NOverwriteAnswer::kNo: return S_OK;
756370b324cSopenharmony_ci          case NOverwriteAnswer::kNoToAll: OverwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK;
757370b324cSopenharmony_ci          case NOverwriteAnswer::kYes: break;
758370b324cSopenharmony_ci          case NOverwriteAnswer::kYesToAll: OverwriteMode = NExtract::NOverwriteMode::kOverwrite; break;
759370b324cSopenharmony_ci          case NOverwriteAnswer::kAutoRename: OverwriteMode = NExtract::NOverwriteMode::kRename; break;
760370b324cSopenharmony_ci          default:
761370b324cSopenharmony_ci            return E_FAIL;
762370b324cSopenharmony_ci        }
763370b324cSopenharmony_ci        break;
764370b324cSopenharmony_ci      }
765370b324cSopenharmony_ci      default:
766370b324cSopenharmony_ci        break;
767370b324cSopenharmony_ci    }
768370b324cSopenharmony_ci
769370b324cSopenharmony_ci    if (OverwriteMode == NExtract::NOverwriteMode::kRename)
770370b324cSopenharmony_ci    {
771370b324cSopenharmony_ci      if (!AutoRenamePath(destPathSys))
772370b324cSopenharmony_ci      {
773370b324cSopenharmony_ci        RINOK(MessageError("Cannot create name for file", destPathSys))
774370b324cSopenharmony_ci        return E_ABORT;
775370b324cSopenharmony_ci      }
776370b324cSopenharmony_ci      destPathResultTemp = fs2us(destPathSys);
777370b324cSopenharmony_ci    }
778370b324cSopenharmony_ci    else
779370b324cSopenharmony_ci    {
780370b324cSopenharmony_ci      if (NFind::DoesFileExist_Raw(destPathSys))
781370b324cSopenharmony_ci      if (!NDir::DeleteFileAlways(destPathSys))
782370b324cSopenharmony_ci      if (GetLastError() != ERROR_FILE_NOT_FOUND)
783370b324cSopenharmony_ci      {
784370b324cSopenharmony_ci        RINOK(MessageError("Cannot delete output file", destPathSys))
785370b324cSopenharmony_ci        return E_ABORT;
786370b324cSopenharmony_ci      }
787370b324cSopenharmony_ci    }
788370b324cSopenharmony_ci  }
789370b324cSopenharmony_ci  *writeAnswer = BoolToInt(true);
790370b324cSopenharmony_ci  return StringToBstr(destPathResultTemp, destPathResult);
791370b324cSopenharmony_ci}
792370b324cSopenharmony_ci
793370b324cSopenharmony_ci
794370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::UseExtractToStream(Int32 *res))
795370b324cSopenharmony_ci{
796370b324cSopenharmony_ci  *res = BoolToInt(StreamMode);
797370b324cSopenharmony_ci  return S_OK;
798370b324cSopenharmony_ci}
799370b324cSopenharmony_ci
800370b324cSopenharmony_cistatic HRESULT GetTime(IGetProp *getProp, PROPID propID, FILETIME &ft, bool &ftDefined)
801370b324cSopenharmony_ci{
802370b324cSopenharmony_ci  ftDefined = false;
803370b324cSopenharmony_ci  NCOM::CPropVariant prop;
804370b324cSopenharmony_ci  RINOK(getProp->GetProp(propID, &prop))
805370b324cSopenharmony_ci  if (prop.vt == VT_FILETIME)
806370b324cSopenharmony_ci  {
807370b324cSopenharmony_ci    ft = prop.filetime;
808370b324cSopenharmony_ci    ftDefined = (ft.dwHighDateTime != 0 || ft.dwLowDateTime != 0);
809370b324cSopenharmony_ci  }
810370b324cSopenharmony_ci  else if (prop.vt != VT_EMPTY)
811370b324cSopenharmony_ci    return E_FAIL;
812370b324cSopenharmony_ci  return S_OK;
813370b324cSopenharmony_ci}
814370b324cSopenharmony_ci
815370b324cSopenharmony_ci
816370b324cSopenharmony_cistatic HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result)
817370b324cSopenharmony_ci{
818370b324cSopenharmony_ci  NCOM::CPropVariant prop;
819370b324cSopenharmony_ci  result = false;
820370b324cSopenharmony_ci  RINOK(getProp->GetProp(propID, &prop))
821370b324cSopenharmony_ci  if (prop.vt == VT_BOOL)
822370b324cSopenharmony_ci    result = VARIANT_BOOLToBool(prop.boolVal);
823370b324cSopenharmony_ci  else if (prop.vt != VT_EMPTY)
824370b324cSopenharmony_ci    return E_FAIL;
825370b324cSopenharmony_ci  return S_OK;
826370b324cSopenharmony_ci}
827370b324cSopenharmony_ci
828370b324cSopenharmony_ci
829370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name,
830370b324cSopenharmony_ci    Int32 isDir,
831370b324cSopenharmony_ci    ISequentialOutStream **outStream, Int32 askExtractMode,
832370b324cSopenharmony_ci    IGetProp *getProp))
833370b324cSopenharmony_ci{
834370b324cSopenharmony_ci  COM_TRY_BEGIN
835370b324cSopenharmony_ci  *outStream = NULL;
836370b324cSopenharmony_ci  _newVirtFileWasAdded = false;
837370b324cSopenharmony_ci  _hashStreamWasUsed = false;
838370b324cSopenharmony_ci  _needUpdateStat = false;
839370b324cSopenharmony_ci
840370b324cSopenharmony_ci  if (_hashStream)
841370b324cSopenharmony_ci    _hashStreamSpec->ReleaseStream();
842370b324cSopenharmony_ci
843370b324cSopenharmony_ci  GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream);
844370b324cSopenharmony_ci
845370b324cSopenharmony_ci  if (!ProcessAltStreams && _isAltStream)
846370b324cSopenharmony_ci    return S_OK;
847370b324cSopenharmony_ci
848370b324cSopenharmony_ci  _filePath = name;
849370b324cSopenharmony_ci  _isFolder = IntToBool(isDir);
850370b324cSopenharmony_ci  _curSize = 0;
851370b324cSopenharmony_ci  _curSize_Defined = false;
852370b324cSopenharmony_ci
853370b324cSopenharmony_ci  UInt64 size = 0;
854370b324cSopenharmony_ci  bool sizeDefined;
855370b324cSopenharmony_ci  {
856370b324cSopenharmony_ci    NCOM::CPropVariant prop;
857370b324cSopenharmony_ci    RINOK(getProp->GetProp(kpidSize, &prop))
858370b324cSopenharmony_ci    sizeDefined = ConvertPropVariantToUInt64(prop, size);
859370b324cSopenharmony_ci  }
860370b324cSopenharmony_ci
861370b324cSopenharmony_ci  if (sizeDefined)
862370b324cSopenharmony_ci  {
863370b324cSopenharmony_ci    _curSize = size;
864370b324cSopenharmony_ci    _curSize_Defined = true;
865370b324cSopenharmony_ci  }
866370b324cSopenharmony_ci
867370b324cSopenharmony_ci  if (askExtractMode != NArchive::NExtract::NAskMode::kExtract &&
868370b324cSopenharmony_ci      askExtractMode != NArchive::NExtract::NAskMode::kTest)
869370b324cSopenharmony_ci    return S_OK;
870370b324cSopenharmony_ci
871370b324cSopenharmony_ci  _needUpdateStat = true;
872370b324cSopenharmony_ci
873370b324cSopenharmony_ci  CMyComPtr<ISequentialOutStream> outStreamLoc;
874370b324cSopenharmony_ci
875370b324cSopenharmony_ci  if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract)
876370b324cSopenharmony_ci  {
877370b324cSopenharmony_ci    CVirtFile &file = VirtFileSystemSpec->AddNewFile();
878370b324cSopenharmony_ci    _newVirtFileWasAdded = true;
879370b324cSopenharmony_ci    file.Name = name;
880370b324cSopenharmony_ci    file.IsDir = IntToBool(isDir);
881370b324cSopenharmony_ci    file.IsAltStream = _isAltStream;
882370b324cSopenharmony_ci    file.Size = 0;
883370b324cSopenharmony_ci
884370b324cSopenharmony_ci    RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined))
885370b324cSopenharmony_ci    RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined))
886370b324cSopenharmony_ci    RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined))
887370b324cSopenharmony_ci
888370b324cSopenharmony_ci    NCOM::CPropVariant prop;
889370b324cSopenharmony_ci    RINOK(getProp->GetProp(kpidAttrib, &prop))
890370b324cSopenharmony_ci    if (prop.vt == VT_UI4)
891370b324cSopenharmony_ci    {
892370b324cSopenharmony_ci      file.Attrib = prop.ulVal;
893370b324cSopenharmony_ci      file.AttribDefined = true;
894370b324cSopenharmony_ci    }
895370b324cSopenharmony_ci    // else if (isDir) file.Attrib = FILE_ATTRIBUTE_DIRECTORY;
896370b324cSopenharmony_ci
897370b324cSopenharmony_ci    file.ExpectedSize = 0;
898370b324cSopenharmony_ci    if (sizeDefined)
899370b324cSopenharmony_ci      file.ExpectedSize = size;
900370b324cSopenharmony_ci    outStreamLoc = VirtFileSystem;
901370b324cSopenharmony_ci  }
902370b324cSopenharmony_ci
903370b324cSopenharmony_ci  if (_hashStream)
904370b324cSopenharmony_ci  {
905370b324cSopenharmony_ci    {
906370b324cSopenharmony_ci      _hashStreamSpec->SetStream(outStreamLoc);
907370b324cSopenharmony_ci      outStreamLoc = _hashStream;
908370b324cSopenharmony_ci      _hashStreamSpec->Init(true);
909370b324cSopenharmony_ci      _hashStreamWasUsed = true;
910370b324cSopenharmony_ci    }
911370b324cSopenharmony_ci  }
912370b324cSopenharmony_ci
913370b324cSopenharmony_ci  if (outStreamLoc)
914370b324cSopenharmony_ci    *outStream = outStreamLoc.Detach();
915370b324cSopenharmony_ci  return S_OK;
916370b324cSopenharmony_ci  COM_TRY_END
917370b324cSopenharmony_ci}
918370b324cSopenharmony_ci
919370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode))
920370b324cSopenharmony_ci{
921370b324cSopenharmony_ci  COM_TRY_BEGIN
922370b324cSopenharmony_ci  _needUpdateStat = (
923370b324cSopenharmony_ci         askExtractMode == NArchive::NExtract::NAskMode::kExtract
924370b324cSopenharmony_ci      || askExtractMode == NArchive::NExtract::NAskMode::kTest
925370b324cSopenharmony_ci      || askExtractMode == NArchive::NExtract::NAskMode::kReadExternal
926370b324cSopenharmony_ci      );
927370b324cSopenharmony_ci
928370b324cSopenharmony_ci  /*
929370b324cSopenharmony_ci  _extractMode = false;
930370b324cSopenharmony_ci  switch (askExtractMode)
931370b324cSopenharmony_ci  {
932370b324cSopenharmony_ci    case NArchive::NExtract::NAskMode::kExtract:
933370b324cSopenharmony_ci      if (_testMode)
934370b324cSopenharmony_ci        askExtractMode = NArchive::NExtract::NAskMode::kTest;
935370b324cSopenharmony_ci      else
936370b324cSopenharmony_ci        _extractMode = true;
937370b324cSopenharmony_ci      break;
938370b324cSopenharmony_ci  };
939370b324cSopenharmony_ci  */
940370b324cSopenharmony_ci  return SetCurrentFilePath2(_filePath);
941370b324cSopenharmony_ci  COM_TRY_END
942370b324cSopenharmony_ci}
943370b324cSopenharmony_ci
944370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetOperationResult8(Int32 opRes, Int32 encrypted, UInt64 size))
945370b324cSopenharmony_ci{
946370b324cSopenharmony_ci  COM_TRY_BEGIN
947370b324cSopenharmony_ci  if (VirtFileSystem && _newVirtFileWasAdded)
948370b324cSopenharmony_ci  {
949370b324cSopenharmony_ci    // FIXME: probably we must request file size from VirtFileSystem
950370b324cSopenharmony_ci    // _curSize = VirtFileSystem->GetLastFileSize()
951370b324cSopenharmony_ci    // _curSize_Defined = true;
952370b324cSopenharmony_ci    RINOK(VirtFileSystemSpec->CloseMemFile())
953370b324cSopenharmony_ci  }
954370b324cSopenharmony_ci  if (_hashStream && _hashStreamWasUsed)
955370b324cSopenharmony_ci  {
956370b324cSopenharmony_ci    _hashStreamSpec->_hash->Final(_isFolder, _isAltStream, _filePath);
957370b324cSopenharmony_ci    _curSize = _hashStreamSpec->GetSize();
958370b324cSopenharmony_ci    _curSize_Defined = true;
959370b324cSopenharmony_ci    _hashStreamSpec->ReleaseStream();
960370b324cSopenharmony_ci    _hashStreamWasUsed = false;
961370b324cSopenharmony_ci  }
962370b324cSopenharmony_ci  else if (_hashCalc && _needUpdateStat)
963370b324cSopenharmony_ci  {
964370b324cSopenharmony_ci    _hashCalc->SetSize(size); // (_curSize) before 21.04
965370b324cSopenharmony_ci    _hashCalc->Final(_isFolder, _isAltStream, _filePath);
966370b324cSopenharmony_ci  }
967370b324cSopenharmony_ci  return SetOperationResult(opRes, encrypted);
968370b324cSopenharmony_ci  COM_TRY_END
969370b324cSopenharmony_ci}
970370b324cSopenharmony_ci
971370b324cSopenharmony_ci
972370b324cSopenharmony_ci
973370b324cSopenharmony_ci// static const UInt32 kBlockSize = ((UInt32)1 << 31);
974370b324cSopenharmony_ci
975370b324cSopenharmony_ciZ7_COM7F_IMF(CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize))
976370b324cSopenharmony_ci{
977370b324cSopenharmony_ci  if (processedSize)
978370b324cSopenharmony_ci    *processedSize = 0;
979370b324cSopenharmony_ci  if (size == 0)
980370b324cSopenharmony_ci    return S_OK;
981370b324cSopenharmony_ci  if (!_fileMode)
982370b324cSopenharmony_ci  {
983370b324cSopenharmony_ci    CVirtFile &file = Files.Back();
984370b324cSopenharmony_ci    size_t rem = file.Data.Size() - (size_t)file.Size;
985370b324cSopenharmony_ci    bool useMem = true;
986370b324cSopenharmony_ci    if (rem < size)
987370b324cSopenharmony_ci    {
988370b324cSopenharmony_ci      UInt64 b = 0;
989370b324cSopenharmony_ci      if (file.Data.Size() == 0)
990370b324cSopenharmony_ci        b = file.ExpectedSize;
991370b324cSopenharmony_ci      UInt64 a = file.Size + size;
992370b324cSopenharmony_ci      if (b < a)
993370b324cSopenharmony_ci        b = a;
994370b324cSopenharmony_ci      a = (UInt64)file.Data.Size() * 2;
995370b324cSopenharmony_ci      if (b < a)
996370b324cSopenharmony_ci        b = a;
997370b324cSopenharmony_ci      useMem = false;
998370b324cSopenharmony_ci      const size_t b_sizet = (size_t)b;
999370b324cSopenharmony_ci      if (b == b_sizet && b <= MaxTotalAllocSize)
1000370b324cSopenharmony_ci        useMem = file.Data.ReAlloc_KeepData(b_sizet, (size_t)file.Size);
1001370b324cSopenharmony_ci    }
1002370b324cSopenharmony_ci    if (useMem)
1003370b324cSopenharmony_ci    {
1004370b324cSopenharmony_ci      memcpy(file.Data + file.Size, data, size);
1005370b324cSopenharmony_ci      file.Size += size;
1006370b324cSopenharmony_ci      if (processedSize)
1007370b324cSopenharmony_ci        *processedSize = (UInt32)size;
1008370b324cSopenharmony_ci      return S_OK;
1009370b324cSopenharmony_ci    }
1010370b324cSopenharmony_ci    _fileMode = true;
1011370b324cSopenharmony_ci  }
1012370b324cSopenharmony_ci  RINOK(FlushToDisk(false))
1013370b324cSopenharmony_ci  return _outFileStream->Write(data, size, processedSize);
1014370b324cSopenharmony_ci}
1015370b324cSopenharmony_ci
1016370b324cSopenharmony_ciHRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
1017370b324cSopenharmony_ci{
1018370b324cSopenharmony_ci  if (!_outFileStream)
1019370b324cSopenharmony_ci  {
1020370b324cSopenharmony_ci    _outFileStreamSpec = new COutFileStream;
1021370b324cSopenharmony_ci    _outFileStream = _outFileStreamSpec;
1022370b324cSopenharmony_ci  }
1023370b324cSopenharmony_ci  while (_numFlushed < Files.Size())
1024370b324cSopenharmony_ci  {
1025370b324cSopenharmony_ci    const CVirtFile &file = Files[_numFlushed];
1026370b324cSopenharmony_ci    const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name));
1027370b324cSopenharmony_ci    if (!_fileIsOpen)
1028370b324cSopenharmony_ci    {
1029370b324cSopenharmony_ci      if (!_outFileStreamSpec->Create(path, false))
1030370b324cSopenharmony_ci      {
1031370b324cSopenharmony_ci        _outFileStream.Release();
1032370b324cSopenharmony_ci        return E_FAIL;
1033370b324cSopenharmony_ci        // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath));
1034370b324cSopenharmony_ci      }
1035370b324cSopenharmony_ci      _fileIsOpen = true;
1036370b324cSopenharmony_ci      RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size))
1037370b324cSopenharmony_ci    }
1038370b324cSopenharmony_ci    if (_numFlushed == Files.Size() - 1 && !closeLast)
1039370b324cSopenharmony_ci      break;
1040370b324cSopenharmony_ci    if (file.CTimeDefined ||
1041370b324cSopenharmony_ci        file.ATimeDefined ||
1042370b324cSopenharmony_ci        file.MTimeDefined)
1043370b324cSopenharmony_ci      _outFileStreamSpec->SetTime(
1044370b324cSopenharmony_ci          file.CTimeDefined ? &file.CTime : NULL,
1045370b324cSopenharmony_ci          file.ATimeDefined ? &file.ATime : NULL,
1046370b324cSopenharmony_ci          file.MTimeDefined ? &file.MTime : NULL);
1047370b324cSopenharmony_ci    _outFileStreamSpec->Close();
1048370b324cSopenharmony_ci    _numFlushed++;
1049370b324cSopenharmony_ci    _fileIsOpen = false;
1050370b324cSopenharmony_ci    if (file.AttribDefined)
1051370b324cSopenharmony_ci      NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib);
1052370b324cSopenharmony_ci  }
1053370b324cSopenharmony_ci  return S_OK;
1054370b324cSopenharmony_ci}
1055370b324cSopenharmony_ci
1056370b324cSopenharmony_ci#endif
1057