1*f6dc9357SAndroid Build Coastguard Worker // NSisHandler.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 "../../../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
9*f6dc9357SAndroid Build Coastguard Worker
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ProgressUtils.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ItemNameUtils.h"
16*f6dc9357SAndroid Build Coastguard Worker
17*f6dc9357SAndroid Build Coastguard Worker #include "NsisHandler.h"
18*f6dc9357SAndroid Build Coastguard Worker
19*f6dc9357SAndroid Build Coastguard Worker #define Get32(p) GetUi32(p)
20*f6dc9357SAndroid Build Coastguard Worker
21*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
22*f6dc9357SAndroid Build Coastguard Worker
23*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
24*f6dc9357SAndroid Build Coastguard Worker namespace NNsis {
25*f6dc9357SAndroid Build Coastguard Worker
26*f6dc9357SAndroid Build Coastguard Worker #define kBcjMethod "BCJ"
27*f6dc9357SAndroid Build Coastguard Worker #define kUnknownMethod "Unknown"
28*f6dc9357SAndroid Build Coastguard Worker
29*f6dc9357SAndroid Build Coastguard Worker static const char * const kMethods[] =
30*f6dc9357SAndroid Build Coastguard Worker {
31*f6dc9357SAndroid Build Coastguard Worker "Copy"
32*f6dc9357SAndroid Build Coastguard Worker , "Deflate"
33*f6dc9357SAndroid Build Coastguard Worker , "BZip2"
34*f6dc9357SAndroid Build Coastguard Worker , "LZMA"
35*f6dc9357SAndroid Build Coastguard Worker };
36*f6dc9357SAndroid Build Coastguard Worker
37*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
38*f6dc9357SAndroid Build Coastguard Worker {
39*f6dc9357SAndroid Build Coastguard Worker kpidPath,
40*f6dc9357SAndroid Build Coastguard Worker kpidSize,
41*f6dc9357SAndroid Build Coastguard Worker kpidPackSize,
42*f6dc9357SAndroid Build Coastguard Worker kpidMTime,
43*f6dc9357SAndroid Build Coastguard Worker kpidAttrib,
44*f6dc9357SAndroid Build Coastguard Worker kpidMethod,
45*f6dc9357SAndroid Build Coastguard Worker kpidSolid,
46*f6dc9357SAndroid Build Coastguard Worker kpidOffset
47*f6dc9357SAndroid Build Coastguard Worker };
48*f6dc9357SAndroid Build Coastguard Worker
49*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
50*f6dc9357SAndroid Build Coastguard Worker {
51*f6dc9357SAndroid Build Coastguard Worker kpidMethod,
52*f6dc9357SAndroid Build Coastguard Worker kpidSolid,
53*f6dc9357SAndroid Build Coastguard Worker kpidBit64,
54*f6dc9357SAndroid Build Coastguard Worker kpidHeadersSize,
55*f6dc9357SAndroid Build Coastguard Worker kpidEmbeddedStubSize,
56*f6dc9357SAndroid Build Coastguard Worker kpidSubType
57*f6dc9357SAndroid Build Coastguard Worker // kpidCodePage
58*f6dc9357SAndroid Build Coastguard Worker };
59*f6dc9357SAndroid Build Coastguard Worker
60*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
61*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
62*f6dc9357SAndroid Build Coastguard Worker
63*f6dc9357SAndroid Build Coastguard Worker
AddDictProp(AString & s,UInt32 val)64*f6dc9357SAndroid Build Coastguard Worker static void AddDictProp(AString &s, UInt32 val)
65*f6dc9357SAndroid Build Coastguard Worker {
66*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < 32; i++)
67*f6dc9357SAndroid Build Coastguard Worker if (((UInt32)1 << i) == val)
68*f6dc9357SAndroid Build Coastguard Worker {
69*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(i);
70*f6dc9357SAndroid Build Coastguard Worker return;
71*f6dc9357SAndroid Build Coastguard Worker }
72*f6dc9357SAndroid Build Coastguard Worker char c = 'b';
73*f6dc9357SAndroid Build Coastguard Worker if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
74*f6dc9357SAndroid Build Coastguard Worker else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
75*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(val);
76*f6dc9357SAndroid Build Coastguard Worker s.Add_Char(c);
77*f6dc9357SAndroid Build Coastguard Worker }
78*f6dc9357SAndroid Build Coastguard Worker
GetMethod(bool useFilter,NMethodType::EEnum method,UInt32 dict)79*f6dc9357SAndroid Build Coastguard Worker static AString GetMethod(bool useFilter, NMethodType::EEnum method, UInt32 dict)
80*f6dc9357SAndroid Build Coastguard Worker {
81*f6dc9357SAndroid Build Coastguard Worker AString s;
82*f6dc9357SAndroid Build Coastguard Worker if (useFilter)
83*f6dc9357SAndroid Build Coastguard Worker {
84*f6dc9357SAndroid Build Coastguard Worker s += kBcjMethod;
85*f6dc9357SAndroid Build Coastguard Worker s.Add_Space();
86*f6dc9357SAndroid Build Coastguard Worker }
87*f6dc9357SAndroid Build Coastguard Worker s += ((unsigned)method < Z7_ARRAY_SIZE(kMethods)) ? kMethods[(unsigned)method] : kUnknownMethod;
88*f6dc9357SAndroid Build Coastguard Worker if (method == NMethodType::kLZMA)
89*f6dc9357SAndroid Build Coastguard Worker {
90*f6dc9357SAndroid Build Coastguard Worker s.Add_Colon();
91*f6dc9357SAndroid Build Coastguard Worker AddDictProp(s, dict);
92*f6dc9357SAndroid Build Coastguard Worker }
93*f6dc9357SAndroid Build Coastguard Worker return s;
94*f6dc9357SAndroid Build Coastguard Worker }
95*f6dc9357SAndroid Build Coastguard Worker
96*f6dc9357SAndroid Build Coastguard Worker /*
97*f6dc9357SAndroid Build Coastguard Worker AString CHandler::GetMethod(NMethodType::EEnum method, bool useItemFilter, UInt32 dictionary) const
98*f6dc9357SAndroid Build Coastguard Worker {
99*f6dc9357SAndroid Build Coastguard Worker AString s;
100*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter)
101*f6dc9357SAndroid Build Coastguard Worker {
102*f6dc9357SAndroid Build Coastguard Worker s += kBcjMethod;
103*f6dc9357SAndroid Build Coastguard Worker s.Add_Space();
104*f6dc9357SAndroid Build Coastguard Worker }
105*f6dc9357SAndroid Build Coastguard Worker s += (method < Z7_ARRAY_SIZE(kMethods)) ? kMethods[method] : kUnknownMethod;
106*f6dc9357SAndroid Build Coastguard Worker if (method == NMethodType::kLZMA)
107*f6dc9357SAndroid Build Coastguard Worker {
108*f6dc9357SAndroid Build Coastguard Worker s.Add_Colon();
109*f6dc9357SAndroid Build Coastguard Worker s += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary);
110*f6dc9357SAndroid Build Coastguard Worker }
111*f6dc9357SAndroid Build Coastguard Worker return s;
112*f6dc9357SAndroid Build Coastguard Worker }
113*f6dc9357SAndroid Build Coastguard Worker */
114*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetArchiveProperty (PROPID propID,PROPVARIANT * value))115*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
116*f6dc9357SAndroid Build Coastguard Worker {
117*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
118*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
119*f6dc9357SAndroid Build Coastguard Worker switch (propID)
120*f6dc9357SAndroid Build Coastguard Worker {
121*f6dc9357SAndroid Build Coastguard Worker // case kpidCodePage: if (_archive.IsUnicode) prop = "UTF-16"; break;
122*f6dc9357SAndroid Build Coastguard Worker case kpidSubType:
123*f6dc9357SAndroid Build Coastguard Worker {
124*f6dc9357SAndroid Build Coastguard Worker AString s (_archive.GetFormatDescription());
125*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsInstaller)
126*f6dc9357SAndroid Build Coastguard Worker {
127*f6dc9357SAndroid Build Coastguard Worker s.Add_Space_if_NotEmpty();
128*f6dc9357SAndroid Build Coastguard Worker s += "(Uninstall)";
129*f6dc9357SAndroid Build Coastguard Worker }
130*f6dc9357SAndroid Build Coastguard Worker if (!s.IsEmpty())
131*f6dc9357SAndroid Build Coastguard Worker prop = s;
132*f6dc9357SAndroid Build Coastguard Worker break;
133*f6dc9357SAndroid Build Coastguard Worker }
134*f6dc9357SAndroid Build Coastguard Worker
135*f6dc9357SAndroid Build Coastguard Worker case kpidBit64: if (_archive.Is64Bit) prop = true; break;
136*f6dc9357SAndroid Build Coastguard Worker case kpidMethod: prop = _methodString; break;
137*f6dc9357SAndroid Build Coastguard Worker case kpidSolid: prop = _archive.IsSolid; break;
138*f6dc9357SAndroid Build Coastguard Worker case kpidOffset: prop = _archive.StartOffset; break;
139*f6dc9357SAndroid Build Coastguard Worker case kpidPhySize: prop = (UInt64)((UInt64)_archive.ExeStub.Size() + _archive.FirstHeader.ArcSize); break;
140*f6dc9357SAndroid Build Coastguard Worker case kpidEmbeddedStubSize: prop = (UInt64)_archive.ExeStub.Size(); break;
141*f6dc9357SAndroid Build Coastguard Worker case kpidHeadersSize: prop = _archive.FirstHeader.HeaderSize; break;
142*f6dc9357SAndroid Build Coastguard Worker
143*f6dc9357SAndroid Build Coastguard Worker case kpidErrorFlags:
144*f6dc9357SAndroid Build Coastguard Worker {
145*f6dc9357SAndroid Build Coastguard Worker UInt32 v = 0;
146*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc;
147*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsTruncated()) v |= kpv_ErrorFlags_UnexpectedEnd;
148*f6dc9357SAndroid Build Coastguard Worker prop = v;
149*f6dc9357SAndroid Build Coastguard Worker break;
150*f6dc9357SAndroid Build Coastguard Worker }
151*f6dc9357SAndroid Build Coastguard Worker
152*f6dc9357SAndroid Build Coastguard Worker case kpidName:
153*f6dc9357SAndroid Build Coastguard Worker {
154*f6dc9357SAndroid Build Coastguard Worker AString s;
155*f6dc9357SAndroid Build Coastguard Worker
156*f6dc9357SAndroid Build Coastguard Worker #ifdef NSIS_SCRIPT
157*f6dc9357SAndroid Build Coastguard Worker if (!_archive.Name.IsEmpty())
158*f6dc9357SAndroid Build Coastguard Worker s = _archive.Name;
159*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsInstaller)
160*f6dc9357SAndroid Build Coastguard Worker {
161*f6dc9357SAndroid Build Coastguard Worker if (!s.IsEmpty())
162*f6dc9357SAndroid Build Coastguard Worker s.Add_Dot();
163*f6dc9357SAndroid Build Coastguard Worker s += "Uninstall";
164*f6dc9357SAndroid Build Coastguard Worker }
165*f6dc9357SAndroid Build Coastguard Worker #endif
166*f6dc9357SAndroid Build Coastguard Worker
167*f6dc9357SAndroid Build Coastguard Worker if (s.IsEmpty())
168*f6dc9357SAndroid Build Coastguard Worker s = _archive.IsInstaller ? "Install" : "Uninstall";
169*f6dc9357SAndroid Build Coastguard Worker s += (_archive.ExeStub.Size() == 0) ? ".nsis" : ".exe";
170*f6dc9357SAndroid Build Coastguard Worker
171*f6dc9357SAndroid Build Coastguard Worker prop = _archive.ConvertToUnicode(s);
172*f6dc9357SAndroid Build Coastguard Worker break;
173*f6dc9357SAndroid Build Coastguard Worker }
174*f6dc9357SAndroid Build Coastguard Worker
175*f6dc9357SAndroid Build Coastguard Worker #ifdef NSIS_SCRIPT
176*f6dc9357SAndroid Build Coastguard Worker case kpidShortComment:
177*f6dc9357SAndroid Build Coastguard Worker {
178*f6dc9357SAndroid Build Coastguard Worker if (!_archive.BrandingText.IsEmpty())
179*f6dc9357SAndroid Build Coastguard Worker prop = _archive.ConvertToUnicode(_archive.BrandingText);
180*f6dc9357SAndroid Build Coastguard Worker break;
181*f6dc9357SAndroid Build Coastguard Worker }
182*f6dc9357SAndroid Build Coastguard Worker #endif
183*f6dc9357SAndroid Build Coastguard Worker }
184*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
185*f6dc9357SAndroid Build Coastguard Worker return S_OK;
186*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
187*f6dc9357SAndroid Build Coastguard Worker }
188*f6dc9357SAndroid Build Coastguard Worker
189*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Open (IInStream * stream,const UInt64 * maxCheckStartPosition,IArchiveOpenCallback *))190*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */))
191*f6dc9357SAndroid Build Coastguard Worker {
192*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
193*f6dc9357SAndroid Build Coastguard Worker Close();
194*f6dc9357SAndroid Build Coastguard Worker {
195*f6dc9357SAndroid Build Coastguard Worker if (_archive.Open(stream, maxCheckStartPosition) != S_OK)
196*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
197*f6dc9357SAndroid Build Coastguard Worker {
198*f6dc9357SAndroid Build Coastguard Worker UInt32 dict = _archive.DictionarySize;
199*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsSolid)
200*f6dc9357SAndroid Build Coastguard Worker {
201*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, _archive.Items)
202*f6dc9357SAndroid Build Coastguard Worker {
203*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _archive.Items[i];
204*f6dc9357SAndroid Build Coastguard Worker if (item.DictionarySize > dict)
205*f6dc9357SAndroid Build Coastguard Worker dict = item.DictionarySize;
206*f6dc9357SAndroid Build Coastguard Worker }
207*f6dc9357SAndroid Build Coastguard Worker }
208*f6dc9357SAndroid Build Coastguard Worker _methodString = GetMethod(_archive.UseFilter, _archive.Method, dict);
209*f6dc9357SAndroid Build Coastguard Worker }
210*f6dc9357SAndroid Build Coastguard Worker }
211*f6dc9357SAndroid Build Coastguard Worker return S_OK;
212*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
213*f6dc9357SAndroid Build Coastguard Worker }
214*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Close ())215*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
216*f6dc9357SAndroid Build Coastguard Worker {
217*f6dc9357SAndroid Build Coastguard Worker _archive.Clear();
218*f6dc9357SAndroid Build Coastguard Worker _archive.Release();
219*f6dc9357SAndroid Build Coastguard Worker return S_OK;
220*f6dc9357SAndroid Build Coastguard Worker }
221*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetNumberOfItems (UInt32 * numItems))222*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
223*f6dc9357SAndroid Build Coastguard Worker {
224*f6dc9357SAndroid Build Coastguard Worker *numItems = _archive.Items.Size()
225*f6dc9357SAndroid Build Coastguard Worker #ifdef NSIS_SCRIPT
226*f6dc9357SAndroid Build Coastguard Worker + 1 + _archive.LicenseFiles.Size()
227*f6dc9357SAndroid Build Coastguard Worker #endif
228*f6dc9357SAndroid Build Coastguard Worker ;
229*f6dc9357SAndroid Build Coastguard Worker return S_OK;
230*f6dc9357SAndroid Build Coastguard Worker }
231*f6dc9357SAndroid Build Coastguard Worker
GetUncompressedSize(unsigned index,UInt32 & size) const232*f6dc9357SAndroid Build Coastguard Worker bool CHandler::GetUncompressedSize(unsigned index, UInt32 &size) const
233*f6dc9357SAndroid Build Coastguard Worker {
234*f6dc9357SAndroid Build Coastguard Worker size = 0;
235*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _archive.Items[index];
236*f6dc9357SAndroid Build Coastguard Worker if (item.Size_Defined)
237*f6dc9357SAndroid Build Coastguard Worker size = item.Size;
238*f6dc9357SAndroid Build Coastguard Worker else if (_archive.IsSolid && item.EstimatedSize_Defined)
239*f6dc9357SAndroid Build Coastguard Worker size = item.EstimatedSize;
240*f6dc9357SAndroid Build Coastguard Worker else if (!item.IsEmptyFile)
241*f6dc9357SAndroid Build Coastguard Worker return false;
242*f6dc9357SAndroid Build Coastguard Worker return true;
243*f6dc9357SAndroid Build Coastguard Worker }
244*f6dc9357SAndroid Build Coastguard Worker
GetCompressedSize(unsigned index,UInt32 & size) const245*f6dc9357SAndroid Build Coastguard Worker bool CHandler::GetCompressedSize(unsigned index, UInt32 &size) const
246*f6dc9357SAndroid Build Coastguard Worker {
247*f6dc9357SAndroid Build Coastguard Worker size = 0;
248*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _archive.Items[index];
249*f6dc9357SAndroid Build Coastguard Worker if (item.CompressedSize_Defined)
250*f6dc9357SAndroid Build Coastguard Worker size = item.CompressedSize;
251*f6dc9357SAndroid Build Coastguard Worker else
252*f6dc9357SAndroid Build Coastguard Worker {
253*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid)
254*f6dc9357SAndroid Build Coastguard Worker {
255*f6dc9357SAndroid Build Coastguard Worker if (index == 0)
256*f6dc9357SAndroid Build Coastguard Worker size = _archive.FirstHeader.GetDataSize();
257*f6dc9357SAndroid Build Coastguard Worker else
258*f6dc9357SAndroid Build Coastguard Worker return false;
259*f6dc9357SAndroid Build Coastguard Worker }
260*f6dc9357SAndroid Build Coastguard Worker else
261*f6dc9357SAndroid Build Coastguard Worker {
262*f6dc9357SAndroid Build Coastguard Worker if (!item.IsCompressed)
263*f6dc9357SAndroid Build Coastguard Worker size = item.Size;
264*f6dc9357SAndroid Build Coastguard Worker else
265*f6dc9357SAndroid Build Coastguard Worker return false;
266*f6dc9357SAndroid Build Coastguard Worker }
267*f6dc9357SAndroid Build Coastguard Worker }
268*f6dc9357SAndroid Build Coastguard Worker return true;
269*f6dc9357SAndroid Build Coastguard Worker }
270*f6dc9357SAndroid Build Coastguard Worker
271*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetProperty (UInt32 index,PROPID propID,PROPVARIANT * value))272*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
273*f6dc9357SAndroid Build Coastguard Worker {
274*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
275*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
276*f6dc9357SAndroid Build Coastguard Worker #ifdef NSIS_SCRIPT
277*f6dc9357SAndroid Build Coastguard Worker if (index >= (UInt32)_archive.Items.Size())
278*f6dc9357SAndroid Build Coastguard Worker {
279*f6dc9357SAndroid Build Coastguard Worker if (index == (UInt32)_archive.Items.Size())
280*f6dc9357SAndroid Build Coastguard Worker {
281*f6dc9357SAndroid Build Coastguard Worker switch (propID)
282*f6dc9357SAndroid Build Coastguard Worker {
283*f6dc9357SAndroid Build Coastguard Worker case kpidPath: prop = "[NSIS].nsi"; break;
284*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
285*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize: prop = (UInt64)_archive.Script.Len(); break;
286*f6dc9357SAndroid Build Coastguard Worker case kpidSolid: prop = false; break;
287*f6dc9357SAndroid Build Coastguard Worker }
288*f6dc9357SAndroid Build Coastguard Worker }
289*f6dc9357SAndroid Build Coastguard Worker else
290*f6dc9357SAndroid Build Coastguard Worker {
291*f6dc9357SAndroid Build Coastguard Worker const CLicenseFile &lic = _archive.LicenseFiles[index - (_archive.Items.Size() + 1)];
292*f6dc9357SAndroid Build Coastguard Worker switch (propID)
293*f6dc9357SAndroid Build Coastguard Worker {
294*f6dc9357SAndroid Build Coastguard Worker case kpidPath: prop = lic.Name; break;
295*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
296*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize: prop = (UInt64)lic.Size; break;
297*f6dc9357SAndroid Build Coastguard Worker case kpidSolid: prop = false; break;
298*f6dc9357SAndroid Build Coastguard Worker }
299*f6dc9357SAndroid Build Coastguard Worker }
300*f6dc9357SAndroid Build Coastguard Worker }
301*f6dc9357SAndroid Build Coastguard Worker else
302*f6dc9357SAndroid Build Coastguard Worker #endif
303*f6dc9357SAndroid Build Coastguard Worker {
304*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _archive.Items[index];
305*f6dc9357SAndroid Build Coastguard Worker switch (propID)
306*f6dc9357SAndroid Build Coastguard Worker {
307*f6dc9357SAndroid Build Coastguard Worker case kpidOffset: prop = item.Pos; break;
308*f6dc9357SAndroid Build Coastguard Worker case kpidPath:
309*f6dc9357SAndroid Build Coastguard Worker {
310*f6dc9357SAndroid Build Coastguard Worker UString s = NItemName::WinPathToOsPath(_archive.GetReducedName(index));
311*f6dc9357SAndroid Build Coastguard Worker if (!s.IsEmpty())
312*f6dc9357SAndroid Build Coastguard Worker prop = (const wchar_t *)s;
313*f6dc9357SAndroid Build Coastguard Worker break;
314*f6dc9357SAndroid Build Coastguard Worker }
315*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
316*f6dc9357SAndroid Build Coastguard Worker {
317*f6dc9357SAndroid Build Coastguard Worker UInt32 size;
318*f6dc9357SAndroid Build Coastguard Worker if (GetUncompressedSize(index, size))
319*f6dc9357SAndroid Build Coastguard Worker prop = (UInt64)size;
320*f6dc9357SAndroid Build Coastguard Worker break;
321*f6dc9357SAndroid Build Coastguard Worker }
322*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize:
323*f6dc9357SAndroid Build Coastguard Worker {
324*f6dc9357SAndroid Build Coastguard Worker UInt32 size;
325*f6dc9357SAndroid Build Coastguard Worker if (GetCompressedSize(index, size))
326*f6dc9357SAndroid Build Coastguard Worker prop = (UInt64)size;
327*f6dc9357SAndroid Build Coastguard Worker break;
328*f6dc9357SAndroid Build Coastguard Worker }
329*f6dc9357SAndroid Build Coastguard Worker case kpidMTime:
330*f6dc9357SAndroid Build Coastguard Worker {
331*f6dc9357SAndroid Build Coastguard Worker if (item.MTime.dwHighDateTime > 0x01000000 &&
332*f6dc9357SAndroid Build Coastguard Worker item.MTime.dwHighDateTime < 0xFF000000)
333*f6dc9357SAndroid Build Coastguard Worker prop = item.MTime;
334*f6dc9357SAndroid Build Coastguard Worker break;
335*f6dc9357SAndroid Build Coastguard Worker }
336*f6dc9357SAndroid Build Coastguard Worker case kpidAttrib:
337*f6dc9357SAndroid Build Coastguard Worker {
338*f6dc9357SAndroid Build Coastguard Worker if (item.Attrib_Defined)
339*f6dc9357SAndroid Build Coastguard Worker prop = item.Attrib;
340*f6dc9357SAndroid Build Coastguard Worker break;
341*f6dc9357SAndroid Build Coastguard Worker }
342*f6dc9357SAndroid Build Coastguard Worker
343*f6dc9357SAndroid Build Coastguard Worker case kpidMethod:
344*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid)
345*f6dc9357SAndroid Build Coastguard Worker prop = _methodString;
346*f6dc9357SAndroid Build Coastguard Worker else
347*f6dc9357SAndroid Build Coastguard Worker prop = GetMethod(_archive.UseFilter, item.IsCompressed ? _archive.Method :
348*f6dc9357SAndroid Build Coastguard Worker NMethodType::kCopy, item.DictionarySize);
349*f6dc9357SAndroid Build Coastguard Worker break;
350*f6dc9357SAndroid Build Coastguard Worker
351*f6dc9357SAndroid Build Coastguard Worker case kpidSolid: prop = _archive.IsSolid; break;
352*f6dc9357SAndroid Build Coastguard Worker }
353*f6dc9357SAndroid Build Coastguard Worker }
354*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
355*f6dc9357SAndroid Build Coastguard Worker return S_OK;
356*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
357*f6dc9357SAndroid Build Coastguard Worker }
358*f6dc9357SAndroid Build Coastguard Worker
359*f6dc9357SAndroid Build Coastguard Worker
UninstallerPatch(const Byte * p,size_t size,Byte * dest,size_t destSize)360*f6dc9357SAndroid Build Coastguard Worker static bool UninstallerPatch(const Byte *p, size_t size, Byte *dest, size_t destSize)
361*f6dc9357SAndroid Build Coastguard Worker {
362*f6dc9357SAndroid Build Coastguard Worker for (;;)
363*f6dc9357SAndroid Build Coastguard Worker {
364*f6dc9357SAndroid Build Coastguard Worker if (size < 4)
365*f6dc9357SAndroid Build Coastguard Worker return false;
366*f6dc9357SAndroid Build Coastguard Worker const UInt32 len = Get32(p);
367*f6dc9357SAndroid Build Coastguard Worker if (len == 0)
368*f6dc9357SAndroid Build Coastguard Worker return size == 4;
369*f6dc9357SAndroid Build Coastguard Worker if (size < 8)
370*f6dc9357SAndroid Build Coastguard Worker return false;
371*f6dc9357SAndroid Build Coastguard Worker const UInt32 offs = Get32(p + 4);
372*f6dc9357SAndroid Build Coastguard Worker p += 8;
373*f6dc9357SAndroid Build Coastguard Worker size -= 8;
374*f6dc9357SAndroid Build Coastguard Worker if (size < len || offs > destSize || len > destSize - offs)
375*f6dc9357SAndroid Build Coastguard Worker return false;
376*f6dc9357SAndroid Build Coastguard Worker memcpy(dest + offs, p, len);
377*f6dc9357SAndroid Build Coastguard Worker p += len;
378*f6dc9357SAndroid Build Coastguard Worker size -= len;
379*f6dc9357SAndroid Build Coastguard Worker }
380*f6dc9357SAndroid Build Coastguard Worker }
381*f6dc9357SAndroid Build Coastguard Worker
382*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Extract (const UInt32 * indices,UInt32 numItems,Int32 testMode,IArchiveExtractCallback * extractCallback))383*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
384*f6dc9357SAndroid Build Coastguard Worker Int32 testMode, IArchiveExtractCallback *extractCallback))
385*f6dc9357SAndroid Build Coastguard Worker {
386*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
387*f6dc9357SAndroid Build Coastguard Worker const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
388*f6dc9357SAndroid Build Coastguard Worker if (allFilesMode)
389*f6dc9357SAndroid Build Coastguard Worker GetNumberOfItems(&numItems);
390*f6dc9357SAndroid Build Coastguard Worker if (numItems == 0)
391*f6dc9357SAndroid Build Coastguard Worker return S_OK;
392*f6dc9357SAndroid Build Coastguard Worker
393*f6dc9357SAndroid Build Coastguard Worker UInt64 totalSize = 0;
394*f6dc9357SAndroid Build Coastguard Worker UInt64 solidPosMax = 0;
395*f6dc9357SAndroid Build Coastguard Worker
396*f6dc9357SAndroid Build Coastguard Worker UInt32 i;
397*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numItems; i++)
398*f6dc9357SAndroid Build Coastguard Worker {
399*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = (allFilesMode ? i : indices[i]);
400*f6dc9357SAndroid Build Coastguard Worker
401*f6dc9357SAndroid Build Coastguard Worker #ifdef NSIS_SCRIPT
402*f6dc9357SAndroid Build Coastguard Worker if (index >= _archive.Items.Size())
403*f6dc9357SAndroid Build Coastguard Worker {
404*f6dc9357SAndroid Build Coastguard Worker if (index == _archive.Items.Size())
405*f6dc9357SAndroid Build Coastguard Worker totalSize += _archive.Script.Len();
406*f6dc9357SAndroid Build Coastguard Worker else
407*f6dc9357SAndroid Build Coastguard Worker totalSize += _archive.LicenseFiles[index - (_archive.Items.Size() + 1)].Size;
408*f6dc9357SAndroid Build Coastguard Worker }
409*f6dc9357SAndroid Build Coastguard Worker else
410*f6dc9357SAndroid Build Coastguard Worker #endif
411*f6dc9357SAndroid Build Coastguard Worker {
412*f6dc9357SAndroid Build Coastguard Worker UInt32 size;
413*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid)
414*f6dc9357SAndroid Build Coastguard Worker {
415*f6dc9357SAndroid Build Coastguard Worker GetUncompressedSize(index, size);
416*f6dc9357SAndroid Build Coastguard Worker UInt64 pos = (UInt64)_archive.GetPosOfSolidItem(index) + size;
417*f6dc9357SAndroid Build Coastguard Worker if (solidPosMax < pos)
418*f6dc9357SAndroid Build Coastguard Worker solidPosMax = pos;
419*f6dc9357SAndroid Build Coastguard Worker }
420*f6dc9357SAndroid Build Coastguard Worker else
421*f6dc9357SAndroid Build Coastguard Worker {
422*f6dc9357SAndroid Build Coastguard Worker GetCompressedSize(index, size);
423*f6dc9357SAndroid Build Coastguard Worker totalSize += size;
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 extractCallback->SetTotal(totalSize + solidPosMax);
429*f6dc9357SAndroid Build Coastguard Worker
430*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
431*f6dc9357SAndroid Build Coastguard Worker lps->Init(extractCallback, !_archive.IsSolid);
432*f6dc9357SAndroid Build Coastguard Worker
433*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid)
434*f6dc9357SAndroid Build Coastguard Worker {
435*f6dc9357SAndroid Build Coastguard Worker RINOK(_archive.SeekTo_DataStreamOffset())
436*f6dc9357SAndroid Build Coastguard Worker RINOK(_archive.InitDecoder())
437*f6dc9357SAndroid Build Coastguard Worker _archive.Decoder.StreamPos = 0;
438*f6dc9357SAndroid Build Coastguard Worker }
439*f6dc9357SAndroid Build Coastguard Worker
440*f6dc9357SAndroid Build Coastguard Worker /* We use tempBuf for solid archives, if there is duplicate item.
441*f6dc9357SAndroid Build Coastguard Worker We don't know uncompressed size for non-solid archives, so we can't
442*f6dc9357SAndroid Build Coastguard Worker allocate exact buffer.
443*f6dc9357SAndroid Build Coastguard Worker We use tempBuf also for first part (EXE stub) of unistall.exe
444*f6dc9357SAndroid Build Coastguard Worker and tempBuf2 is used for second part (NSIS script). */
445*f6dc9357SAndroid Build Coastguard Worker
446*f6dc9357SAndroid Build Coastguard Worker CByteBuffer tempBuf;
447*f6dc9357SAndroid Build Coastguard Worker CByteBuffer tempBuf2;
448*f6dc9357SAndroid Build Coastguard Worker
449*f6dc9357SAndroid Build Coastguard Worker /* tempPos is pos in uncompressed stream of previous item for solid archive, that
450*f6dc9357SAndroid Build Coastguard Worker was written to tempBuf */
451*f6dc9357SAndroid Build Coastguard Worker UInt64 tempPos = (UInt64)(Int64)-1;
452*f6dc9357SAndroid Build Coastguard Worker
453*f6dc9357SAndroid Build Coastguard Worker /* prevPos is pos in uncompressed stream of previous item for solid archive.
454*f6dc9357SAndroid Build Coastguard Worker It's used for test mode (where we don't need to test same file second time */
455*f6dc9357SAndroid Build Coastguard Worker UInt64 prevPos = (UInt64)(Int64)-1;
456*f6dc9357SAndroid Build Coastguard Worker
457*f6dc9357SAndroid Build Coastguard Worker // if there is error in solid archive, we show error for all subsequent files
458*f6dc9357SAndroid Build Coastguard Worker bool solidDataError = false;
459*f6dc9357SAndroid Build Coastguard Worker
460*f6dc9357SAndroid Build Coastguard Worker UInt64 curTotalPacked = 0, curTotalUnpacked = 0;
461*f6dc9357SAndroid Build Coastguard Worker UInt32 curPacked = 0;
462*f6dc9357SAndroid Build Coastguard Worker UInt64 curUnpacked = 0;
463*f6dc9357SAndroid Build Coastguard Worker
464*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numItems; i++,
465*f6dc9357SAndroid Build Coastguard Worker curTotalPacked += curPacked,
466*f6dc9357SAndroid Build Coastguard Worker curTotalUnpacked += curUnpacked)
467*f6dc9357SAndroid Build Coastguard Worker {
468*f6dc9357SAndroid Build Coastguard Worker lps->InSize = curTotalPacked;
469*f6dc9357SAndroid Build Coastguard Worker lps->OutSize = curTotalUnpacked;
470*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid)
471*f6dc9357SAndroid Build Coastguard Worker lps->OutSize += _archive.Decoder.StreamPos;
472*f6dc9357SAndroid Build Coastguard Worker
473*f6dc9357SAndroid Build Coastguard Worker curPacked = 0;
474*f6dc9357SAndroid Build Coastguard Worker curUnpacked = 0;
475*f6dc9357SAndroid Build Coastguard Worker RINOK(lps->SetCur())
476*f6dc9357SAndroid Build Coastguard Worker
477*f6dc9357SAndroid Build Coastguard Worker // RINOK(extractCallback->SetCompleted(¤tTotalSize))
478*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> realOutStream;
479*f6dc9357SAndroid Build Coastguard Worker const Int32 askMode = testMode ?
480*f6dc9357SAndroid Build Coastguard Worker NExtract::NAskMode::kTest :
481*f6dc9357SAndroid Build Coastguard Worker NExtract::NAskMode::kExtract;
482*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = allFilesMode ? i : indices[i];
483*f6dc9357SAndroid Build Coastguard Worker
484*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
485*f6dc9357SAndroid Build Coastguard Worker
486*f6dc9357SAndroid Build Coastguard Worker bool dataError = false;
487*f6dc9357SAndroid Build Coastguard Worker
488*f6dc9357SAndroid Build Coastguard Worker #ifdef NSIS_SCRIPT
489*f6dc9357SAndroid Build Coastguard Worker if (index >= (UInt32)_archive.Items.Size())
490*f6dc9357SAndroid Build Coastguard Worker {
491*f6dc9357SAndroid Build Coastguard Worker const void *data;
492*f6dc9357SAndroid Build Coastguard Worker size_t size;
493*f6dc9357SAndroid Build Coastguard Worker if (index == (UInt32)_archive.Items.Size())
494*f6dc9357SAndroid Build Coastguard Worker {
495*f6dc9357SAndroid Build Coastguard Worker data = (const Byte *)_archive.Script;
496*f6dc9357SAndroid Build Coastguard Worker size = _archive.Script.Len();
497*f6dc9357SAndroid Build Coastguard Worker }
498*f6dc9357SAndroid Build Coastguard Worker else
499*f6dc9357SAndroid Build Coastguard Worker {
500*f6dc9357SAndroid Build Coastguard Worker CLicenseFile &lic = _archive.LicenseFiles[index - (_archive.Items.Size() + 1)];
501*f6dc9357SAndroid Build Coastguard Worker if (lic.Text.Size() != 0)
502*f6dc9357SAndroid Build Coastguard Worker data = lic.Text;
503*f6dc9357SAndroid Build Coastguard Worker else
504*f6dc9357SAndroid Build Coastguard Worker data = _archive._data + lic.Offset;
505*f6dc9357SAndroid Build Coastguard Worker size = lic.Size;
506*f6dc9357SAndroid Build Coastguard Worker }
507*f6dc9357SAndroid Build Coastguard Worker curUnpacked = size;
508*f6dc9357SAndroid Build Coastguard Worker if (!testMode && !realOutStream)
509*f6dc9357SAndroid Build Coastguard Worker continue;
510*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->PrepareOperation(askMode))
511*f6dc9357SAndroid Build Coastguard Worker if (realOutStream)
512*f6dc9357SAndroid Build Coastguard Worker RINOK(WriteStream(realOutStream, data, size))
513*f6dc9357SAndroid Build Coastguard Worker }
514*f6dc9357SAndroid Build Coastguard Worker else
515*f6dc9357SAndroid Build Coastguard Worker #endif
516*f6dc9357SAndroid Build Coastguard Worker {
517*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _archive.Items[index];
518*f6dc9357SAndroid Build Coastguard Worker
519*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsSolid)
520*f6dc9357SAndroid Build Coastguard Worker GetCompressedSize(index, curPacked);
521*f6dc9357SAndroid Build Coastguard Worker
522*f6dc9357SAndroid Build Coastguard Worker if (!testMode && !realOutStream)
523*f6dc9357SAndroid Build Coastguard Worker continue;
524*f6dc9357SAndroid Build Coastguard Worker
525*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->PrepareOperation(askMode))
526*f6dc9357SAndroid Build Coastguard Worker
527*f6dc9357SAndroid Build Coastguard Worker dataError = solidDataError;
528*f6dc9357SAndroid Build Coastguard Worker
529*f6dc9357SAndroid Build Coastguard Worker bool needDecompress = false;
530*f6dc9357SAndroid Build Coastguard Worker
531*f6dc9357SAndroid Build Coastguard Worker if (!item.IsEmptyFile)
532*f6dc9357SAndroid Build Coastguard Worker {
533*f6dc9357SAndroid Build Coastguard Worker needDecompress = !solidDataError;
534*f6dc9357SAndroid Build Coastguard Worker if (needDecompress)
535*f6dc9357SAndroid Build Coastguard Worker {
536*f6dc9357SAndroid Build Coastguard Worker if (testMode && _archive.IsSolid && _archive.GetPosOfSolidItem(index) == prevPos)
537*f6dc9357SAndroid Build Coastguard Worker needDecompress = false;
538*f6dc9357SAndroid Build Coastguard Worker }
539*f6dc9357SAndroid Build Coastguard Worker }
540*f6dc9357SAndroid Build Coastguard Worker
541*f6dc9357SAndroid Build Coastguard Worker if (needDecompress)
542*f6dc9357SAndroid Build Coastguard Worker {
543*f6dc9357SAndroid Build Coastguard Worker bool writeToTemp = false;
544*f6dc9357SAndroid Build Coastguard Worker bool readFromTemp = false;
545*f6dc9357SAndroid Build Coastguard Worker
546*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsSolid)
547*f6dc9357SAndroid Build Coastguard Worker {
548*f6dc9357SAndroid Build Coastguard Worker RINOK(_archive.SeekToNonSolidItem(index))
549*f6dc9357SAndroid Build Coastguard Worker }
550*f6dc9357SAndroid Build Coastguard Worker else
551*f6dc9357SAndroid Build Coastguard Worker {
552*f6dc9357SAndroid Build Coastguard Worker UInt64 pos = _archive.GetPosOfSolidItem(index);
553*f6dc9357SAndroid Build Coastguard Worker if (pos < _archive.Decoder.StreamPos)
554*f6dc9357SAndroid Build Coastguard Worker {
555*f6dc9357SAndroid Build Coastguard Worker if (pos != tempPos)
556*f6dc9357SAndroid Build Coastguard Worker solidDataError = dataError = true;
557*f6dc9357SAndroid Build Coastguard Worker readFromTemp = true;
558*f6dc9357SAndroid Build Coastguard Worker }
559*f6dc9357SAndroid Build Coastguard Worker else
560*f6dc9357SAndroid Build Coastguard Worker {
561*f6dc9357SAndroid Build Coastguard Worker HRESULT res = _archive.Decoder.SetToPos(pos, lps);
562*f6dc9357SAndroid Build Coastguard Worker if (res != S_OK)
563*f6dc9357SAndroid Build Coastguard Worker {
564*f6dc9357SAndroid Build Coastguard Worker if (res != S_FALSE)
565*f6dc9357SAndroid Build Coastguard Worker return res;
566*f6dc9357SAndroid Build Coastguard Worker solidDataError = dataError = true;
567*f6dc9357SAndroid Build Coastguard Worker }
568*f6dc9357SAndroid Build Coastguard Worker else if (!testMode && i + 1 < numItems)
569*f6dc9357SAndroid Build Coastguard Worker {
570*f6dc9357SAndroid Build Coastguard Worker const UInt32 next = allFilesMode ? i + 1 : indices[i + 1];
571*f6dc9357SAndroid Build Coastguard Worker if (next < _archive.Items.Size())
572*f6dc9357SAndroid Build Coastguard Worker {
573*f6dc9357SAndroid Build Coastguard Worker // next cannot be IsEmptyFile
574*f6dc9357SAndroid Build Coastguard Worker const UInt64 nextPos = _archive.GetPosOfSolidItem(next);
575*f6dc9357SAndroid Build Coastguard Worker if (nextPos == pos)
576*f6dc9357SAndroid Build Coastguard Worker {
577*f6dc9357SAndroid Build Coastguard Worker writeToTemp = true;
578*f6dc9357SAndroid Build Coastguard Worker tempPos = pos;
579*f6dc9357SAndroid Build Coastguard Worker }
580*f6dc9357SAndroid Build Coastguard Worker }
581*f6dc9357SAndroid Build Coastguard Worker }
582*f6dc9357SAndroid Build Coastguard Worker }
583*f6dc9357SAndroid Build Coastguard Worker prevPos = pos;
584*f6dc9357SAndroid Build Coastguard Worker }
585*f6dc9357SAndroid Build Coastguard Worker
586*f6dc9357SAndroid Build Coastguard Worker /* nsis 3.08 can use (PatchSize == 0) for uninstaller without patched section */
587*f6dc9357SAndroid Build Coastguard Worker
588*f6dc9357SAndroid Build Coastguard Worker const bool is_PatchedUninstaller = item.Is_PatchedUninstaller();
589*f6dc9357SAndroid Build Coastguard Worker
590*f6dc9357SAndroid Build Coastguard Worker if (!dataError)
591*f6dc9357SAndroid Build Coastguard Worker {
592*f6dc9357SAndroid Build Coastguard Worker // UInt32 unpackSize = 0;
593*f6dc9357SAndroid Build Coastguard Worker // bool unpackSize_Defined = false;
594*f6dc9357SAndroid Build Coastguard Worker bool writeToTemp1 = writeToTemp;
595*f6dc9357SAndroid Build Coastguard Worker if (is_PatchedUninstaller)
596*f6dc9357SAndroid Build Coastguard Worker {
597*f6dc9357SAndroid Build Coastguard Worker // unpackSize = item.PatchSize;
598*f6dc9357SAndroid Build Coastguard Worker // unpackSize_Defined = true;
599*f6dc9357SAndroid Build Coastguard Worker if (!readFromTemp)
600*f6dc9357SAndroid Build Coastguard Worker writeToTemp = true;
601*f6dc9357SAndroid Build Coastguard Worker writeToTemp1 = writeToTemp;
602*f6dc9357SAndroid Build Coastguard Worker if (_archive.ExeStub.Size() == 0)
603*f6dc9357SAndroid Build Coastguard Worker {
604*f6dc9357SAndroid Build Coastguard Worker if (writeToTemp1 && !readFromTemp)
605*f6dc9357SAndroid Build Coastguard Worker tempBuf.Free();
606*f6dc9357SAndroid Build Coastguard Worker writeToTemp1 = false;
607*f6dc9357SAndroid Build Coastguard Worker }
608*f6dc9357SAndroid Build Coastguard Worker }
609*f6dc9357SAndroid Build Coastguard Worker
610*f6dc9357SAndroid Build Coastguard Worker if (readFromTemp)
611*f6dc9357SAndroid Build Coastguard Worker {
612*f6dc9357SAndroid Build Coastguard Worker if (realOutStream && !is_PatchedUninstaller)
613*f6dc9357SAndroid Build Coastguard Worker RINOK(WriteStream(realOutStream, tempBuf, tempBuf.Size()))
614*f6dc9357SAndroid Build Coastguard Worker }
615*f6dc9357SAndroid Build Coastguard Worker else
616*f6dc9357SAndroid Build Coastguard Worker {
617*f6dc9357SAndroid Build Coastguard Worker UInt32 curUnpacked32 = 0;
618*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = _archive.Decoder.Decode(
619*f6dc9357SAndroid Build Coastguard Worker writeToTemp1 ? &tempBuf : NULL,
620*f6dc9357SAndroid Build Coastguard Worker is_PatchedUninstaller, item.PatchSize,
621*f6dc9357SAndroid Build Coastguard Worker is_PatchedUninstaller ? NULL : (ISequentialOutStream *)realOutStream,
622*f6dc9357SAndroid Build Coastguard Worker lps,
623*f6dc9357SAndroid Build Coastguard Worker curPacked, curUnpacked32);
624*f6dc9357SAndroid Build Coastguard Worker curUnpacked = curUnpacked32;
625*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid)
626*f6dc9357SAndroid Build Coastguard Worker curUnpacked = 0;
627*f6dc9357SAndroid Build Coastguard Worker if (res != S_OK)
628*f6dc9357SAndroid Build Coastguard Worker {
629*f6dc9357SAndroid Build Coastguard Worker if (res != S_FALSE)
630*f6dc9357SAndroid Build Coastguard Worker return res;
631*f6dc9357SAndroid Build Coastguard Worker dataError = true;
632*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid)
633*f6dc9357SAndroid Build Coastguard Worker solidDataError = true;
634*f6dc9357SAndroid Build Coastguard Worker }
635*f6dc9357SAndroid Build Coastguard Worker }
636*f6dc9357SAndroid Build Coastguard Worker }
637*f6dc9357SAndroid Build Coastguard Worker
638*f6dc9357SAndroid Build Coastguard Worker if (!dataError && is_PatchedUninstaller)
639*f6dc9357SAndroid Build Coastguard Worker {
640*f6dc9357SAndroid Build Coastguard Worker if (_archive.ExeStub.Size() != 0)
641*f6dc9357SAndroid Build Coastguard Worker {
642*f6dc9357SAndroid Build Coastguard Worker CByteBuffer destBuf = _archive.ExeStub;
643*f6dc9357SAndroid Build Coastguard Worker dataError = !UninstallerPatch(tempBuf, tempBuf.Size(), destBuf, destBuf.Size());
644*f6dc9357SAndroid Build Coastguard Worker if (realOutStream)
645*f6dc9357SAndroid Build Coastguard Worker RINOK(WriteStream(realOutStream, destBuf, destBuf.Size()))
646*f6dc9357SAndroid Build Coastguard Worker }
647*f6dc9357SAndroid Build Coastguard Worker
648*f6dc9357SAndroid Build Coastguard Worker if (readFromTemp)
649*f6dc9357SAndroid Build Coastguard Worker {
650*f6dc9357SAndroid Build Coastguard Worker if (realOutStream)
651*f6dc9357SAndroid Build Coastguard Worker RINOK(WriteStream(realOutStream, tempBuf2, tempBuf2.Size()))
652*f6dc9357SAndroid Build Coastguard Worker }
653*f6dc9357SAndroid Build Coastguard Worker else
654*f6dc9357SAndroid Build Coastguard Worker {
655*f6dc9357SAndroid Build Coastguard Worker UInt32 curPacked2 = 0;
656*f6dc9357SAndroid Build Coastguard Worker UInt32 curUnpacked2 = 0;
657*f6dc9357SAndroid Build Coastguard Worker
658*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsSolid)
659*f6dc9357SAndroid Build Coastguard Worker {
660*f6dc9357SAndroid Build Coastguard Worker RINOK(_archive.SeekTo(_archive.GetPosOfNonSolidItem(index) + 4 + curPacked ))
661*f6dc9357SAndroid Build Coastguard Worker }
662*f6dc9357SAndroid Build Coastguard Worker
663*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = _archive.Decoder.Decode(
664*f6dc9357SAndroid Build Coastguard Worker writeToTemp ? &tempBuf2 : NULL,
665*f6dc9357SAndroid Build Coastguard Worker false, 0,
666*f6dc9357SAndroid Build Coastguard Worker realOutStream,
667*f6dc9357SAndroid Build Coastguard Worker lps,
668*f6dc9357SAndroid Build Coastguard Worker curPacked2, curUnpacked2);
669*f6dc9357SAndroid Build Coastguard Worker curPacked += curPacked2;
670*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsSolid)
671*f6dc9357SAndroid Build Coastguard Worker curUnpacked += curUnpacked2;
672*f6dc9357SAndroid Build Coastguard Worker if (res != S_OK)
673*f6dc9357SAndroid Build Coastguard Worker {
674*f6dc9357SAndroid Build Coastguard Worker if (res != S_FALSE)
675*f6dc9357SAndroid Build Coastguard Worker return res;
676*f6dc9357SAndroid Build Coastguard Worker dataError = true;
677*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSolid)
678*f6dc9357SAndroid Build Coastguard Worker solidDataError = true;
679*f6dc9357SAndroid Build Coastguard Worker }
680*f6dc9357SAndroid Build Coastguard Worker }
681*f6dc9357SAndroid Build Coastguard Worker }
682*f6dc9357SAndroid Build Coastguard Worker }
683*f6dc9357SAndroid Build Coastguard Worker }
684*f6dc9357SAndroid Build Coastguard Worker realOutStream.Release();
685*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->SetOperationResult(dataError ?
686*f6dc9357SAndroid Build Coastguard Worker NExtract::NOperationResult::kDataError :
687*f6dc9357SAndroid Build Coastguard Worker NExtract::NOperationResult::kOK))
688*f6dc9357SAndroid Build Coastguard Worker }
689*f6dc9357SAndroid Build Coastguard Worker return S_OK;
690*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
691*f6dc9357SAndroid Build Coastguard Worker }
692*f6dc9357SAndroid Build Coastguard Worker
693*f6dc9357SAndroid Build Coastguard Worker }}
694