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