xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Client7z/Client7z.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Client7z.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 <stdio.h>
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyWindows.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyInitGuid.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Defs.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/DLL.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileFind.h"
17*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
18*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/NtCheck.h"
19*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
20*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariantConv.h"
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FileStreams.h"
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker #include "../../Archive/IArchive.h"
25*f6dc9357SAndroid Build Coastguard Worker 
26*f6dc9357SAndroid Build Coastguard Worker #if 0
27*f6dc9357SAndroid Build Coastguard Worker // for password request functions:
28*f6dc9357SAndroid Build Coastguard Worker #include "../../UI/Console/UserInputUtils.h"
29*f6dc9357SAndroid Build Coastguard Worker #endif
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker #include "../../IPassword.h"
32*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/7zVersion.h"
33*f6dc9357SAndroid Build Coastguard Worker 
34*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
35*f6dc9357SAndroid Build Coastguard Worker extern
36*f6dc9357SAndroid Build Coastguard Worker HINSTANCE g_hInstance;
37*f6dc9357SAndroid Build Coastguard Worker HINSTANCE g_hInstance = NULL;
38*f6dc9357SAndroid Build Coastguard Worker #endif
39*f6dc9357SAndroid Build Coastguard Worker 
40*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
41*f6dc9357SAndroid Build Coastguard Worker 
42*f6dc9357SAndroid Build Coastguard Worker // You can find full list of all GUIDs supported by 7-Zip in Guid.txt file.
43*f6dc9357SAndroid Build Coastguard Worker // 7z format GUID: {23170F69-40C1-278A-1000-000110070000}
44*f6dc9357SAndroid Build Coastguard Worker 
45*f6dc9357SAndroid Build Coastguard Worker #define DEFINE_GUID_ARC(name, id) Z7_DEFINE_GUID(name, \
46*f6dc9357SAndroid Build Coastguard Worker   0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, id, 0x00, 0x00);
47*f6dc9357SAndroid Build Coastguard Worker 
48*f6dc9357SAndroid Build Coastguard Worker enum
49*f6dc9357SAndroid Build Coastguard Worker {
50*f6dc9357SAndroid Build Coastguard Worker   kId_Zip = 1,
51*f6dc9357SAndroid Build Coastguard Worker   kId_BZip2 = 2,
52*f6dc9357SAndroid Build Coastguard Worker   kId_7z = 7,
53*f6dc9357SAndroid Build Coastguard Worker   kId_Xz = 0xC,
54*f6dc9357SAndroid Build Coastguard Worker   kId_Tar = 0xEE,
55*f6dc9357SAndroid Build Coastguard Worker   kId_GZip = 0xEF
56*f6dc9357SAndroid Build Coastguard Worker };
57*f6dc9357SAndroid Build Coastguard Worker 
58*f6dc9357SAndroid Build Coastguard Worker // use another id, if you want to support other formats (zip, Xz, ...).
59*f6dc9357SAndroid Build Coastguard Worker // DEFINE_GUID_ARC (CLSID_Format, kId_Zip)
60*f6dc9357SAndroid Build Coastguard Worker // DEFINE_GUID_ARC (CLSID_Format, kId_BZip2)
61*f6dc9357SAndroid Build Coastguard Worker // DEFINE_GUID_ARC (CLSID_Format, kId_Xz)
62*f6dc9357SAndroid Build Coastguard Worker // DEFINE_GUID_ARC (CLSID_Format, kId_Tar)
63*f6dc9357SAndroid Build Coastguard Worker // DEFINE_GUID_ARC (CLSID_Format, kId_GZip)
64*f6dc9357SAndroid Build Coastguard Worker DEFINE_GUID_ARC (CLSID_Format, kId_7z)
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
67*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
68*f6dc9357SAndroid Build Coastguard Worker using namespace NDir;
69*f6dc9357SAndroid Build Coastguard Worker 
70*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
71*f6dc9357SAndroid Build Coastguard Worker #define kDllName "7z.dll"
72*f6dc9357SAndroid Build Coastguard Worker #else
73*f6dc9357SAndroid Build Coastguard Worker #define kDllName "7z.so"
74*f6dc9357SAndroid Build Coastguard Worker #endif
75*f6dc9357SAndroid Build Coastguard Worker 
76*f6dc9357SAndroid Build Coastguard Worker static const char * const kCopyrightString =
77*f6dc9357SAndroid Build Coastguard Worker   "\n"
78*f6dc9357SAndroid Build Coastguard Worker   "7-Zip"
79*f6dc9357SAndroid Build Coastguard Worker   " (" kDllName " client)"
80*f6dc9357SAndroid Build Coastguard Worker   " " MY_VERSION
81*f6dc9357SAndroid Build Coastguard Worker   " : " MY_COPYRIGHT_DATE
82*f6dc9357SAndroid Build Coastguard Worker   "\n";
83*f6dc9357SAndroid Build Coastguard Worker 
84*f6dc9357SAndroid Build Coastguard Worker static const char * const kHelpString =
85*f6dc9357SAndroid Build Coastguard Worker "Usage: 7zcl.exe [a | l | x] archive.7z [fileName ...]\n"
86*f6dc9357SAndroid Build Coastguard Worker "Examples:\n"
87*f6dc9357SAndroid Build Coastguard Worker "  7zcl.exe a archive.7z f1.txt f2.txt  : compress two files to archive.7z\n"
88*f6dc9357SAndroid Build Coastguard Worker "  7zcl.exe l archive.7z   : List contents of archive.7z\n"
89*f6dc9357SAndroid Build Coastguard Worker "  7zcl.exe x archive.7z   : eXtract files from archive.7z\n";
90*f6dc9357SAndroid Build Coastguard Worker 
91*f6dc9357SAndroid Build Coastguard Worker 
Convert_UString_to_AString(const UString & s,AString & temp)92*f6dc9357SAndroid Build Coastguard Worker static void Convert_UString_to_AString(const UString &s, AString &temp)
93*f6dc9357SAndroid Build Coastguard Worker {
94*f6dc9357SAndroid Build Coastguard Worker   int codePage = CP_OEMCP;
95*f6dc9357SAndroid Build Coastguard Worker   /*
96*f6dc9357SAndroid Build Coastguard Worker   int g_CodePage = -1;
97*f6dc9357SAndroid Build Coastguard Worker   int codePage = g_CodePage;
98*f6dc9357SAndroid Build Coastguard Worker   if (codePage == -1)
99*f6dc9357SAndroid Build Coastguard Worker     codePage = CP_OEMCP;
100*f6dc9357SAndroid Build Coastguard Worker   if (codePage == CP_UTF8)
101*f6dc9357SAndroid Build Coastguard Worker     ConvertUnicodeToUTF8(s, temp);
102*f6dc9357SAndroid Build Coastguard Worker   else
103*f6dc9357SAndroid Build Coastguard Worker   */
104*f6dc9357SAndroid Build Coastguard Worker     UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
105*f6dc9357SAndroid Build Coastguard Worker }
106*f6dc9357SAndroid Build Coastguard Worker 
CmdStringToFString(const char * s)107*f6dc9357SAndroid Build Coastguard Worker static FString CmdStringToFString(const char *s)
108*f6dc9357SAndroid Build Coastguard Worker {
109*f6dc9357SAndroid Build Coastguard Worker   return us2fs(GetUnicodeString(s));
110*f6dc9357SAndroid Build Coastguard Worker }
111*f6dc9357SAndroid Build Coastguard Worker 
Print(const char * s)112*f6dc9357SAndroid Build Coastguard Worker static void Print(const char *s)
113*f6dc9357SAndroid Build Coastguard Worker {
114*f6dc9357SAndroid Build Coastguard Worker   fputs(s, stdout);
115*f6dc9357SAndroid Build Coastguard Worker }
116*f6dc9357SAndroid Build Coastguard Worker 
Print(const AString & s)117*f6dc9357SAndroid Build Coastguard Worker static void Print(const AString &s)
118*f6dc9357SAndroid Build Coastguard Worker {
119*f6dc9357SAndroid Build Coastguard Worker   Print(s.Ptr());
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker 
Print(const UString & s)122*f6dc9357SAndroid Build Coastguard Worker static void Print(const UString &s)
123*f6dc9357SAndroid Build Coastguard Worker {
124*f6dc9357SAndroid Build Coastguard Worker   AString as;
125*f6dc9357SAndroid Build Coastguard Worker   Convert_UString_to_AString(s, as);
126*f6dc9357SAndroid Build Coastguard Worker   Print(as);
127*f6dc9357SAndroid Build Coastguard Worker }
128*f6dc9357SAndroid Build Coastguard Worker 
Print(const wchar_t * s)129*f6dc9357SAndroid Build Coastguard Worker static void Print(const wchar_t *s)
130*f6dc9357SAndroid Build Coastguard Worker {
131*f6dc9357SAndroid Build Coastguard Worker   Print(UString(s));
132*f6dc9357SAndroid Build Coastguard Worker }
133*f6dc9357SAndroid Build Coastguard Worker 
PrintNewLine()134*f6dc9357SAndroid Build Coastguard Worker static void PrintNewLine()
135*f6dc9357SAndroid Build Coastguard Worker {
136*f6dc9357SAndroid Build Coastguard Worker   Print("\n");
137*f6dc9357SAndroid Build Coastguard Worker }
138*f6dc9357SAndroid Build Coastguard Worker 
PrintStringLn(const char * s)139*f6dc9357SAndroid Build Coastguard Worker static void PrintStringLn(const char *s)
140*f6dc9357SAndroid Build Coastguard Worker {
141*f6dc9357SAndroid Build Coastguard Worker   Print(s);
142*f6dc9357SAndroid Build Coastguard Worker   PrintNewLine();
143*f6dc9357SAndroid Build Coastguard Worker }
144*f6dc9357SAndroid Build Coastguard Worker 
PrintError(const char * message)145*f6dc9357SAndroid Build Coastguard Worker static void PrintError(const char *message)
146*f6dc9357SAndroid Build Coastguard Worker {
147*f6dc9357SAndroid Build Coastguard Worker   Print("Error: ");
148*f6dc9357SAndroid Build Coastguard Worker   PrintNewLine();
149*f6dc9357SAndroid Build Coastguard Worker   Print(message);
150*f6dc9357SAndroid Build Coastguard Worker   PrintNewLine();
151*f6dc9357SAndroid Build Coastguard Worker }
152*f6dc9357SAndroid Build Coastguard Worker 
PrintError(const char * message,const FString & name)153*f6dc9357SAndroid Build Coastguard Worker static void PrintError(const char *message, const FString &name)
154*f6dc9357SAndroid Build Coastguard Worker {
155*f6dc9357SAndroid Build Coastguard Worker   PrintError(message);
156*f6dc9357SAndroid Build Coastguard Worker   Print(name);
157*f6dc9357SAndroid Build Coastguard Worker }
158*f6dc9357SAndroid Build Coastguard Worker 
159*f6dc9357SAndroid Build Coastguard Worker 
IsArchiveItemProp(IInArchive * archive,UInt32 index,PROPID propID,bool & result)160*f6dc9357SAndroid Build Coastguard Worker static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
161*f6dc9357SAndroid Build Coastguard Worker {
162*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
163*f6dc9357SAndroid Build Coastguard Worker   RINOK(archive->GetProperty(index, propID, &prop))
164*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_BOOL)
165*f6dc9357SAndroid Build Coastguard Worker     result = VARIANT_BOOLToBool(prop.boolVal);
166*f6dc9357SAndroid Build Coastguard Worker   else if (prop.vt == VT_EMPTY)
167*f6dc9357SAndroid Build Coastguard Worker     result = false;
168*f6dc9357SAndroid Build Coastguard Worker   else
169*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
170*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
171*f6dc9357SAndroid Build Coastguard Worker }
172*f6dc9357SAndroid Build Coastguard Worker 
IsArchiveItemFolder(IInArchive * archive,UInt32 index,bool & result)173*f6dc9357SAndroid Build Coastguard Worker static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
174*f6dc9357SAndroid Build Coastguard Worker {
175*f6dc9357SAndroid Build Coastguard Worker   return IsArchiveItemProp(archive, index, kpidIsDir, result);
176*f6dc9357SAndroid Build Coastguard Worker }
177*f6dc9357SAndroid Build Coastguard Worker 
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker static const wchar_t * const kEmptyFileAlias = L"[Content]";
180*f6dc9357SAndroid Build Coastguard Worker 
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////
183*f6dc9357SAndroid Build Coastguard Worker // Archive Open callback class
184*f6dc9357SAndroid Build Coastguard Worker 
185*f6dc9357SAndroid Build Coastguard Worker 
186*f6dc9357SAndroid Build Coastguard Worker class CArchiveOpenCallback Z7_final:
187*f6dc9357SAndroid Build Coastguard Worker   public IArchiveOpenCallback,
188*f6dc9357SAndroid Build Coastguard Worker   public ICryptoGetTextPassword,
189*f6dc9357SAndroid Build Coastguard Worker   public CMyUnknownImp
190*f6dc9357SAndroid Build Coastguard Worker {
191*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACES_IMP_UNK_2(IArchiveOpenCallback, ICryptoGetTextPassword)
192*f6dc9357SAndroid Build Coastguard Worker public:
193*f6dc9357SAndroid Build Coastguard Worker 
194*f6dc9357SAndroid Build Coastguard Worker   bool PasswordIsDefined;
195*f6dc9357SAndroid Build Coastguard Worker   UString Password;
196*f6dc9357SAndroid Build Coastguard Worker 
CArchiveOpenCallback()197*f6dc9357SAndroid Build Coastguard Worker   CArchiveOpenCallback() : PasswordIsDefined(false) {}
198*f6dc9357SAndroid Build Coastguard Worker };
199*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveOpenCallback::SetTotal (const UInt64 *,const UInt64 *))200*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */))
201*f6dc9357SAndroid Build Coastguard Worker {
202*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
203*f6dc9357SAndroid Build Coastguard Worker }
204*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveOpenCallback::SetCompleted (const UInt64 *,const UInt64 *))205*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */))
206*f6dc9357SAndroid Build Coastguard Worker {
207*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
208*f6dc9357SAndroid Build Coastguard Worker }
209*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveOpenCallback::CryptoGetTextPassword (BSTR * password))210*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password))
211*f6dc9357SAndroid Build Coastguard Worker {
212*f6dc9357SAndroid Build Coastguard Worker   if (!PasswordIsDefined)
213*f6dc9357SAndroid Build Coastguard Worker   {
214*f6dc9357SAndroid Build Coastguard Worker     // You can ask real password here from user
215*f6dc9357SAndroid Build Coastguard Worker #if 0
216*f6dc9357SAndroid Build Coastguard Worker     RINOK(GetPassword_HRESULT(&g_StdOut, Password))
217*f6dc9357SAndroid Build Coastguard Worker     PasswordIsDefined = true;
218*f6dc9357SAndroid Build Coastguard Worker #else
219*f6dc9357SAndroid Build Coastguard Worker     PrintError("Password is not defined");
220*f6dc9357SAndroid Build Coastguard Worker     return E_ABORT;
221*f6dc9357SAndroid Build Coastguard Worker #endif
222*f6dc9357SAndroid Build Coastguard Worker   }
223*f6dc9357SAndroid Build Coastguard Worker   return StringToBstr(Password, password);
224*f6dc9357SAndroid Build Coastguard Worker }
225*f6dc9357SAndroid Build Coastguard Worker 
226*f6dc9357SAndroid Build Coastguard Worker 
227*f6dc9357SAndroid Build Coastguard Worker 
228*f6dc9357SAndroid Build Coastguard Worker static const char * const kIncorrectCommand = "incorrect command";
229*f6dc9357SAndroid Build Coastguard Worker 
230*f6dc9357SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////
231*f6dc9357SAndroid Build Coastguard Worker // Archive Extracting callback class
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker static const char * const kTestingString    =  "Testing     ";
234*f6dc9357SAndroid Build Coastguard Worker static const char * const kExtractingString =  "Extracting  ";
235*f6dc9357SAndroid Build Coastguard Worker static const char * const kSkippingString   =  "Skipping    ";
236*f6dc9357SAndroid Build Coastguard Worker static const char * const kReadingString    =  "Reading     ";
237*f6dc9357SAndroid Build Coastguard Worker 
238*f6dc9357SAndroid Build Coastguard Worker static const char * const kUnsupportedMethod = "Unsupported Method";
239*f6dc9357SAndroid Build Coastguard Worker static const char * const kCRCFailed = "CRC Failed";
240*f6dc9357SAndroid Build Coastguard Worker static const char * const kDataError = "Data Error";
241*f6dc9357SAndroid Build Coastguard Worker static const char * const kUnavailableData = "Unavailable data";
242*f6dc9357SAndroid Build Coastguard Worker static const char * const kUnexpectedEnd = "Unexpected end of data";
243*f6dc9357SAndroid Build Coastguard Worker static const char * const kDataAfterEnd = "There are some data after the end of the payload data";
244*f6dc9357SAndroid Build Coastguard Worker static const char * const kIsNotArc = "Is not archive";
245*f6dc9357SAndroid Build Coastguard Worker static const char * const kHeadersError = "Headers Error";
246*f6dc9357SAndroid Build Coastguard Worker 
247*f6dc9357SAndroid Build Coastguard Worker 
248*f6dc9357SAndroid Build Coastguard Worker struct CArcTime
249*f6dc9357SAndroid Build Coastguard Worker {
250*f6dc9357SAndroid Build Coastguard Worker   FILETIME FT;
251*f6dc9357SAndroid Build Coastguard Worker   UInt16 Prec;
252*f6dc9357SAndroid Build Coastguard Worker   Byte Ns100;
253*f6dc9357SAndroid Build Coastguard Worker   bool Def;
254*f6dc9357SAndroid Build Coastguard Worker 
CArcTimeCArcTime255*f6dc9357SAndroid Build Coastguard Worker   CArcTime()
256*f6dc9357SAndroid Build Coastguard Worker   {
257*f6dc9357SAndroid Build Coastguard Worker     Clear();
258*f6dc9357SAndroid Build Coastguard Worker   }
259*f6dc9357SAndroid Build Coastguard Worker 
ClearCArcTime260*f6dc9357SAndroid Build Coastguard Worker   void Clear()
261*f6dc9357SAndroid Build Coastguard Worker   {
262*f6dc9357SAndroid Build Coastguard Worker     FT.dwHighDateTime = FT.dwLowDateTime = 0;
263*f6dc9357SAndroid Build Coastguard Worker     Prec = 0;
264*f6dc9357SAndroid Build Coastguard Worker     Ns100 = 0;
265*f6dc9357SAndroid Build Coastguard Worker     Def = false;
266*f6dc9357SAndroid Build Coastguard Worker   }
267*f6dc9357SAndroid Build Coastguard Worker 
IsZeroCArcTime268*f6dc9357SAndroid Build Coastguard Worker   bool IsZero() const
269*f6dc9357SAndroid Build Coastguard Worker   {
270*f6dc9357SAndroid Build Coastguard Worker     return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0;
271*f6dc9357SAndroid Build Coastguard Worker   }
272*f6dc9357SAndroid Build Coastguard Worker 
GetNumDigitsCArcTime273*f6dc9357SAndroid Build Coastguard Worker   int GetNumDigits() const
274*f6dc9357SAndroid Build Coastguard Worker   {
275*f6dc9357SAndroid Build Coastguard Worker     if (Prec == k_PropVar_TimePrec_Unix ||
276*f6dc9357SAndroid Build Coastguard Worker         Prec == k_PropVar_TimePrec_DOS)
277*f6dc9357SAndroid Build Coastguard Worker       return 0;
278*f6dc9357SAndroid Build Coastguard Worker     if (Prec == k_PropVar_TimePrec_HighPrec)
279*f6dc9357SAndroid Build Coastguard Worker       return 9;
280*f6dc9357SAndroid Build Coastguard Worker     if (Prec == k_PropVar_TimePrec_0)
281*f6dc9357SAndroid Build Coastguard Worker       return 7;
282*f6dc9357SAndroid Build Coastguard Worker     int digits = (int)Prec - (int)k_PropVar_TimePrec_Base;
283*f6dc9357SAndroid Build Coastguard Worker     if (digits < 0)
284*f6dc9357SAndroid Build Coastguard Worker       digits = 0;
285*f6dc9357SAndroid Build Coastguard Worker     return digits;
286*f6dc9357SAndroid Build Coastguard Worker   }
287*f6dc9357SAndroid Build Coastguard Worker 
Write_To_FiTimeCArcTime288*f6dc9357SAndroid Build Coastguard Worker   void Write_To_FiTime(CFiTime &dest) const
289*f6dc9357SAndroid Build Coastguard Worker   {
290*f6dc9357SAndroid Build Coastguard Worker    #ifdef _WIN32
291*f6dc9357SAndroid Build Coastguard Worker     dest = FT;
292*f6dc9357SAndroid Build Coastguard Worker    #else
293*f6dc9357SAndroid Build Coastguard Worker     if (FILETIME_To_timespec(FT, dest))
294*f6dc9357SAndroid Build Coastguard Worker     if ((Prec == k_PropVar_TimePrec_Base + 8 ||
295*f6dc9357SAndroid Build Coastguard Worker          Prec == k_PropVar_TimePrec_Base + 9)
296*f6dc9357SAndroid Build Coastguard Worker         && Ns100 != 0)
297*f6dc9357SAndroid Build Coastguard Worker     {
298*f6dc9357SAndroid Build Coastguard Worker       dest.tv_nsec += Ns100;
299*f6dc9357SAndroid Build Coastguard Worker     }
300*f6dc9357SAndroid Build Coastguard Worker    #endif
301*f6dc9357SAndroid Build Coastguard Worker   }
302*f6dc9357SAndroid Build Coastguard Worker 
Set_From_PropCArcTime303*f6dc9357SAndroid Build Coastguard Worker   void Set_From_Prop(const PROPVARIANT &prop)
304*f6dc9357SAndroid Build Coastguard Worker   {
305*f6dc9357SAndroid Build Coastguard Worker     FT = prop.filetime;
306*f6dc9357SAndroid Build Coastguard Worker     unsigned prec = 0;
307*f6dc9357SAndroid Build Coastguard Worker     unsigned ns100 = 0;
308*f6dc9357SAndroid Build Coastguard Worker     const unsigned prec_Temp = prop.wReserved1;
309*f6dc9357SAndroid Build Coastguard Worker     if (prec_Temp != 0
310*f6dc9357SAndroid Build Coastguard Worker         && prec_Temp <= k_PropVar_TimePrec_1ns
311*f6dc9357SAndroid Build Coastguard Worker         && prop.wReserved3 == 0)
312*f6dc9357SAndroid Build Coastguard Worker     {
313*f6dc9357SAndroid Build Coastguard Worker       const unsigned ns100_Temp = prop.wReserved2;
314*f6dc9357SAndroid Build Coastguard Worker       if (ns100_Temp < 100)
315*f6dc9357SAndroid Build Coastguard Worker       {
316*f6dc9357SAndroid Build Coastguard Worker         ns100 = ns100_Temp;
317*f6dc9357SAndroid Build Coastguard Worker         prec = prec_Temp;
318*f6dc9357SAndroid Build Coastguard Worker       }
319*f6dc9357SAndroid Build Coastguard Worker     }
320*f6dc9357SAndroid Build Coastguard Worker     Prec = (UInt16)prec;
321*f6dc9357SAndroid Build Coastguard Worker     Ns100 = (Byte)ns100;
322*f6dc9357SAndroid Build Coastguard Worker     Def = true;
323*f6dc9357SAndroid Build Coastguard Worker   }
324*f6dc9357SAndroid Build Coastguard Worker };
325*f6dc9357SAndroid Build Coastguard Worker 
326*f6dc9357SAndroid Build Coastguard Worker 
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker class CArchiveExtractCallback Z7_final:
329*f6dc9357SAndroid Build Coastguard Worker   public IArchiveExtractCallback,
330*f6dc9357SAndroid Build Coastguard Worker   public ICryptoGetTextPassword,
331*f6dc9357SAndroid Build Coastguard Worker   public CMyUnknownImp
332*f6dc9357SAndroid Build Coastguard Worker {
333*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACES_IMP_UNK_2(IArchiveExtractCallback, ICryptoGetTextPassword)
334*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IProgress)
335*f6dc9357SAndroid Build Coastguard Worker 
336*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IInArchive> _archiveHandler;
337*f6dc9357SAndroid Build Coastguard Worker   FString _directoryPath;  // Output directory
338*f6dc9357SAndroid Build Coastguard Worker   UString _filePath;       // name inside arcvhive
339*f6dc9357SAndroid Build Coastguard Worker   FString _diskFilePath;   // full path to file on disk
340*f6dc9357SAndroid Build Coastguard Worker   bool _extractMode;
341*f6dc9357SAndroid Build Coastguard Worker   struct CProcessedFileInfo
342*f6dc9357SAndroid Build Coastguard Worker   {
343*f6dc9357SAndroid Build Coastguard Worker     CArcTime MTime;
344*f6dc9357SAndroid Build Coastguard Worker     UInt32 Attrib;
345*f6dc9357SAndroid Build Coastguard Worker     bool isDir;
346*f6dc9357SAndroid Build Coastguard Worker     bool Attrib_Defined;
347*f6dc9357SAndroid Build Coastguard Worker   } _processedFileInfo;
348*f6dc9357SAndroid Build Coastguard Worker 
349*f6dc9357SAndroid Build Coastguard Worker   COutFileStream *_outFileStreamSpec;
350*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> _outFileStream;
351*f6dc9357SAndroid Build Coastguard Worker 
352*f6dc9357SAndroid Build Coastguard Worker public:
353*f6dc9357SAndroid Build Coastguard Worker   void Init(IInArchive *archiveHandler, const FString &directoryPath);
354*f6dc9357SAndroid Build Coastguard Worker 
355*f6dc9357SAndroid Build Coastguard Worker   UInt64 NumErrors;
356*f6dc9357SAndroid Build Coastguard Worker   bool PasswordIsDefined;
357*f6dc9357SAndroid Build Coastguard Worker   UString Password;
358*f6dc9357SAndroid Build Coastguard Worker 
CArchiveExtractCallback()359*f6dc9357SAndroid Build Coastguard Worker   CArchiveExtractCallback() : PasswordIsDefined(false) {}
360*f6dc9357SAndroid Build Coastguard Worker };
361*f6dc9357SAndroid Build Coastguard Worker 
Init(IInArchive * archiveHandler,const FString & directoryPath)362*f6dc9357SAndroid Build Coastguard Worker void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &directoryPath)
363*f6dc9357SAndroid Build Coastguard Worker {
364*f6dc9357SAndroid Build Coastguard Worker   NumErrors = 0;
365*f6dc9357SAndroid Build Coastguard Worker   _archiveHandler = archiveHandler;
366*f6dc9357SAndroid Build Coastguard Worker   _directoryPath = directoryPath;
367*f6dc9357SAndroid Build Coastguard Worker   NName::NormalizeDirPathPrefix(_directoryPath);
368*f6dc9357SAndroid Build Coastguard Worker }
369*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal (UInt64))370*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 /* size */))
371*f6dc9357SAndroid Build Coastguard Worker {
372*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
373*f6dc9357SAndroid Build Coastguard Worker }
374*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted (const UInt64 *))375*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */))
376*f6dc9357SAndroid Build Coastguard Worker {
377*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
378*f6dc9357SAndroid Build Coastguard Worker }
379*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveExtractCallback::GetStream (UInt32 index,ISequentialOutStream ** outStream,Int32 askExtractMode))380*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index,
381*f6dc9357SAndroid Build Coastguard Worker     ISequentialOutStream **outStream, Int32 askExtractMode))
382*f6dc9357SAndroid Build Coastguard Worker {
383*f6dc9357SAndroid Build Coastguard Worker   *outStream = NULL;
384*f6dc9357SAndroid Build Coastguard Worker   _outFileStream.Release();
385*f6dc9357SAndroid Build Coastguard Worker 
386*f6dc9357SAndroid Build Coastguard Worker   {
387*f6dc9357SAndroid Build Coastguard Worker     // Get Name
388*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
389*f6dc9357SAndroid Build Coastguard Worker     RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop))
390*f6dc9357SAndroid Build Coastguard Worker 
391*f6dc9357SAndroid Build Coastguard Worker     UString fullPath;
392*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_EMPTY)
393*f6dc9357SAndroid Build Coastguard Worker       fullPath = kEmptyFileAlias;
394*f6dc9357SAndroid Build Coastguard Worker     else
395*f6dc9357SAndroid Build Coastguard Worker     {
396*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_BSTR)
397*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
398*f6dc9357SAndroid Build Coastguard Worker       fullPath = prop.bstrVal;
399*f6dc9357SAndroid Build Coastguard Worker     }
400*f6dc9357SAndroid Build Coastguard Worker     _filePath = fullPath;
401*f6dc9357SAndroid Build Coastguard Worker   }
402*f6dc9357SAndroid Build Coastguard Worker 
403*f6dc9357SAndroid Build Coastguard Worker   if (askExtractMode != NArchive::NExtract::NAskMode::kExtract)
404*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
405*f6dc9357SAndroid Build Coastguard Worker 
406*f6dc9357SAndroid Build Coastguard Worker   {
407*f6dc9357SAndroid Build Coastguard Worker     // Get Attrib
408*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
409*f6dc9357SAndroid Build Coastguard Worker     RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop))
410*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_EMPTY)
411*f6dc9357SAndroid Build Coastguard Worker     {
412*f6dc9357SAndroid Build Coastguard Worker       _processedFileInfo.Attrib = 0;
413*f6dc9357SAndroid Build Coastguard Worker       _processedFileInfo.Attrib_Defined = false;
414*f6dc9357SAndroid Build Coastguard Worker     }
415*f6dc9357SAndroid Build Coastguard Worker     else
416*f6dc9357SAndroid Build Coastguard Worker     {
417*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI4)
418*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
419*f6dc9357SAndroid Build Coastguard Worker       _processedFileInfo.Attrib = prop.ulVal;
420*f6dc9357SAndroid Build Coastguard Worker       _processedFileInfo.Attrib_Defined = true;
421*f6dc9357SAndroid Build Coastguard Worker     }
422*f6dc9357SAndroid Build Coastguard Worker   }
423*f6dc9357SAndroid Build Coastguard Worker 
424*f6dc9357SAndroid Build Coastguard Worker   RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir))
425*f6dc9357SAndroid Build Coastguard Worker 
426*f6dc9357SAndroid Build Coastguard Worker   {
427*f6dc9357SAndroid Build Coastguard Worker     _processedFileInfo.MTime.Clear();
428*f6dc9357SAndroid Build Coastguard Worker     // Get Modified Time
429*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
430*f6dc9357SAndroid Build Coastguard Worker     RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop))
431*f6dc9357SAndroid Build Coastguard Worker     switch (prop.vt)
432*f6dc9357SAndroid Build Coastguard Worker     {
433*f6dc9357SAndroid Build Coastguard Worker       case VT_EMPTY:
434*f6dc9357SAndroid Build Coastguard Worker         // _processedFileInfo.MTime = _utcMTimeDefault;
435*f6dc9357SAndroid Build Coastguard Worker         break;
436*f6dc9357SAndroid Build Coastguard Worker       case VT_FILETIME:
437*f6dc9357SAndroid Build Coastguard Worker         _processedFileInfo.MTime.Set_From_Prop(prop);
438*f6dc9357SAndroid Build Coastguard Worker         break;
439*f6dc9357SAndroid Build Coastguard Worker       default:
440*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
441*f6dc9357SAndroid Build Coastguard Worker     }
442*f6dc9357SAndroid Build Coastguard Worker 
443*f6dc9357SAndroid Build Coastguard Worker   }
444*f6dc9357SAndroid Build Coastguard Worker   {
445*f6dc9357SAndroid Build Coastguard Worker     // Get Size
446*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
447*f6dc9357SAndroid Build Coastguard Worker     RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop))
448*f6dc9357SAndroid Build Coastguard Worker     UInt64 newFileSize;
449*f6dc9357SAndroid Build Coastguard Worker     /* bool newFileSizeDefined = */ ConvertPropVariantToUInt64(prop, newFileSize);
450*f6dc9357SAndroid Build Coastguard Worker   }
451*f6dc9357SAndroid Build Coastguard Worker 
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker   {
454*f6dc9357SAndroid Build Coastguard Worker     // Create folders for file
455*f6dc9357SAndroid Build Coastguard Worker     int slashPos = _filePath.ReverseFind_PathSepar();
456*f6dc9357SAndroid Build Coastguard Worker     if (slashPos >= 0)
457*f6dc9357SAndroid Build Coastguard Worker       CreateComplexDir(_directoryPath + us2fs(_filePath.Left(slashPos)));
458*f6dc9357SAndroid Build Coastguard Worker   }
459*f6dc9357SAndroid Build Coastguard Worker 
460*f6dc9357SAndroid Build Coastguard Worker   FString fullProcessedPath = _directoryPath + us2fs(_filePath);
461*f6dc9357SAndroid Build Coastguard Worker   _diskFilePath = fullProcessedPath;
462*f6dc9357SAndroid Build Coastguard Worker 
463*f6dc9357SAndroid Build Coastguard Worker   if (_processedFileInfo.isDir)
464*f6dc9357SAndroid Build Coastguard Worker   {
465*f6dc9357SAndroid Build Coastguard Worker     CreateComplexDir(fullProcessedPath);
466*f6dc9357SAndroid Build Coastguard Worker   }
467*f6dc9357SAndroid Build Coastguard Worker   else
468*f6dc9357SAndroid Build Coastguard Worker   {
469*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo fi;
470*f6dc9357SAndroid Build Coastguard Worker     if (fi.Find(fullProcessedPath))
471*f6dc9357SAndroid Build Coastguard Worker     {
472*f6dc9357SAndroid Build Coastguard Worker       if (!DeleteFileAlways(fullProcessedPath))
473*f6dc9357SAndroid Build Coastguard Worker       {
474*f6dc9357SAndroid Build Coastguard Worker         PrintError("Cannot delete output file", fullProcessedPath);
475*f6dc9357SAndroid Build Coastguard Worker         return E_ABORT;
476*f6dc9357SAndroid Build Coastguard Worker       }
477*f6dc9357SAndroid Build Coastguard Worker     }
478*f6dc9357SAndroid Build Coastguard Worker 
479*f6dc9357SAndroid Build Coastguard Worker     _outFileStreamSpec = new COutFileStream;
480*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
481*f6dc9357SAndroid Build Coastguard Worker     if (!_outFileStreamSpec->Create_ALWAYS(fullProcessedPath))
482*f6dc9357SAndroid Build Coastguard Worker     {
483*f6dc9357SAndroid Build Coastguard Worker       PrintError("Cannot open output file", fullProcessedPath);
484*f6dc9357SAndroid Build Coastguard Worker       return E_ABORT;
485*f6dc9357SAndroid Build Coastguard Worker     }
486*f6dc9357SAndroid Build Coastguard Worker     _outFileStream = outStreamLoc;
487*f6dc9357SAndroid Build Coastguard Worker     *outStream = outStreamLoc.Detach();
488*f6dc9357SAndroid Build Coastguard Worker   }
489*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
490*f6dc9357SAndroid Build Coastguard Worker }
491*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation (Int32 askExtractMode))492*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode))
493*f6dc9357SAndroid Build Coastguard Worker {
494*f6dc9357SAndroid Build Coastguard Worker   _extractMode = false;
495*f6dc9357SAndroid Build Coastguard Worker   switch (askExtractMode)
496*f6dc9357SAndroid Build Coastguard Worker   {
497*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kExtract:  _extractMode = true; break;
498*f6dc9357SAndroid Build Coastguard Worker   }
499*f6dc9357SAndroid Build Coastguard Worker   switch (askExtractMode)
500*f6dc9357SAndroid Build Coastguard Worker   {
501*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kExtract:  Print(kExtractingString); break;
502*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kTest:  Print(kTestingString); break;
503*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kSkip:  Print(kSkippingString); break;
504*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NAskMode::kReadExternal: Print(kReadingString); break;
505*f6dc9357SAndroid Build Coastguard Worker     default:
506*f6dc9357SAndroid Build Coastguard Worker       Print("??? "); break;
507*f6dc9357SAndroid Build Coastguard Worker   }
508*f6dc9357SAndroid Build Coastguard Worker   Print(_filePath);
509*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
510*f6dc9357SAndroid Build Coastguard Worker }
511*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult (Int32 operationResult))512*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 operationResult))
513*f6dc9357SAndroid Build Coastguard Worker {
514*f6dc9357SAndroid Build Coastguard Worker   switch (operationResult)
515*f6dc9357SAndroid Build Coastguard Worker   {
516*f6dc9357SAndroid Build Coastguard Worker     case NArchive::NExtract::NOperationResult::kOK:
517*f6dc9357SAndroid Build Coastguard Worker       break;
518*f6dc9357SAndroid Build Coastguard Worker     default:
519*f6dc9357SAndroid Build Coastguard Worker     {
520*f6dc9357SAndroid Build Coastguard Worker       NumErrors++;
521*f6dc9357SAndroid Build Coastguard Worker       Print("  :  ");
522*f6dc9357SAndroid Build Coastguard Worker       const char *s = NULL;
523*f6dc9357SAndroid Build Coastguard Worker       switch (operationResult)
524*f6dc9357SAndroid Build Coastguard Worker       {
525*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
526*f6dc9357SAndroid Build Coastguard Worker           s = kUnsupportedMethod;
527*f6dc9357SAndroid Build Coastguard Worker           break;
528*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kCRCError:
529*f6dc9357SAndroid Build Coastguard Worker           s = kCRCFailed;
530*f6dc9357SAndroid Build Coastguard Worker           break;
531*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kDataError:
532*f6dc9357SAndroid Build Coastguard Worker           s = kDataError;
533*f6dc9357SAndroid Build Coastguard Worker           break;
534*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kUnavailable:
535*f6dc9357SAndroid Build Coastguard Worker           s = kUnavailableData;
536*f6dc9357SAndroid Build Coastguard Worker           break;
537*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
538*f6dc9357SAndroid Build Coastguard Worker           s = kUnexpectedEnd;
539*f6dc9357SAndroid Build Coastguard Worker           break;
540*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kDataAfterEnd:
541*f6dc9357SAndroid Build Coastguard Worker           s = kDataAfterEnd;
542*f6dc9357SAndroid Build Coastguard Worker           break;
543*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kIsNotArc:
544*f6dc9357SAndroid Build Coastguard Worker           s = kIsNotArc;
545*f6dc9357SAndroid Build Coastguard Worker           break;
546*f6dc9357SAndroid Build Coastguard Worker         case NArchive::NExtract::NOperationResult::kHeadersError:
547*f6dc9357SAndroid Build Coastguard Worker           s = kHeadersError;
548*f6dc9357SAndroid Build Coastguard Worker           break;
549*f6dc9357SAndroid Build Coastguard Worker       }
550*f6dc9357SAndroid Build Coastguard Worker       if (s)
551*f6dc9357SAndroid Build Coastguard Worker       {
552*f6dc9357SAndroid Build Coastguard Worker         Print("Error : ");
553*f6dc9357SAndroid Build Coastguard Worker         Print(s);
554*f6dc9357SAndroid Build Coastguard Worker       }
555*f6dc9357SAndroid Build Coastguard Worker       else
556*f6dc9357SAndroid Build Coastguard Worker       {
557*f6dc9357SAndroid Build Coastguard Worker         char temp[16];
558*f6dc9357SAndroid Build Coastguard Worker         ConvertUInt32ToString((UInt32)operationResult, temp);
559*f6dc9357SAndroid Build Coastguard Worker         Print("Error #");
560*f6dc9357SAndroid Build Coastguard Worker         Print(temp);
561*f6dc9357SAndroid Build Coastguard Worker       }
562*f6dc9357SAndroid Build Coastguard Worker     }
563*f6dc9357SAndroid Build Coastguard Worker   }
564*f6dc9357SAndroid Build Coastguard Worker 
565*f6dc9357SAndroid Build Coastguard Worker   if (_outFileStream)
566*f6dc9357SAndroid Build Coastguard Worker   {
567*f6dc9357SAndroid Build Coastguard Worker     if (_processedFileInfo.MTime.Def)
568*f6dc9357SAndroid Build Coastguard Worker     {
569*f6dc9357SAndroid Build Coastguard Worker       CFiTime ft;
570*f6dc9357SAndroid Build Coastguard Worker       _processedFileInfo.MTime.Write_To_FiTime(ft);
571*f6dc9357SAndroid Build Coastguard Worker       _outFileStreamSpec->SetMTime(&ft);
572*f6dc9357SAndroid Build Coastguard Worker     }
573*f6dc9357SAndroid Build Coastguard Worker     RINOK(_outFileStreamSpec->Close())
574*f6dc9357SAndroid Build Coastguard Worker   }
575*f6dc9357SAndroid Build Coastguard Worker   _outFileStream.Release();
576*f6dc9357SAndroid Build Coastguard Worker   if (_extractMode && _processedFileInfo.Attrib_Defined)
577*f6dc9357SAndroid Build Coastguard Worker     SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib);
578*f6dc9357SAndroid Build Coastguard Worker   PrintNewLine();
579*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
580*f6dc9357SAndroid Build Coastguard Worker }
581*f6dc9357SAndroid Build Coastguard Worker 
582*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword (BSTR * password))583*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password))
584*f6dc9357SAndroid Build Coastguard Worker {
585*f6dc9357SAndroid Build Coastguard Worker   if (!PasswordIsDefined)
586*f6dc9357SAndroid Build Coastguard Worker   {
587*f6dc9357SAndroid Build Coastguard Worker #if 0
588*f6dc9357SAndroid Build Coastguard Worker     // You can ask real password here from user
589*f6dc9357SAndroid Build Coastguard Worker     RINOK(GetPassword_HRESULT(&g_StdOut, Password))
590*f6dc9357SAndroid Build Coastguard Worker     PasswordIsDefined = true;
591*f6dc9357SAndroid Build Coastguard Worker #else
592*f6dc9357SAndroid Build Coastguard Worker     PrintError("Password is not defined");
593*f6dc9357SAndroid Build Coastguard Worker     return E_ABORT;
594*f6dc9357SAndroid Build Coastguard Worker #endif
595*f6dc9357SAndroid Build Coastguard Worker   }
596*f6dc9357SAndroid Build Coastguard Worker   return StringToBstr(Password, password);
597*f6dc9357SAndroid Build Coastguard Worker }
598*f6dc9357SAndroid Build Coastguard Worker 
599*f6dc9357SAndroid Build Coastguard Worker 
600*f6dc9357SAndroid Build Coastguard Worker 
601*f6dc9357SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////
602*f6dc9357SAndroid Build Coastguard Worker // Archive Creating callback class
603*f6dc9357SAndroid Build Coastguard Worker 
604*f6dc9357SAndroid Build Coastguard Worker struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase
605*f6dc9357SAndroid Build Coastguard Worker {
606*f6dc9357SAndroid Build Coastguard Worker   UString Path_For_Handler;
607*f6dc9357SAndroid Build Coastguard Worker   FString FullPath; // for filesystem
608*f6dc9357SAndroid Build Coastguard Worker 
CDirItemCDirItem609*f6dc9357SAndroid Build Coastguard Worker   CDirItem(const NWindows::NFile::NFind::CFileInfo &fi):
610*f6dc9357SAndroid Build Coastguard Worker       CFileInfoBase(fi)
611*f6dc9357SAndroid Build Coastguard Worker     {}
612*f6dc9357SAndroid Build Coastguard Worker };
613*f6dc9357SAndroid Build Coastguard Worker 
614*f6dc9357SAndroid Build Coastguard Worker class CArchiveUpdateCallback Z7_final:
615*f6dc9357SAndroid Build Coastguard Worker   public IArchiveUpdateCallback2,
616*f6dc9357SAndroid Build Coastguard Worker   public ICryptoGetTextPassword2,
617*f6dc9357SAndroid Build Coastguard Worker   public CMyUnknownImp
618*f6dc9357SAndroid Build Coastguard Worker {
619*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACES_IMP_UNK_2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
620*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IProgress)
621*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IArchiveUpdateCallback)
622*f6dc9357SAndroid Build Coastguard Worker 
623*f6dc9357SAndroid Build Coastguard Worker public:
624*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<UInt64> VolumesSizes;
625*f6dc9357SAndroid Build Coastguard Worker   UString VolName;
626*f6dc9357SAndroid Build Coastguard Worker   UString VolExt;
627*f6dc9357SAndroid Build Coastguard Worker 
628*f6dc9357SAndroid Build Coastguard Worker   FString DirPrefix;
629*f6dc9357SAndroid Build Coastguard Worker   const CObjectVector<CDirItem> *DirItems;
630*f6dc9357SAndroid Build Coastguard Worker 
631*f6dc9357SAndroid Build Coastguard Worker   bool PasswordIsDefined;
632*f6dc9357SAndroid Build Coastguard Worker   UString Password;
633*f6dc9357SAndroid Build Coastguard Worker   bool AskPassword;
634*f6dc9357SAndroid Build Coastguard Worker 
635*f6dc9357SAndroid Build Coastguard Worker   bool m_NeedBeClosed;
636*f6dc9357SAndroid Build Coastguard Worker 
637*f6dc9357SAndroid Build Coastguard Worker   FStringVector FailedFiles;
638*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<HRESULT> FailedCodes;
639*f6dc9357SAndroid Build Coastguard Worker 
CArchiveUpdateCallback()640*f6dc9357SAndroid Build Coastguard Worker   CArchiveUpdateCallback():
641*f6dc9357SAndroid Build Coastguard Worker       DirItems(NULL),
642*f6dc9357SAndroid Build Coastguard Worker       PasswordIsDefined(false),
643*f6dc9357SAndroid Build Coastguard Worker       AskPassword(false)
644*f6dc9357SAndroid Build Coastguard Worker       {}
645*f6dc9357SAndroid Build Coastguard Worker 
~CArchiveUpdateCallback()646*f6dc9357SAndroid Build Coastguard Worker   ~CArchiveUpdateCallback() { Finilize(); }
647*f6dc9357SAndroid Build Coastguard Worker   HRESULT Finilize();
648*f6dc9357SAndroid Build Coastguard Worker 
Init(const CObjectVector<CDirItem> * dirItems)649*f6dc9357SAndroid Build Coastguard Worker   void Init(const CObjectVector<CDirItem> *dirItems)
650*f6dc9357SAndroid Build Coastguard Worker   {
651*f6dc9357SAndroid Build Coastguard Worker     DirItems = dirItems;
652*f6dc9357SAndroid Build Coastguard Worker     m_NeedBeClosed = false;
653*f6dc9357SAndroid Build Coastguard Worker     FailedFiles.Clear();
654*f6dc9357SAndroid Build Coastguard Worker     FailedCodes.Clear();
655*f6dc9357SAndroid Build Coastguard Worker   }
656*f6dc9357SAndroid Build Coastguard Worker };
657*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal (UInt64))658*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 /* size */))
659*f6dc9357SAndroid Build Coastguard Worker {
660*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
661*f6dc9357SAndroid Build Coastguard Worker }
662*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted (const UInt64 *))663*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */))
664*f6dc9357SAndroid Build Coastguard Worker {
665*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
666*f6dc9357SAndroid Build Coastguard Worker }
667*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo (UInt32,Int32 * newData,Int32 * newProperties,UInt32 * indexInArchive))668*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,
669*f6dc9357SAndroid Build Coastguard Worker       Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive))
670*f6dc9357SAndroid Build Coastguard Worker {
671*f6dc9357SAndroid Build Coastguard Worker   if (newData)
672*f6dc9357SAndroid Build Coastguard Worker     *newData = BoolToInt(true);
673*f6dc9357SAndroid Build Coastguard Worker   if (newProperties)
674*f6dc9357SAndroid Build Coastguard Worker     *newProperties = BoolToInt(true);
675*f6dc9357SAndroid Build Coastguard Worker   if (indexInArchive)
676*f6dc9357SAndroid Build Coastguard Worker     *indexInArchive = (UInt32)(Int32)-1;
677*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
678*f6dc9357SAndroid Build Coastguard Worker }
679*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty (UInt32 index,PROPID propID,PROPVARIANT * value))680*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
681*f6dc9357SAndroid Build Coastguard Worker {
682*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
683*f6dc9357SAndroid Build Coastguard Worker 
684*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidIsAnti)
685*f6dc9357SAndroid Build Coastguard Worker   {
686*f6dc9357SAndroid Build Coastguard Worker     prop = false;
687*f6dc9357SAndroid Build Coastguard Worker     prop.Detach(value);
688*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
689*f6dc9357SAndroid Build Coastguard Worker   }
690*f6dc9357SAndroid Build Coastguard Worker 
691*f6dc9357SAndroid Build Coastguard Worker   {
692*f6dc9357SAndroid Build Coastguard Worker     const CDirItem &di = (*DirItems)[index];
693*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
694*f6dc9357SAndroid Build Coastguard Worker     {
695*f6dc9357SAndroid Build Coastguard Worker       case kpidPath:  prop = di.Path_For_Handler; break;
696*f6dc9357SAndroid Build Coastguard Worker       case kpidIsDir:  prop = di.IsDir(); break;
697*f6dc9357SAndroid Build Coastguard Worker       case kpidSize:  prop = di.Size; break;
698*f6dc9357SAndroid Build Coastguard Worker       case kpidCTime:  PropVariant_SetFrom_FiTime(prop, di.CTime); break;
699*f6dc9357SAndroid Build Coastguard Worker       case kpidATime:  PropVariant_SetFrom_FiTime(prop, di.ATime); break;
700*f6dc9357SAndroid Build Coastguard Worker       case kpidMTime:  PropVariant_SetFrom_FiTime(prop, di.MTime); break;
701*f6dc9357SAndroid Build Coastguard Worker       case kpidAttrib:  prop = (UInt32)di.GetWinAttrib(); break;
702*f6dc9357SAndroid Build Coastguard Worker       case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break;
703*f6dc9357SAndroid Build Coastguard Worker     }
704*f6dc9357SAndroid Build Coastguard Worker   }
705*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
706*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
707*f6dc9357SAndroid Build Coastguard Worker }
708*f6dc9357SAndroid Build Coastguard Worker 
Finilize()709*f6dc9357SAndroid Build Coastguard Worker HRESULT CArchiveUpdateCallback::Finilize()
710*f6dc9357SAndroid Build Coastguard Worker {
711*f6dc9357SAndroid Build Coastguard Worker   if (m_NeedBeClosed)
712*f6dc9357SAndroid Build Coastguard Worker   {
713*f6dc9357SAndroid Build Coastguard Worker     PrintNewLine();
714*f6dc9357SAndroid Build Coastguard Worker     m_NeedBeClosed = false;
715*f6dc9357SAndroid Build Coastguard Worker   }
716*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
717*f6dc9357SAndroid Build Coastguard Worker }
718*f6dc9357SAndroid Build Coastguard Worker 
GetStream2(const wchar_t * name)719*f6dc9357SAndroid Build Coastguard Worker static void GetStream2(const wchar_t *name)
720*f6dc9357SAndroid Build Coastguard Worker {
721*f6dc9357SAndroid Build Coastguard Worker   Print("Compressing  ");
722*f6dc9357SAndroid Build Coastguard Worker   if (name[0] == 0)
723*f6dc9357SAndroid Build Coastguard Worker     name = kEmptyFileAlias;
724*f6dc9357SAndroid Build Coastguard Worker   Print(name);
725*f6dc9357SAndroid Build Coastguard Worker }
726*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream (UInt32 index,ISequentialInStream ** inStream))727*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream))
728*f6dc9357SAndroid Build Coastguard Worker {
729*f6dc9357SAndroid Build Coastguard Worker   RINOK(Finilize())
730*f6dc9357SAndroid Build Coastguard Worker 
731*f6dc9357SAndroid Build Coastguard Worker   const CDirItem &dirItem = (*DirItems)[index];
732*f6dc9357SAndroid Build Coastguard Worker   GetStream2(dirItem.Path_For_Handler);
733*f6dc9357SAndroid Build Coastguard Worker 
734*f6dc9357SAndroid Build Coastguard Worker   if (dirItem.IsDir())
735*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
736*f6dc9357SAndroid Build Coastguard Worker 
737*f6dc9357SAndroid Build Coastguard Worker   {
738*f6dc9357SAndroid Build Coastguard Worker     CInFileStream *inStreamSpec = new CInFileStream;
739*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
740*f6dc9357SAndroid Build Coastguard Worker     FString path = DirPrefix + dirItem.FullPath;
741*f6dc9357SAndroid Build Coastguard Worker     if (!inStreamSpec->Open(path))
742*f6dc9357SAndroid Build Coastguard Worker     {
743*f6dc9357SAndroid Build Coastguard Worker       const DWORD sysError = ::GetLastError();
744*f6dc9357SAndroid Build Coastguard Worker       FailedCodes.Add(HRESULT_FROM_WIN32(sysError));
745*f6dc9357SAndroid Build Coastguard Worker       FailedFiles.Add(path);
746*f6dc9357SAndroid Build Coastguard Worker       // if (systemError == ERROR_SHARING_VIOLATION)
747*f6dc9357SAndroid Build Coastguard Worker       {
748*f6dc9357SAndroid Build Coastguard Worker         PrintNewLine();
749*f6dc9357SAndroid Build Coastguard Worker         PrintError("WARNING: can't open file");
750*f6dc9357SAndroid Build Coastguard Worker         // Print(NError::MyFormatMessageW(systemError));
751*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
752*f6dc9357SAndroid Build Coastguard Worker       }
753*f6dc9357SAndroid Build Coastguard Worker       // return sysError;
754*f6dc9357SAndroid Build Coastguard Worker     }
755*f6dc9357SAndroid Build Coastguard Worker     *inStream = inStreamLoc.Detach();
756*f6dc9357SAndroid Build Coastguard Worker   }
757*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
758*f6dc9357SAndroid Build Coastguard Worker }
759*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult (Int32))760*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */))
761*f6dc9357SAndroid Build Coastguard Worker {
762*f6dc9357SAndroid Build Coastguard Worker   m_NeedBeClosed = true;
763*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
764*f6dc9357SAndroid Build Coastguard Worker }
765*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize (UInt32 index,UInt64 * size))766*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size))
767*f6dc9357SAndroid Build Coastguard Worker {
768*f6dc9357SAndroid Build Coastguard Worker   if (VolumesSizes.Size() == 0)
769*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
770*f6dc9357SAndroid Build Coastguard Worker   if (index >= (UInt32)VolumesSizes.Size())
771*f6dc9357SAndroid Build Coastguard Worker     index = VolumesSizes.Size() - 1;
772*f6dc9357SAndroid Build Coastguard Worker   *size = VolumesSizes[index];
773*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
774*f6dc9357SAndroid Build Coastguard Worker }
775*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream (UInt32 index,ISequentialOutStream ** volumeStream))776*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream))
777*f6dc9357SAndroid Build Coastguard Worker {
778*f6dc9357SAndroid Build Coastguard Worker   wchar_t temp[16];
779*f6dc9357SAndroid Build Coastguard Worker   ConvertUInt32ToString(index + 1, temp);
780*f6dc9357SAndroid Build Coastguard Worker   UString res = temp;
781*f6dc9357SAndroid Build Coastguard Worker   while (res.Len() < 2)
782*f6dc9357SAndroid Build Coastguard Worker     res.InsertAtFront(L'0');
783*f6dc9357SAndroid Build Coastguard Worker   UString fileName = VolName;
784*f6dc9357SAndroid Build Coastguard Worker   fileName.Add_Dot();
785*f6dc9357SAndroid Build Coastguard Worker   fileName += res;
786*f6dc9357SAndroid Build Coastguard Worker   fileName += VolExt;
787*f6dc9357SAndroid Build Coastguard Worker   COutFileStream *streamSpec = new COutFileStream;
788*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
789*f6dc9357SAndroid Build Coastguard Worker   if (!streamSpec->Create_NEW(us2fs(fileName)))
790*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
791*f6dc9357SAndroid Build Coastguard Worker   *volumeStream = streamLoc.Detach();
792*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
793*f6dc9357SAndroid Build Coastguard Worker }
794*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2 (Int32 * passwordIsDefined,BSTR * password))795*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password))
796*f6dc9357SAndroid Build Coastguard Worker {
797*f6dc9357SAndroid Build Coastguard Worker   if (!PasswordIsDefined)
798*f6dc9357SAndroid Build Coastguard Worker   {
799*f6dc9357SAndroid Build Coastguard Worker     if (AskPassword)
800*f6dc9357SAndroid Build Coastguard Worker     {
801*f6dc9357SAndroid Build Coastguard Worker #if 0
802*f6dc9357SAndroid Build Coastguard Worker       RINOK(GetPassword_HRESULT(&g_StdOut, Password))
803*f6dc9357SAndroid Build Coastguard Worker       PasswordIsDefined = true;
804*f6dc9357SAndroid Build Coastguard Worker #else
805*f6dc9357SAndroid Build Coastguard Worker       PrintError("Password is not defined");
806*f6dc9357SAndroid Build Coastguard Worker       return E_ABORT;
807*f6dc9357SAndroid Build Coastguard Worker #endif
808*f6dc9357SAndroid Build Coastguard Worker     }
809*f6dc9357SAndroid Build Coastguard Worker   }
810*f6dc9357SAndroid Build Coastguard Worker   *passwordIsDefined = BoolToInt(PasswordIsDefined);
811*f6dc9357SAndroid Build Coastguard Worker   return StringToBstr(Password, password);
812*f6dc9357SAndroid Build Coastguard Worker }
813*f6dc9357SAndroid Build Coastguard Worker 
814*f6dc9357SAndroid Build Coastguard Worker 
815*f6dc9357SAndroid Build Coastguard Worker // Main function
816*f6dc9357SAndroid Build Coastguard Worker 
817*f6dc9357SAndroid Build Coastguard Worker #if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
818*f6dc9357SAndroid Build Coastguard Worker #define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
819*f6dc9357SAndroid Build Coastguard Worker #endif
820*f6dc9357SAndroid Build Coastguard Worker 
main(int numArgs,const char * args[])821*f6dc9357SAndroid Build Coastguard Worker int Z7_CDECL main(int numArgs, const char *args[])
822*f6dc9357SAndroid Build Coastguard Worker {
823*f6dc9357SAndroid Build Coastguard Worker   NT_CHECK
824*f6dc9357SAndroid Build Coastguard Worker 
825*f6dc9357SAndroid Build Coastguard Worker   #ifdef ENV_HAVE_LOCALE
826*f6dc9357SAndroid Build Coastguard Worker   MY_SetLocale();
827*f6dc9357SAndroid Build Coastguard Worker   #endif
828*f6dc9357SAndroid Build Coastguard Worker 
829*f6dc9357SAndroid Build Coastguard Worker   PrintStringLn(kCopyrightString);
830*f6dc9357SAndroid Build Coastguard Worker 
831*f6dc9357SAndroid Build Coastguard Worker   if (numArgs < 2)
832*f6dc9357SAndroid Build Coastguard Worker   {
833*f6dc9357SAndroid Build Coastguard Worker     PrintStringLn(kHelpString);
834*f6dc9357SAndroid Build Coastguard Worker     return 0;
835*f6dc9357SAndroid Build Coastguard Worker   }
836*f6dc9357SAndroid Build Coastguard Worker 
837*f6dc9357SAndroid Build Coastguard Worker   FString dllPrefix;
838*f6dc9357SAndroid Build Coastguard Worker 
839*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
840*f6dc9357SAndroid Build Coastguard Worker   dllPrefix = NDLL::GetModuleDirPrefix();
841*f6dc9357SAndroid Build Coastguard Worker   #else
842*f6dc9357SAndroid Build Coastguard Worker   {
843*f6dc9357SAndroid Build Coastguard Worker     AString s (args[0]);
844*f6dc9357SAndroid Build Coastguard Worker     int sep = s.ReverseFind_PathSepar();
845*f6dc9357SAndroid Build Coastguard Worker     s.DeleteFrom(sep + 1);
846*f6dc9357SAndroid Build Coastguard Worker     dllPrefix = s;
847*f6dc9357SAndroid Build Coastguard Worker   }
848*f6dc9357SAndroid Build Coastguard Worker   #endif
849*f6dc9357SAndroid Build Coastguard Worker 
850*f6dc9357SAndroid Build Coastguard Worker   NDLL::CLibrary lib;
851*f6dc9357SAndroid Build Coastguard Worker   if (!lib.Load(dllPrefix + FTEXT(kDllName)))
852*f6dc9357SAndroid Build Coastguard Worker   {
853*f6dc9357SAndroid Build Coastguard Worker     PrintError("Cannot load 7-zip library");
854*f6dc9357SAndroid Build Coastguard Worker     return 1;
855*f6dc9357SAndroid Build Coastguard Worker   }
856*f6dc9357SAndroid Build Coastguard Worker 
857*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__)
858*f6dc9357SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wc++98-compat-pedantic"
859*f6dc9357SAndroid Build Coastguard Worker #endif
860*f6dc9357SAndroid Build Coastguard Worker 
861*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
862*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
863*f6dc9357SAndroid Build Coastguard Worker #endif
864*f6dc9357SAndroid Build Coastguard Worker 
865*f6dc9357SAndroid Build Coastguard Worker   Func_CreateObject
866*f6dc9357SAndroid Build Coastguard Worker      f_CreateObject = Z7_GET_PROC_ADDRESS(
867*f6dc9357SAndroid Build Coastguard Worker   Func_CreateObject, lib.Get_HMODULE(),
868*f6dc9357SAndroid Build Coastguard Worker       "CreateObject");
869*f6dc9357SAndroid Build Coastguard Worker   if (!f_CreateObject)
870*f6dc9357SAndroid Build Coastguard Worker   {
871*f6dc9357SAndroid Build Coastguard Worker     PrintError("Cannot get CreateObject");
872*f6dc9357SAndroid Build Coastguard Worker     return 1;
873*f6dc9357SAndroid Build Coastguard Worker   }
874*f6dc9357SAndroid Build Coastguard Worker 
875*f6dc9357SAndroid Build Coastguard Worker   char c = 0;
876*f6dc9357SAndroid Build Coastguard Worker   UString password;
877*f6dc9357SAndroid Build Coastguard Worker   bool passwordIsDefined = false;
878*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<FString> params;
879*f6dc9357SAndroid Build Coastguard Worker 
880*f6dc9357SAndroid Build Coastguard Worker   for (int curCmd = 1; curCmd < numArgs; curCmd++)
881*f6dc9357SAndroid Build Coastguard Worker   {
882*f6dc9357SAndroid Build Coastguard Worker     AString a(args[curCmd]);
883*f6dc9357SAndroid Build Coastguard Worker 
884*f6dc9357SAndroid Build Coastguard Worker     if (!a.IsEmpty())
885*f6dc9357SAndroid Build Coastguard Worker     {
886*f6dc9357SAndroid Build Coastguard Worker       if (a[0] == '-')
887*f6dc9357SAndroid Build Coastguard Worker       {
888*f6dc9357SAndroid Build Coastguard Worker         if (!passwordIsDefined && a[1] == 'p')
889*f6dc9357SAndroid Build Coastguard Worker         {
890*f6dc9357SAndroid Build Coastguard Worker           password = GetUnicodeString(a.Ptr(2));
891*f6dc9357SAndroid Build Coastguard Worker           passwordIsDefined = true;
892*f6dc9357SAndroid Build Coastguard Worker           continue;
893*f6dc9357SAndroid Build Coastguard Worker         }
894*f6dc9357SAndroid Build Coastguard Worker       }
895*f6dc9357SAndroid Build Coastguard Worker       else
896*f6dc9357SAndroid Build Coastguard Worker       {
897*f6dc9357SAndroid Build Coastguard Worker         if (c)
898*f6dc9357SAndroid Build Coastguard Worker         {
899*f6dc9357SAndroid Build Coastguard Worker           params.Add(CmdStringToFString(a));
900*f6dc9357SAndroid Build Coastguard Worker           continue;
901*f6dc9357SAndroid Build Coastguard Worker         }
902*f6dc9357SAndroid Build Coastguard Worker         if (a.Len() == 1)
903*f6dc9357SAndroid Build Coastguard Worker         {
904*f6dc9357SAndroid Build Coastguard Worker           c = (char)MyCharLower_Ascii(a[0]);
905*f6dc9357SAndroid Build Coastguard Worker           continue;
906*f6dc9357SAndroid Build Coastguard Worker         }
907*f6dc9357SAndroid Build Coastguard Worker       }
908*f6dc9357SAndroid Build Coastguard Worker     }
909*f6dc9357SAndroid Build Coastguard Worker     {
910*f6dc9357SAndroid Build Coastguard Worker       PrintError(kIncorrectCommand);
911*f6dc9357SAndroid Build Coastguard Worker       return 1;
912*f6dc9357SAndroid Build Coastguard Worker     }
913*f6dc9357SAndroid Build Coastguard Worker   }
914*f6dc9357SAndroid Build Coastguard Worker 
915*f6dc9357SAndroid Build Coastguard Worker   if (!c || params.Size() < 1)
916*f6dc9357SAndroid Build Coastguard Worker   {
917*f6dc9357SAndroid Build Coastguard Worker     PrintError(kIncorrectCommand);
918*f6dc9357SAndroid Build Coastguard Worker     return 1;
919*f6dc9357SAndroid Build Coastguard Worker   }
920*f6dc9357SAndroid Build Coastguard Worker 
921*f6dc9357SAndroid Build Coastguard Worker   const FString &archiveName = params[0];
922*f6dc9357SAndroid Build Coastguard Worker 
923*f6dc9357SAndroid Build Coastguard Worker   if (c == 'a')
924*f6dc9357SAndroid Build Coastguard Worker   {
925*f6dc9357SAndroid Build Coastguard Worker     // create archive command
926*f6dc9357SAndroid Build Coastguard Worker     if (params.Size() < 2)
927*f6dc9357SAndroid Build Coastguard Worker     {
928*f6dc9357SAndroid Build Coastguard Worker       PrintError(kIncorrectCommand);
929*f6dc9357SAndroid Build Coastguard Worker       return 1;
930*f6dc9357SAndroid Build Coastguard Worker     }
931*f6dc9357SAndroid Build Coastguard Worker     CObjectVector<CDirItem> dirItems;
932*f6dc9357SAndroid Build Coastguard Worker     {
933*f6dc9357SAndroid Build Coastguard Worker       unsigned i;
934*f6dc9357SAndroid Build Coastguard Worker       for (i = 1; i < params.Size(); i++)
935*f6dc9357SAndroid Build Coastguard Worker       {
936*f6dc9357SAndroid Build Coastguard Worker         const FString &name = params[i];
937*f6dc9357SAndroid Build Coastguard Worker 
938*f6dc9357SAndroid Build Coastguard Worker         NFind::CFileInfo fi;
939*f6dc9357SAndroid Build Coastguard Worker         if (!fi.Find(name))
940*f6dc9357SAndroid Build Coastguard Worker         {
941*f6dc9357SAndroid Build Coastguard Worker           PrintError("Can't find file", name);
942*f6dc9357SAndroid Build Coastguard Worker           return 1;
943*f6dc9357SAndroid Build Coastguard Worker         }
944*f6dc9357SAndroid Build Coastguard Worker 
945*f6dc9357SAndroid Build Coastguard Worker         CDirItem di(fi);
946*f6dc9357SAndroid Build Coastguard Worker 
947*f6dc9357SAndroid Build Coastguard Worker         di.Path_For_Handler = fs2us(name);
948*f6dc9357SAndroid Build Coastguard Worker         di.FullPath = name;
949*f6dc9357SAndroid Build Coastguard Worker         dirItems.Add(di);
950*f6dc9357SAndroid Build Coastguard Worker       }
951*f6dc9357SAndroid Build Coastguard Worker     }
952*f6dc9357SAndroid Build Coastguard Worker 
953*f6dc9357SAndroid Build Coastguard Worker     COutFileStream *outFileStreamSpec = new COutFileStream;
954*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
955*f6dc9357SAndroid Build Coastguard Worker     if (!outFileStreamSpec->Create_NEW(archiveName))
956*f6dc9357SAndroid Build Coastguard Worker     {
957*f6dc9357SAndroid Build Coastguard Worker       PrintError("can't create archive file");
958*f6dc9357SAndroid Build Coastguard Worker       return 1;
959*f6dc9357SAndroid Build Coastguard Worker     }
960*f6dc9357SAndroid Build Coastguard Worker 
961*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IOutArchive> outArchive;
962*f6dc9357SAndroid Build Coastguard Worker     if (f_CreateObject(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK)
963*f6dc9357SAndroid Build Coastguard Worker     {
964*f6dc9357SAndroid Build Coastguard Worker       PrintError("Cannot get class object");
965*f6dc9357SAndroid Build Coastguard Worker       return 1;
966*f6dc9357SAndroid Build Coastguard Worker     }
967*f6dc9357SAndroid Build Coastguard Worker 
968*f6dc9357SAndroid Build Coastguard Worker     CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
969*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
970*f6dc9357SAndroid Build Coastguard Worker     updateCallbackSpec->Init(&dirItems);
971*f6dc9357SAndroid Build Coastguard Worker     updateCallbackSpec->PasswordIsDefined = passwordIsDefined;
972*f6dc9357SAndroid Build Coastguard Worker     updateCallbackSpec->Password = password;
973*f6dc9357SAndroid Build Coastguard Worker 
974*f6dc9357SAndroid Build Coastguard Worker     /*
975*f6dc9357SAndroid Build Coastguard Worker     {
976*f6dc9357SAndroid Build Coastguard Worker       const wchar_t *names[] =
977*f6dc9357SAndroid Build Coastguard Worker       {
978*f6dc9357SAndroid Build Coastguard Worker         L"m",
979*f6dc9357SAndroid Build Coastguard Worker         L"s",
980*f6dc9357SAndroid Build Coastguard Worker         L"x"
981*f6dc9357SAndroid Build Coastguard Worker       };
982*f6dc9357SAndroid Build Coastguard Worker       const unsigned kNumProps = Z7_ARRAY_SIZE(names);
983*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant values[kNumProps] =
984*f6dc9357SAndroid Build Coastguard Worker       {
985*f6dc9357SAndroid Build Coastguard Worker         L"lzma",
986*f6dc9357SAndroid Build Coastguard Worker         false,    // solid mode OFF
987*f6dc9357SAndroid Build Coastguard Worker         (UInt32)9 // compression level = 9 - ultra
988*f6dc9357SAndroid Build Coastguard Worker       };
989*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISetProperties> setProperties;
990*f6dc9357SAndroid Build Coastguard Worker       outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties);
991*f6dc9357SAndroid Build Coastguard Worker       if (!setProperties)
992*f6dc9357SAndroid Build Coastguard Worker       {
993*f6dc9357SAndroid Build Coastguard Worker         PrintError("ISetProperties unsupported");
994*f6dc9357SAndroid Build Coastguard Worker         return 1;
995*f6dc9357SAndroid Build Coastguard Worker       }
996*f6dc9357SAndroid Build Coastguard Worker       if (setProperties->SetProperties(names, values, kNumProps) != S_OK)
997*f6dc9357SAndroid Build Coastguard Worker       {
998*f6dc9357SAndroid Build Coastguard Worker         PrintError("SetProperties() error");
999*f6dc9357SAndroid Build Coastguard Worker         return 1;
1000*f6dc9357SAndroid Build Coastguard Worker       }
1001*f6dc9357SAndroid Build Coastguard Worker     }
1002*f6dc9357SAndroid Build Coastguard Worker     */
1003*f6dc9357SAndroid Build Coastguard Worker 
1004*f6dc9357SAndroid Build Coastguard Worker     HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);
1005*f6dc9357SAndroid Build Coastguard Worker 
1006*f6dc9357SAndroid Build Coastguard Worker     updateCallbackSpec->Finilize();
1007*f6dc9357SAndroid Build Coastguard Worker 
1008*f6dc9357SAndroid Build Coastguard Worker     if (result != S_OK)
1009*f6dc9357SAndroid Build Coastguard Worker     {
1010*f6dc9357SAndroid Build Coastguard Worker       PrintError("Update Error");
1011*f6dc9357SAndroid Build Coastguard Worker       return 1;
1012*f6dc9357SAndroid Build Coastguard Worker     }
1013*f6dc9357SAndroid Build Coastguard Worker 
1014*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, updateCallbackSpec->FailedFiles)
1015*f6dc9357SAndroid Build Coastguard Worker     {
1016*f6dc9357SAndroid Build Coastguard Worker       PrintNewLine();
1017*f6dc9357SAndroid Build Coastguard Worker       PrintError("Error for file", updateCallbackSpec->FailedFiles[i]);
1018*f6dc9357SAndroid Build Coastguard Worker     }
1019*f6dc9357SAndroid Build Coastguard Worker 
1020*f6dc9357SAndroid Build Coastguard Worker     if (updateCallbackSpec->FailedFiles.Size() != 0)
1021*f6dc9357SAndroid Build Coastguard Worker       return 1;
1022*f6dc9357SAndroid Build Coastguard Worker   }
1023*f6dc9357SAndroid Build Coastguard Worker   else
1024*f6dc9357SAndroid Build Coastguard Worker   {
1025*f6dc9357SAndroid Build Coastguard Worker     if (params.Size() != 1)
1026*f6dc9357SAndroid Build Coastguard Worker     {
1027*f6dc9357SAndroid Build Coastguard Worker       PrintError(kIncorrectCommand);
1028*f6dc9357SAndroid Build Coastguard Worker       return 1;
1029*f6dc9357SAndroid Build Coastguard Worker     }
1030*f6dc9357SAndroid Build Coastguard Worker 
1031*f6dc9357SAndroid Build Coastguard Worker     bool listCommand;
1032*f6dc9357SAndroid Build Coastguard Worker 
1033*f6dc9357SAndroid Build Coastguard Worker     if (c == 'l')
1034*f6dc9357SAndroid Build Coastguard Worker       listCommand = true;
1035*f6dc9357SAndroid Build Coastguard Worker     else if (c == 'x')
1036*f6dc9357SAndroid Build Coastguard Worker       listCommand = false;
1037*f6dc9357SAndroid Build Coastguard Worker     else
1038*f6dc9357SAndroid Build Coastguard Worker     {
1039*f6dc9357SAndroid Build Coastguard Worker       PrintError(kIncorrectCommand);
1040*f6dc9357SAndroid Build Coastguard Worker       return 1;
1041*f6dc9357SAndroid Build Coastguard Worker     }
1042*f6dc9357SAndroid Build Coastguard Worker 
1043*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IInArchive> archive;
1044*f6dc9357SAndroid Build Coastguard Worker     if (f_CreateObject(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK)
1045*f6dc9357SAndroid Build Coastguard Worker     {
1046*f6dc9357SAndroid Build Coastguard Worker       PrintError("Cannot get class object");
1047*f6dc9357SAndroid Build Coastguard Worker       return 1;
1048*f6dc9357SAndroid Build Coastguard Worker     }
1049*f6dc9357SAndroid Build Coastguard Worker 
1050*f6dc9357SAndroid Build Coastguard Worker     CInFileStream *fileSpec = new CInFileStream;
1051*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IInStream> file = fileSpec;
1052*f6dc9357SAndroid Build Coastguard Worker 
1053*f6dc9357SAndroid Build Coastguard Worker     if (!fileSpec->Open(archiveName))
1054*f6dc9357SAndroid Build Coastguard Worker     {
1055*f6dc9357SAndroid Build Coastguard Worker       PrintError("Cannot open archive file", archiveName);
1056*f6dc9357SAndroid Build Coastguard Worker       return 1;
1057*f6dc9357SAndroid Build Coastguard Worker     }
1058*f6dc9357SAndroid Build Coastguard Worker 
1059*f6dc9357SAndroid Build Coastguard Worker     {
1060*f6dc9357SAndroid Build Coastguard Worker       CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;
1061*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
1062*f6dc9357SAndroid Build Coastguard Worker       openCallbackSpec->PasswordIsDefined = passwordIsDefined;
1063*f6dc9357SAndroid Build Coastguard Worker       openCallbackSpec->Password = password;
1064*f6dc9357SAndroid Build Coastguard Worker 
1065*f6dc9357SAndroid Build Coastguard Worker       const UInt64 scanSize = 1 << 23;
1066*f6dc9357SAndroid Build Coastguard Worker       if (archive->Open(file, &scanSize, openCallback) != S_OK)
1067*f6dc9357SAndroid Build Coastguard Worker       {
1068*f6dc9357SAndroid Build Coastguard Worker         PrintError("Cannot open file as archive", archiveName);
1069*f6dc9357SAndroid Build Coastguard Worker         return 1;
1070*f6dc9357SAndroid Build Coastguard Worker       }
1071*f6dc9357SAndroid Build Coastguard Worker     }
1072*f6dc9357SAndroid Build Coastguard Worker 
1073*f6dc9357SAndroid Build Coastguard Worker     if (listCommand)
1074*f6dc9357SAndroid Build Coastguard Worker     {
1075*f6dc9357SAndroid Build Coastguard Worker       // List command
1076*f6dc9357SAndroid Build Coastguard Worker       UInt32 numItems = 0;
1077*f6dc9357SAndroid Build Coastguard Worker       archive->GetNumberOfItems(&numItems);
1078*f6dc9357SAndroid Build Coastguard Worker       for (UInt32 i = 0; i < numItems; i++)
1079*f6dc9357SAndroid Build Coastguard Worker       {
1080*f6dc9357SAndroid Build Coastguard Worker         {
1081*f6dc9357SAndroid Build Coastguard Worker           // Get uncompressed size of file
1082*f6dc9357SAndroid Build Coastguard Worker           NCOM::CPropVariant prop;
1083*f6dc9357SAndroid Build Coastguard Worker           archive->GetProperty(i, kpidSize, &prop);
1084*f6dc9357SAndroid Build Coastguard Worker           char s[64];
1085*f6dc9357SAndroid Build Coastguard Worker           ConvertPropVariantToShortString(prop, s);
1086*f6dc9357SAndroid Build Coastguard Worker           Print(s);
1087*f6dc9357SAndroid Build Coastguard Worker           Print("  ");
1088*f6dc9357SAndroid Build Coastguard Worker         }
1089*f6dc9357SAndroid Build Coastguard Worker         {
1090*f6dc9357SAndroid Build Coastguard Worker           // Get name of file
1091*f6dc9357SAndroid Build Coastguard Worker           NCOM::CPropVariant prop;
1092*f6dc9357SAndroid Build Coastguard Worker           archive->GetProperty(i, kpidPath, &prop);
1093*f6dc9357SAndroid Build Coastguard Worker           if (prop.vt == VT_BSTR)
1094*f6dc9357SAndroid Build Coastguard Worker             Print(prop.bstrVal);
1095*f6dc9357SAndroid Build Coastguard Worker           else if (prop.vt != VT_EMPTY)
1096*f6dc9357SAndroid Build Coastguard Worker             Print("ERROR!");
1097*f6dc9357SAndroid Build Coastguard Worker         }
1098*f6dc9357SAndroid Build Coastguard Worker         PrintNewLine();
1099*f6dc9357SAndroid Build Coastguard Worker       }
1100*f6dc9357SAndroid Build Coastguard Worker     }
1101*f6dc9357SAndroid Build Coastguard Worker     else
1102*f6dc9357SAndroid Build Coastguard Worker     {
1103*f6dc9357SAndroid Build Coastguard Worker       // Extract command
1104*f6dc9357SAndroid Build Coastguard Worker       CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
1105*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
1106*f6dc9357SAndroid Build Coastguard Worker       extractCallbackSpec->Init(archive, FString()); // second parameter is output folder path
1107*f6dc9357SAndroid Build Coastguard Worker       extractCallbackSpec->PasswordIsDefined = passwordIsDefined;
1108*f6dc9357SAndroid Build Coastguard Worker       extractCallbackSpec->Password = password;
1109*f6dc9357SAndroid Build Coastguard Worker 
1110*f6dc9357SAndroid Build Coastguard Worker       /*
1111*f6dc9357SAndroid Build Coastguard Worker       const wchar_t *names[] =
1112*f6dc9357SAndroid Build Coastguard Worker       {
1113*f6dc9357SAndroid Build Coastguard Worker         L"mt",
1114*f6dc9357SAndroid Build Coastguard Worker         L"mtf"
1115*f6dc9357SAndroid Build Coastguard Worker       };
1116*f6dc9357SAndroid Build Coastguard Worker       const unsigned kNumProps = sizeof(names) / sizeof(names[0]);
1117*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant values[kNumProps] =
1118*f6dc9357SAndroid Build Coastguard Worker       {
1119*f6dc9357SAndroid Build Coastguard Worker         (UInt32)1,
1120*f6dc9357SAndroid Build Coastguard Worker         false
1121*f6dc9357SAndroid Build Coastguard Worker       };
1122*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISetProperties> setProperties;
1123*f6dc9357SAndroid Build Coastguard Worker       archive->QueryInterface(IID_ISetProperties, (void **)&setProperties);
1124*f6dc9357SAndroid Build Coastguard Worker       if (setProperties)
1125*f6dc9357SAndroid Build Coastguard Worker       {
1126*f6dc9357SAndroid Build Coastguard Worker         if (setProperties->SetProperties(names, values, kNumProps) != S_OK)
1127*f6dc9357SAndroid Build Coastguard Worker         {
1128*f6dc9357SAndroid Build Coastguard Worker           PrintError("SetProperties() error");
1129*f6dc9357SAndroid Build Coastguard Worker           return 1;
1130*f6dc9357SAndroid Build Coastguard Worker         }
1131*f6dc9357SAndroid Build Coastguard Worker       }
1132*f6dc9357SAndroid Build Coastguard Worker       */
1133*f6dc9357SAndroid Build Coastguard Worker 
1134*f6dc9357SAndroid Build Coastguard Worker       HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);
1135*f6dc9357SAndroid Build Coastguard Worker 
1136*f6dc9357SAndroid Build Coastguard Worker       if (result != S_OK)
1137*f6dc9357SAndroid Build Coastguard Worker       {
1138*f6dc9357SAndroid Build Coastguard Worker         PrintError("Extract Error");
1139*f6dc9357SAndroid Build Coastguard Worker         return 1;
1140*f6dc9357SAndroid Build Coastguard Worker       }
1141*f6dc9357SAndroid Build Coastguard Worker     }
1142*f6dc9357SAndroid Build Coastguard Worker   }
1143*f6dc9357SAndroid Build Coastguard Worker 
1144*f6dc9357SAndroid Build Coastguard Worker   return 0;
1145*f6dc9357SAndroid Build Coastguard Worker }
1146