1*f6dc9357SAndroid Build Coastguard Worker // ZipHandlerOut.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringToInt.h"
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/TimeUtils.h"
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker #include "../../IPassword.h"
13*f6dc9357SAndroid Build Coastguard Worker
14*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/OutBuffer.h"
15*f6dc9357SAndroid Build Coastguard Worker
16*f6dc9357SAndroid Build Coastguard Worker #include "../../Crypto/WzAes.h"
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ItemNameUtils.h"
19*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ParseProperties.h"
20*f6dc9357SAndroid Build Coastguard Worker
21*f6dc9357SAndroid Build Coastguard Worker #include "ZipHandler.h"
22*f6dc9357SAndroid Build Coastguard Worker #include "ZipUpdate.h"
23*f6dc9357SAndroid Build Coastguard Worker
24*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
25*f6dc9357SAndroid Build Coastguard Worker using namespace NCOM;
26*f6dc9357SAndroid Build Coastguard Worker using namespace NTime;
27*f6dc9357SAndroid Build Coastguard Worker
28*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
29*f6dc9357SAndroid Build Coastguard Worker namespace NZip {
30*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetFileTimeType (UInt32 * timeType))31*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType))
32*f6dc9357SAndroid Build Coastguard Worker {
33*f6dc9357SAndroid Build Coastguard Worker *timeType = TimeOptions.Prec;
34*f6dc9357SAndroid Build Coastguard Worker return S_OK;
35*f6dc9357SAndroid Build Coastguard Worker }
36*f6dc9357SAndroid Build Coastguard Worker
IsSimpleAsciiString(const wchar_t * s)37*f6dc9357SAndroid Build Coastguard Worker static bool IsSimpleAsciiString(const wchar_t *s)
38*f6dc9357SAndroid Build Coastguard Worker {
39*f6dc9357SAndroid Build Coastguard Worker for (;;)
40*f6dc9357SAndroid Build Coastguard Worker {
41*f6dc9357SAndroid Build Coastguard Worker wchar_t c = *s++;
42*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
43*f6dc9357SAndroid Build Coastguard Worker return true;
44*f6dc9357SAndroid Build Coastguard Worker if (c < 0x20 || c > 0x7F)
45*f6dc9357SAndroid Build Coastguard Worker return false;
46*f6dc9357SAndroid Build Coastguard Worker }
47*f6dc9357SAndroid Build Coastguard Worker }
48*f6dc9357SAndroid Build Coastguard Worker
49*f6dc9357SAndroid Build Coastguard Worker
FindZipMethod(const char * s,const char * const * names,unsigned num)50*f6dc9357SAndroid Build Coastguard Worker static int FindZipMethod(const char *s, const char * const *names, unsigned num)
51*f6dc9357SAndroid Build Coastguard Worker {
52*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < num; i++)
53*f6dc9357SAndroid Build Coastguard Worker {
54*f6dc9357SAndroid Build Coastguard Worker const char *name = names[i];
55*f6dc9357SAndroid Build Coastguard Worker if (name && StringsAreEqualNoCase_Ascii(s, name))
56*f6dc9357SAndroid Build Coastguard Worker return (int)i;
57*f6dc9357SAndroid Build Coastguard Worker }
58*f6dc9357SAndroid Build Coastguard Worker return -1;
59*f6dc9357SAndroid Build Coastguard Worker }
60*f6dc9357SAndroid Build Coastguard Worker
FindZipMethod(const char * s)61*f6dc9357SAndroid Build Coastguard Worker static int FindZipMethod(const char *s)
62*f6dc9357SAndroid Build Coastguard Worker {
63*f6dc9357SAndroid Build Coastguard Worker int k = FindZipMethod(s, kMethodNames1, kNumMethodNames1);
64*f6dc9357SAndroid Build Coastguard Worker if (k >= 0)
65*f6dc9357SAndroid Build Coastguard Worker return k;
66*f6dc9357SAndroid Build Coastguard Worker k = FindZipMethod(s, kMethodNames2, kNumMethodNames2);
67*f6dc9357SAndroid Build Coastguard Worker if (k >= 0)
68*f6dc9357SAndroid Build Coastguard Worker return (int)kMethodNames2Start + k;
69*f6dc9357SAndroid Build Coastguard Worker return -1;
70*f6dc9357SAndroid Build Coastguard Worker }
71*f6dc9357SAndroid Build Coastguard Worker
72*f6dc9357SAndroid Build Coastguard Worker
73*f6dc9357SAndroid Build Coastguard Worker #define COM_TRY_BEGIN2 try {
74*f6dc9357SAndroid Build Coastguard Worker #define COM_TRY_END2 } \
75*f6dc9357SAndroid Build Coastguard Worker catch(const CSystemException &e) { return e.ErrorCode; } \
76*f6dc9357SAndroid Build Coastguard Worker catch(...) { return E_OUTOFMEMORY; }
77*f6dc9357SAndroid Build Coastguard Worker
GetTime(IArchiveUpdateCallback * callback,unsigned index,PROPID propID,FILETIME & filetime)78*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetTime(IArchiveUpdateCallback *callback, unsigned index, PROPID propID, FILETIME &filetime)
79*f6dc9357SAndroid Build Coastguard Worker {
80*f6dc9357SAndroid Build Coastguard Worker filetime.dwHighDateTime = filetime.dwLowDateTime = 0;
81*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
82*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetProperty(index, propID, &prop))
83*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_FILETIME)
84*f6dc9357SAndroid Build Coastguard Worker filetime = prop.filetime;
85*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
86*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
87*f6dc9357SAndroid Build Coastguard Worker return S_OK;
88*f6dc9357SAndroid Build Coastguard Worker }
89*f6dc9357SAndroid Build Coastguard Worker
90*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::UpdateItems (ISequentialOutStream * outStream,UInt32 numItems,IArchiveUpdateCallback * callback))91*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
92*f6dc9357SAndroid Build Coastguard Worker IArchiveUpdateCallback *callback))
93*f6dc9357SAndroid Build Coastguard Worker {
94*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN2
95*f6dc9357SAndroid Build Coastguard Worker
96*f6dc9357SAndroid Build Coastguard Worker if (m_Archive.IsOpen())
97*f6dc9357SAndroid Build Coastguard Worker {
98*f6dc9357SAndroid Build Coastguard Worker if (!m_Archive.CanUpdate())
99*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
100*f6dc9357SAndroid Build Coastguard Worker }
101*f6dc9357SAndroid Build Coastguard Worker
102*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CUpdateItem> updateItems;
103*f6dc9357SAndroid Build Coastguard Worker updateItems.ClearAndReserve(numItems);
104*f6dc9357SAndroid Build Coastguard Worker
105*f6dc9357SAndroid Build Coastguard Worker bool thereAreAesUpdates = false;
106*f6dc9357SAndroid Build Coastguard Worker UInt64 largestSize = 0;
107*f6dc9357SAndroid Build Coastguard Worker bool largestSizeDefined = false;
108*f6dc9357SAndroid Build Coastguard Worker
109*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
110*f6dc9357SAndroid Build Coastguard Worker const UINT oemCP = GetOEMCP();
111*f6dc9357SAndroid Build Coastguard Worker #endif
112*f6dc9357SAndroid Build Coastguard Worker
113*f6dc9357SAndroid Build Coastguard Worker UString name;
114*f6dc9357SAndroid Build Coastguard Worker CUpdateItem ui;
115*f6dc9357SAndroid Build Coastguard Worker
116*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numItems; i++)
117*f6dc9357SAndroid Build Coastguard Worker {
118*f6dc9357SAndroid Build Coastguard Worker Int32 newData;
119*f6dc9357SAndroid Build Coastguard Worker Int32 newProps;
120*f6dc9357SAndroid Build Coastguard Worker UInt32 indexInArc;
121*f6dc9357SAndroid Build Coastguard Worker
122*f6dc9357SAndroid Build Coastguard Worker if (!callback)
123*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
124*f6dc9357SAndroid Build Coastguard Worker
125*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc))
126*f6dc9357SAndroid Build Coastguard Worker
127*f6dc9357SAndroid Build Coastguard Worker name.Empty();
128*f6dc9357SAndroid Build Coastguard Worker ui.Clear();
129*f6dc9357SAndroid Build Coastguard Worker
130*f6dc9357SAndroid Build Coastguard Worker ui.NewProps = IntToBool(newProps);
131*f6dc9357SAndroid Build Coastguard Worker ui.NewData = IntToBool(newData);
132*f6dc9357SAndroid Build Coastguard Worker ui.IndexInArc = (int)indexInArc;
133*f6dc9357SAndroid Build Coastguard Worker ui.IndexInClient = i;
134*f6dc9357SAndroid Build Coastguard Worker
135*f6dc9357SAndroid Build Coastguard Worker bool existInArchive = (indexInArc != (UInt32)(Int32)-1);
136*f6dc9357SAndroid Build Coastguard Worker if (existInArchive)
137*f6dc9357SAndroid Build Coastguard Worker {
138*f6dc9357SAndroid Build Coastguard Worker const CItemEx &inputItem = m_Items[indexInArc];
139*f6dc9357SAndroid Build Coastguard Worker if (inputItem.IsAesEncrypted())
140*f6dc9357SAndroid Build Coastguard Worker thereAreAesUpdates = true;
141*f6dc9357SAndroid Build Coastguard Worker if (!IntToBool(newProps))
142*f6dc9357SAndroid Build Coastguard Worker ui.IsDir = inputItem.IsDir();
143*f6dc9357SAndroid Build Coastguard Worker // ui.IsAltStream = inputItem.IsAltStream();
144*f6dc9357SAndroid Build Coastguard Worker }
145*f6dc9357SAndroid Build Coastguard Worker
146*f6dc9357SAndroid Build Coastguard Worker if (IntToBool(newProps))
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker {
149*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
150*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetProperty(i, kpidAttrib, &prop))
151*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
152*f6dc9357SAndroid Build Coastguard Worker ui.Attrib = 0;
153*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_UI4)
154*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
155*f6dc9357SAndroid Build Coastguard Worker else
156*f6dc9357SAndroid Build Coastguard Worker ui.Attrib = prop.ulVal;
157*f6dc9357SAndroid Build Coastguard Worker }
158*f6dc9357SAndroid Build Coastguard Worker
159*f6dc9357SAndroid Build Coastguard Worker {
160*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
161*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetProperty(i, kpidPath, &prop))
162*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
163*f6dc9357SAndroid Build Coastguard Worker {
164*f6dc9357SAndroid Build Coastguard Worker // name.Empty();
165*f6dc9357SAndroid Build Coastguard Worker }
166*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_BSTR)
167*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
168*f6dc9357SAndroid Build Coastguard Worker else
169*f6dc9357SAndroid Build Coastguard Worker name = prop.bstrVal;
170*f6dc9357SAndroid Build Coastguard Worker }
171*f6dc9357SAndroid Build Coastguard Worker
172*f6dc9357SAndroid Build Coastguard Worker {
173*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
174*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetProperty(i, kpidIsDir, &prop))
175*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
176*f6dc9357SAndroid Build Coastguard Worker ui.IsDir = false;
177*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_BOOL)
178*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
179*f6dc9357SAndroid Build Coastguard Worker else
180*f6dc9357SAndroid Build Coastguard Worker ui.IsDir = (prop.boolVal != VARIANT_FALSE);
181*f6dc9357SAndroid Build Coastguard Worker }
182*f6dc9357SAndroid Build Coastguard Worker
183*f6dc9357SAndroid Build Coastguard Worker /*
184*f6dc9357SAndroid Build Coastguard Worker {
185*f6dc9357SAndroid Build Coastguard Worker bool isAltStream = false;
186*f6dc9357SAndroid Build Coastguard Worker {
187*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
188*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetProperty(i, kpidIsAltStream, &prop));
189*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_BOOL)
190*f6dc9357SAndroid Build Coastguard Worker isAltStream = (prop.boolVal != VARIANT_FALSE);
191*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
192*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
193*f6dc9357SAndroid Build Coastguard Worker }
194*f6dc9357SAndroid Build Coastguard Worker
195*f6dc9357SAndroid Build Coastguard Worker if (isAltStream)
196*f6dc9357SAndroid Build Coastguard Worker {
197*f6dc9357SAndroid Build Coastguard Worker if (ui.IsDir)
198*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
199*f6dc9357SAndroid Build Coastguard Worker int delim = name.ReverseFind(L':');
200*f6dc9357SAndroid Build Coastguard Worker if (delim >= 0)
201*f6dc9357SAndroid Build Coastguard Worker {
202*f6dc9357SAndroid Build Coastguard Worker name.Delete(delim, 1);
203*f6dc9357SAndroid Build Coastguard Worker name.Insert(delim, UString(k_SpecName_NTFS_STREAM));
204*f6dc9357SAndroid Build Coastguard Worker ui.IsAltStream = true;
205*f6dc9357SAndroid Build Coastguard Worker }
206*f6dc9357SAndroid Build Coastguard Worker }
207*f6dc9357SAndroid Build Coastguard Worker }
208*f6dc9357SAndroid Build Coastguard Worker */
209*f6dc9357SAndroid Build Coastguard Worker
210*f6dc9357SAndroid Build Coastguard Worker // 22.00 : kpidTimeType is useless here : the code was disabled
211*f6dc9357SAndroid Build Coastguard Worker /*
212*f6dc9357SAndroid Build Coastguard Worker {
213*f6dc9357SAndroid Build Coastguard Worker CPropVariant prop;
214*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetProperty(i, kpidTimeType, &prop));
215*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_UI4)
216*f6dc9357SAndroid Build Coastguard Worker ui.NtfsTime_IsDefined = (prop.ulVal == NFileTimeType::kWindows);
217*f6dc9357SAndroid Build Coastguard Worker else
218*f6dc9357SAndroid Build Coastguard Worker ui.NtfsTime_IsDefined = _Write_NtfsTime;
219*f6dc9357SAndroid Build Coastguard Worker }
220*f6dc9357SAndroid Build Coastguard Worker */
221*f6dc9357SAndroid Build Coastguard Worker
222*f6dc9357SAndroid Build Coastguard Worker if (TimeOptions.Write_MTime.Val) RINOK (GetTime (callback, i, kpidMTime, ui.Ntfs_MTime))
223*f6dc9357SAndroid Build Coastguard Worker if (TimeOptions.Write_ATime.Val) RINOK (GetTime (callback, i, kpidATime, ui.Ntfs_ATime))
224*f6dc9357SAndroid Build Coastguard Worker if (TimeOptions.Write_CTime.Val) RINOK (GetTime (callback, i, kpidCTime, ui.Ntfs_CTime))
225*f6dc9357SAndroid Build Coastguard Worker
226*f6dc9357SAndroid Build Coastguard Worker if (TimeOptions.Prec != k_PropVar_TimePrec_DOS)
227*f6dc9357SAndroid Build Coastguard Worker {
228*f6dc9357SAndroid Build Coastguard Worker if (TimeOptions.Prec == k_PropVar_TimePrec_Unix ||
229*f6dc9357SAndroid Build Coastguard Worker TimeOptions.Prec == k_PropVar_TimePrec_Base)
230*f6dc9357SAndroid Build Coastguard Worker ui.Write_UnixTime = ! FILETIME_IsZero (ui.Ntfs_MTime);
231*f6dc9357SAndroid Build Coastguard Worker else
232*f6dc9357SAndroid Build Coastguard Worker {
233*f6dc9357SAndroid Build Coastguard Worker /*
234*f6dc9357SAndroid Build Coastguard Worker // if we want to store zero timestamps as zero timestamp, use the following:
235*f6dc9357SAndroid Build Coastguard Worker ui.Write_NtfsTime =
236*f6dc9357SAndroid Build Coastguard Worker _Write_MTime ||
237*f6dc9357SAndroid Build Coastguard Worker _Write_ATime ||
238*f6dc9357SAndroid Build Coastguard Worker _Write_CTime;
239*f6dc9357SAndroid Build Coastguard Worker */
240*f6dc9357SAndroid Build Coastguard Worker
241*f6dc9357SAndroid Build Coastguard Worker // We treat zero timestamp as no timestamp
242*f6dc9357SAndroid Build Coastguard Worker ui.Write_NtfsTime =
243*f6dc9357SAndroid Build Coastguard Worker ! FILETIME_IsZero (ui.Ntfs_MTime) ||
244*f6dc9357SAndroid Build Coastguard Worker ! FILETIME_IsZero (ui.Ntfs_ATime) ||
245*f6dc9357SAndroid Build Coastguard Worker ! FILETIME_IsZero (ui.Ntfs_CTime);
246*f6dc9357SAndroid Build Coastguard Worker }
247*f6dc9357SAndroid Build Coastguard Worker }
248*f6dc9357SAndroid Build Coastguard Worker
249*f6dc9357SAndroid Build Coastguard Worker /*
250*f6dc9357SAndroid Build Coastguard Worker how 0 in dos time works:
251*f6dc9357SAndroid Build Coastguard Worker win10 explorer extract : some random date 1601-04-25.
252*f6dc9357SAndroid Build Coastguard Worker winrar 6.10 : write time.
253*f6dc9357SAndroid Build Coastguard Worker 7zip : MTime of archive is used
254*f6dc9357SAndroid Build Coastguard Worker how 0 in tar works:
255*f6dc9357SAndroid Build Coastguard Worker winrar 6.10 : 1970
256*f6dc9357SAndroid Build Coastguard Worker 0 in dos field can show that there is no timestamp.
257*f6dc9357SAndroid Build Coastguard Worker we write correct 1970-01-01 in dos field, to support correct extraction in Win10.
258*f6dc9357SAndroid Build Coastguard Worker */
259*f6dc9357SAndroid Build Coastguard Worker
260*f6dc9357SAndroid Build Coastguard Worker UtcFileTime_To_LocalDosTime(ui.Ntfs_MTime, ui.Time);
261*f6dc9357SAndroid Build Coastguard Worker
262*f6dc9357SAndroid Build Coastguard Worker NItemName::ReplaceSlashes_OsToUnix(name);
263*f6dc9357SAndroid Build Coastguard Worker
264*f6dc9357SAndroid Build Coastguard Worker bool needSlash = ui.IsDir;
265*f6dc9357SAndroid Build Coastguard Worker const wchar_t kSlash = L'/';
266*f6dc9357SAndroid Build Coastguard Worker if (!name.IsEmpty())
267*f6dc9357SAndroid Build Coastguard Worker {
268*f6dc9357SAndroid Build Coastguard Worker if (name.Back() == kSlash)
269*f6dc9357SAndroid Build Coastguard Worker {
270*f6dc9357SAndroid Build Coastguard Worker if (!ui.IsDir)
271*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
272*f6dc9357SAndroid Build Coastguard Worker needSlash = false;
273*f6dc9357SAndroid Build Coastguard Worker }
274*f6dc9357SAndroid Build Coastguard Worker }
275*f6dc9357SAndroid Build Coastguard Worker if (needSlash)
276*f6dc9357SAndroid Build Coastguard Worker name += kSlash;
277*f6dc9357SAndroid Build Coastguard Worker
278*f6dc9357SAndroid Build Coastguard Worker const UINT codePage = _forceCodePage ? _specifiedCodePage : CP_OEMCP;
279*f6dc9357SAndroid Build Coastguard Worker bool tryUtf8 = true;
280*f6dc9357SAndroid Build Coastguard Worker
281*f6dc9357SAndroid Build Coastguard Worker /*
282*f6dc9357SAndroid Build Coastguard Worker Windows 10 allows users to set UTF-8 in Region Settings via option:
283*f6dc9357SAndroid Build Coastguard Worker "Beta: Use Unicode UTF-8 for worldwide language support"
284*f6dc9357SAndroid Build Coastguard Worker In that case Windows uses CP_UTF8 when we use CP_OEMCP.
285*f6dc9357SAndroid Build Coastguard Worker 21.02 fixed:
286*f6dc9357SAndroid Build Coastguard Worker we set UTF-8 mark for non-latin files for such UTF-8 mode in Windows.
287*f6dc9357SAndroid Build Coastguard Worker we write additional Info-Zip Utf-8 FileName Extra for non-latin names/
288*f6dc9357SAndroid Build Coastguard Worker */
289*f6dc9357SAndroid Build Coastguard Worker
290*f6dc9357SAndroid Build Coastguard Worker if ((codePage != CP_UTF8) &&
291*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
292*f6dc9357SAndroid Build Coastguard Worker (m_ForceLocal || !m_ForceUtf8) && (oemCP != CP_UTF8)
293*f6dc9357SAndroid Build Coastguard Worker #else
294*f6dc9357SAndroid Build Coastguard Worker (m_ForceLocal && !m_ForceUtf8)
295*f6dc9357SAndroid Build Coastguard Worker #endif
296*f6dc9357SAndroid Build Coastguard Worker )
297*f6dc9357SAndroid Build Coastguard Worker {
298*f6dc9357SAndroid Build Coastguard Worker bool defaultCharWasUsed;
299*f6dc9357SAndroid Build Coastguard Worker ui.Name = UnicodeStringToMultiByte(name, codePage, '_', defaultCharWasUsed);
300*f6dc9357SAndroid Build Coastguard Worker tryUtf8 = (!m_ForceLocal && (defaultCharWasUsed ||
301*f6dc9357SAndroid Build Coastguard Worker MultiByteToUnicodeString(ui.Name, codePage) != name));
302*f6dc9357SAndroid Build Coastguard Worker }
303*f6dc9357SAndroid Build Coastguard Worker
304*f6dc9357SAndroid Build Coastguard Worker const bool isNonLatin = !name.IsAscii();
305*f6dc9357SAndroid Build Coastguard Worker
306*f6dc9357SAndroid Build Coastguard Worker if (tryUtf8)
307*f6dc9357SAndroid Build Coastguard Worker {
308*f6dc9357SAndroid Build Coastguard Worker ui.IsUtf8 = isNonLatin;
309*f6dc9357SAndroid Build Coastguard Worker ConvertUnicodeToUTF8(name, ui.Name);
310*f6dc9357SAndroid Build Coastguard Worker
311*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
312*f6dc9357SAndroid Build Coastguard Worker if (ui.IsUtf8 && !CheckUTF8_AString(ui.Name))
313*f6dc9357SAndroid Build Coastguard Worker {
314*f6dc9357SAndroid Build Coastguard Worker // if it's non-Windows and there are non-UTF8 characters we clear UTF8-flag
315*f6dc9357SAndroid Build Coastguard Worker ui.IsUtf8 = false;
316*f6dc9357SAndroid Build Coastguard Worker }
317*f6dc9357SAndroid Build Coastguard Worker #endif
318*f6dc9357SAndroid Build Coastguard Worker }
319*f6dc9357SAndroid Build Coastguard Worker else if (isNonLatin)
320*f6dc9357SAndroid Build Coastguard Worker Convert_Unicode_To_UTF8_Buf(name, ui.Name_Utf);
321*f6dc9357SAndroid Build Coastguard Worker
322*f6dc9357SAndroid Build Coastguard Worker if (ui.Name.Len() >= (1 << 16)
323*f6dc9357SAndroid Build Coastguard Worker || ui.Name_Utf.Size() >= (1 << 16) - 128)
324*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
325*f6dc9357SAndroid Build Coastguard Worker
326*f6dc9357SAndroid Build Coastguard Worker {
327*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
328*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetProperty(i, kpidComment, &prop))
329*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_EMPTY)
330*f6dc9357SAndroid Build Coastguard Worker {
331*f6dc9357SAndroid Build Coastguard Worker // ui.Comment.Free();
332*f6dc9357SAndroid Build Coastguard Worker }
333*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_BSTR)
334*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
335*f6dc9357SAndroid Build Coastguard Worker else
336*f6dc9357SAndroid Build Coastguard Worker {
337*f6dc9357SAndroid Build Coastguard Worker UString s = prop.bstrVal;
338*f6dc9357SAndroid Build Coastguard Worker AString a;
339*f6dc9357SAndroid Build Coastguard Worker if (ui.IsUtf8)
340*f6dc9357SAndroid Build Coastguard Worker ConvertUnicodeToUTF8(s, a);
341*f6dc9357SAndroid Build Coastguard Worker else
342*f6dc9357SAndroid Build Coastguard Worker {
343*f6dc9357SAndroid Build Coastguard Worker bool defaultCharWasUsed;
344*f6dc9357SAndroid Build Coastguard Worker a = UnicodeStringToMultiByte(s, codePage, '_', defaultCharWasUsed);
345*f6dc9357SAndroid Build Coastguard Worker }
346*f6dc9357SAndroid Build Coastguard Worker if (a.Len() >= (1 << 16))
347*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
348*f6dc9357SAndroid Build Coastguard Worker ui.Comment.CopyFrom((const Byte *)(const char *)a, a.Len());
349*f6dc9357SAndroid Build Coastguard Worker }
350*f6dc9357SAndroid Build Coastguard Worker }
351*f6dc9357SAndroid Build Coastguard Worker
352*f6dc9357SAndroid Build Coastguard Worker
353*f6dc9357SAndroid Build Coastguard Worker /*
354*f6dc9357SAndroid Build Coastguard Worker if (existInArchive)
355*f6dc9357SAndroid Build Coastguard Worker {
356*f6dc9357SAndroid Build Coastguard Worker const CItemEx &itemInfo = m_Items[indexInArc];
357*f6dc9357SAndroid Build Coastguard Worker // ui.Commented = itemInfo.IsCommented();
358*f6dc9357SAndroid Build Coastguard Worker ui.Commented = false;
359*f6dc9357SAndroid Build Coastguard Worker if (ui.Commented)
360*f6dc9357SAndroid Build Coastguard Worker {
361*f6dc9357SAndroid Build Coastguard Worker ui.CommentRange.Position = itemInfo.GetCommentPosition();
362*f6dc9357SAndroid Build Coastguard Worker ui.CommentRange.Size = itemInfo.CommentSize;
363*f6dc9357SAndroid Build Coastguard Worker }
364*f6dc9357SAndroid Build Coastguard Worker }
365*f6dc9357SAndroid Build Coastguard Worker else
366*f6dc9357SAndroid Build Coastguard Worker ui.Commented = false;
367*f6dc9357SAndroid Build Coastguard Worker */
368*f6dc9357SAndroid Build Coastguard Worker }
369*f6dc9357SAndroid Build Coastguard Worker
370*f6dc9357SAndroid Build Coastguard Worker
371*f6dc9357SAndroid Build Coastguard Worker if (IntToBool(newData))
372*f6dc9357SAndroid Build Coastguard Worker {
373*f6dc9357SAndroid Build Coastguard Worker UInt64 size = 0;
374*f6dc9357SAndroid Build Coastguard Worker if (!ui.IsDir)
375*f6dc9357SAndroid Build Coastguard Worker {
376*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
377*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->GetProperty(i, kpidSize, &prop))
378*f6dc9357SAndroid Build Coastguard Worker if (prop.vt != VT_UI8)
379*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
380*f6dc9357SAndroid Build Coastguard Worker size = prop.uhVal.QuadPart;
381*f6dc9357SAndroid Build Coastguard Worker if (largestSize < size)
382*f6dc9357SAndroid Build Coastguard Worker largestSize = size;
383*f6dc9357SAndroid Build Coastguard Worker largestSizeDefined = true;
384*f6dc9357SAndroid Build Coastguard Worker }
385*f6dc9357SAndroid Build Coastguard Worker ui.Size = size;
386*f6dc9357SAndroid Build Coastguard Worker }
387*f6dc9357SAndroid Build Coastguard Worker
388*f6dc9357SAndroid Build Coastguard Worker updateItems.Add(ui);
389*f6dc9357SAndroid Build Coastguard Worker }
390*f6dc9357SAndroid Build Coastguard Worker
391*f6dc9357SAndroid Build Coastguard Worker
392*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
393*f6dc9357SAndroid Build Coastguard Worker {
394*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IArchiveUpdateCallback> udateCallBack2(callback);
395*f6dc9357SAndroid Build Coastguard Worker udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
396*f6dc9357SAndroid Build Coastguard Worker }
397*f6dc9357SAndroid Build Coastguard Worker CCompressionMethodMode options;
398*f6dc9357SAndroid Build Coastguard Worker (CBaseProps &)options = _props;
399*f6dc9357SAndroid Build Coastguard Worker options.DataSizeReduce = largestSize;
400*f6dc9357SAndroid Build Coastguard Worker options.DataSizeReduce_Defined = largestSizeDefined;
401*f6dc9357SAndroid Build Coastguard Worker
402*f6dc9357SAndroid Build Coastguard Worker options.Password_Defined = false;
403*f6dc9357SAndroid Build Coastguard Worker options.Password.Wipe_and_Empty();
404*f6dc9357SAndroid Build Coastguard Worker if (getTextPassword)
405*f6dc9357SAndroid Build Coastguard Worker {
406*f6dc9357SAndroid Build Coastguard Worker CMyComBSTR_Wipe password;
407*f6dc9357SAndroid Build Coastguard Worker Int32 passwordIsDefined;
408*f6dc9357SAndroid Build Coastguard Worker RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password))
409*f6dc9357SAndroid Build Coastguard Worker options.Password_Defined = IntToBool(passwordIsDefined);
410*f6dc9357SAndroid Build Coastguard Worker if (options.Password_Defined)
411*f6dc9357SAndroid Build Coastguard Worker {
412*f6dc9357SAndroid Build Coastguard Worker if (!m_ForceAesMode)
413*f6dc9357SAndroid Build Coastguard Worker options.IsAesMode = thereAreAesUpdates;
414*f6dc9357SAndroid Build Coastguard Worker
415*f6dc9357SAndroid Build Coastguard Worker if (!IsSimpleAsciiString(password))
416*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
417*f6dc9357SAndroid Build Coastguard Worker if (password)
418*f6dc9357SAndroid Build Coastguard Worker UnicodeStringToMultiByte2(options.Password, (LPCOLESTR)password, CP_OEMCP);
419*f6dc9357SAndroid Build Coastguard Worker if (options.IsAesMode)
420*f6dc9357SAndroid Build Coastguard Worker {
421*f6dc9357SAndroid Build Coastguard Worker if (options.Password.Len() > NCrypto::NWzAes::kPasswordSizeMax)
422*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
423*f6dc9357SAndroid Build Coastguard Worker }
424*f6dc9357SAndroid Build Coastguard Worker }
425*f6dc9357SAndroid Build Coastguard Worker }
426*f6dc9357SAndroid Build Coastguard Worker
427*f6dc9357SAndroid Build Coastguard Worker
428*f6dc9357SAndroid Build Coastguard Worker int mainMethod = m_MainMethod;
429*f6dc9357SAndroid Build Coastguard Worker
430*f6dc9357SAndroid Build Coastguard Worker if (mainMethod < 0)
431*f6dc9357SAndroid Build Coastguard Worker {
432*f6dc9357SAndroid Build Coastguard Worker if (!_props._methods.IsEmpty())
433*f6dc9357SAndroid Build Coastguard Worker {
434*f6dc9357SAndroid Build Coastguard Worker const AString &methodName = _props._methods.Front().MethodName;
435*f6dc9357SAndroid Build Coastguard Worker if (!methodName.IsEmpty())
436*f6dc9357SAndroid Build Coastguard Worker {
437*f6dc9357SAndroid Build Coastguard Worker mainMethod = FindZipMethod(methodName);
438*f6dc9357SAndroid Build Coastguard Worker if (mainMethod < 0)
439*f6dc9357SAndroid Build Coastguard Worker {
440*f6dc9357SAndroid Build Coastguard Worker CMethodId methodId;
441*f6dc9357SAndroid Build Coastguard Worker UInt32 numStreams;
442*f6dc9357SAndroid Build Coastguard Worker bool isFilter;
443*f6dc9357SAndroid Build Coastguard Worker if (FindMethod_Index(EXTERNAL_CODECS_VARS methodName, true,
444*f6dc9357SAndroid Build Coastguard Worker methodId, numStreams, isFilter) < 0)
445*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
446*f6dc9357SAndroid Build Coastguard Worker if (numStreams != 1)
447*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
448*f6dc9357SAndroid Build Coastguard Worker if (methodId == kMethodId_BZip2)
449*f6dc9357SAndroid Build Coastguard Worker mainMethod = NFileHeader::NCompressionMethod::kBZip2;
450*f6dc9357SAndroid Build Coastguard Worker else
451*f6dc9357SAndroid Build Coastguard Worker {
452*f6dc9357SAndroid Build Coastguard Worker if (methodId < kMethodId_ZipBase)
453*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
454*f6dc9357SAndroid Build Coastguard Worker methodId -= kMethodId_ZipBase;
455*f6dc9357SAndroid Build Coastguard Worker if (methodId > 0xFF)
456*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
457*f6dc9357SAndroid Build Coastguard Worker mainMethod = (int)methodId;
458*f6dc9357SAndroid Build Coastguard Worker }
459*f6dc9357SAndroid Build Coastguard Worker }
460*f6dc9357SAndroid Build Coastguard Worker }
461*f6dc9357SAndroid Build Coastguard Worker }
462*f6dc9357SAndroid Build Coastguard Worker }
463*f6dc9357SAndroid Build Coastguard Worker
464*f6dc9357SAndroid Build Coastguard Worker if (mainMethod < 0)
465*f6dc9357SAndroid Build Coastguard Worker mainMethod = (Byte)(((_props.GetLevel() == 0) ?
466*f6dc9357SAndroid Build Coastguard Worker NFileHeader::NCompressionMethod::kStore :
467*f6dc9357SAndroid Build Coastguard Worker NFileHeader::NCompressionMethod::kDeflate));
468*f6dc9357SAndroid Build Coastguard Worker else
469*f6dc9357SAndroid Build Coastguard Worker mainMethod = (Byte)mainMethod;
470*f6dc9357SAndroid Build Coastguard Worker
471*f6dc9357SAndroid Build Coastguard Worker options.MethodSequence.Add((Byte)mainMethod);
472*f6dc9357SAndroid Build Coastguard Worker
473*f6dc9357SAndroid Build Coastguard Worker if (mainMethod != NFileHeader::NCompressionMethod::kStore)
474*f6dc9357SAndroid Build Coastguard Worker options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStore);
475*f6dc9357SAndroid Build Coastguard Worker
476*f6dc9357SAndroid Build Coastguard Worker options.Force_SeqOutMode = _force_SeqOutMode;
477*f6dc9357SAndroid Build Coastguard Worker
478*f6dc9357SAndroid Build Coastguard Worker CUpdateOptions uo;
479*f6dc9357SAndroid Build Coastguard Worker uo.Write_MTime = TimeOptions.Write_MTime.Val;
480*f6dc9357SAndroid Build Coastguard Worker uo.Write_ATime = TimeOptions.Write_ATime.Val;
481*f6dc9357SAndroid Build Coastguard Worker uo.Write_CTime = TimeOptions.Write_CTime.Val;
482*f6dc9357SAndroid Build Coastguard Worker /*
483*f6dc9357SAndroid Build Coastguard Worker uo.Write_NtfsTime = _Write_NtfsTime &&
484*f6dc9357SAndroid Build Coastguard Worker (_Write_MTime || _Write_ATime || _Write_CTime);
485*f6dc9357SAndroid Build Coastguard Worker uo.Write_UnixTime = _Write_UnixTime;
486*f6dc9357SAndroid Build Coastguard Worker */
487*f6dc9357SAndroid Build Coastguard Worker
488*f6dc9357SAndroid Build Coastguard Worker return Update(
489*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_VARS
490*f6dc9357SAndroid Build Coastguard Worker m_Items, updateItems, outStream,
491*f6dc9357SAndroid Build Coastguard Worker m_Archive.IsOpen() ? &m_Archive : NULL, _removeSfxBlock,
492*f6dc9357SAndroid Build Coastguard Worker uo, options, callback);
493*f6dc9357SAndroid Build Coastguard Worker
494*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END2
495*f6dc9357SAndroid Build Coastguard Worker }
496*f6dc9357SAndroid Build Coastguard Worker
497*f6dc9357SAndroid Build Coastguard Worker
498*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::SetProperties (const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps))499*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
500*f6dc9357SAndroid Build Coastguard Worker {
501*f6dc9357SAndroid Build Coastguard Worker InitMethodProps();
502*f6dc9357SAndroid Build Coastguard Worker
503*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numProps; i++)
504*f6dc9357SAndroid Build Coastguard Worker {
505*f6dc9357SAndroid Build Coastguard Worker UString name = names[i];
506*f6dc9357SAndroid Build Coastguard Worker name.MakeLower_Ascii();
507*f6dc9357SAndroid Build Coastguard Worker if (name.IsEmpty())
508*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
509*f6dc9357SAndroid Build Coastguard Worker
510*f6dc9357SAndroid Build Coastguard Worker const PROPVARIANT &prop = values[i];
511*f6dc9357SAndroid Build Coastguard Worker
512*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo_Ascii_NoCase("em"))
513*f6dc9357SAndroid Build Coastguard Worker {
514*f6dc9357SAndroid Build Coastguard Worker if (prop.vt != VT_BSTR)
515*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
516*f6dc9357SAndroid Build Coastguard Worker {
517*f6dc9357SAndroid Build Coastguard Worker const wchar_t *m = prop.bstrVal;
518*f6dc9357SAndroid Build Coastguard Worker if (IsString1PrefixedByString2_NoCase_Ascii(m, "AES"))
519*f6dc9357SAndroid Build Coastguard Worker {
520*f6dc9357SAndroid Build Coastguard Worker m += 3;
521*f6dc9357SAndroid Build Coastguard Worker UInt32 v = 3;
522*f6dc9357SAndroid Build Coastguard Worker if (*m != 0)
523*f6dc9357SAndroid Build Coastguard Worker {
524*f6dc9357SAndroid Build Coastguard Worker if (*m == '-')
525*f6dc9357SAndroid Build Coastguard Worker m++;
526*f6dc9357SAndroid Build Coastguard Worker const wchar_t *end;
527*f6dc9357SAndroid Build Coastguard Worker v = ConvertStringToUInt32(m, &end);
528*f6dc9357SAndroid Build Coastguard Worker if (*end != 0 || v % 64 != 0)
529*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
530*f6dc9357SAndroid Build Coastguard Worker v /= 64;
531*f6dc9357SAndroid Build Coastguard Worker v -= 2;
532*f6dc9357SAndroid Build Coastguard Worker if (v >= 3)
533*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
534*f6dc9357SAndroid Build Coastguard Worker v++;
535*f6dc9357SAndroid Build Coastguard Worker }
536*f6dc9357SAndroid Build Coastguard Worker _props.AesKeyMode = (Byte)v;
537*f6dc9357SAndroid Build Coastguard Worker _props.IsAesMode = true;
538*f6dc9357SAndroid Build Coastguard Worker m_ForceAesMode = true;
539*f6dc9357SAndroid Build Coastguard Worker }
540*f6dc9357SAndroid Build Coastguard Worker else if (StringsAreEqualNoCase_Ascii(m, "ZipCrypto"))
541*f6dc9357SAndroid Build Coastguard Worker {
542*f6dc9357SAndroid Build Coastguard Worker _props.IsAesMode = false;
543*f6dc9357SAndroid Build Coastguard Worker m_ForceAesMode = true;
544*f6dc9357SAndroid Build Coastguard Worker }
545*f6dc9357SAndroid Build Coastguard Worker else
546*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
547*f6dc9357SAndroid Build Coastguard Worker }
548*f6dc9357SAndroid Build Coastguard Worker }
549*f6dc9357SAndroid Build Coastguard Worker
550*f6dc9357SAndroid Build Coastguard Worker
551*f6dc9357SAndroid Build Coastguard Worker
552*f6dc9357SAndroid Build Coastguard Worker else if (name.IsEqualTo("cl"))
553*f6dc9357SAndroid Build Coastguard Worker {
554*f6dc9357SAndroid Build Coastguard Worker RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal))
555*f6dc9357SAndroid Build Coastguard Worker if (m_ForceLocal)
556*f6dc9357SAndroid Build Coastguard Worker m_ForceUtf8 = false;
557*f6dc9357SAndroid Build Coastguard Worker }
558*f6dc9357SAndroid Build Coastguard Worker else if (name.IsEqualTo("cu"))
559*f6dc9357SAndroid Build Coastguard Worker {
560*f6dc9357SAndroid Build Coastguard Worker RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8))
561*f6dc9357SAndroid Build Coastguard Worker if (m_ForceUtf8)
562*f6dc9357SAndroid Build Coastguard Worker m_ForceLocal = false;
563*f6dc9357SAndroid Build Coastguard Worker }
564*f6dc9357SAndroid Build Coastguard Worker else if (name.IsEqualTo("cp"))
565*f6dc9357SAndroid Build Coastguard Worker {
566*f6dc9357SAndroid Build Coastguard Worker UInt32 cp = CP_OEMCP;
567*f6dc9357SAndroid Build Coastguard Worker RINOK(ParsePropToUInt32(L"", prop, cp))
568*f6dc9357SAndroid Build Coastguard Worker _forceCodePage = true;
569*f6dc9357SAndroid Build Coastguard Worker _specifiedCodePage = cp;
570*f6dc9357SAndroid Build Coastguard Worker }
571*f6dc9357SAndroid Build Coastguard Worker else if (name.IsEqualTo("rsfx"))
572*f6dc9357SAndroid Build Coastguard Worker {
573*f6dc9357SAndroid Build Coastguard Worker RINOK(PROPVARIANT_to_bool(prop, _removeSfxBlock))
574*f6dc9357SAndroid Build Coastguard Worker }
575*f6dc9357SAndroid Build Coastguard Worker else if (name.IsEqualTo("rws"))
576*f6dc9357SAndroid Build Coastguard Worker {
577*f6dc9357SAndroid Build Coastguard Worker RINOK(PROPVARIANT_to_bool(prop, _force_SeqOutMode))
578*f6dc9357SAndroid Build Coastguard Worker }
579*f6dc9357SAndroid Build Coastguard Worker else if (name.IsEqualTo("ros"))
580*f6dc9357SAndroid Build Coastguard Worker {
581*f6dc9357SAndroid Build Coastguard Worker RINOK(PROPVARIANT_to_bool(prop, _force_OpenSeq))
582*f6dc9357SAndroid Build Coastguard Worker }
583*f6dc9357SAndroid Build Coastguard Worker else
584*f6dc9357SAndroid Build Coastguard Worker {
585*f6dc9357SAndroid Build Coastguard Worker if (name.IsEqualTo_Ascii_NoCase("m") && prop.vt == VT_UI4)
586*f6dc9357SAndroid Build Coastguard Worker {
587*f6dc9357SAndroid Build Coastguard Worker UInt32 id = prop.ulVal;
588*f6dc9357SAndroid Build Coastguard Worker if (id > 0xFF)
589*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
590*f6dc9357SAndroid Build Coastguard Worker m_MainMethod = (int)id;
591*f6dc9357SAndroid Build Coastguard Worker }
592*f6dc9357SAndroid Build Coastguard Worker else
593*f6dc9357SAndroid Build Coastguard Worker {
594*f6dc9357SAndroid Build Coastguard Worker bool processed = false;
595*f6dc9357SAndroid Build Coastguard Worker RINOK(TimeOptions.Parse(name, prop, processed))
596*f6dc9357SAndroid Build Coastguard Worker if (!processed)
597*f6dc9357SAndroid Build Coastguard Worker {
598*f6dc9357SAndroid Build Coastguard Worker RINOK(_props.SetProperty(name, prop))
599*f6dc9357SAndroid Build Coastguard Worker }
600*f6dc9357SAndroid Build Coastguard Worker }
601*f6dc9357SAndroid Build Coastguard Worker // RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop));
602*f6dc9357SAndroid Build Coastguard Worker }
603*f6dc9357SAndroid Build Coastguard Worker }
604*f6dc9357SAndroid Build Coastguard Worker
605*f6dc9357SAndroid Build Coastguard Worker _props._methods.DeleteFrontal(_props.GetNumEmptyMethods());
606*f6dc9357SAndroid Build Coastguard Worker if (_props._methods.Size() > 1)
607*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
608*f6dc9357SAndroid Build Coastguard Worker if (_props._methods.Size() == 1)
609*f6dc9357SAndroid Build Coastguard Worker {
610*f6dc9357SAndroid Build Coastguard Worker const AString &methodName = _props._methods[0].MethodName;
611*f6dc9357SAndroid Build Coastguard Worker
612*f6dc9357SAndroid Build Coastguard Worker if (!methodName.IsEmpty())
613*f6dc9357SAndroid Build Coastguard Worker {
614*f6dc9357SAndroid Build Coastguard Worker const char *end;
615*f6dc9357SAndroid Build Coastguard Worker UInt32 id = ConvertStringToUInt32(methodName, &end);
616*f6dc9357SAndroid Build Coastguard Worker if (*end == 0 && id <= 0xFF)
617*f6dc9357SAndroid Build Coastguard Worker m_MainMethod = (int)id;
618*f6dc9357SAndroid Build Coastguard Worker else if (methodName.IsEqualTo_Ascii_NoCase("Copy")) // it's alias for "Store"
619*f6dc9357SAndroid Build Coastguard Worker m_MainMethod = 0;
620*f6dc9357SAndroid Build Coastguard Worker }
621*f6dc9357SAndroid Build Coastguard Worker }
622*f6dc9357SAndroid Build Coastguard Worker
623*f6dc9357SAndroid Build Coastguard Worker return S_OK;
624*f6dc9357SAndroid Build Coastguard Worker }
625*f6dc9357SAndroid Build Coastguard Worker
626*f6dc9357SAndroid Build Coastguard Worker }}
627