xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // ExtractCallback.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Lang.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/ErrorMsg.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileFind.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariantConv.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FilePathAutoRename.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
17*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ExtractingFilePath.h"
18*f6dc9357SAndroid Build Coastguard Worker 
19*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
20*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ZipRegistry.h"
21*f6dc9357SAndroid Build Coastguard Worker #endif
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker #include "../GUI/ExtractRes.h"
24*f6dc9357SAndroid Build Coastguard Worker #include "resourceGui.h"
25*f6dc9357SAndroid Build Coastguard Worker 
26*f6dc9357SAndroid Build Coastguard Worker #include "ExtractCallback.h"
27*f6dc9357SAndroid Build Coastguard Worker #include "FormatUtils.h"
28*f6dc9357SAndroid Build Coastguard Worker #include "LangUtils.h"
29*f6dc9357SAndroid Build Coastguard Worker #include "MemDialog.h"
30*f6dc9357SAndroid Build Coastguard Worker #include "OverwriteDialog.h"
31*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
32*f6dc9357SAndroid Build Coastguard Worker #include "PasswordDialog.h"
33*f6dc9357SAndroid Build Coastguard Worker #endif
34*f6dc9357SAndroid Build Coastguard Worker #include "PropertyName.h"
35*f6dc9357SAndroid Build Coastguard Worker 
36*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
37*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
38*f6dc9357SAndroid Build Coastguard Worker using namespace NFind;
39*f6dc9357SAndroid Build Coastguard Worker 
40*f6dc9357SAndroid Build Coastguard Worker extern bool g_DisableUserQuestions;
41*f6dc9357SAndroid Build Coastguard Worker 
~CExtractCallbackImp()42*f6dc9357SAndroid Build Coastguard Worker CExtractCallbackImp::~CExtractCallbackImp() {}
43*f6dc9357SAndroid Build Coastguard Worker 
Init()44*f6dc9357SAndroid Build Coastguard Worker void CExtractCallbackImp::Init()
45*f6dc9357SAndroid Build Coastguard Worker {
46*f6dc9357SAndroid Build Coastguard Worker   LangString(IDS_PROGRESS_EXTRACTING, _lang_Extracting);
47*f6dc9357SAndroid Build Coastguard Worker   LangString(IDS_PROGRESS_TESTING, _lang_Testing);
48*f6dc9357SAndroid Build Coastguard Worker   LangString(IDS_PROGRESS_SKIPPING, _lang_Skipping);
49*f6dc9357SAndroid Build Coastguard Worker   _lang_Reading = "Reading";
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker   NumArchiveErrors = 0;
52*f6dc9357SAndroid Build Coastguard Worker   ThereAreMessageErrors = false;
53*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
54*f6dc9357SAndroid Build Coastguard Worker   NumFolders = NumFiles = 0;
55*f6dc9357SAndroid Build Coastguard Worker   NeedAddFile = false;
56*f6dc9357SAndroid Build Coastguard Worker   #endif
57*f6dc9357SAndroid Build Coastguard Worker }
58*f6dc9357SAndroid Build Coastguard Worker 
AddError_Message(LPCWSTR s)59*f6dc9357SAndroid Build Coastguard Worker void CExtractCallbackImp::AddError_Message(LPCWSTR s)
60*f6dc9357SAndroid Build Coastguard Worker {
61*f6dc9357SAndroid Build Coastguard Worker   ThereAreMessageErrors = true;
62*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.AddError_Message(s);
63*f6dc9357SAndroid Build Coastguard Worker }
64*f6dc9357SAndroid Build Coastguard Worker 
AddError_Message_ShowArcPath(LPCWSTR s)65*f6dc9357SAndroid Build Coastguard Worker void CExtractCallbackImp::AddError_Message_ShowArcPath(LPCWSTR s)
66*f6dc9357SAndroid Build Coastguard Worker {
67*f6dc9357SAndroid Build Coastguard Worker   Add_ArchiveName_Error();
68*f6dc9357SAndroid Build Coastguard Worker   AddError_Message(s);
69*f6dc9357SAndroid Build Coastguard Worker }
70*f6dc9357SAndroid Build Coastguard Worker 
71*f6dc9357SAndroid Build Coastguard Worker 
72*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
73*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetNumFiles (UInt64 numFiles))74*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetNumFiles(UInt64 numFiles))
75*f6dc9357SAndroid Build Coastguard Worker {
76*f6dc9357SAndroid Build Coastguard Worker  #ifdef Z7_SFX
77*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(numFiles)
78*f6dc9357SAndroid Build Coastguard Worker  #else
79*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.Set_NumFilesTotal(numFiles);
80*f6dc9357SAndroid Build Coastguard Worker  #endif
81*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
82*f6dc9357SAndroid Build Coastguard Worker }
83*f6dc9357SAndroid Build Coastguard Worker 
84*f6dc9357SAndroid Build Coastguard Worker #endif
85*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetTotal (UInt64 total))86*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 total))
87*f6dc9357SAndroid Build Coastguard Worker {
88*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.Set_NumBytesTotal(total);
89*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
90*f6dc9357SAndroid Build Coastguard Worker }
91*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted (const UInt64 * value))92*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *value))
93*f6dc9357SAndroid Build Coastguard Worker {
94*f6dc9357SAndroid Build Coastguard Worker   return ProgressDialog->Sync.Set_NumBytesCur(value);
95*f6dc9357SAndroid Build Coastguard Worker }
96*f6dc9357SAndroid Build Coastguard Worker 
Open_CheckBreak()97*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_CheckBreak()
98*f6dc9357SAndroid Build Coastguard Worker {
99*f6dc9357SAndroid Build Coastguard Worker   return ProgressDialog->Sync.CheckStop();
100*f6dc9357SAndroid Build Coastguard Worker }
101*f6dc9357SAndroid Build Coastguard Worker 
Open_SetTotal(const UInt64 * files,const UInt64 * bytes)102*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *bytes)
103*f6dc9357SAndroid Build Coastguard Worker {
104*f6dc9357SAndroid Build Coastguard Worker   HRESULT res = S_OK;
105*f6dc9357SAndroid Build Coastguard Worker   if (!MultiArcMode)
106*f6dc9357SAndroid Build Coastguard Worker   {
107*f6dc9357SAndroid Build Coastguard Worker     if (files)
108*f6dc9357SAndroid Build Coastguard Worker     {
109*f6dc9357SAndroid Build Coastguard Worker       _totalFiles_Defined = true;
110*f6dc9357SAndroid Build Coastguard Worker       // res = ProgressDialog->Sync.Set_NumFilesTotal(*files);
111*f6dc9357SAndroid Build Coastguard Worker     }
112*f6dc9357SAndroid Build Coastguard Worker     else
113*f6dc9357SAndroid Build Coastguard Worker       _totalFiles_Defined = false;
114*f6dc9357SAndroid Build Coastguard Worker 
115*f6dc9357SAndroid Build Coastguard Worker     if (bytes)
116*f6dc9357SAndroid Build Coastguard Worker     {
117*f6dc9357SAndroid Build Coastguard Worker       _totalBytes_Defined = true;
118*f6dc9357SAndroid Build Coastguard Worker       ProgressDialog->Sync.Set_NumBytesTotal(*bytes);
119*f6dc9357SAndroid Build Coastguard Worker     }
120*f6dc9357SAndroid Build Coastguard Worker     else
121*f6dc9357SAndroid Build Coastguard Worker       _totalBytes_Defined = false;
122*f6dc9357SAndroid Build Coastguard Worker   }
123*f6dc9357SAndroid Build Coastguard Worker 
124*f6dc9357SAndroid Build Coastguard Worker   return res;
125*f6dc9357SAndroid Build Coastguard Worker }
126*f6dc9357SAndroid Build Coastguard Worker 
Open_SetCompleted(const UInt64 * files,const UInt64 * bytes)127*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes)
128*f6dc9357SAndroid Build Coastguard Worker {
129*f6dc9357SAndroid Build Coastguard Worker   if (!MultiArcMode)
130*f6dc9357SAndroid Build Coastguard Worker   {
131*f6dc9357SAndroid Build Coastguard Worker     if (files)
132*f6dc9357SAndroid Build Coastguard Worker     {
133*f6dc9357SAndroid Build Coastguard Worker       ProgressDialog->Sync.Set_NumFilesCur(*files);
134*f6dc9357SAndroid Build Coastguard Worker     }
135*f6dc9357SAndroid Build Coastguard Worker 
136*f6dc9357SAndroid Build Coastguard Worker     if (bytes)
137*f6dc9357SAndroid Build Coastguard Worker     {
138*f6dc9357SAndroid Build Coastguard Worker     }
139*f6dc9357SAndroid Build Coastguard Worker   }
140*f6dc9357SAndroid Build Coastguard Worker 
141*f6dc9357SAndroid Build Coastguard Worker   return ProgressDialog->Sync.CheckStop();
142*f6dc9357SAndroid Build Coastguard Worker }
143*f6dc9357SAndroid Build Coastguard Worker 
Open_Finished()144*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_Finished()
145*f6dc9357SAndroid Build Coastguard Worker {
146*f6dc9357SAndroid Build Coastguard Worker   return ProgressDialog->Sync.CheckStop();
147*f6dc9357SAndroid Build Coastguard Worker }
148*f6dc9357SAndroid Build Coastguard Worker 
149*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
150*f6dc9357SAndroid Build Coastguard Worker 
Open_CryptoGetTextPassword(BSTR * password)151*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password)
152*f6dc9357SAndroid Build Coastguard Worker {
153*f6dc9357SAndroid Build Coastguard Worker   return CryptoGetTextPassword(password);
154*f6dc9357SAndroid Build Coastguard Worker }
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker /*
157*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password)
158*f6dc9357SAndroid Build Coastguard Worker {
159*f6dc9357SAndroid Build Coastguard Worker   passwordIsDefined = PasswordIsDefined;
160*f6dc9357SAndroid Build Coastguard Worker   password = Password;
161*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
162*f6dc9357SAndroid Build Coastguard Worker }
163*f6dc9357SAndroid Build Coastguard Worker 
164*f6dc9357SAndroid Build Coastguard Worker bool CExtractCallbackImp::Open_WasPasswordAsked()
165*f6dc9357SAndroid Build Coastguard Worker {
166*f6dc9357SAndroid Build Coastguard Worker   return PasswordWasAsked;
167*f6dc9357SAndroid Build Coastguard Worker }
168*f6dc9357SAndroid Build Coastguard Worker 
169*f6dc9357SAndroid Build Coastguard Worker void CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag()
170*f6dc9357SAndroid Build Coastguard Worker {
171*f6dc9357SAndroid Build Coastguard Worker   PasswordWasAsked = false;
172*f6dc9357SAndroid Build Coastguard Worker }
173*f6dc9357SAndroid Build Coastguard Worker */
174*f6dc9357SAndroid Build Coastguard Worker 
175*f6dc9357SAndroid Build Coastguard Worker #endif
176*f6dc9357SAndroid Build Coastguard Worker 
177*f6dc9357SAndroid Build Coastguard Worker 
178*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
Z7_COM7F_IMF(CExtractCallbackImp::SetRatioInfo (const UInt64 * inSize,const UInt64 * outSize))179*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
180*f6dc9357SAndroid Build Coastguard Worker {
181*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.Set_Ratio(inSize, outSize);
182*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
183*f6dc9357SAndroid Build Coastguard Worker }
184*f6dc9357SAndroid Build Coastguard Worker #endif
185*f6dc9357SAndroid Build Coastguard Worker 
186*f6dc9357SAndroid Build Coastguard Worker /*
187*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetTotalFiles(UInt64 total)
188*f6dc9357SAndroid Build Coastguard Worker {
189*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.SetNumFilesTotal(total);
190*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
191*f6dc9357SAndroid Build Coastguard Worker }
192*f6dc9357SAndroid Build Coastguard Worker 
193*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetCompletedFiles(const UInt64 *value)
194*f6dc9357SAndroid Build Coastguard Worker {
195*f6dc9357SAndroid Build Coastguard Worker   if (value != NULL)
196*f6dc9357SAndroid Build Coastguard Worker     ProgressDialog->Sync.SetNumFilesCur(*value);
197*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
198*f6dc9357SAndroid Build Coastguard Worker }
199*f6dc9357SAndroid Build Coastguard Worker */
200*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite (const wchar_t * existName,const FILETIME * existTime,const UInt64 * existSize,const wchar_t * newName,const FILETIME * newTime,const UInt64 * newSize,Int32 * answer))201*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite(
202*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
203*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
204*f6dc9357SAndroid Build Coastguard Worker     Int32 *answer))
205*f6dc9357SAndroid Build Coastguard Worker {
206*f6dc9357SAndroid Build Coastguard Worker   COverwriteDialog dialog;
207*f6dc9357SAndroid Build Coastguard Worker 
208*f6dc9357SAndroid Build Coastguard Worker   dialog.OldFileInfo.SetTime2(existTime);
209*f6dc9357SAndroid Build Coastguard Worker   dialog.OldFileInfo.SetSize2(existSize);
210*f6dc9357SAndroid Build Coastguard Worker   dialog.OldFileInfo.Path = existName;
211*f6dc9357SAndroid Build Coastguard Worker   dialog.OldFileInfo.Is_FileSystemFile = true;
212*f6dc9357SAndroid Build Coastguard Worker 
213*f6dc9357SAndroid Build Coastguard Worker   dialog.NewFileInfo.SetTime2(newTime);
214*f6dc9357SAndroid Build Coastguard Worker   dialog.NewFileInfo.SetSize2(newSize);
215*f6dc9357SAndroid Build Coastguard Worker   dialog.NewFileInfo.Path = newName;
216*f6dc9357SAndroid Build Coastguard Worker   dialog.NewFileInfo.Is_FileSystemFile = Src_Is_IO_FS_Folder;
217*f6dc9357SAndroid Build Coastguard Worker 
218*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->WaitCreating();
219*f6dc9357SAndroid Build Coastguard Worker   const INT_PTR writeAnswer = dialog.Create(*ProgressDialog);
220*f6dc9357SAndroid Build Coastguard Worker 
221*f6dc9357SAndroid Build Coastguard Worker   switch (writeAnswer)
222*f6dc9357SAndroid Build Coastguard Worker   {
223*f6dc9357SAndroid Build Coastguard Worker     case IDCANCEL:        *answer = NOverwriteAnswer::kCancel; return E_ABORT;
224*f6dc9357SAndroid Build Coastguard Worker     case IDYES:           *answer = NOverwriteAnswer::kYes; break;
225*f6dc9357SAndroid Build Coastguard Worker     case IDNO:            *answer = NOverwriteAnswer::kNo; break;
226*f6dc9357SAndroid Build Coastguard Worker     case IDB_YES_TO_ALL:  *answer = NOverwriteAnswer::kYesToAll; break;
227*f6dc9357SAndroid Build Coastguard Worker     case IDB_NO_TO_ALL:   *answer = NOverwriteAnswer::kNoToAll; break;
228*f6dc9357SAndroid Build Coastguard Worker     case IDB_AUTO_RENAME: *answer = NOverwriteAnswer::kAutoRename; break;
229*f6dc9357SAndroid Build Coastguard Worker     default: return E_FAIL;
230*f6dc9357SAndroid Build Coastguard Worker   }
231*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
232*f6dc9357SAndroid Build Coastguard Worker }
233*f6dc9357SAndroid Build Coastguard Worker 
234*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation (const wchar_t * name,Int32 isFolder,Int32 askExtractMode,const UInt64 *))235*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */))
236*f6dc9357SAndroid Build Coastguard Worker {
237*f6dc9357SAndroid Build Coastguard Worker   _isFolder = IntToBool(isFolder);
238*f6dc9357SAndroid Build Coastguard Worker   _currentFilePath = name;
239*f6dc9357SAndroid Build Coastguard Worker 
240*f6dc9357SAndroid Build Coastguard Worker   const UString *msg = &_lang_Empty;
241*f6dc9357SAndroid Build Coastguard Worker   switch (askExtractMode)
242*f6dc9357SAndroid Build Coastguard Worker   {
243*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break;
244*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kTest:    msg = &_lang_Testing; break;
245*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kSkip:    msg = &_lang_Skipping; break;
246*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kReadExternal: msg = &_lang_Reading; break;
247*f6dc9357SAndroid Build Coastguard Worker     // default: s = "Unknown operation";
248*f6dc9357SAndroid Build Coastguard Worker   }
249*f6dc9357SAndroid Build Coastguard Worker 
250*f6dc9357SAndroid Build Coastguard Worker   return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder));
251*f6dc9357SAndroid Build Coastguard Worker }
252*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::MessageError (const wchar_t * s))253*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::MessageError(const wchar_t *s))
254*f6dc9357SAndroid Build Coastguard Worker {
255*f6dc9357SAndroid Build Coastguard Worker   AddError_Message(s);
256*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
257*f6dc9357SAndroid Build Coastguard Worker }
258*f6dc9357SAndroid Build Coastguard Worker 
MessageError(const char * message,const FString & path)259*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::MessageError(const char *message, const FString &path)
260*f6dc9357SAndroid Build Coastguard Worker {
261*f6dc9357SAndroid Build Coastguard Worker   ThereAreMessageErrors = true;
262*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.AddError_Message_Name(GetUnicodeString(message), fs2us(path));
263*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
264*f6dc9357SAndroid Build Coastguard Worker }
265*f6dc9357SAndroid Build Coastguard Worker 
266*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
267*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::ShowMessage (const wchar_t * s))268*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::ShowMessage(const wchar_t *s))
269*f6dc9357SAndroid Build Coastguard Worker {
270*f6dc9357SAndroid Build Coastguard Worker   AddError_Message(s);
271*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
272*f6dc9357SAndroid Build Coastguard Worker }
273*f6dc9357SAndroid Build Coastguard Worker 
274*f6dc9357SAndroid Build Coastguard Worker #endif
275*f6dc9357SAndroid Build Coastguard Worker 
276*f6dc9357SAndroid Build Coastguard Worker void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s);
SetExtractErrorMessage(Int32 opRes,Int32 encrypted,const wchar_t * fileName,UString & s)277*f6dc9357SAndroid Build Coastguard Worker void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s)
278*f6dc9357SAndroid Build Coastguard Worker {
279*f6dc9357SAndroid Build Coastguard Worker   s.Empty();
280*f6dc9357SAndroid Build Coastguard Worker 
281*f6dc9357SAndroid Build Coastguard Worker   if (opRes == NArchive::NExtract::NOperationResult::kOK)
282*f6dc9357SAndroid Build Coastguard Worker     return;
283*f6dc9357SAndroid Build Coastguard Worker 
284*f6dc9357SAndroid Build Coastguard Worker  #ifndef Z7_SFX
285*f6dc9357SAndroid Build Coastguard Worker   UINT messageID = 0;
286*f6dc9357SAndroid Build Coastguard Worker  #endif
287*f6dc9357SAndroid Build Coastguard Worker   UINT id = 0;
288*f6dc9357SAndroid Build Coastguard Worker 
289*f6dc9357SAndroid Build Coastguard Worker   switch (opRes)
290*f6dc9357SAndroid Build Coastguard Worker   {
291*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
292*f6dc9357SAndroid Build Coastguard Worker      #ifndef Z7_SFX
293*f6dc9357SAndroid Build Coastguard Worker       messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
294*f6dc9357SAndroid Build Coastguard Worker      #endif
295*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD;
296*f6dc9357SAndroid Build Coastguard Worker       break;
297*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kDataError:
298*f6dc9357SAndroid Build Coastguard Worker      #ifndef Z7_SFX
299*f6dc9357SAndroid Build Coastguard Worker       messageID = encrypted ?
300*f6dc9357SAndroid Build Coastguard Worker           IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED:
301*f6dc9357SAndroid Build Coastguard Worker           IDS_EXTRACT_MESSAGE_DATA_ERROR;
302*f6dc9357SAndroid Build Coastguard Worker      #endif
303*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_DATA_ERROR;
304*f6dc9357SAndroid Build Coastguard Worker       break;
305*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kCRCError:
306*f6dc9357SAndroid Build Coastguard Worker      #ifndef Z7_SFX
307*f6dc9357SAndroid Build Coastguard Worker       messageID = encrypted ?
308*f6dc9357SAndroid Build Coastguard Worker           IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED:
309*f6dc9357SAndroid Build Coastguard Worker           IDS_EXTRACT_MESSAGE_CRC_ERROR;
310*f6dc9357SAndroid Build Coastguard Worker      #endif
311*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_CRC_ERROR;
312*f6dc9357SAndroid Build Coastguard Worker       break;
313*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kUnavailable:
314*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA;
315*f6dc9357SAndroid Build Coastguard Worker       break;
316*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
317*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_UEXPECTED_END;
318*f6dc9357SAndroid Build Coastguard Worker       break;
319*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kDataAfterEnd:
320*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_DATA_AFTER_END;
321*f6dc9357SAndroid Build Coastguard Worker       break;
322*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kIsNotArc:
323*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_IS_NOT_ARC;
324*f6dc9357SAndroid Build Coastguard Worker       break;
325*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kHeadersError:
326*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_HEADERS_ERROR;
327*f6dc9357SAndroid Build Coastguard Worker       break;
328*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kWrongPassword:
329*f6dc9357SAndroid Build Coastguard Worker       id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM;
330*f6dc9357SAndroid Build Coastguard Worker       break;
331*f6dc9357SAndroid Build Coastguard Worker     /*
332*f6dc9357SAndroid Build Coastguard Worker     default:
333*f6dc9357SAndroid Build Coastguard Worker       messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR;
334*f6dc9357SAndroid Build Coastguard Worker       break;
335*f6dc9357SAndroid Build Coastguard Worker     */
336*f6dc9357SAndroid Build Coastguard Worker   }
337*f6dc9357SAndroid Build Coastguard Worker 
338*f6dc9357SAndroid Build Coastguard Worker   UString msg;
339*f6dc9357SAndroid Build Coastguard Worker 
340*f6dc9357SAndroid Build Coastguard Worker  #ifndef Z7_SFX
341*f6dc9357SAndroid Build Coastguard Worker   UString msgOld;
342*f6dc9357SAndroid Build Coastguard Worker  #ifdef Z7_LANG
343*f6dc9357SAndroid Build Coastguard Worker   if (id != 0)
344*f6dc9357SAndroid Build Coastguard Worker     LangString_OnlyFromLangFile(id, msg);
345*f6dc9357SAndroid Build Coastguard Worker   if (messageID != 0 && msg.IsEmpty())
346*f6dc9357SAndroid Build Coastguard Worker     LangString_OnlyFromLangFile(messageID, msgOld);
347*f6dc9357SAndroid Build Coastguard Worker  #endif
348*f6dc9357SAndroid Build Coastguard Worker   if (msg.IsEmpty() && !msgOld.IsEmpty())
349*f6dc9357SAndroid Build Coastguard Worker     s = MyFormatNew(msgOld, fileName);
350*f6dc9357SAndroid Build Coastguard Worker   else
351*f6dc9357SAndroid Build Coastguard Worker  #endif
352*f6dc9357SAndroid Build Coastguard Worker   {
353*f6dc9357SAndroid Build Coastguard Worker     if (msg.IsEmpty() && id != 0)
354*f6dc9357SAndroid Build Coastguard Worker       LangString(id, msg);
355*f6dc9357SAndroid Build Coastguard Worker     if (!msg.IsEmpty())
356*f6dc9357SAndroid Build Coastguard Worker       s += msg;
357*f6dc9357SAndroid Build Coastguard Worker     else
358*f6dc9357SAndroid Build Coastguard Worker     {
359*f6dc9357SAndroid Build Coastguard Worker       s += "Error #";
360*f6dc9357SAndroid Build Coastguard Worker       s.Add_UInt32((UInt32)opRes);
361*f6dc9357SAndroid Build Coastguard Worker     }
362*f6dc9357SAndroid Build Coastguard Worker 
363*f6dc9357SAndroid Build Coastguard Worker     if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword)
364*f6dc9357SAndroid Build Coastguard Worker     {
365*f6dc9357SAndroid Build Coastguard Worker       // s += " : ";
366*f6dc9357SAndroid Build Coastguard Worker       // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED);
367*f6dc9357SAndroid Build Coastguard Worker       s += " : ";
368*f6dc9357SAndroid Build Coastguard Worker       AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
369*f6dc9357SAndroid Build Coastguard Worker     }
370*f6dc9357SAndroid Build Coastguard Worker     s += " : ";
371*f6dc9357SAndroid Build Coastguard Worker     s += fileName;
372*f6dc9357SAndroid Build Coastguard Worker   }
373*f6dc9357SAndroid Build Coastguard Worker }
374*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult (Int32 opRes,Int32 encrypted))375*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted))
376*f6dc9357SAndroid Build Coastguard Worker {
377*f6dc9357SAndroid Build Coastguard Worker   switch (opRes)
378*f6dc9357SAndroid Build Coastguard Worker   {
379*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kOK:
380*f6dc9357SAndroid Build Coastguard Worker       break;
381*f6dc9357SAndroid Build Coastguard Worker     default:
382*f6dc9357SAndroid Build Coastguard Worker     {
383*f6dc9357SAndroid Build Coastguard Worker       UString s;
384*f6dc9357SAndroid Build Coastguard Worker       SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s);
385*f6dc9357SAndroid Build Coastguard Worker       AddError_Message_ShowArcPath(s);
386*f6dc9357SAndroid Build Coastguard Worker     }
387*f6dc9357SAndroid Build Coastguard Worker   }
388*f6dc9357SAndroid Build Coastguard Worker 
389*f6dc9357SAndroid Build Coastguard Worker   _currentFilePath.Empty();
390*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
391*f6dc9357SAndroid Build Coastguard Worker   if (_isFolder)
392*f6dc9357SAndroid Build Coastguard Worker     NumFolders++;
393*f6dc9357SAndroid Build Coastguard Worker   else
394*f6dc9357SAndroid Build Coastguard Worker     NumFiles++;
395*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.Set_NumFilesCur(NumFiles);
396*f6dc9357SAndroid Build Coastguard Worker   #endif
397*f6dc9357SAndroid Build Coastguard Worker 
398*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
399*f6dc9357SAndroid Build Coastguard Worker }
400*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult (Int32 opRes,Int32 encrypted,const wchar_t * name))401*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name))
402*f6dc9357SAndroid Build Coastguard Worker {
403*f6dc9357SAndroid Build Coastguard Worker   if (opRes != NArchive::NExtract::NOperationResult::kOK)
404*f6dc9357SAndroid Build Coastguard Worker   {
405*f6dc9357SAndroid Build Coastguard Worker     UString s;
406*f6dc9357SAndroid Build Coastguard Worker     SetExtractErrorMessage(opRes, encrypted, name, s);
407*f6dc9357SAndroid Build Coastguard Worker     AddError_Message_ShowArcPath(s);
408*f6dc9357SAndroid Build Coastguard Worker   }
409*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
410*f6dc9357SAndroid Build Coastguard Worker }
411*f6dc9357SAndroid Build Coastguard Worker 
412*f6dc9357SAndroid Build Coastguard Worker ////////////////////////////////////////
413*f6dc9357SAndroid Build Coastguard Worker // IExtractCallbackUI
414*f6dc9357SAndroid Build Coastguard Worker 
BeforeOpen(const wchar_t * name,bool)415*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */)
416*f6dc9357SAndroid Build Coastguard Worker {
417*f6dc9357SAndroid Build Coastguard Worker   _currentArchivePath = name;
418*f6dc9357SAndroid Build Coastguard Worker   _needWriteArchivePath = true;
419*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
420*f6dc9357SAndroid Build Coastguard Worker   RINOK(ProgressDialog->Sync.CheckStop())
421*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.Set_TitleFileName(name);
422*f6dc9357SAndroid Build Coastguard Worker   #endif
423*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
424*f6dc9357SAndroid Build Coastguard Worker }
425*f6dc9357SAndroid Build Coastguard Worker 
SetCurrentFilePath2(const wchar_t * path)426*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path)
427*f6dc9357SAndroid Build Coastguard Worker {
428*f6dc9357SAndroid Build Coastguard Worker   _currentFilePath = path;
429*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
430*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.Set_FilePath(path);
431*f6dc9357SAndroid Build Coastguard Worker   #endif
432*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
433*f6dc9357SAndroid Build Coastguard Worker }
434*f6dc9357SAndroid Build Coastguard Worker 
435*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
436*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetCurrentFilePath (const wchar_t * path))437*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path))
438*f6dc9357SAndroid Build Coastguard Worker {
439*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
440*f6dc9357SAndroid Build Coastguard Worker   if (NeedAddFile)
441*f6dc9357SAndroid Build Coastguard Worker     NumFiles++;
442*f6dc9357SAndroid Build Coastguard Worker   NeedAddFile = true;
443*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.Set_NumFilesCur(NumFiles);
444*f6dc9357SAndroid Build Coastguard Worker   #endif
445*f6dc9357SAndroid Build Coastguard Worker   return SetCurrentFilePath2(path);
446*f6dc9357SAndroid Build Coastguard Worker }
447*f6dc9357SAndroid Build Coastguard Worker 
448*f6dc9357SAndroid Build Coastguard Worker #endif
449*f6dc9357SAndroid Build Coastguard Worker 
450*f6dc9357SAndroid Build Coastguard Worker UString HResultToMessage(HRESULT errorCode);
451*f6dc9357SAndroid Build Coastguard Worker 
452*f6dc9357SAndroid Build Coastguard Worker static const UInt32 k_ErrorFlagsIds[] =
453*f6dc9357SAndroid Build Coastguard Worker {
454*f6dc9357SAndroid Build Coastguard Worker   IDS_EXTRACT_MSG_IS_NOT_ARC,
455*f6dc9357SAndroid Build Coastguard Worker   IDS_EXTRACT_MSG_HEADERS_ERROR,
456*f6dc9357SAndroid Build Coastguard Worker   IDS_EXTRACT_MSG_HEADERS_ERROR,
457*f6dc9357SAndroid Build Coastguard Worker   IDS_OPEN_MSG_UNAVAILABLE_START,
458*f6dc9357SAndroid Build Coastguard Worker   IDS_OPEN_MSG_UNCONFIRMED_START,
459*f6dc9357SAndroid Build Coastguard Worker   IDS_EXTRACT_MSG_UEXPECTED_END,
460*f6dc9357SAndroid Build Coastguard Worker   IDS_EXTRACT_MSG_DATA_AFTER_END,
461*f6dc9357SAndroid Build Coastguard Worker   IDS_EXTRACT_MSG_UNSUPPORTED_METHOD,
462*f6dc9357SAndroid Build Coastguard Worker   IDS_OPEN_MSG_UNSUPPORTED_FEATURE,
463*f6dc9357SAndroid Build Coastguard Worker   IDS_EXTRACT_MSG_DATA_ERROR,
464*f6dc9357SAndroid Build Coastguard Worker   IDS_EXTRACT_MSG_CRC_ERROR
465*f6dc9357SAndroid Build Coastguard Worker };
466*f6dc9357SAndroid Build Coastguard Worker 
AddNewLineString(UString & s,const UString & m)467*f6dc9357SAndroid Build Coastguard Worker static void AddNewLineString(UString &s, const UString &m)
468*f6dc9357SAndroid Build Coastguard Worker {
469*f6dc9357SAndroid Build Coastguard Worker   s += m;
470*f6dc9357SAndroid Build Coastguard Worker   s.Add_LF();
471*f6dc9357SAndroid Build Coastguard Worker }
472*f6dc9357SAndroid Build Coastguard Worker 
473*f6dc9357SAndroid Build Coastguard Worker UString GetOpenArcErrorMessage(UInt32 errorFlags);
GetOpenArcErrorMessage(UInt32 errorFlags)474*f6dc9357SAndroid Build Coastguard Worker UString GetOpenArcErrorMessage(UInt32 errorFlags)
475*f6dc9357SAndroid Build Coastguard Worker {
476*f6dc9357SAndroid Build Coastguard Worker   UString s;
477*f6dc9357SAndroid Build Coastguard Worker 
478*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsIds); i++)
479*f6dc9357SAndroid Build Coastguard Worker   {
480*f6dc9357SAndroid Build Coastguard Worker     const UInt32 f = (UInt32)1 << i;
481*f6dc9357SAndroid Build Coastguard Worker     if ((errorFlags & f) == 0)
482*f6dc9357SAndroid Build Coastguard Worker       continue;
483*f6dc9357SAndroid Build Coastguard Worker     const UInt32 id = k_ErrorFlagsIds[i];
484*f6dc9357SAndroid Build Coastguard Worker     UString m = LangString(id);
485*f6dc9357SAndroid Build Coastguard Worker     if (m.IsEmpty())
486*f6dc9357SAndroid Build Coastguard Worker       continue;
487*f6dc9357SAndroid Build Coastguard Worker     if (f == kpv_ErrorFlags_EncryptedHeadersError)
488*f6dc9357SAndroid Build Coastguard Worker     {
489*f6dc9357SAndroid Build Coastguard Worker       m += " : ";
490*f6dc9357SAndroid Build Coastguard Worker       AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
491*f6dc9357SAndroid Build Coastguard Worker     }
492*f6dc9357SAndroid Build Coastguard Worker     if (!s.IsEmpty())
493*f6dc9357SAndroid Build Coastguard Worker       s.Add_LF();
494*f6dc9357SAndroid Build Coastguard Worker     s += m;
495*f6dc9357SAndroid Build Coastguard Worker     errorFlags &= ~f;
496*f6dc9357SAndroid Build Coastguard Worker   }
497*f6dc9357SAndroid Build Coastguard Worker 
498*f6dc9357SAndroid Build Coastguard Worker   if (errorFlags != 0)
499*f6dc9357SAndroid Build Coastguard Worker   {
500*f6dc9357SAndroid Build Coastguard Worker     char sz[16];
501*f6dc9357SAndroid Build Coastguard Worker     sz[0] = '0';
502*f6dc9357SAndroid Build Coastguard Worker     sz[1] = 'x';
503*f6dc9357SAndroid Build Coastguard Worker     ConvertUInt32ToHex(errorFlags, sz + 2);
504*f6dc9357SAndroid Build Coastguard Worker     if (!s.IsEmpty())
505*f6dc9357SAndroid Build Coastguard Worker       s.Add_LF();
506*f6dc9357SAndroid Build Coastguard Worker     s += sz;
507*f6dc9357SAndroid Build Coastguard Worker   }
508*f6dc9357SAndroid Build Coastguard Worker 
509*f6dc9357SAndroid Build Coastguard Worker   return s;
510*f6dc9357SAndroid Build Coastguard Worker }
511*f6dc9357SAndroid Build Coastguard Worker 
ErrorInfo_Print(UString & s,const CArcErrorInfo & er)512*f6dc9357SAndroid Build Coastguard Worker static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
513*f6dc9357SAndroid Build Coastguard Worker {
514*f6dc9357SAndroid Build Coastguard Worker   const UInt32 errorFlags = er.GetErrorFlags();
515*f6dc9357SAndroid Build Coastguard Worker   const UInt32 warningFlags = er.GetWarningFlags();
516*f6dc9357SAndroid Build Coastguard Worker 
517*f6dc9357SAndroid Build Coastguard Worker   if (errorFlags != 0)
518*f6dc9357SAndroid Build Coastguard Worker     AddNewLineString(s, GetOpenArcErrorMessage(errorFlags));
519*f6dc9357SAndroid Build Coastguard Worker 
520*f6dc9357SAndroid Build Coastguard Worker   if (!er.ErrorMessage.IsEmpty())
521*f6dc9357SAndroid Build Coastguard Worker     AddNewLineString(s, er.ErrorMessage);
522*f6dc9357SAndroid Build Coastguard Worker 
523*f6dc9357SAndroid Build Coastguard Worker   if (warningFlags != 0)
524*f6dc9357SAndroid Build Coastguard Worker   {
525*f6dc9357SAndroid Build Coastguard Worker     s += GetNameOfProperty(kpidWarningFlags, L"Warnings");
526*f6dc9357SAndroid Build Coastguard Worker     s.Add_Colon();
527*f6dc9357SAndroid Build Coastguard Worker     s.Add_LF();
528*f6dc9357SAndroid Build Coastguard Worker     AddNewLineString(s, GetOpenArcErrorMessage(warningFlags));
529*f6dc9357SAndroid Build Coastguard Worker   }
530*f6dc9357SAndroid Build Coastguard Worker 
531*f6dc9357SAndroid Build Coastguard Worker   if (!er.WarningMessage.IsEmpty())
532*f6dc9357SAndroid Build Coastguard Worker   {
533*f6dc9357SAndroid Build Coastguard Worker     s += GetNameOfProperty(kpidWarning, L"Warning");
534*f6dc9357SAndroid Build Coastguard Worker     s += ": ";
535*f6dc9357SAndroid Build Coastguard Worker     s += er.WarningMessage;
536*f6dc9357SAndroid Build Coastguard Worker     s.Add_LF();
537*f6dc9357SAndroid Build Coastguard Worker   }
538*f6dc9357SAndroid Build Coastguard Worker }
539*f6dc9357SAndroid Build Coastguard Worker 
GetBracedType(const wchar_t * type)540*f6dc9357SAndroid Build Coastguard Worker static UString GetBracedType(const wchar_t *type)
541*f6dc9357SAndroid Build Coastguard Worker {
542*f6dc9357SAndroid Build Coastguard Worker   UString s ('[');
543*f6dc9357SAndroid Build Coastguard Worker   s += type;
544*f6dc9357SAndroid Build Coastguard Worker   s.Add_Char(']');
545*f6dc9357SAndroid Build Coastguard Worker   return s;
546*f6dc9357SAndroid Build Coastguard Worker }
547*f6dc9357SAndroid Build Coastguard Worker 
548*f6dc9357SAndroid Build Coastguard Worker void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result);
OpenResult_GUI(UString & s,const CCodecs * codecs,const CArchiveLink & arcLink,const wchar_t * name,HRESULT result)549*f6dc9357SAndroid Build Coastguard Worker void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
550*f6dc9357SAndroid Build Coastguard Worker {
551*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (level, arcLink.Arcs)
552*f6dc9357SAndroid Build Coastguard Worker   {
553*f6dc9357SAndroid Build Coastguard Worker     const CArc &arc = arcLink.Arcs[level];
554*f6dc9357SAndroid Build Coastguard Worker     const CArcErrorInfo &er = arc.ErrorInfo;
555*f6dc9357SAndroid Build Coastguard Worker 
556*f6dc9357SAndroid Build Coastguard Worker     if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0)
557*f6dc9357SAndroid Build Coastguard Worker       continue;
558*f6dc9357SAndroid Build Coastguard Worker 
559*f6dc9357SAndroid Build Coastguard Worker     if (s.IsEmpty())
560*f6dc9357SAndroid Build Coastguard Worker     {
561*f6dc9357SAndroid Build Coastguard Worker       s += name;
562*f6dc9357SAndroid Build Coastguard Worker       s.Add_LF();
563*f6dc9357SAndroid Build Coastguard Worker     }
564*f6dc9357SAndroid Build Coastguard Worker 
565*f6dc9357SAndroid Build Coastguard Worker     if (level != 0)
566*f6dc9357SAndroid Build Coastguard Worker     {
567*f6dc9357SAndroid Build Coastguard Worker       AddNewLineString(s, arc.Path);
568*f6dc9357SAndroid Build Coastguard Worker     }
569*f6dc9357SAndroid Build Coastguard Worker 
570*f6dc9357SAndroid Build Coastguard Worker     ErrorInfo_Print(s, er);
571*f6dc9357SAndroid Build Coastguard Worker 
572*f6dc9357SAndroid Build Coastguard Worker     if (er.ErrorFormatIndex >= 0)
573*f6dc9357SAndroid Build Coastguard Worker     {
574*f6dc9357SAndroid Build Coastguard Worker       AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning"));
575*f6dc9357SAndroid Build Coastguard Worker       if (arc.FormatIndex == er.ErrorFormatIndex)
576*f6dc9357SAndroid Build Coastguard Worker       {
577*f6dc9357SAndroid Build Coastguard Worker         AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET));
578*f6dc9357SAndroid Build Coastguard Worker       }
579*f6dc9357SAndroid Build Coastguard Worker       else
580*f6dc9357SAndroid Build Coastguard Worker       {
581*f6dc9357SAndroid Build Coastguard Worker         AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex))));
582*f6dc9357SAndroid Build Coastguard Worker         AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex))));
583*f6dc9357SAndroid Build Coastguard Worker       }
584*f6dc9357SAndroid Build Coastguard Worker     }
585*f6dc9357SAndroid Build Coastguard Worker   }
586*f6dc9357SAndroid Build Coastguard Worker 
587*f6dc9357SAndroid Build Coastguard Worker   if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK)
588*f6dc9357SAndroid Build Coastguard Worker   {
589*f6dc9357SAndroid Build Coastguard Worker     s += name;
590*f6dc9357SAndroid Build Coastguard Worker     s.Add_LF();
591*f6dc9357SAndroid Build Coastguard Worker     if (!arcLink.Arcs.IsEmpty())
592*f6dc9357SAndroid Build Coastguard Worker       AddNewLineString(s, arcLink.NonOpen_ArcPath);
593*f6dc9357SAndroid Build Coastguard Worker 
594*f6dc9357SAndroid Build Coastguard Worker     if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE)
595*f6dc9357SAndroid Build Coastguard Worker     {
596*f6dc9357SAndroid Build Coastguard Worker       UINT id = IDS_CANT_OPEN_ARCHIVE;
597*f6dc9357SAndroid Build Coastguard Worker       UString param;
598*f6dc9357SAndroid Build Coastguard Worker       if (arcLink.PasswordWasAsked)
599*f6dc9357SAndroid Build Coastguard Worker         id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE;
600*f6dc9357SAndroid Build Coastguard Worker       else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
601*f6dc9357SAndroid Build Coastguard Worker       {
602*f6dc9357SAndroid Build Coastguard Worker         id = IDS_CANT_OPEN_AS_TYPE;
603*f6dc9357SAndroid Build Coastguard Worker         param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex));
604*f6dc9357SAndroid Build Coastguard Worker       }
605*f6dc9357SAndroid Build Coastguard Worker       UString s2 = MyFormatNew(id, param);
606*f6dc9357SAndroid Build Coastguard Worker       s2.Replace(L" ''", L"");
607*f6dc9357SAndroid Build Coastguard Worker       s2.Replace(L"''", L"");
608*f6dc9357SAndroid Build Coastguard Worker       s += s2;
609*f6dc9357SAndroid Build Coastguard Worker     }
610*f6dc9357SAndroid Build Coastguard Worker     else
611*f6dc9357SAndroid Build Coastguard Worker       s += HResultToMessage(result);
612*f6dc9357SAndroid Build Coastguard Worker 
613*f6dc9357SAndroid Build Coastguard Worker     s.Add_LF();
614*f6dc9357SAndroid Build Coastguard Worker     ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo);
615*f6dc9357SAndroid Build Coastguard Worker   }
616*f6dc9357SAndroid Build Coastguard Worker 
617*f6dc9357SAndroid Build Coastguard Worker   if (!s.IsEmpty() && s.Back() == '\n')
618*f6dc9357SAndroid Build Coastguard Worker     s.DeleteBack();
619*f6dc9357SAndroid Build Coastguard Worker }
620*f6dc9357SAndroid Build Coastguard Worker 
OpenResult(const CCodecs * codecs,const CArchiveLink & arcLink,const wchar_t * name,HRESULT result)621*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
622*f6dc9357SAndroid Build Coastguard Worker {
623*f6dc9357SAndroid Build Coastguard Worker   _currentArchivePath = name;
624*f6dc9357SAndroid Build Coastguard Worker   _needWriteArchivePath = true;
625*f6dc9357SAndroid Build Coastguard Worker 
626*f6dc9357SAndroid Build Coastguard Worker   UString s;
627*f6dc9357SAndroid Build Coastguard Worker   OpenResult_GUI(s, codecs, arcLink, name, result);
628*f6dc9357SAndroid Build Coastguard Worker   if (!s.IsEmpty())
629*f6dc9357SAndroid Build Coastguard Worker   {
630*f6dc9357SAndroid Build Coastguard Worker     NumArchiveErrors++;
631*f6dc9357SAndroid Build Coastguard Worker     AddError_Message(s);
632*f6dc9357SAndroid Build Coastguard Worker     _needWriteArchivePath = false;
633*f6dc9357SAndroid Build Coastguard Worker   }
634*f6dc9357SAndroid Build Coastguard Worker 
635*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
636*f6dc9357SAndroid Build Coastguard Worker }
637*f6dc9357SAndroid Build Coastguard Worker 
ThereAreNoFiles()638*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::ThereAreNoFiles()
639*f6dc9357SAndroid Build Coastguard Worker {
640*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
641*f6dc9357SAndroid Build Coastguard Worker }
642*f6dc9357SAndroid Build Coastguard Worker 
Add_ArchiveName_Error()643*f6dc9357SAndroid Build Coastguard Worker void CExtractCallbackImp::Add_ArchiveName_Error()
644*f6dc9357SAndroid Build Coastguard Worker {
645*f6dc9357SAndroid Build Coastguard Worker   if (_needWriteArchivePath)
646*f6dc9357SAndroid Build Coastguard Worker   {
647*f6dc9357SAndroid Build Coastguard Worker     if (!_currentArchivePath.IsEmpty())
648*f6dc9357SAndroid Build Coastguard Worker       AddError_Message(_currentArchivePath);
649*f6dc9357SAndroid Build Coastguard Worker     _needWriteArchivePath = false;
650*f6dc9357SAndroid Build Coastguard Worker   }
651*f6dc9357SAndroid Build Coastguard Worker }
652*f6dc9357SAndroid Build Coastguard Worker 
ExtractResult(HRESULT result)653*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
654*f6dc9357SAndroid Build Coastguard Worker {
655*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
656*f6dc9357SAndroid Build Coastguard Worker   ProgressDialog->Sync.Set_FilePath(L"");
657*f6dc9357SAndroid Build Coastguard Worker   #endif
658*f6dc9357SAndroid Build Coastguard Worker 
659*f6dc9357SAndroid Build Coastguard Worker   if (result == S_OK)
660*f6dc9357SAndroid Build Coastguard Worker     return result;
661*f6dc9357SAndroid Build Coastguard Worker   NumArchiveErrors++;
662*f6dc9357SAndroid Build Coastguard Worker   if (result == E_ABORT
663*f6dc9357SAndroid Build Coastguard Worker       || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)
664*f6dc9357SAndroid Build Coastguard Worker       )
665*f6dc9357SAndroid Build Coastguard Worker     return result;
666*f6dc9357SAndroid Build Coastguard Worker 
667*f6dc9357SAndroid Build Coastguard Worker   Add_ArchiveName_Error();
668*f6dc9357SAndroid Build Coastguard Worker   if (!_currentFilePath.IsEmpty())
669*f6dc9357SAndroid Build Coastguard Worker     MessageError(_currentFilePath);
670*f6dc9357SAndroid Build Coastguard Worker   MessageError(NError::MyFormatMessage(result));
671*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
672*f6dc9357SAndroid Build Coastguard Worker }
673*f6dc9357SAndroid Build Coastguard Worker 
674*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
675*f6dc9357SAndroid Build Coastguard Worker 
SetPassword(const UString & password)676*f6dc9357SAndroid Build Coastguard Worker HRESULT CExtractCallbackImp::SetPassword(const UString &password)
677*f6dc9357SAndroid Build Coastguard Worker {
678*f6dc9357SAndroid Build Coastguard Worker   PasswordIsDefined = true;
679*f6dc9357SAndroid Build Coastguard Worker   Password = password;
680*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
681*f6dc9357SAndroid Build Coastguard Worker }
682*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword (BSTR * password))683*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword(BSTR *password))
684*f6dc9357SAndroid Build Coastguard Worker {
685*f6dc9357SAndroid Build Coastguard Worker   PasswordWasAsked = true;
686*f6dc9357SAndroid Build Coastguard Worker   if (!PasswordIsDefined)
687*f6dc9357SAndroid Build Coastguard Worker   {
688*f6dc9357SAndroid Build Coastguard Worker     CPasswordDialog dialog;
689*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_SFX
690*f6dc9357SAndroid Build Coastguard Worker     const bool showPassword = NExtract::Read_ShowPassword();
691*f6dc9357SAndroid Build Coastguard Worker     dialog.ShowPassword = showPassword;
692*f6dc9357SAndroid Build Coastguard Worker     #endif
693*f6dc9357SAndroid Build Coastguard Worker     ProgressDialog->WaitCreating();
694*f6dc9357SAndroid Build Coastguard Worker     if (dialog.Create(*ProgressDialog) != IDOK)
695*f6dc9357SAndroid Build Coastguard Worker       return E_ABORT;
696*f6dc9357SAndroid Build Coastguard Worker     Password = dialog.Password;
697*f6dc9357SAndroid Build Coastguard Worker     PasswordIsDefined = true;
698*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_SFX
699*f6dc9357SAndroid Build Coastguard Worker     if (dialog.ShowPassword != showPassword)
700*f6dc9357SAndroid Build Coastguard Worker       NExtract::Save_ShowPassword(dialog.ShowPassword);
701*f6dc9357SAndroid Build Coastguard Worker     #endif
702*f6dc9357SAndroid Build Coastguard Worker   }
703*f6dc9357SAndroid Build Coastguard Worker   return StringToBstr(Password, password);
704*f6dc9357SAndroid Build Coastguard Worker }
705*f6dc9357SAndroid Build Coastguard Worker 
706*f6dc9357SAndroid Build Coastguard Worker #endif
707*f6dc9357SAndroid Build Coastguard Worker 
708*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
709*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::AskWrite (const wchar_t * srcPath,Int32 srcIsFolder,const FILETIME * srcTime,const UInt64 * srcSize,const wchar_t * destPath,BSTR * destPathResult,Int32 * writeAnswer))710*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::AskWrite(
711*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *srcPath, Int32 srcIsFolder,
712*f6dc9357SAndroid Build Coastguard Worker     const FILETIME *srcTime, const UInt64 *srcSize,
713*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *destPath,
714*f6dc9357SAndroid Build Coastguard Worker     BSTR *destPathResult,
715*f6dc9357SAndroid Build Coastguard Worker     Int32 *writeAnswer))
716*f6dc9357SAndroid Build Coastguard Worker {
717*f6dc9357SAndroid Build Coastguard Worker   UString destPathResultTemp = destPath;
718*f6dc9357SAndroid Build Coastguard Worker 
719*f6dc9357SAndroid Build Coastguard Worker   // RINOK(StringToBstr(destPath, destPathResult));
720*f6dc9357SAndroid Build Coastguard Worker 
721*f6dc9357SAndroid Build Coastguard Worker   *destPathResult = NULL;
722*f6dc9357SAndroid Build Coastguard Worker   *writeAnswer = BoolToInt(false);
723*f6dc9357SAndroid Build Coastguard Worker 
724*f6dc9357SAndroid Build Coastguard Worker   FString destPathSys = us2fs(destPath);
725*f6dc9357SAndroid Build Coastguard Worker   const bool srcIsFolderSpec = IntToBool(srcIsFolder);
726*f6dc9357SAndroid Build Coastguard Worker   CFileInfo destFileInfo;
727*f6dc9357SAndroid Build Coastguard Worker 
728*f6dc9357SAndroid Build Coastguard Worker   if (destFileInfo.Find(destPathSys))
729*f6dc9357SAndroid Build Coastguard Worker   {
730*f6dc9357SAndroid Build Coastguard Worker     if (srcIsFolderSpec)
731*f6dc9357SAndroid Build Coastguard Worker     {
732*f6dc9357SAndroid Build Coastguard Worker       if (!destFileInfo.IsDir())
733*f6dc9357SAndroid Build Coastguard Worker       {
734*f6dc9357SAndroid Build Coastguard Worker         RINOK(MessageError("Cannot replace file with folder with same name", destPathSys))
735*f6dc9357SAndroid Build Coastguard Worker         return E_ABORT;
736*f6dc9357SAndroid Build Coastguard Worker       }
737*f6dc9357SAndroid Build Coastguard Worker       *writeAnswer = BoolToInt(false);
738*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
739*f6dc9357SAndroid Build Coastguard Worker     }
740*f6dc9357SAndroid Build Coastguard Worker 
741*f6dc9357SAndroid Build Coastguard Worker     if (destFileInfo.IsDir())
742*f6dc9357SAndroid Build Coastguard Worker     {
743*f6dc9357SAndroid Build Coastguard Worker       RINOK(MessageError("Cannot replace folder with file with same name", destPathSys))
744*f6dc9357SAndroid Build Coastguard Worker       *writeAnswer = BoolToInt(false);
745*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
746*f6dc9357SAndroid Build Coastguard Worker     }
747*f6dc9357SAndroid Build Coastguard Worker 
748*f6dc9357SAndroid Build Coastguard Worker     switch ((int)OverwriteMode)
749*f6dc9357SAndroid Build Coastguard Worker     {
750*f6dc9357SAndroid Build Coastguard Worker       case NExtract::NOverwriteMode::kSkip:
751*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
752*f6dc9357SAndroid Build Coastguard Worker       case NExtract::NOverwriteMode::kAsk:
753*f6dc9357SAndroid Build Coastguard Worker       {
754*f6dc9357SAndroid Build Coastguard Worker         Int32 overwriteResult;
755*f6dc9357SAndroid Build Coastguard Worker         UString destPathSpec = destPath;
756*f6dc9357SAndroid Build Coastguard Worker         const int slashPos = destPathSpec.ReverseFind_PathSepar();
757*f6dc9357SAndroid Build Coastguard Worker         destPathSpec.DeleteFrom((unsigned)(slashPos + 1));
758*f6dc9357SAndroid Build Coastguard Worker         destPathSpec += fs2us(destFileInfo.Name);
759*f6dc9357SAndroid Build Coastguard Worker 
760*f6dc9357SAndroid Build Coastguard Worker         RINOK(AskOverwrite(
761*f6dc9357SAndroid Build Coastguard Worker             destPathSpec,
762*f6dc9357SAndroid Build Coastguard Worker             &destFileInfo.MTime, &destFileInfo.Size,
763*f6dc9357SAndroid Build Coastguard Worker             srcPath,
764*f6dc9357SAndroid Build Coastguard Worker             srcTime, srcSize,
765*f6dc9357SAndroid Build Coastguard Worker             &overwriteResult))
766*f6dc9357SAndroid Build Coastguard Worker 
767*f6dc9357SAndroid Build Coastguard Worker         switch (overwriteResult)
768*f6dc9357SAndroid Build Coastguard Worker         {
769*f6dc9357SAndroid Build Coastguard Worker           case NOverwriteAnswer::kCancel: return E_ABORT;
770*f6dc9357SAndroid Build Coastguard Worker           case NOverwriteAnswer::kNo: return S_OK;
771*f6dc9357SAndroid Build Coastguard Worker           case NOverwriteAnswer::kNoToAll: OverwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK;
772*f6dc9357SAndroid Build Coastguard Worker           case NOverwriteAnswer::kYes: break;
773*f6dc9357SAndroid Build Coastguard Worker           case NOverwriteAnswer::kYesToAll: OverwriteMode = NExtract::NOverwriteMode::kOverwrite; break;
774*f6dc9357SAndroid Build Coastguard Worker           case NOverwriteAnswer::kAutoRename: OverwriteMode = NExtract::NOverwriteMode::kRename; break;
775*f6dc9357SAndroid Build Coastguard Worker           default:
776*f6dc9357SAndroid Build Coastguard Worker             return E_FAIL;
777*f6dc9357SAndroid Build Coastguard Worker         }
778*f6dc9357SAndroid Build Coastguard Worker         break;
779*f6dc9357SAndroid Build Coastguard Worker       }
780*f6dc9357SAndroid Build Coastguard Worker       default:
781*f6dc9357SAndroid Build Coastguard Worker         break;
782*f6dc9357SAndroid Build Coastguard Worker     }
783*f6dc9357SAndroid Build Coastguard Worker 
784*f6dc9357SAndroid Build Coastguard Worker     if (OverwriteMode == NExtract::NOverwriteMode::kRename)
785*f6dc9357SAndroid Build Coastguard Worker     {
786*f6dc9357SAndroid Build Coastguard Worker       if (!AutoRenamePath(destPathSys))
787*f6dc9357SAndroid Build Coastguard Worker       {
788*f6dc9357SAndroid Build Coastguard Worker         RINOK(MessageError("Cannot create name for file", destPathSys))
789*f6dc9357SAndroid Build Coastguard Worker         return E_ABORT;
790*f6dc9357SAndroid Build Coastguard Worker       }
791*f6dc9357SAndroid Build Coastguard Worker       destPathResultTemp = fs2us(destPathSys);
792*f6dc9357SAndroid Build Coastguard Worker     }
793*f6dc9357SAndroid Build Coastguard Worker     else
794*f6dc9357SAndroid Build Coastguard Worker     {
795*f6dc9357SAndroid Build Coastguard Worker       if (NFind::DoesFileExist_Raw(destPathSys))
796*f6dc9357SAndroid Build Coastguard Worker       if (!NDir::DeleteFileAlways(destPathSys))
797*f6dc9357SAndroid Build Coastguard Worker       if (GetLastError() != ERROR_FILE_NOT_FOUND)
798*f6dc9357SAndroid Build Coastguard Worker       {
799*f6dc9357SAndroid Build Coastguard Worker         RINOK(MessageError("Cannot delete output file", destPathSys))
800*f6dc9357SAndroid Build Coastguard Worker         return E_ABORT;
801*f6dc9357SAndroid Build Coastguard Worker       }
802*f6dc9357SAndroid Build Coastguard Worker     }
803*f6dc9357SAndroid Build Coastguard Worker   }
804*f6dc9357SAndroid Build Coastguard Worker   *writeAnswer = BoolToInt(true);
805*f6dc9357SAndroid Build Coastguard Worker   return StringToBstr(destPathResultTemp, destPathResult);
806*f6dc9357SAndroid Build Coastguard Worker }
807*f6dc9357SAndroid Build Coastguard Worker 
808*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::UseExtractToStream (Int32 * res))809*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::UseExtractToStream(Int32 *res))
810*f6dc9357SAndroid Build Coastguard Worker {
811*f6dc9357SAndroid Build Coastguard Worker   *res = BoolToInt(StreamMode);
812*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
813*f6dc9357SAndroid Build Coastguard Worker }
814*f6dc9357SAndroid Build Coastguard Worker 
GetTime(IGetProp * getProp,PROPID propID,FILETIME & ft,bool & ftDefined)815*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetTime(IGetProp *getProp, PROPID propID, FILETIME &ft, bool &ftDefined)
816*f6dc9357SAndroid Build Coastguard Worker {
817*f6dc9357SAndroid Build Coastguard Worker   ftDefined = false;
818*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
819*f6dc9357SAndroid Build Coastguard Worker   RINOK(getProp->GetProp(propID, &prop))
820*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_FILETIME)
821*f6dc9357SAndroid Build Coastguard Worker   {
822*f6dc9357SAndroid Build Coastguard Worker     ft = prop.filetime;
823*f6dc9357SAndroid Build Coastguard Worker     ftDefined = (ft.dwHighDateTime != 0 || ft.dwLowDateTime != 0);
824*f6dc9357SAndroid Build Coastguard Worker   }
825*f6dc9357SAndroid Build Coastguard Worker   else if (prop.vt != VT_EMPTY)
826*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
827*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
828*f6dc9357SAndroid Build Coastguard Worker }
829*f6dc9357SAndroid Build Coastguard Worker 
830*f6dc9357SAndroid Build Coastguard Worker 
GetItemBoolProp(IGetProp * getProp,PROPID propID,bool & result)831*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result)
832*f6dc9357SAndroid Build Coastguard Worker {
833*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
834*f6dc9357SAndroid Build Coastguard Worker   result = false;
835*f6dc9357SAndroid Build Coastguard Worker   RINOK(getProp->GetProp(propID, &prop))
836*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_BOOL)
837*f6dc9357SAndroid Build Coastguard Worker     result = VARIANT_BOOLToBool(prop.boolVal);
838*f6dc9357SAndroid Build Coastguard Worker   else if (prop.vt != VT_EMPTY)
839*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
840*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
841*f6dc9357SAndroid Build Coastguard Worker }
842*f6dc9357SAndroid Build Coastguard Worker 
843*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::GetStream7 (const wchar_t * name,Int32 isDir,ISequentialOutStream ** outStream,Int32 askExtractMode,IGetProp * getProp))844*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name,
845*f6dc9357SAndroid Build Coastguard Worker     Int32 isDir,
846*f6dc9357SAndroid Build Coastguard Worker     ISequentialOutStream **outStream, Int32 askExtractMode,
847*f6dc9357SAndroid Build Coastguard Worker     IGetProp *getProp))
848*f6dc9357SAndroid Build Coastguard Worker {
849*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
850*f6dc9357SAndroid Build Coastguard Worker   *outStream = NULL;
851*f6dc9357SAndroid Build Coastguard Worker   _newVirtFileWasAdded = false;
852*f6dc9357SAndroid Build Coastguard Worker   _hashStream_WasUsed = false;
853*f6dc9357SAndroid Build Coastguard Worker   _needUpdateStat = false;
854*f6dc9357SAndroid Build Coastguard Worker   _isFolder = IntToBool(isDir);
855*f6dc9357SAndroid Build Coastguard Worker   _curSize_Defined = false;
856*f6dc9357SAndroid Build Coastguard Worker   _curSize = 0;
857*f6dc9357SAndroid Build Coastguard Worker 
858*f6dc9357SAndroid Build Coastguard Worker   if (_hashStream)
859*f6dc9357SAndroid Build Coastguard Worker     _hashStream->ReleaseStream();
860*f6dc9357SAndroid Build Coastguard Worker 
861*f6dc9357SAndroid Build Coastguard Worker   _filePath = name;
862*f6dc9357SAndroid Build Coastguard Worker 
863*f6dc9357SAndroid Build Coastguard Worker   UInt64 size = 0;
864*f6dc9357SAndroid Build Coastguard Worker   bool size_Defined;
865*f6dc9357SAndroid Build Coastguard Worker   {
866*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
867*f6dc9357SAndroid Build Coastguard Worker     RINOK(getProp->GetProp(kpidSize, &prop))
868*f6dc9357SAndroid Build Coastguard Worker     size_Defined = ConvertPropVariantToUInt64(prop, size);
869*f6dc9357SAndroid Build Coastguard Worker   }
870*f6dc9357SAndroid Build Coastguard Worker   if (size_Defined)
871*f6dc9357SAndroid Build Coastguard Worker   {
872*f6dc9357SAndroid Build Coastguard Worker     _curSize = size;
873*f6dc9357SAndroid Build Coastguard Worker     _curSize_Defined = true;
874*f6dc9357SAndroid Build Coastguard Worker   }
875*f6dc9357SAndroid Build Coastguard Worker 
876*f6dc9357SAndroid Build Coastguard Worker   GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream);
877*f6dc9357SAndroid Build Coastguard Worker   if (!ProcessAltStreams && _isAltStream)
878*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
879*f6dc9357SAndroid Build Coastguard Worker 
880*f6dc9357SAndroid Build Coastguard Worker   if (isDir) // we don't support dir items extraction in this code
881*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
882*f6dc9357SAndroid Build Coastguard Worker 
883*f6dc9357SAndroid Build Coastguard Worker   if (askExtractMode != NArchive::NExtract::NAskMode::kExtract &&
884*f6dc9357SAndroid Build Coastguard Worker       askExtractMode != NArchive::NExtract::NAskMode::kTest)
885*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
886*f6dc9357SAndroid Build Coastguard Worker 
887*f6dc9357SAndroid Build Coastguard Worker   _needUpdateStat = true;
888*f6dc9357SAndroid Build Coastguard Worker 
889*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> outStreamLoc;
890*f6dc9357SAndroid Build Coastguard Worker 
891*f6dc9357SAndroid Build Coastguard Worker   if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract)
892*f6dc9357SAndroid Build Coastguard Worker   {
893*f6dc9357SAndroid Build Coastguard Worker     if (!VirtFileSystemSpec->Files.IsEmpty())
894*f6dc9357SAndroid Build Coastguard Worker       VirtFileSystemSpec->MaxTotalAllocSize -= VirtFileSystemSpec->Files.Back().Data.Size();
895*f6dc9357SAndroid Build Coastguard Worker     CVirtFile &file = VirtFileSystemSpec->Files.AddNew();
896*f6dc9357SAndroid Build Coastguard Worker     _newVirtFileWasAdded = true;
897*f6dc9357SAndroid Build Coastguard Worker     // file.IsDir = _isFolder;
898*f6dc9357SAndroid Build Coastguard Worker     file.IsAltStream = _isAltStream;
899*f6dc9357SAndroid Build Coastguard Worker     file.WrittenSize = 0;
900*f6dc9357SAndroid Build Coastguard Worker     file.ExpectedSize = 0;
901*f6dc9357SAndroid Build Coastguard Worker     if (size_Defined)
902*f6dc9357SAndroid Build Coastguard Worker       file.ExpectedSize = size;
903*f6dc9357SAndroid Build Coastguard Worker 
904*f6dc9357SAndroid Build Coastguard Worker     if (VirtFileSystemSpec->Index_of_MainExtractedFile_in_Files < 0)
905*f6dc9357SAndroid Build Coastguard Worker       if (!file.IsAltStream || VirtFileSystemSpec->IsAltStreamFile)
906*f6dc9357SAndroid Build Coastguard Worker         VirtFileSystemSpec->Index_of_MainExtractedFile_in_Files =
907*f6dc9357SAndroid Build Coastguard Worker             (int)(VirtFileSystemSpec->Files.Size() - 1);
908*f6dc9357SAndroid Build Coastguard Worker 
909*f6dc9357SAndroid Build Coastguard Worker     /* if we open only AltStream, then (name) contains only name without "fileName:" prefix */
910*f6dc9357SAndroid Build Coastguard Worker     file.BaseName = name;
911*f6dc9357SAndroid Build Coastguard Worker 
912*f6dc9357SAndroid Build Coastguard Worker     if (file.IsAltStream
913*f6dc9357SAndroid Build Coastguard Worker         && !VirtFileSystemSpec->IsAltStreamFile
914*f6dc9357SAndroid Build Coastguard Worker         && file.BaseName.IsPrefixedBy_NoCase(VirtFileSystemSpec->FileName))
915*f6dc9357SAndroid Build Coastguard Worker     {
916*f6dc9357SAndroid Build Coastguard Worker       const unsigned colonPos = VirtFileSystemSpec->FileName.Len();
917*f6dc9357SAndroid Build Coastguard Worker       if (file.BaseName[colonPos] == ':')
918*f6dc9357SAndroid Build Coastguard Worker       {
919*f6dc9357SAndroid Build Coastguard Worker         file.ColonWasUsed = true;
920*f6dc9357SAndroid Build Coastguard Worker         file.AltStreamName = name + (size_t)colonPos + 1;
921*f6dc9357SAndroid Build Coastguard Worker         file.BaseName.DeleteFrom(colonPos);
922*f6dc9357SAndroid Build Coastguard Worker         if (Is_ZoneId_StreamName(file.AltStreamName))
923*f6dc9357SAndroid Build Coastguard Worker         {
924*f6dc9357SAndroid Build Coastguard Worker           if (VirtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files < 0)
925*f6dc9357SAndroid Build Coastguard Worker             VirtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files =
926*f6dc9357SAndroid Build Coastguard Worker               (int)(VirtFileSystemSpec->Files.Size() - 1);
927*f6dc9357SAndroid Build Coastguard Worker         }
928*f6dc9357SAndroid Build Coastguard Worker       }
929*f6dc9357SAndroid Build Coastguard Worker     }
930*f6dc9357SAndroid Build Coastguard Worker     RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTime_Defined))
931*f6dc9357SAndroid Build Coastguard Worker     RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATime_Defined))
932*f6dc9357SAndroid Build Coastguard Worker     RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTime_Defined))
933*f6dc9357SAndroid Build Coastguard Worker     {
934*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant prop;
935*f6dc9357SAndroid Build Coastguard Worker       RINOK(getProp->GetProp(kpidAttrib, &prop))
936*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt == VT_UI4)
937*f6dc9357SAndroid Build Coastguard Worker       {
938*f6dc9357SAndroid Build Coastguard Worker         file.Attrib = prop.ulVal;
939*f6dc9357SAndroid Build Coastguard Worker         file.Attrib_Defined = true;
940*f6dc9357SAndroid Build Coastguard Worker       }
941*f6dc9357SAndroid Build Coastguard Worker     }
942*f6dc9357SAndroid Build Coastguard Worker     outStreamLoc = VirtFileSystem;
943*f6dc9357SAndroid Build Coastguard Worker   }
944*f6dc9357SAndroid Build Coastguard Worker 
945*f6dc9357SAndroid Build Coastguard Worker   if (_hashStream)
946*f6dc9357SAndroid Build Coastguard Worker   {
947*f6dc9357SAndroid Build Coastguard Worker     _hashStream->SetStream(outStreamLoc);
948*f6dc9357SAndroid Build Coastguard Worker     outStreamLoc = _hashStream;
949*f6dc9357SAndroid Build Coastguard Worker     _hashStream->Init(true);
950*f6dc9357SAndroid Build Coastguard Worker     _hashStream_WasUsed = true;
951*f6dc9357SAndroid Build Coastguard Worker   }
952*f6dc9357SAndroid Build Coastguard Worker 
953*f6dc9357SAndroid Build Coastguard Worker   if (outStreamLoc)
954*f6dc9357SAndroid Build Coastguard Worker     *outStream = outStreamLoc.Detach();
955*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
956*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
957*f6dc9357SAndroid Build Coastguard Worker }
958*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation7 (Int32 askExtractMode))959*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode))
960*f6dc9357SAndroid Build Coastguard Worker {
961*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
962*f6dc9357SAndroid Build Coastguard Worker   _needUpdateStat = (
963*f6dc9357SAndroid Build Coastguard Worker          askExtractMode == NArchive::NExtract::NAskMode::kExtract
964*f6dc9357SAndroid Build Coastguard Worker       || askExtractMode == NArchive::NExtract::NAskMode::kTest
965*f6dc9357SAndroid Build Coastguard Worker       || askExtractMode == NArchive::NExtract::NAskMode::kReadExternal
966*f6dc9357SAndroid Build Coastguard Worker       );
967*f6dc9357SAndroid Build Coastguard Worker 
968*f6dc9357SAndroid Build Coastguard Worker   /*
969*f6dc9357SAndroid Build Coastguard Worker   _extractMode = false;
970*f6dc9357SAndroid Build Coastguard Worker   switch (askExtractMode)
971*f6dc9357SAndroid Build Coastguard Worker   {
972*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kExtract:
973*f6dc9357SAndroid Build Coastguard Worker       if (_testMode)
974*f6dc9357SAndroid Build Coastguard Worker         askExtractMode = NArchive::NExtract::NAskMode::kTest;
975*f6dc9357SAndroid Build Coastguard Worker       else
976*f6dc9357SAndroid Build Coastguard Worker         _extractMode = true;
977*f6dc9357SAndroid Build Coastguard Worker       break;
978*f6dc9357SAndroid Build Coastguard Worker   };
979*f6dc9357SAndroid Build Coastguard Worker   */
980*f6dc9357SAndroid Build Coastguard Worker   return SetCurrentFilePath2(_filePath);
981*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
982*f6dc9357SAndroid Build Coastguard Worker }
983*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult8 (Int32 opRes,Int32 encrypted,UInt64 size))984*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult8(Int32 opRes, Int32 encrypted, UInt64 size))
985*f6dc9357SAndroid Build Coastguard Worker {
986*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
987*f6dc9357SAndroid Build Coastguard Worker   if (VirtFileSystem && _newVirtFileWasAdded)
988*f6dc9357SAndroid Build Coastguard Worker   {
989*f6dc9357SAndroid Build Coastguard Worker     // FIXME: probably we must request file size from VirtFileSystem
990*f6dc9357SAndroid Build Coastguard Worker     // _curSize = VirtFileSystem->GetLastFileSize()
991*f6dc9357SAndroid Build Coastguard Worker     // _curSize_Defined = true;
992*f6dc9357SAndroid Build Coastguard Worker     RINOK(VirtFileSystemSpec->CloseMemFile())
993*f6dc9357SAndroid Build Coastguard Worker   }
994*f6dc9357SAndroid Build Coastguard Worker   if (_hashStream && _hashStream_WasUsed)
995*f6dc9357SAndroid Build Coastguard Worker   {
996*f6dc9357SAndroid Build Coastguard Worker     _hashStream->_hash->Final(_isFolder, _isAltStream, _filePath);
997*f6dc9357SAndroid Build Coastguard Worker     _curSize = _hashStream->GetSize();
998*f6dc9357SAndroid Build Coastguard Worker     _curSize_Defined = true;
999*f6dc9357SAndroid Build Coastguard Worker     _hashStream->ReleaseStream();
1000*f6dc9357SAndroid Build Coastguard Worker     _hashStream_WasUsed = false;
1001*f6dc9357SAndroid Build Coastguard Worker   }
1002*f6dc9357SAndroid Build Coastguard Worker   else if (_hashCalc && _needUpdateStat)
1003*f6dc9357SAndroid Build Coastguard Worker   {
1004*f6dc9357SAndroid Build Coastguard Worker     _hashCalc->SetSize(size); // (_curSize) before 21.04
1005*f6dc9357SAndroid Build Coastguard Worker     _hashCalc->Final(_isFolder, _isAltStream, _filePath);
1006*f6dc9357SAndroid Build Coastguard Worker   }
1007*f6dc9357SAndroid Build Coastguard Worker   return SetOperationResult(opRes, encrypted);
1008*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
1009*f6dc9357SAndroid Build Coastguard Worker }
1010*f6dc9357SAndroid Build Coastguard Worker 
1011*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CExtractCallbackImp::RequestMemoryUse (UInt32 flags,UInt32 indexType,UInt32,const wchar_t * path,UInt64 requiredSize,UInt64 * allowedSize,UInt32 * answerFlags))1012*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CExtractCallbackImp::RequestMemoryUse(
1013*f6dc9357SAndroid Build Coastguard Worker     UInt32 flags, UInt32 indexType, UInt32 /* index */, const wchar_t *path,
1014*f6dc9357SAndroid Build Coastguard Worker     UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags))
1015*f6dc9357SAndroid Build Coastguard Worker {
1016*f6dc9357SAndroid Build Coastguard Worker   UInt32 limit_GB = (UInt32)((*allowedSize + ((1u << 30) - 1)) >> 30);
1017*f6dc9357SAndroid Build Coastguard Worker 
1018*f6dc9357SAndroid Build Coastguard Worker   if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0)
1019*f6dc9357SAndroid Build Coastguard Worker   {
1020*f6dc9357SAndroid Build Coastguard Worker     UInt64 limit_bytes = *allowedSize;
1021*f6dc9357SAndroid Build Coastguard Worker     const UInt32 limit_GB_Registry = NExtract::Read_LimitGB();
1022*f6dc9357SAndroid Build Coastguard Worker     if (limit_GB_Registry != 0 && limit_GB_Registry != (UInt32)(Int32)-1)
1023*f6dc9357SAndroid Build Coastguard Worker     {
1024*f6dc9357SAndroid Build Coastguard Worker       const UInt64 limit_bytes_Registry = (UInt64)limit_GB_Registry << 30;
1025*f6dc9357SAndroid Build Coastguard Worker       // registry_WasForced = true;
1026*f6dc9357SAndroid Build Coastguard Worker       if ((flags & NRequestMemoryUseFlags::k_AllowedSize_WasForced) == 0
1027*f6dc9357SAndroid Build Coastguard Worker           || limit_bytes < limit_bytes_Registry)
1028*f6dc9357SAndroid Build Coastguard Worker       {
1029*f6dc9357SAndroid Build Coastguard Worker         limit_bytes = limit_bytes_Registry;
1030*f6dc9357SAndroid Build Coastguard Worker         limit_GB = limit_GB_Registry;
1031*f6dc9357SAndroid Build Coastguard Worker       }
1032*f6dc9357SAndroid Build Coastguard Worker     }
1033*f6dc9357SAndroid Build Coastguard Worker     *allowedSize = limit_bytes;
1034*f6dc9357SAndroid Build Coastguard Worker     if (requiredSize <= limit_bytes)
1035*f6dc9357SAndroid Build Coastguard Worker     {
1036*f6dc9357SAndroid Build Coastguard Worker       *answerFlags = NRequestMemoryAnswerFlags::k_Allow;
1037*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1038*f6dc9357SAndroid Build Coastguard Worker     }
1039*f6dc9357SAndroid Build Coastguard Worker     // default answer can be k_Allow, if limit was not forced,
1040*f6dc9357SAndroid Build Coastguard Worker     // so we change answer to non-allowed here,
1041*f6dc9357SAndroid Build Coastguard Worker     // because user has chance to change limit in GUI.
1042*f6dc9357SAndroid Build Coastguard Worker     *answerFlags = NRequestMemoryAnswerFlags::k_Limit_Exceeded;
1043*f6dc9357SAndroid Build Coastguard Worker     if (flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected)
1044*f6dc9357SAndroid Build Coastguard Worker       *answerFlags |= NRequestMemoryAnswerFlags::k_SkipArc;
1045*f6dc9357SAndroid Build Coastguard Worker   }
1046*f6dc9357SAndroid Build Coastguard Worker 
1047*f6dc9357SAndroid Build Coastguard Worker   const UInt32 required_GB = (UInt32)((requiredSize + ((1u << 30) - 1)) >> 30);
1048*f6dc9357SAndroid Build Coastguard Worker 
1049*f6dc9357SAndroid Build Coastguard Worker   CMemDialog dialog;
1050*f6dc9357SAndroid Build Coastguard Worker   dialog.Limit_GB = limit_GB;
1051*f6dc9357SAndroid Build Coastguard Worker   dialog.Required_GB = required_GB;
1052*f6dc9357SAndroid Build Coastguard Worker   dialog.TestMode = TestMode;
1053*f6dc9357SAndroid Build Coastguard Worker   if (MultiArcMode)
1054*f6dc9357SAndroid Build Coastguard Worker     dialog.ArcPath = _currentArchivePath;
1055*f6dc9357SAndroid Build Coastguard Worker   if (path)
1056*f6dc9357SAndroid Build Coastguard Worker     dialog.FilePath = path;
1057*f6dc9357SAndroid Build Coastguard Worker 
1058*f6dc9357SAndroid Build Coastguard Worker   if (!g_DisableUserQuestions
1059*f6dc9357SAndroid Build Coastguard Worker       && (flags & NRequestMemoryUseFlags::k_IsReport) == 0)
1060*f6dc9357SAndroid Build Coastguard Worker   {
1061*f6dc9357SAndroid Build Coastguard Worker     if (_remember)
1062*f6dc9357SAndroid Build Coastguard Worker       dialog.SkipArc = _skipArc;
1063*f6dc9357SAndroid Build Coastguard Worker     else
1064*f6dc9357SAndroid Build Coastguard Worker     {
1065*f6dc9357SAndroid Build Coastguard Worker       dialog.ShowRemember =
1066*f6dc9357SAndroid Build Coastguard Worker         (MultiArcMode
1067*f6dc9357SAndroid Build Coastguard Worker           || indexType != NArchive::NEventIndexType::kNoIndex
1068*f6dc9357SAndroid Build Coastguard Worker           || path);
1069*f6dc9357SAndroid Build Coastguard Worker       ProgressDialog->WaitCreating();
1070*f6dc9357SAndroid Build Coastguard Worker       if (dialog.Create(*ProgressDialog) != IDCONTINUE)
1071*f6dc9357SAndroid Build Coastguard Worker       {
1072*f6dc9357SAndroid Build Coastguard Worker         *answerFlags = NRequestMemoryAnswerFlags::k_Stop;
1073*f6dc9357SAndroid Build Coastguard Worker         return E_ABORT;
1074*f6dc9357SAndroid Build Coastguard Worker       }
1075*f6dc9357SAndroid Build Coastguard Worker       if (dialog.NeedSave)
1076*f6dc9357SAndroid Build Coastguard Worker         NExtract::Save_LimitGB(dialog.Limit_GB);
1077*f6dc9357SAndroid Build Coastguard Worker       if (dialog.Remember)
1078*f6dc9357SAndroid Build Coastguard Worker       {
1079*f6dc9357SAndroid Build Coastguard Worker         _remember = true;
1080*f6dc9357SAndroid Build Coastguard Worker         _skipArc = dialog.SkipArc;
1081*f6dc9357SAndroid Build Coastguard Worker       }
1082*f6dc9357SAndroid Build Coastguard Worker     }
1083*f6dc9357SAndroid Build Coastguard Worker 
1084*f6dc9357SAndroid Build Coastguard Worker     *allowedSize = (UInt64)dialog.Limit_GB << 30;
1085*f6dc9357SAndroid Build Coastguard Worker     if (!dialog.SkipArc)
1086*f6dc9357SAndroid Build Coastguard Worker     {
1087*f6dc9357SAndroid Build Coastguard Worker       *answerFlags = NRequestMemoryAnswerFlags::k_Allow;
1088*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1089*f6dc9357SAndroid Build Coastguard Worker     }
1090*f6dc9357SAndroid Build Coastguard Worker     *answerFlags =
1091*f6dc9357SAndroid Build Coastguard Worker         NRequestMemoryAnswerFlags::k_SkipArc
1092*f6dc9357SAndroid Build Coastguard Worker       | NRequestMemoryAnswerFlags::k_Limit_Exceeded;
1093*f6dc9357SAndroid Build Coastguard Worker     flags |= NRequestMemoryUseFlags::k_Report_SkipArc;
1094*f6dc9357SAndroid Build Coastguard Worker   }
1095*f6dc9357SAndroid Build Coastguard Worker 
1096*f6dc9357SAndroid Build Coastguard Worker   if ((flags & NRequestMemoryUseFlags::k_NoErrorMessage) == 0)
1097*f6dc9357SAndroid Build Coastguard Worker   {
1098*f6dc9357SAndroid Build Coastguard Worker     UString s ("ERROR: ");
1099*f6dc9357SAndroid Build Coastguard Worker     dialog.AddInfoMessage_To_String(s);
1100*f6dc9357SAndroid Build Coastguard Worker     s.Add_LF();
1101*f6dc9357SAndroid Build Coastguard Worker     // if (indexType == NArchive::NEventIndexType::kNoIndex)
1102*f6dc9357SAndroid Build Coastguard Worker     if ((flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) ||
1103*f6dc9357SAndroid Build Coastguard Worker         (flags & NRequestMemoryUseFlags::k_Report_SkipArc))
1104*f6dc9357SAndroid Build Coastguard Worker       AddLangString(s, IDS_MSG_ARC_UNPACKING_WAS_SKIPPED);
1105*f6dc9357SAndroid Build Coastguard Worker /*
1106*f6dc9357SAndroid Build Coastguard Worker     else
1107*f6dc9357SAndroid Build Coastguard Worker       AddLangString(, IDS_MSG_ARC_FILES_UNPACKING_WAS_SKIPPED);
1108*f6dc9357SAndroid Build Coastguard Worker */
1109*f6dc9357SAndroid Build Coastguard Worker     AddError_Message_ShowArcPath(s);
1110*f6dc9357SAndroid Build Coastguard Worker   }
1111*f6dc9357SAndroid Build Coastguard Worker 
1112*f6dc9357SAndroid Build Coastguard Worker /*
1113*f6dc9357SAndroid Build Coastguard Worker   if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0)
1114*f6dc9357SAndroid Build Coastguard Worker     *answerFlags |= NRequestMemoryAnswerFlags::k_Limit_Exceeded;
1115*f6dc9357SAndroid Build Coastguard Worker */
1116*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1117*f6dc9357SAndroid Build Coastguard Worker }
1118*f6dc9357SAndroid Build Coastguard Worker 
1119*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CVirtFileSystem::Write (const void * data,UInt32 size,UInt32 * processedSize))1120*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize))
1121*f6dc9357SAndroid Build Coastguard Worker {
1122*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
1123*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
1124*f6dc9357SAndroid Build Coastguard Worker   if (size == 0)
1125*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
1126*f6dc9357SAndroid Build Coastguard Worker   if (!_wasSwitchedToFsMode)
1127*f6dc9357SAndroid Build Coastguard Worker   {
1128*f6dc9357SAndroid Build Coastguard Worker     CVirtFile &file = Files.Back();
1129*f6dc9357SAndroid Build Coastguard Worker     const size_t rem = file.Data.Size() - file.WrittenSize;
1130*f6dc9357SAndroid Build Coastguard Worker     bool useMem = true;
1131*f6dc9357SAndroid Build Coastguard Worker     if (rem < size)
1132*f6dc9357SAndroid Build Coastguard Worker     {
1133*f6dc9357SAndroid Build Coastguard Worker       UInt64 b = 0;
1134*f6dc9357SAndroid Build Coastguard Worker       if (file.Data.Size() == 0)
1135*f6dc9357SAndroid Build Coastguard Worker         b = file.ExpectedSize;
1136*f6dc9357SAndroid Build Coastguard Worker       UInt64 a = (UInt64)file.WrittenSize + size;
1137*f6dc9357SAndroid Build Coastguard Worker       if (b < a)
1138*f6dc9357SAndroid Build Coastguard Worker         b = a;
1139*f6dc9357SAndroid Build Coastguard Worker       a = (UInt64)file.Data.Size() * 2;
1140*f6dc9357SAndroid Build Coastguard Worker       if (b < a)
1141*f6dc9357SAndroid Build Coastguard Worker         b = a;
1142*f6dc9357SAndroid Build Coastguard Worker       useMem = false;
1143*f6dc9357SAndroid Build Coastguard Worker       if (b <= MaxTotalAllocSize)
1144*f6dc9357SAndroid Build Coastguard Worker         useMem = file.Data.ReAlloc_KeepData((size_t)b, file.WrittenSize);
1145*f6dc9357SAndroid Build Coastguard Worker     }
1146*f6dc9357SAndroid Build Coastguard Worker 
1147*f6dc9357SAndroid Build Coastguard Worker #if 0 // 1 for debug : FLUSHING TO FS
1148*f6dc9357SAndroid Build Coastguard Worker     useMem = false;
1149*f6dc9357SAndroid Build Coastguard Worker #endif
1150*f6dc9357SAndroid Build Coastguard Worker 
1151*f6dc9357SAndroid Build Coastguard Worker     if (useMem)
1152*f6dc9357SAndroid Build Coastguard Worker     {
1153*f6dc9357SAndroid Build Coastguard Worker       memcpy(file.Data + file.WrittenSize, data, size);
1154*f6dc9357SAndroid Build Coastguard Worker       file.WrittenSize += size;
1155*f6dc9357SAndroid Build Coastguard Worker       if (processedSize)
1156*f6dc9357SAndroid Build Coastguard Worker         *processedSize = (UInt32)size;
1157*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1158*f6dc9357SAndroid Build Coastguard Worker     }
1159*f6dc9357SAndroid Build Coastguard Worker     _wasSwitchedToFsMode = true;
1160*f6dc9357SAndroid Build Coastguard Worker   }
1161*f6dc9357SAndroid Build Coastguard Worker 
1162*f6dc9357SAndroid Build Coastguard Worker   if (!_newVirtFileStream_IsReadyToWrite) // we check for _newVirtFileStream_IsReadyToWrite to optimize execution
1163*f6dc9357SAndroid Build Coastguard Worker   {
1164*f6dc9357SAndroid Build Coastguard Worker     RINOK(FlushToDisk(false))
1165*f6dc9357SAndroid Build Coastguard Worker   }
1166*f6dc9357SAndroid Build Coastguard Worker 
1167*f6dc9357SAndroid Build Coastguard Worker   if (_needWriteToRealFile)
1168*f6dc9357SAndroid Build Coastguard Worker     return _outFileStream.Interface()->Write(data, size, processedSize);
1169*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
1170*f6dc9357SAndroid Build Coastguard Worker     *processedSize = size;
1171*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1172*f6dc9357SAndroid Build Coastguard Worker }
1173*f6dc9357SAndroid Build Coastguard Worker 
1174*f6dc9357SAndroid Build Coastguard Worker 
FlushToDisk(bool closeLast)1175*f6dc9357SAndroid Build Coastguard Worker HRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
1176*f6dc9357SAndroid Build Coastguard Worker {
1177*f6dc9357SAndroid Build Coastguard Worker   while (_numFlushed < Files.Size())
1178*f6dc9357SAndroid Build Coastguard Worker   {
1179*f6dc9357SAndroid Build Coastguard Worker     CVirtFile &file = Files[_numFlushed];
1180*f6dc9357SAndroid Build Coastguard Worker     const FString basePath = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.BaseName));
1181*f6dc9357SAndroid Build Coastguard Worker     FString path = basePath;
1182*f6dc9357SAndroid Build Coastguard Worker 
1183*f6dc9357SAndroid Build Coastguard Worker     if (file.ColonWasUsed)
1184*f6dc9357SAndroid Build Coastguard Worker     {
1185*f6dc9357SAndroid Build Coastguard Worker       if (ZoneBuf.Size() != 0
1186*f6dc9357SAndroid Build Coastguard Worker           && Is_ZoneId_StreamName(file.AltStreamName))
1187*f6dc9357SAndroid Build Coastguard Worker       {
1188*f6dc9357SAndroid Build Coastguard Worker         // it's expected that
1189*f6dc9357SAndroid Build Coastguard Worker         // CArchiveExtractCallback::GetStream() have excluded
1190*f6dc9357SAndroid Build Coastguard Worker         // ZoneId alt stream from extraction already.
1191*f6dc9357SAndroid Build Coastguard Worker         // But we exclude alt stream extraction here too.
1192*f6dc9357SAndroid Build Coastguard Worker         _numFlushed++;
1193*f6dc9357SAndroid Build Coastguard Worker         continue;
1194*f6dc9357SAndroid Build Coastguard Worker       }
1195*f6dc9357SAndroid Build Coastguard Worker       path.Add_Colon();
1196*f6dc9357SAndroid Build Coastguard Worker       path += us2fs(Get_Correct_FsFile_Name(file.AltStreamName));
1197*f6dc9357SAndroid Build Coastguard Worker     }
1198*f6dc9357SAndroid Build Coastguard Worker 
1199*f6dc9357SAndroid Build Coastguard Worker     if (!_newVirtFileStream_IsReadyToWrite)
1200*f6dc9357SAndroid Build Coastguard Worker     {
1201*f6dc9357SAndroid Build Coastguard Worker       if (file.ColonWasUsed)
1202*f6dc9357SAndroid Build Coastguard Worker       {
1203*f6dc9357SAndroid Build Coastguard Worker         NFind::CFileInfo parentFi;
1204*f6dc9357SAndroid Build Coastguard Worker         if (parentFi.Find(basePath)
1205*f6dc9357SAndroid Build Coastguard Worker             && parentFi.IsReadOnly())
1206*f6dc9357SAndroid Build Coastguard Worker         {
1207*f6dc9357SAndroid Build Coastguard Worker           _altStream_NeedRestore_Attrib_bool = true;
1208*f6dc9357SAndroid Build Coastguard Worker           _altStream_NeedRestore_AttribVal = parentFi.Attrib;
1209*f6dc9357SAndroid Build Coastguard Worker           NDir::SetFileAttrib(basePath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY);
1210*f6dc9357SAndroid Build Coastguard Worker         }
1211*f6dc9357SAndroid Build Coastguard Worker       }
1212*f6dc9357SAndroid Build Coastguard Worker       _outFileStream.Create_if_Empty();
1213*f6dc9357SAndroid Build Coastguard Worker       _needWriteToRealFile = _outFileStream->Create_NEW(path);
1214*f6dc9357SAndroid Build Coastguard Worker       if (!_needWriteToRealFile)
1215*f6dc9357SAndroid Build Coastguard Worker       {
1216*f6dc9357SAndroid Build Coastguard Worker         if (!file.ColonWasUsed)
1217*f6dc9357SAndroid Build Coastguard Worker           return GetLastError_noZero_HRESULT(); // it's main file and we can't ignore such error.
1218*f6dc9357SAndroid Build Coastguard Worker         // (file.ColonWasUsed == true)
1219*f6dc9357SAndroid Build Coastguard Worker         // So it's additional alt stream.
1220*f6dc9357SAndroid Build Coastguard Worker         // And we ignore file creation error for additional alt stream.
1221*f6dc9357SAndroid Build Coastguard Worker         // ShowErrorMessage(UString("Can't create file ") + fs2us(path));
1222*f6dc9357SAndroid Build Coastguard Worker       }
1223*f6dc9357SAndroid Build Coastguard Worker       _newVirtFileStream_IsReadyToWrite = true;
1224*f6dc9357SAndroid Build Coastguard Worker       // _openFilePath = path;
1225*f6dc9357SAndroid Build Coastguard Worker       HRESULT hres = S_OK;
1226*f6dc9357SAndroid Build Coastguard Worker       if (_needWriteToRealFile)
1227*f6dc9357SAndroid Build Coastguard Worker         hres = WriteStream(_outFileStream, file.Data, file.WrittenSize);
1228*f6dc9357SAndroid Build Coastguard Worker       // we free allocated memory buffer after data flushing:
1229*f6dc9357SAndroid Build Coastguard Worker       file.WrittenSize = 0;
1230*f6dc9357SAndroid Build Coastguard Worker       file.Data.Free();
1231*f6dc9357SAndroid Build Coastguard Worker       RINOK(hres)
1232*f6dc9357SAndroid Build Coastguard Worker     }
1233*f6dc9357SAndroid Build Coastguard Worker 
1234*f6dc9357SAndroid Build Coastguard Worker     if (_numFlushed == Files.Size() - 1 && !closeLast)
1235*f6dc9357SAndroid Build Coastguard Worker       break;
1236*f6dc9357SAndroid Build Coastguard Worker 
1237*f6dc9357SAndroid Build Coastguard Worker     if (_needWriteToRealFile)
1238*f6dc9357SAndroid Build Coastguard Worker     {
1239*f6dc9357SAndroid Build Coastguard Worker       if (file.CTime_Defined ||
1240*f6dc9357SAndroid Build Coastguard Worker           file.ATime_Defined ||
1241*f6dc9357SAndroid Build Coastguard Worker           file.MTime_Defined)
1242*f6dc9357SAndroid Build Coastguard Worker         _outFileStream->SetTime(
1243*f6dc9357SAndroid Build Coastguard Worker           file.CTime_Defined ? &file.CTime : NULL,
1244*f6dc9357SAndroid Build Coastguard Worker           file.ATime_Defined ? &file.ATime : NULL,
1245*f6dc9357SAndroid Build Coastguard Worker           file.MTime_Defined ? &file.MTime : NULL);
1246*f6dc9357SAndroid Build Coastguard Worker       _outFileStream->Close();
1247*f6dc9357SAndroid Build Coastguard Worker     }
1248*f6dc9357SAndroid Build Coastguard Worker 
1249*f6dc9357SAndroid Build Coastguard Worker     _numFlushed++;
1250*f6dc9357SAndroid Build Coastguard Worker     _newVirtFileStream_IsReadyToWrite = false;
1251*f6dc9357SAndroid Build Coastguard Worker 
1252*f6dc9357SAndroid Build Coastguard Worker     if (_needWriteToRealFile)
1253*f6dc9357SAndroid Build Coastguard Worker     {
1254*f6dc9357SAndroid Build Coastguard Worker       if (!file.ColonWasUsed
1255*f6dc9357SAndroid Build Coastguard Worker           && ZoneBuf.Size() != 0)
1256*f6dc9357SAndroid Build Coastguard Worker         WriteZoneFile_To_BaseFile(path, ZoneBuf);
1257*f6dc9357SAndroid Build Coastguard Worker       if (file.Attrib_Defined)
1258*f6dc9357SAndroid Build Coastguard Worker         NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib);
1259*f6dc9357SAndroid Build Coastguard Worker       // _openFilePath.Empty();
1260*f6dc9357SAndroid Build Coastguard Worker       _needWriteToRealFile = false;
1261*f6dc9357SAndroid Build Coastguard Worker     }
1262*f6dc9357SAndroid Build Coastguard Worker 
1263*f6dc9357SAndroid Build Coastguard Worker     if (_altStream_NeedRestore_Attrib_bool)
1264*f6dc9357SAndroid Build Coastguard Worker     {
1265*f6dc9357SAndroid Build Coastguard Worker       _altStream_NeedRestore_Attrib_bool = false;
1266*f6dc9357SAndroid Build Coastguard Worker       NDir::SetFileAttrib(basePath, _altStream_NeedRestore_AttribVal);
1267*f6dc9357SAndroid Build Coastguard Worker     }
1268*f6dc9357SAndroid Build Coastguard Worker   }
1269*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1270*f6dc9357SAndroid Build Coastguard Worker }
1271*f6dc9357SAndroid Build Coastguard Worker 
1272*f6dc9357SAndroid Build Coastguard Worker #endif
1273