1 // ExtractEngine.h
2
3 #include "StdAfx.h"
4
5 #ifndef Z7_ST
6 #include "../../../Windows/Synchronization.h"
7 #endif
8
9 #include "../../../Common/StringConvert.h"
10
11 #include "ExtractEngine.h"
12 #include "FarUtils.h"
13 #include "Messages.h"
14 #include "OverwriteDialogFar.h"
15
16 using namespace NWindows;
17 using namespace NFar;
18
19 #ifndef Z7_ST
20 static NSynchronization::CCriticalSection g_CriticalSection;
21 #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
22 #else
23 #define MT_LOCK
24 #endif
25
26
CheckBreak2()27 static HRESULT CheckBreak2()
28 {
29 return WasEscPressed() ? E_ABORT : S_OK;
30 }
31
32 extern void PrintMessage(const char *message);
33
Init(UINT codePage,CProgressBox * progressBox,bool passwordIsDefined,const UString & password)34 void CExtractCallbackImp::Init(
35 UINT codePage,
36 CProgressBox *progressBox,
37 bool passwordIsDefined,
38 const UString &password)
39 {
40 m_PasswordIsDefined = passwordIsDefined;
41 m_Password = password;
42 m_CodePage = codePage;
43 _percent = progressBox;
44 }
45
Z7_COM7F_IMF(CExtractCallbackImp::SetTotal (UInt64 size))46 Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 size))
47 {
48 MT_LOCK
49
50 if (_percent)
51 {
52 _percent->Total = size;
53 _percent->Print();
54 }
55 return CheckBreak2();
56 }
57
Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted (const UInt64 * completeValue))58 Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *completeValue))
59 {
60 MT_LOCK
61
62 if (_percent)
63 {
64 if (completeValue)
65 _percent->Completed = *completeValue;
66 _percent->Print();
67 }
68 return CheckBreak2();
69 }
70
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))71 Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite(
72 const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
73 const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
74 Int32 *answer))
75 {
76 MT_LOCK
77
78 NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo;
79 oldFileInfo.TimeIsDefined = (existTime != NULL);
80 if (oldFileInfo.TimeIsDefined)
81 oldFileInfo.Time = *existTime;
82 oldFileInfo.SizeIsDefined = (existSize != NULL);
83 if (oldFileInfo.SizeIsDefined)
84 oldFileInfo.Size = *existSize;
85 oldFileInfo.Name = existName;
86
87 newFileInfo.TimeIsDefined = (newTime != NULL);
88 if (newFileInfo.TimeIsDefined)
89 newFileInfo.Time = *newTime;
90 newFileInfo.SizeIsDefined = (newSize != NULL);
91 if (newFileInfo.SizeIsDefined)
92 newFileInfo.Size = *newSize;
93 newFileInfo.Name = newName;
94
95 NOverwriteDialog::NResult::EEnum result =
96 NOverwriteDialog::Execute(oldFileInfo, newFileInfo);
97
98 switch ((int)result)
99 {
100 case NOverwriteDialog::NResult::kCancel:
101 // *answer = NOverwriteAnswer::kCancel;
102 // break;
103 return E_ABORT;
104 case NOverwriteDialog::NResult::kNo:
105 *answer = NOverwriteAnswer::kNo;
106 break;
107 case NOverwriteDialog::NResult::kNoToAll:
108 *answer = NOverwriteAnswer::kNoToAll;
109 break;
110 case NOverwriteDialog::NResult::kYesToAll:
111 *answer = NOverwriteAnswer::kYesToAll;
112 break;
113 case NOverwriteDialog::NResult::kYes:
114 *answer = NOverwriteAnswer::kYes;
115 break;
116 case NOverwriteDialog::NResult::kAutoRename:
117 *answer = NOverwriteAnswer::kAutoRename;
118 break;
119 default:
120 return E_FAIL;
121 }
122
123 return CheckBreak2();
124 }
125
126 static const char * const kTestString = "Testing";
127 static const char * const kExtractString = "Extracting";
128 static const char * const kSkipString = "Skipping";
129 static const char * const kReadString = "Reading";
130
Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation (const wchar_t * name,Int32,Int32 askExtractMode,const UInt64 *))131 Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 * /* position */))
132 {
133 MT_LOCK
134
135 m_CurrentFilePath = name;
136 const char *s;
137
138 switch (askExtractMode)
139 {
140 case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break;
141 case NArchive::NExtract::NAskMode::kTest: s = kTestString; break;
142 case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; break;
143 case NArchive::NExtract::NAskMode::kReadExternal: s = kReadString; break;
144 default: s = "???"; // return E_FAIL;
145 }
146
147 if (_percent)
148 {
149 _percent->Command = s;
150 _percent->FileName = name;
151 _percent->Print();
152 }
153
154 return CheckBreak2();
155 }
156
Z7_COM7F_IMF(CExtractCallbackImp::MessageError (const wchar_t * message))157 Z7_COM7F_IMF(CExtractCallbackImp::MessageError(const wchar_t *message))
158 {
159 MT_LOCK
160
161 AString s (UnicodeStringToMultiByte(message, CP_OEMCP));
162 if (g_StartupInfo.ShowErrorMessage((const char *)s) == -1)
163 return E_ABORT;
164
165 return CheckBreak2();
166 }
167
168 void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s);
SetExtractErrorMessage(Int32 opRes,Int32 encrypted,AString & s)169 void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s)
170 {
171 s.Empty();
172
173 switch (opRes)
174 {
175 case NArchive::NExtract::NOperationResult::kOK:
176 return;
177 default:
178 {
179 UINT messageID = 0;
180 switch (opRes)
181 {
182 case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
183 messageID = NMessageID::kExtractUnsupportedMethod;
184 break;
185 case NArchive::NExtract::NOperationResult::kCRCError:
186 messageID = encrypted ?
187 NMessageID::kExtractCRCFailedEncrypted :
188 NMessageID::kExtractCRCFailed;
189 break;
190 case NArchive::NExtract::NOperationResult::kDataError:
191 messageID = encrypted ?
192 NMessageID::kExtractDataErrorEncrypted :
193 NMessageID::kExtractDataError;
194 break;
195 }
196 if (messageID != 0)
197 {
198 s = g_StartupInfo.GetMsgString((int)messageID);
199 s.Replace((AString)" '%s'", AString());
200 }
201 else if (opRes == NArchive::NExtract::NOperationResult::kUnavailable)
202 s = "Unavailable data";
203 else if (opRes == NArchive::NExtract::NOperationResult::kUnexpectedEnd)
204 s = "Unexpected end of data";
205 else if (opRes == NArchive::NExtract::NOperationResult::kDataAfterEnd)
206 s = "There are some data after the end of the payload data";
207 else if (opRes == NArchive::NExtract::NOperationResult::kIsNotArc)
208 s = "Is not archive";
209 else if (opRes == NArchive::NExtract::NOperationResult::kHeadersError)
210 s = "kHeaders Error";
211 else if (opRes == NArchive::NExtract::NOperationResult::kWrongPassword)
212 s = "Wrong Password";
213 else
214 {
215 s = "Error #";
216 s.Add_UInt32((UInt32)opRes);
217 }
218 }
219 }
220 }
221
Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult (Int32 opRes,Int32 encrypted))222 Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted))
223 {
224 MT_LOCK
225
226 if (opRes == NArchive::NExtract::NOperationResult::kOK)
227 {
228 if (_percent)
229 {
230 _percent->Command.Empty();
231 _percent->FileName.Empty();
232 _percent->Files++;
233 }
234 }
235 else
236 {
237 AString s;
238 SetExtractErrorMessage(opRes, encrypted, s);
239 if (PrintErrorMessage(s, m_CurrentFilePath) == -1)
240 return E_ABORT;
241 }
242
243 return CheckBreak2();
244 }
245
246
Z7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult (Int32 opRes,Int32 encrypted,const wchar_t * name))247 Z7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name))
248 {
249 MT_LOCK
250
251 if (opRes != NArchive::NExtract::NOperationResult::kOK)
252 {
253 AString s;
254 SetExtractErrorMessage(opRes, encrypted, s);
255 if (PrintErrorMessage(s, name) == -1)
256 return E_ABORT;
257 }
258
259 return CheckBreak2();
260 }
261
262 extern HRESULT GetPassword(UString &password);
263
Z7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword (BSTR * password))264 Z7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword(BSTR *password))
265 {
266 MT_LOCK
267
268 if (!m_PasswordIsDefined)
269 {
270 RINOK(GetPassword(m_Password))
271 m_PasswordIsDefined = true;
272 }
273 return StringToBstr(m_Password, password);
274 }
275