1*f6dc9357SAndroid Build Coastguard Worker // 7zUpdate.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/MyLinux.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringToInt.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
10*f6dc9357SAndroid Build Coastguard Worker
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/CreateCoder.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/LimitedStreams.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ProgressUtils.h"
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/CopyCoder.h"
16*f6dc9357SAndroid Build Coastguard Worker
17*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ItemNameUtils.h"
18*f6dc9357SAndroid Build Coastguard Worker
19*f6dc9357SAndroid Build Coastguard Worker #include "7zDecode.h"
20*f6dc9357SAndroid Build Coastguard Worker #include "7zEncode.h"
21*f6dc9357SAndroid Build Coastguard Worker #include "7zFolderInStream.h"
22*f6dc9357SAndroid Build Coastguard Worker #include "7zHandler.h"
23*f6dc9357SAndroid Build Coastguard Worker #include "7zOut.h"
24*f6dc9357SAndroid Build Coastguard Worker #include "7zUpdate.h"
25*f6dc9357SAndroid Build Coastguard Worker
26*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
27*f6dc9357SAndroid Build Coastguard Worker namespace N7z {
28*f6dc9357SAndroid Build Coastguard Worker
29*f6dc9357SAndroid Build Coastguard Worker #define k_X86 k_BCJ
30*f6dc9357SAndroid Build Coastguard Worker
31*f6dc9357SAndroid Build Coastguard Worker struct CFilterMode
32*f6dc9357SAndroid Build Coastguard Worker {
33*f6dc9357SAndroid Build Coastguard Worker UInt32 Id;
34*f6dc9357SAndroid Build Coastguard Worker UInt32 Delta; // required File Size alignment, if Id is not k_Delta.
35*f6dc9357SAndroid Build Coastguard Worker // (Delta == 0) means unknown alignment
36*f6dc9357SAndroid Build Coastguard Worker UInt32 Offset; // for k_ARM64 / k_RISCV
37*f6dc9357SAndroid Build Coastguard Worker // UInt32 AlignSizeOpt; // for k_ARM64
38*f6dc9357SAndroid Build Coastguard Worker
CFilterModeNArchive::N7z::CFilterMode39*f6dc9357SAndroid Build Coastguard Worker CFilterMode():
40*f6dc9357SAndroid Build Coastguard Worker Id(0),
41*f6dc9357SAndroid Build Coastguard Worker Delta(0),
42*f6dc9357SAndroid Build Coastguard Worker Offset(0)
43*f6dc9357SAndroid Build Coastguard Worker // , AlignSizeOpt(0)
44*f6dc9357SAndroid Build Coastguard Worker {}
45*f6dc9357SAndroid Build Coastguard Worker
ClearFilterModeNArchive::N7z::CFilterMode46*f6dc9357SAndroid Build Coastguard Worker void ClearFilterMode()
47*f6dc9357SAndroid Build Coastguard Worker {
48*f6dc9357SAndroid Build Coastguard Worker Id = 0;
49*f6dc9357SAndroid Build Coastguard Worker Delta = 0;
50*f6dc9357SAndroid Build Coastguard Worker Offset = 0;
51*f6dc9357SAndroid Build Coastguard Worker // AlignSizeOpt = 0;
52*f6dc9357SAndroid Build Coastguard Worker }
53*f6dc9357SAndroid Build Coastguard Worker
54*f6dc9357SAndroid Build Coastguard Worker // it sets Delta as Align value, if Id is exe filter
55*f6dc9357SAndroid Build Coastguard Worker // in another cases it sets Delta = 0, that
SetDeltaNArchive::N7z::CFilterMode56*f6dc9357SAndroid Build Coastguard Worker void SetDelta()
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker if (Id == k_IA64)
59*f6dc9357SAndroid Build Coastguard Worker Delta = 16;
60*f6dc9357SAndroid Build Coastguard Worker else if (Id == k_ARM64 || Id == k_ARM || Id == k_PPC || Id == k_SPARC)
61*f6dc9357SAndroid Build Coastguard Worker Delta = 4;
62*f6dc9357SAndroid Build Coastguard Worker else if (Id == k_ARMT || Id == k_RISCV)
63*f6dc9357SAndroid Build Coastguard Worker Delta = 2;
64*f6dc9357SAndroid Build Coastguard Worker else if (Id == k_BCJ || Id == k_BCJ2)
65*f6dc9357SAndroid Build Coastguard Worker Delta = 1; // do we need it?
66*f6dc9357SAndroid Build Coastguard Worker else
67*f6dc9357SAndroid Build Coastguard Worker Delta = 0;
68*f6dc9357SAndroid Build Coastguard Worker }
69*f6dc9357SAndroid Build Coastguard Worker };
70*f6dc9357SAndroid Build Coastguard Worker
71*f6dc9357SAndroid Build Coastguard Worker
72*f6dc9357SAndroid Build Coastguard Worker /* ---------- PE ---------- */
73*f6dc9357SAndroid Build Coastguard Worker
74*f6dc9357SAndroid Build Coastguard Worker #define MZ_SIG 0x5A4D
75*f6dc9357SAndroid Build Coastguard Worker
76*f6dc9357SAndroid Build Coastguard Worker #define PE_SIG 0x00004550
77*f6dc9357SAndroid Build Coastguard Worker #define PE_OptHeader_Magic_32 0x10B
78*f6dc9357SAndroid Build Coastguard Worker #define PE_OptHeader_Magic_64 0x20B
79*f6dc9357SAndroid Build Coastguard Worker // #define PE_SectHeaderSize 40
80*f6dc9357SAndroid Build Coastguard Worker // #define PE_SECT_EXECUTE 0x20000000
81*f6dc9357SAndroid Build Coastguard Worker
Parse_EXE(const Byte * buf,size_t size,CFilterMode * filterMode)82*f6dc9357SAndroid Build Coastguard Worker static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
83*f6dc9357SAndroid Build Coastguard Worker {
84*f6dc9357SAndroid Build Coastguard Worker if (size < 512 || GetUi16(buf) != MZ_SIG)
85*f6dc9357SAndroid Build Coastguard Worker return 0;
86*f6dc9357SAndroid Build Coastguard Worker
87*f6dc9357SAndroid Build Coastguard Worker const Byte *p;
88*f6dc9357SAndroid Build Coastguard Worker UInt32 peOffset, optHeaderSize, filterId;
89*f6dc9357SAndroid Build Coastguard Worker
90*f6dc9357SAndroid Build Coastguard Worker peOffset = GetUi32(buf + 0x3C);
91*f6dc9357SAndroid Build Coastguard Worker if (peOffset >= 0x1000 || peOffset + 512 > size || (peOffset & 7) != 0)
92*f6dc9357SAndroid Build Coastguard Worker return 0;
93*f6dc9357SAndroid Build Coastguard Worker p = buf + peOffset;
94*f6dc9357SAndroid Build Coastguard Worker if (GetUi32(p) != PE_SIG)
95*f6dc9357SAndroid Build Coastguard Worker return 0;
96*f6dc9357SAndroid Build Coastguard Worker p += 4;
97*f6dc9357SAndroid Build Coastguard Worker
98*f6dc9357SAndroid Build Coastguard Worker const unsigned machine = GetUi16(p);
99*f6dc9357SAndroid Build Coastguard Worker
100*f6dc9357SAndroid Build Coastguard Worker switch (machine)
101*f6dc9357SAndroid Build Coastguard Worker {
102*f6dc9357SAndroid Build Coastguard Worker case 0x014C:
103*f6dc9357SAndroid Build Coastguard Worker case 0x8664: filterId = k_X86; break;
104*f6dc9357SAndroid Build Coastguard Worker case 0xAA64: filterId = k_ARM64; break;
105*f6dc9357SAndroid Build Coastguard Worker
106*f6dc9357SAndroid Build Coastguard Worker /*
107*f6dc9357SAndroid Build Coastguard Worker IMAGE_FILE_MACHINE_ARM 0x01C0 // ARM LE
108*f6dc9357SAndroid Build Coastguard Worker IMAGE_FILE_MACHINE_THUMB 0x01C2 // ARM Thumb / Thumb-2 LE
109*f6dc9357SAndroid Build Coastguard Worker IMAGE_FILE_MACHINE_ARMNT 0x01C4 // ARM Thumb-2, LE
110*f6dc9357SAndroid Build Coastguard Worker Note: We use ARM filter for 0x01C2. (WinCE 5 - 0x01C2) files mostly contain ARM code (not Thumb/Thumb-2).
111*f6dc9357SAndroid Build Coastguard Worker */
112*f6dc9357SAndroid Build Coastguard Worker
113*f6dc9357SAndroid Build Coastguard Worker case 0x01C0: // WinCE old
114*f6dc9357SAndroid Build Coastguard Worker case 0x01C2: filterId = k_ARM; break; // WinCE new
115*f6dc9357SAndroid Build Coastguard Worker case 0x01C4: filterId = k_ARMT; break; // WinRT
116*f6dc9357SAndroid Build Coastguard Worker
117*f6dc9357SAndroid Build Coastguard Worker case 0x5032: // RISCV32
118*f6dc9357SAndroid Build Coastguard Worker case 0x5064: // RISCV64
119*f6dc9357SAndroid Build Coastguard Worker // case 0x5128: // RISCV128
120*f6dc9357SAndroid Build Coastguard Worker filterId = k_RISCV; break;
121*f6dc9357SAndroid Build Coastguard Worker
122*f6dc9357SAndroid Build Coastguard Worker case 0x0200: filterId = k_IA64; break;
123*f6dc9357SAndroid Build Coastguard Worker default: return 0;
124*f6dc9357SAndroid Build Coastguard Worker }
125*f6dc9357SAndroid Build Coastguard Worker
126*f6dc9357SAndroid Build Coastguard Worker const UInt32 numSections = GetUi16(p + 2);
127*f6dc9357SAndroid Build Coastguard Worker optHeaderSize = GetUi16(p + 16);
128*f6dc9357SAndroid Build Coastguard Worker if (optHeaderSize > (1 << 10))
129*f6dc9357SAndroid Build Coastguard Worker return 0;
130*f6dc9357SAndroid Build Coastguard Worker
131*f6dc9357SAndroid Build Coastguard Worker p += 20; /* headerSize */
132*f6dc9357SAndroid Build Coastguard Worker
133*f6dc9357SAndroid Build Coastguard Worker switch (GetUi16(p))
134*f6dc9357SAndroid Build Coastguard Worker {
135*f6dc9357SAndroid Build Coastguard Worker case PE_OptHeader_Magic_32:
136*f6dc9357SAndroid Build Coastguard Worker case PE_OptHeader_Magic_64:
137*f6dc9357SAndroid Build Coastguard Worker break;
138*f6dc9357SAndroid Build Coastguard Worker default:
139*f6dc9357SAndroid Build Coastguard Worker return 0;
140*f6dc9357SAndroid Build Coastguard Worker }
141*f6dc9357SAndroid Build Coastguard Worker
142*f6dc9357SAndroid Build Coastguard Worker // Windows exe file sizes are not aligned for 4 KiB.
143*f6dc9357SAndroid Build Coastguard Worker // So we can't use (CFilterMode::Offset != 0) in solid archives.
144*f6dc9357SAndroid Build Coastguard Worker // So we just don't set Offset here.
145*f6dc9357SAndroid Build Coastguard Worker #define NUM_SCAN_SECTIONS_MAX (1 << 6)
146*f6dc9357SAndroid Build Coastguard Worker // #define EXE_SECTION_OFFSET_MAX (1 << 27)
147*f6dc9357SAndroid Build Coastguard Worker // #define EXE_SECTION_SIZE_MIN (1 << 8)
148*f6dc9357SAndroid Build Coastguard Worker // #define EXE_SECTION_SIZE_MAX (1 << 27)
149*f6dc9357SAndroid Build Coastguard Worker #define PE_SectHeaderSize 40
150*f6dc9357SAndroid Build Coastguard Worker // #define PE_SECT_EXECUTE 0x20000000
151*f6dc9357SAndroid Build Coastguard Worker
152*f6dc9357SAndroid Build Coastguard Worker /*
153*f6dc9357SAndroid Build Coastguard Worker if (numSections > NUM_SCAN_SECTIONS_MAX)
154*f6dc9357SAndroid Build Coastguard Worker return 0;
155*f6dc9357SAndroid Build Coastguard Worker */
156*f6dc9357SAndroid Build Coastguard Worker
157*f6dc9357SAndroid Build Coastguard Worker if ((size_t)(p - buf) + optHeaderSize <= size)
158*f6dc9357SAndroid Build Coastguard Worker {
159*f6dc9357SAndroid Build Coastguard Worker p += optHeaderSize;
160*f6dc9357SAndroid Build Coastguard Worker /*
161*f6dc9357SAndroid Build Coastguard Worker // UInt32 numExeSections = 0;
162*f6dc9357SAndroid Build Coastguard Worker // bool execute_finded = false;
163*f6dc9357SAndroid Build Coastguard Worker // UInt32 sect_va = 0;
164*f6dc9357SAndroid Build Coastguard Worker // UInt32 sect_size = 0;
165*f6dc9357SAndroid Build Coastguard Worker // UInt32 sect_offset = 0;
166*f6dc9357SAndroid Build Coastguard Worker */
167*f6dc9357SAndroid Build Coastguard Worker if (numSections <= NUM_SCAN_SECTIONS_MAX)
168*f6dc9357SAndroid Build Coastguard Worker if (machine == 0x8664)
169*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numSections
170*f6dc9357SAndroid Build Coastguard Worker ; i++, p += PE_SectHeaderSize)
171*f6dc9357SAndroid Build Coastguard Worker {
172*f6dc9357SAndroid Build Coastguard Worker // UInt32 characts, rawSize, offset;
173*f6dc9357SAndroid Build Coastguard Worker if ((UInt32)(p - buf) + PE_SectHeaderSize > size)
174*f6dc9357SAndroid Build Coastguard Worker {
175*f6dc9357SAndroid Build Coastguard Worker // return 0;
176*f6dc9357SAndroid Build Coastguard Worker break;
177*f6dc9357SAndroid Build Coastguard Worker }
178*f6dc9357SAndroid Build Coastguard Worker if (memcmp(p, ".a64xrm", 8) == 0)
179*f6dc9357SAndroid Build Coastguard Worker {
180*f6dc9357SAndroid Build Coastguard Worker // ARM64EC
181*f6dc9357SAndroid Build Coastguard Worker filterId = k_ARM64;
182*f6dc9357SAndroid Build Coastguard Worker break;
183*f6dc9357SAndroid Build Coastguard Worker }
184*f6dc9357SAndroid Build Coastguard Worker /*
185*f6dc9357SAndroid Build Coastguard Worker rawSize = GetUi32(p + 16);
186*f6dc9357SAndroid Build Coastguard Worker offset = GetUi32(p + 20);
187*f6dc9357SAndroid Build Coastguard Worker characts = GetUi32(p + 36);
188*f6dc9357SAndroid Build Coastguard Worker if (rawSize >= EXE_SECTION_SIZE_MIN &&
189*f6dc9357SAndroid Build Coastguard Worker rawSize <= EXE_SECTION_SIZE_MAX &&
190*f6dc9357SAndroid Build Coastguard Worker offset <= EXE_SECTION_OFFSET_MAX &&
191*f6dc9357SAndroid Build Coastguard Worker // offset < limit &&
192*f6dc9357SAndroid Build Coastguard Worker offset > 0)
193*f6dc9357SAndroid Build Coastguard Worker {
194*f6dc9357SAndroid Build Coastguard Worker if ((characts & PE_SECT_EXECUTE) != 0)
195*f6dc9357SAndroid Build Coastguard Worker {
196*f6dc9357SAndroid Build Coastguard Worker // execute_finded = true;
197*f6dc9357SAndroid Build Coastguard Worker // sect_va = GetUi32(p + 12);
198*f6dc9357SAndroid Build Coastguard Worker // sect_size = rawSize;
199*f6dc9357SAndroid Build Coastguard Worker // sect_offset = offset;
200*f6dc9357SAndroid Build Coastguard Worker break;
201*f6dc9357SAndroid Build Coastguard Worker }
202*f6dc9357SAndroid Build Coastguard Worker }
203*f6dc9357SAndroid Build Coastguard Worker */
204*f6dc9357SAndroid Build Coastguard Worker }
205*f6dc9357SAndroid Build Coastguard Worker }
206*f6dc9357SAndroid Build Coastguard Worker
207*f6dc9357SAndroid Build Coastguard Worker /*
208*f6dc9357SAndroid Build Coastguard Worker filterMode->Offset = 0;
209*f6dc9357SAndroid Build Coastguard Worker if (filterId == k_ARM64)
210*f6dc9357SAndroid Build Coastguard Worker {
211*f6dc9357SAndroid Build Coastguard Worker // filterMode->AlignSizeOpt = (1 << 12);
212*f6dc9357SAndroid Build Coastguard Worker // const UInt32 offs = (sect_va - sect_offset) & 0xFFF;
213*f6dc9357SAndroid Build Coastguard Worker // if (offs != 0)
214*f6dc9357SAndroid Build Coastguard Worker // filterMode->Offset = offs; // change it
215*f6dc9357SAndroid Build Coastguard Worker }
216*f6dc9357SAndroid Build Coastguard Worker */
217*f6dc9357SAndroid Build Coastguard Worker filterMode->Id = filterId;
218*f6dc9357SAndroid Build Coastguard Worker return 1;
219*f6dc9357SAndroid Build Coastguard Worker }
220*f6dc9357SAndroid Build Coastguard Worker
221*f6dc9357SAndroid Build Coastguard Worker
222*f6dc9357SAndroid Build Coastguard Worker /*
223*f6dc9357SAndroid Build Coastguard Worker Filters don't improve the compression ratio for relocatable object files (".o").
224*f6dc9357SAndroid Build Coastguard Worker But we can get compression ratio gain, if we compress object
225*f6dc9357SAndroid Build Coastguard Worker files and executables in same solid block.
226*f6dc9357SAndroid Build Coastguard Worker So we use filters for relocatable object files (".o"):
227*f6dc9357SAndroid Build Coastguard Worker */
228*f6dc9357SAndroid Build Coastguard Worker // #define Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
229*f6dc9357SAndroid Build Coastguard Worker
230*f6dc9357SAndroid Build Coastguard Worker /* ---------- ELF ---------- */
231*f6dc9357SAndroid Build Coastguard Worker
232*f6dc9357SAndroid Build Coastguard Worker #define ELF_SIG 0x464C457F
233*f6dc9357SAndroid Build Coastguard Worker
234*f6dc9357SAndroid Build Coastguard Worker #define ELF_CLASS_32 1
235*f6dc9357SAndroid Build Coastguard Worker #define ELF_CLASS_64 2
236*f6dc9357SAndroid Build Coastguard Worker
237*f6dc9357SAndroid Build Coastguard Worker #define ELF_DATA_2LSB 1
238*f6dc9357SAndroid Build Coastguard Worker #define ELF_DATA_2MSB 2
239*f6dc9357SAndroid Build Coastguard Worker
Get16(const Byte * p,BoolInt be)240*f6dc9357SAndroid Build Coastguard Worker static UInt16 Get16(const Byte *p, BoolInt be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
Get32(const Byte * p,BoolInt be)241*f6dc9357SAndroid Build Coastguard Worker static UInt32 Get32(const Byte *p, BoolInt be) { if (be) return GetBe32(p); return GetUi32(p); }
242*f6dc9357SAndroid Build Coastguard Worker // static UInt64 Get64(const Byte *p, BoolInt be) { if (be) return GetBe64(p); return GetUi64(p); }
243*f6dc9357SAndroid Build Coastguard Worker
Parse_ELF(const Byte * buf,size_t size,CFilterMode * filterMode)244*f6dc9357SAndroid Build Coastguard Worker static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
245*f6dc9357SAndroid Build Coastguard Worker {
246*f6dc9357SAndroid Build Coastguard Worker BoolInt /* is32, */ be;
247*f6dc9357SAndroid Build Coastguard Worker UInt32 filterId;
248*f6dc9357SAndroid Build Coastguard Worker
249*f6dc9357SAndroid Build Coastguard Worker if (size < 512 || buf[6] != 1) /* ver */
250*f6dc9357SAndroid Build Coastguard Worker return 0;
251*f6dc9357SAndroid Build Coastguard Worker
252*f6dc9357SAndroid Build Coastguard Worker if (GetUi32(buf) != ELF_SIG)
253*f6dc9357SAndroid Build Coastguard Worker return 0;
254*f6dc9357SAndroid Build Coastguard Worker
255*f6dc9357SAndroid Build Coastguard Worker switch (buf[4])
256*f6dc9357SAndroid Build Coastguard Worker {
257*f6dc9357SAndroid Build Coastguard Worker case ELF_CLASS_32: /* is32 = True; */ break;
258*f6dc9357SAndroid Build Coastguard Worker case ELF_CLASS_64: /* is32 = False; */ break;
259*f6dc9357SAndroid Build Coastguard Worker default: return 0;
260*f6dc9357SAndroid Build Coastguard Worker }
261*f6dc9357SAndroid Build Coastguard Worker
262*f6dc9357SAndroid Build Coastguard Worker switch (buf[5])
263*f6dc9357SAndroid Build Coastguard Worker {
264*f6dc9357SAndroid Build Coastguard Worker case ELF_DATA_2LSB: be = False; break;
265*f6dc9357SAndroid Build Coastguard Worker case ELF_DATA_2MSB: be = True; break;
266*f6dc9357SAndroid Build Coastguard Worker default: return 0;
267*f6dc9357SAndroid Build Coastguard Worker }
268*f6dc9357SAndroid Build Coastguard Worker
269*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
270*f6dc9357SAndroid Build Coastguard Worker #define ELF_ET_REL 1
271*f6dc9357SAndroid Build Coastguard Worker if (Get16(buf + 0x10, be) == ELF_ET_REL)
272*f6dc9357SAndroid Build Coastguard Worker return 0;
273*f6dc9357SAndroid Build Coastguard Worker #endif
274*f6dc9357SAndroid Build Coastguard Worker
275*f6dc9357SAndroid Build Coastguard Worker switch (Get16(buf + 0x12, be))
276*f6dc9357SAndroid Build Coastguard Worker {
277*f6dc9357SAndroid Build Coastguard Worker case 3:
278*f6dc9357SAndroid Build Coastguard Worker case 6:
279*f6dc9357SAndroid Build Coastguard Worker case 62: filterId = k_X86; break;
280*f6dc9357SAndroid Build Coastguard Worker case 2:
281*f6dc9357SAndroid Build Coastguard Worker case 18:
282*f6dc9357SAndroid Build Coastguard Worker case 43: filterId = k_SPARC; break;
283*f6dc9357SAndroid Build Coastguard Worker case 20:
284*f6dc9357SAndroid Build Coastguard Worker case 21: if (!be) return 0; filterId = k_PPC; break;
285*f6dc9357SAndroid Build Coastguard Worker case 40: if (be) return 0; filterId = k_ARM; break;
286*f6dc9357SAndroid Build Coastguard Worker case 183: if (be) return 0; filterId = k_ARM64; break;
287*f6dc9357SAndroid Build Coastguard Worker case 243: if (be) return 0; filterId = k_RISCV; break;
288*f6dc9357SAndroid Build Coastguard Worker
289*f6dc9357SAndroid Build Coastguard Worker /* Some IA-64 ELF executables have size that is not aligned for 16 bytes.
290*f6dc9357SAndroid Build Coastguard Worker So we don't use IA-64 filter for IA-64 ELF */
291*f6dc9357SAndroid Build Coastguard Worker // case 50: if ( be) return 0; filterId = k_IA64; break;
292*f6dc9357SAndroid Build Coastguard Worker
293*f6dc9357SAndroid Build Coastguard Worker default: return 0;
294*f6dc9357SAndroid Build Coastguard Worker }
295*f6dc9357SAndroid Build Coastguard Worker
296*f6dc9357SAndroid Build Coastguard Worker filterMode->Id = filterId;
297*f6dc9357SAndroid Build Coastguard Worker return 1;
298*f6dc9357SAndroid Build Coastguard Worker }
299*f6dc9357SAndroid Build Coastguard Worker
300*f6dc9357SAndroid Build Coastguard Worker
301*f6dc9357SAndroid Build Coastguard Worker
302*f6dc9357SAndroid Build Coastguard Worker /* ---------- Mach-O ---------- */
303*f6dc9357SAndroid Build Coastguard Worker
304*f6dc9357SAndroid Build Coastguard Worker #define MACH_SIG_BE_32 0xCEFAEDFE
305*f6dc9357SAndroid Build Coastguard Worker #define MACH_SIG_BE_64 0xCFFAEDFE
306*f6dc9357SAndroid Build Coastguard Worker #define MACH_SIG_LE_32 0xFEEDFACE
307*f6dc9357SAndroid Build Coastguard Worker #define MACH_SIG_LE_64 0xFEEDFACF
308*f6dc9357SAndroid Build Coastguard Worker
309*f6dc9357SAndroid Build Coastguard Worker #define MACH_ARCH_ABI64 (1 << 24)
310*f6dc9357SAndroid Build Coastguard Worker #define MACH_MACHINE_386 7
311*f6dc9357SAndroid Build Coastguard Worker #define MACH_MACHINE_ARM 12
312*f6dc9357SAndroid Build Coastguard Worker #define MACH_MACHINE_SPARC 14
313*f6dc9357SAndroid Build Coastguard Worker #define MACH_MACHINE_PPC 18
314*f6dc9357SAndroid Build Coastguard Worker #define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC)
315*f6dc9357SAndroid Build Coastguard Worker #define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386)
316*f6dc9357SAndroid Build Coastguard Worker #define MACH_MACHINE_ARM64 (MACH_ARCH_ABI64 | MACH_MACHINE_ARM)
317*f6dc9357SAndroid Build Coastguard Worker
Parse_MACH(const Byte * buf,size_t size,CFilterMode * filterMode)318*f6dc9357SAndroid Build Coastguard Worker static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode)
319*f6dc9357SAndroid Build Coastguard Worker {
320*f6dc9357SAndroid Build Coastguard Worker UInt32 filterId, numCommands, commandsSize;
321*f6dc9357SAndroid Build Coastguard Worker
322*f6dc9357SAndroid Build Coastguard Worker if (size < 512)
323*f6dc9357SAndroid Build Coastguard Worker return 0;
324*f6dc9357SAndroid Build Coastguard Worker
325*f6dc9357SAndroid Build Coastguard Worker BoolInt /* mode64, */ be;
326*f6dc9357SAndroid Build Coastguard Worker switch (GetUi32(buf))
327*f6dc9357SAndroid Build Coastguard Worker {
328*f6dc9357SAndroid Build Coastguard Worker case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break;
329*f6dc9357SAndroid Build Coastguard Worker case MACH_SIG_BE_64: /* mode64 = True; */ be = True; break;
330*f6dc9357SAndroid Build Coastguard Worker case MACH_SIG_LE_32: /* mode64 = False; */ be = False; break;
331*f6dc9357SAndroid Build Coastguard Worker case MACH_SIG_LE_64: /* mode64 = True; */ be = False; break;
332*f6dc9357SAndroid Build Coastguard Worker default: return 0;
333*f6dc9357SAndroid Build Coastguard Worker }
334*f6dc9357SAndroid Build Coastguard Worker
335*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
336*f6dc9357SAndroid Build Coastguard Worker #define MACH_TYPE_OBJECT 1
337*f6dc9357SAndroid Build Coastguard Worker if (Get32(buf + 0xC, be) == MACH_TYPE_OBJECT)
338*f6dc9357SAndroid Build Coastguard Worker return 0;
339*f6dc9357SAndroid Build Coastguard Worker #endif
340*f6dc9357SAndroid Build Coastguard Worker
341*f6dc9357SAndroid Build Coastguard Worker switch (Get32(buf + 4, be))
342*f6dc9357SAndroid Build Coastguard Worker {
343*f6dc9357SAndroid Build Coastguard Worker case MACH_MACHINE_386:
344*f6dc9357SAndroid Build Coastguard Worker case MACH_MACHINE_AMD64: filterId = k_X86; break;
345*f6dc9357SAndroid Build Coastguard Worker case MACH_MACHINE_ARM: if ( be) return 0; filterId = k_ARM; break;
346*f6dc9357SAndroid Build Coastguard Worker case MACH_MACHINE_SPARC: if (!be) return 0; filterId = k_SPARC; break;
347*f6dc9357SAndroid Build Coastguard Worker case MACH_MACHINE_PPC:
348*f6dc9357SAndroid Build Coastguard Worker case MACH_MACHINE_PPC64: if (!be) return 0; filterId = k_PPC; break;
349*f6dc9357SAndroid Build Coastguard Worker case MACH_MACHINE_ARM64: if ( be) return 0; filterId = k_ARM64; break;
350*f6dc9357SAndroid Build Coastguard Worker default: return 0;
351*f6dc9357SAndroid Build Coastguard Worker }
352*f6dc9357SAndroid Build Coastguard Worker
353*f6dc9357SAndroid Build Coastguard Worker numCommands = Get32(buf + 0x10, be);
354*f6dc9357SAndroid Build Coastguard Worker commandsSize = Get32(buf + 0x14, be);
355*f6dc9357SAndroid Build Coastguard Worker
356*f6dc9357SAndroid Build Coastguard Worker if (commandsSize > (1 << 24) || numCommands > (1 << 18))
357*f6dc9357SAndroid Build Coastguard Worker return 0;
358*f6dc9357SAndroid Build Coastguard Worker
359*f6dc9357SAndroid Build Coastguard Worker filterMode->Id = filterId;
360*f6dc9357SAndroid Build Coastguard Worker return 1;
361*f6dc9357SAndroid Build Coastguard Worker }
362*f6dc9357SAndroid Build Coastguard Worker
363*f6dc9357SAndroid Build Coastguard Worker
364*f6dc9357SAndroid Build Coastguard Worker /* ---------- WAV ---------- */
365*f6dc9357SAndroid Build Coastguard Worker
366*f6dc9357SAndroid Build Coastguard Worker #define WAV_SUBCHUNK_fmt 0x20746D66
367*f6dc9357SAndroid Build Coastguard Worker #define WAV_SUBCHUNK_data 0x61746164
368*f6dc9357SAndroid Build Coastguard Worker
369*f6dc9357SAndroid Build Coastguard Worker #define RIFF_SIG 0x46464952
370*f6dc9357SAndroid Build Coastguard Worker
Parse_WAV(const Byte * buf,size_t size,CFilterMode * filterMode)371*f6dc9357SAndroid Build Coastguard Worker static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
372*f6dc9357SAndroid Build Coastguard Worker {
373*f6dc9357SAndroid Build Coastguard Worker UInt32 subChunkSize, pos;
374*f6dc9357SAndroid Build Coastguard Worker if (size < 0x2C)
375*f6dc9357SAndroid Build Coastguard Worker return False;
376*f6dc9357SAndroid Build Coastguard Worker
377*f6dc9357SAndroid Build Coastguard Worker if (GetUi32(buf + 0) != RIFF_SIG ||
378*f6dc9357SAndroid Build Coastguard Worker GetUi32(buf + 8) != 0x45564157 || // WAVE
379*f6dc9357SAndroid Build Coastguard Worker GetUi32(buf + 0xC) != WAV_SUBCHUNK_fmt)
380*f6dc9357SAndroid Build Coastguard Worker return False;
381*f6dc9357SAndroid Build Coastguard Worker subChunkSize = GetUi32(buf + 0x10);
382*f6dc9357SAndroid Build Coastguard Worker /* [0x14 = format] = 1 (PCM) */
383*f6dc9357SAndroid Build Coastguard Worker if (subChunkSize < 0x10 || subChunkSize > 0x12 || GetUi16(buf + 0x14) != 1)
384*f6dc9357SAndroid Build Coastguard Worker return False;
385*f6dc9357SAndroid Build Coastguard Worker
386*f6dc9357SAndroid Build Coastguard Worker const unsigned numChannels = GetUi16(buf + 0x16);
387*f6dc9357SAndroid Build Coastguard Worker const unsigned bitsPerSample = GetUi16(buf + 0x22);
388*f6dc9357SAndroid Build Coastguard Worker if ((bitsPerSample & 0x7) != 0)
389*f6dc9357SAndroid Build Coastguard Worker return False;
390*f6dc9357SAndroid Build Coastguard Worker const UInt32 delta = (UInt32)numChannels * (bitsPerSample >> 3);
391*f6dc9357SAndroid Build Coastguard Worker if (delta == 0 || delta > 256)
392*f6dc9357SAndroid Build Coastguard Worker return False;
393*f6dc9357SAndroid Build Coastguard Worker
394*f6dc9357SAndroid Build Coastguard Worker pos = 0x14 + subChunkSize;
395*f6dc9357SAndroid Build Coastguard Worker
396*f6dc9357SAndroid Build Coastguard Worker const int kNumSubChunksTests = 10;
397*f6dc9357SAndroid Build Coastguard Worker // Do we need to scan more than 3 sub-chunks?
398*f6dc9357SAndroid Build Coastguard Worker for (int i = 0; i < kNumSubChunksTests; i++)
399*f6dc9357SAndroid Build Coastguard Worker {
400*f6dc9357SAndroid Build Coastguard Worker if (pos + 8 > size)
401*f6dc9357SAndroid Build Coastguard Worker return False;
402*f6dc9357SAndroid Build Coastguard Worker subChunkSize = GetUi32(buf + pos + 4);
403*f6dc9357SAndroid Build Coastguard Worker if (GetUi32(buf + pos) == WAV_SUBCHUNK_data)
404*f6dc9357SAndroid Build Coastguard Worker {
405*f6dc9357SAndroid Build Coastguard Worker filterMode->Id = k_Delta;
406*f6dc9357SAndroid Build Coastguard Worker filterMode->Delta = delta;
407*f6dc9357SAndroid Build Coastguard Worker return True;
408*f6dc9357SAndroid Build Coastguard Worker }
409*f6dc9357SAndroid Build Coastguard Worker if (subChunkSize > (1 << 16))
410*f6dc9357SAndroid Build Coastguard Worker return False;
411*f6dc9357SAndroid Build Coastguard Worker pos += subChunkSize + 8;
412*f6dc9357SAndroid Build Coastguard Worker }
413*f6dc9357SAndroid Build Coastguard Worker return False;
414*f6dc9357SAndroid Build Coastguard Worker }
415*f6dc9357SAndroid Build Coastguard Worker
416*f6dc9357SAndroid Build Coastguard Worker
417*f6dc9357SAndroid Build Coastguard Worker /*
418*f6dc9357SAndroid Build Coastguard Worker filterMode->Delta will be set as:
419*f6dc9357SAndroid Build Coastguard Worker = delta value : [1, 256] : for k_Delta
420*f6dc9357SAndroid Build Coastguard Worker = 0 for another filters (branch filters)
421*f6dc9357SAndroid Build Coastguard Worker */
ParseFile(const Byte * buf,size_t size,CFilterMode * filterMode)422*f6dc9357SAndroid Build Coastguard Worker static BoolInt ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode)
423*f6dc9357SAndroid Build Coastguard Worker {
424*f6dc9357SAndroid Build Coastguard Worker filterMode->ClearFilterMode();
425*f6dc9357SAndroid Build Coastguard Worker
426*f6dc9357SAndroid Build Coastguard Worker if (Parse_EXE(buf, size, filterMode)) return True;
427*f6dc9357SAndroid Build Coastguard Worker if (Parse_ELF(buf, size, filterMode)) return True;
428*f6dc9357SAndroid Build Coastguard Worker if (Parse_MACH(buf, size, filterMode)) return True;
429*f6dc9357SAndroid Build Coastguard Worker return Parse_WAV(buf, size, filterMode);
430*f6dc9357SAndroid Build Coastguard Worker }
431*f6dc9357SAndroid Build Coastguard Worker
432*f6dc9357SAndroid Build Coastguard Worker
433*f6dc9357SAndroid Build Coastguard Worker
434*f6dc9357SAndroid Build Coastguard Worker
435*f6dc9357SAndroid Build Coastguard Worker struct CFilterMode2: public CFilterMode
436*f6dc9357SAndroid Build Coastguard Worker {
437*f6dc9357SAndroid Build Coastguard Worker bool Encrypted;
438*f6dc9357SAndroid Build Coastguard Worker unsigned GroupIndex;
439*f6dc9357SAndroid Build Coastguard Worker
CFilterMode2NArchive::N7z::CFilterMode2440*f6dc9357SAndroid Build Coastguard Worker CFilterMode2(): Encrypted(false) {}
441*f6dc9357SAndroid Build Coastguard Worker
CompareNArchive::N7z::CFilterMode2442*f6dc9357SAndroid Build Coastguard Worker int Compare(const CFilterMode2 &m) const
443*f6dc9357SAndroid Build Coastguard Worker {
444*f6dc9357SAndroid Build Coastguard Worker if (!Encrypted)
445*f6dc9357SAndroid Build Coastguard Worker {
446*f6dc9357SAndroid Build Coastguard Worker if (m.Encrypted)
447*f6dc9357SAndroid Build Coastguard Worker return -1;
448*f6dc9357SAndroid Build Coastguard Worker }
449*f6dc9357SAndroid Build Coastguard Worker else if (!m.Encrypted)
450*f6dc9357SAndroid Build Coastguard Worker return 1;
451*f6dc9357SAndroid Build Coastguard Worker
452*f6dc9357SAndroid Build Coastguard Worker const UInt32 id1 = Id;
453*f6dc9357SAndroid Build Coastguard Worker const UInt32 id2 = m.Id;
454*f6dc9357SAndroid Build Coastguard Worker /*
455*f6dc9357SAndroid Build Coastguard Worker // we can change the order to place k_ARM64 files close to another exe files
456*f6dc9357SAndroid Build Coastguard Worker if (id1 <= k_SPARC &&
457*f6dc9357SAndroid Build Coastguard Worker id2 <= k_SPARC)
458*f6dc9357SAndroid Build Coastguard Worker {
459*f6dc9357SAndroid Build Coastguard Worker #define k_ARM64_FOR_SORT 0x3030901
460*f6dc9357SAndroid Build Coastguard Worker if (id1 == k_ARM64) id1 = k_ARM64_FOR_SORT;
461*f6dc9357SAndroid Build Coastguard Worker if (id2 == k_ARM64) id2 = k_ARM64_FOR_SORT;
462*f6dc9357SAndroid Build Coastguard Worker }
463*f6dc9357SAndroid Build Coastguard Worker */
464*f6dc9357SAndroid Build Coastguard Worker if (id1 < id2) return -1;
465*f6dc9357SAndroid Build Coastguard Worker if (id1 > id2) return 1;
466*f6dc9357SAndroid Build Coastguard Worker
467*f6dc9357SAndroid Build Coastguard Worker if (Delta < m.Delta) return -1;
468*f6dc9357SAndroid Build Coastguard Worker if (Delta > m.Delta) return 1;
469*f6dc9357SAndroid Build Coastguard Worker
470*f6dc9357SAndroid Build Coastguard Worker if (Offset < m.Offset) return -1;
471*f6dc9357SAndroid Build Coastguard Worker if (Offset > m.Offset) return 1;
472*f6dc9357SAndroid Build Coastguard Worker
473*f6dc9357SAndroid Build Coastguard Worker /* we don't go here, because GetGroup()
474*f6dc9357SAndroid Build Coastguard Worker and operator ==(const CFilterMode2 &m)
475*f6dc9357SAndroid Build Coastguard Worker add only unique CFilterMode2:: { Id, Delta, Offset, Encrypted } items.
476*f6dc9357SAndroid Build Coastguard Worker */
477*f6dc9357SAndroid Build Coastguard Worker /*
478*f6dc9357SAndroid Build Coastguard Worker if (GroupIndex < m.GroupIndex) return -1;
479*f6dc9357SAndroid Build Coastguard Worker if (GroupIndex > m.GroupIndex) return 1;
480*f6dc9357SAndroid Build Coastguard Worker */
481*f6dc9357SAndroid Build Coastguard Worker return 0;
482*f6dc9357SAndroid Build Coastguard Worker }
483*f6dc9357SAndroid Build Coastguard Worker
operator ==NArchive::N7z::CFilterMode2484*f6dc9357SAndroid Build Coastguard Worker bool operator ==(const CFilterMode2 &m) const
485*f6dc9357SAndroid Build Coastguard Worker {
486*f6dc9357SAndroid Build Coastguard Worker return Id == m.Id
487*f6dc9357SAndroid Build Coastguard Worker && Delta == m.Delta
488*f6dc9357SAndroid Build Coastguard Worker && Offset == m.Offset
489*f6dc9357SAndroid Build Coastguard Worker && Encrypted == m.Encrypted;
490*f6dc9357SAndroid Build Coastguard Worker }
491*f6dc9357SAndroid Build Coastguard Worker };
492*f6dc9357SAndroid Build Coastguard Worker
GetGroup(CRecordVector<CFilterMode2> & filters,const CFilterMode2 & m)493*f6dc9357SAndroid Build Coastguard Worker static unsigned GetGroup(CRecordVector<CFilterMode2> &filters, const CFilterMode2 &m)
494*f6dc9357SAndroid Build Coastguard Worker {
495*f6dc9357SAndroid Build Coastguard Worker unsigned i;
496*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < filters.Size(); i++)
497*f6dc9357SAndroid Build Coastguard Worker {
498*f6dc9357SAndroid Build Coastguard Worker const CFilterMode2 &m2 = filters[i];
499*f6dc9357SAndroid Build Coastguard Worker if (m == m2)
500*f6dc9357SAndroid Build Coastguard Worker return i;
501*f6dc9357SAndroid Build Coastguard Worker /*
502*f6dc9357SAndroid Build Coastguard Worker if (m.Encrypted != m2.Encrypted)
503*f6dc9357SAndroid Build Coastguard Worker {
504*f6dc9357SAndroid Build Coastguard Worker if (!m.Encrypted)
505*f6dc9357SAndroid Build Coastguard Worker break;
506*f6dc9357SAndroid Build Coastguard Worker continue;
507*f6dc9357SAndroid Build Coastguard Worker }
508*f6dc9357SAndroid Build Coastguard Worker
509*f6dc9357SAndroid Build Coastguard Worker if (m.Id < m2.Id) break;
510*f6dc9357SAndroid Build Coastguard Worker if (m.Id != m2.Id) continue;
511*f6dc9357SAndroid Build Coastguard Worker
512*f6dc9357SAndroid Build Coastguard Worker if (m.Delta < m2.Delta) break;
513*f6dc9357SAndroid Build Coastguard Worker if (m.Delta != m2.Delta) continue;
514*f6dc9357SAndroid Build Coastguard Worker */
515*f6dc9357SAndroid Build Coastguard Worker }
516*f6dc9357SAndroid Build Coastguard Worker // filters.Insert(i, m);
517*f6dc9357SAndroid Build Coastguard Worker // return i;
518*f6dc9357SAndroid Build Coastguard Worker return filters.Add(m);
519*f6dc9357SAndroid Build Coastguard Worker }
520*f6dc9357SAndroid Build Coastguard Worker
Is86Filter(CMethodId m)521*f6dc9357SAndroid Build Coastguard Worker static inline bool Is86Filter(CMethodId m)
522*f6dc9357SAndroid Build Coastguard Worker {
523*f6dc9357SAndroid Build Coastguard Worker return (m == k_BCJ || m == k_BCJ2);
524*f6dc9357SAndroid Build Coastguard Worker }
525*f6dc9357SAndroid Build Coastguard Worker
IsExeFilter(CMethodId m)526*f6dc9357SAndroid Build Coastguard Worker static inline bool IsExeFilter(CMethodId m)
527*f6dc9357SAndroid Build Coastguard Worker {
528*f6dc9357SAndroid Build Coastguard Worker switch (m)
529*f6dc9357SAndroid Build Coastguard Worker {
530*f6dc9357SAndroid Build Coastguard Worker case k_ARM64:
531*f6dc9357SAndroid Build Coastguard Worker case k_RISCV:
532*f6dc9357SAndroid Build Coastguard Worker case k_BCJ:
533*f6dc9357SAndroid Build Coastguard Worker case k_BCJ2:
534*f6dc9357SAndroid Build Coastguard Worker case k_ARM:
535*f6dc9357SAndroid Build Coastguard Worker case k_ARMT:
536*f6dc9357SAndroid Build Coastguard Worker case k_PPC:
537*f6dc9357SAndroid Build Coastguard Worker case k_SPARC:
538*f6dc9357SAndroid Build Coastguard Worker case k_IA64:
539*f6dc9357SAndroid Build Coastguard Worker return true;
540*f6dc9357SAndroid Build Coastguard Worker default: break;
541*f6dc9357SAndroid Build Coastguard Worker }
542*f6dc9357SAndroid Build Coastguard Worker return false;
543*f6dc9357SAndroid Build Coastguard Worker }
544*f6dc9357SAndroid Build Coastguard Worker
Get_FilterGroup_for_Folder(CRecordVector<CFilterMode2> & filters,const CFolderEx & f,bool extractFilter)545*f6dc9357SAndroid Build Coastguard Worker static unsigned Get_FilterGroup_for_Folder(
546*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CFilterMode2> &filters, const CFolderEx &f, bool extractFilter)
547*f6dc9357SAndroid Build Coastguard Worker {
548*f6dc9357SAndroid Build Coastguard Worker CFilterMode2 m;
549*f6dc9357SAndroid Build Coastguard Worker // m.Id = 0;
550*f6dc9357SAndroid Build Coastguard Worker // m.Delta = 0;
551*f6dc9357SAndroid Build Coastguard Worker // m.Offset = 0;
552*f6dc9357SAndroid Build Coastguard Worker m.Encrypted = f.IsEncrypted();
553*f6dc9357SAndroid Build Coastguard Worker
554*f6dc9357SAndroid Build Coastguard Worker if (extractFilter)
555*f6dc9357SAndroid Build Coastguard Worker {
556*f6dc9357SAndroid Build Coastguard Worker const CCoderInfo &coder = f.Coders[f.UnpackCoder];
557*f6dc9357SAndroid Build Coastguard Worker
558*f6dc9357SAndroid Build Coastguard Worker if (coder.MethodID == k_Delta)
559*f6dc9357SAndroid Build Coastguard Worker {
560*f6dc9357SAndroid Build Coastguard Worker if (coder.Props.Size() == 1)
561*f6dc9357SAndroid Build Coastguard Worker {
562*f6dc9357SAndroid Build Coastguard Worker m.Delta = (unsigned)coder.Props[0] + 1;
563*f6dc9357SAndroid Build Coastguard Worker m.Id = k_Delta;
564*f6dc9357SAndroid Build Coastguard Worker }
565*f6dc9357SAndroid Build Coastguard Worker }
566*f6dc9357SAndroid Build Coastguard Worker else if (IsExeFilter(coder.MethodID))
567*f6dc9357SAndroid Build Coastguard Worker {
568*f6dc9357SAndroid Build Coastguard Worker m.Id = (UInt32)coder.MethodID;
569*f6dc9357SAndroid Build Coastguard Worker if (m.Id == k_BCJ2)
570*f6dc9357SAndroid Build Coastguard Worker m.Id = k_BCJ;
571*f6dc9357SAndroid Build Coastguard Worker m.SetDelta();
572*f6dc9357SAndroid Build Coastguard Worker if (m.Id == k_ARM64 ||
573*f6dc9357SAndroid Build Coastguard Worker m.Id == k_RISCV)
574*f6dc9357SAndroid Build Coastguard Worker if (coder.Props.Size() == 4)
575*f6dc9357SAndroid Build Coastguard Worker m.Offset = GetUi32(coder.Props);
576*f6dc9357SAndroid Build Coastguard Worker }
577*f6dc9357SAndroid Build Coastguard Worker }
578*f6dc9357SAndroid Build Coastguard Worker
579*f6dc9357SAndroid Build Coastguard Worker return GetGroup(filters, m);
580*f6dc9357SAndroid Build Coastguard Worker }
581*f6dc9357SAndroid Build Coastguard Worker
582*f6dc9357SAndroid Build Coastguard Worker
583*f6dc9357SAndroid Build Coastguard Worker
584*f6dc9357SAndroid Build Coastguard Worker
WriteRange(IInStream * inStream,ISequentialOutStream * outStream,UInt64 position,UInt64 size,ICompressProgressInfo * progress)585*f6dc9357SAndroid Build Coastguard Worker static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
586*f6dc9357SAndroid Build Coastguard Worker UInt64 position, UInt64 size, ICompressProgressInfo *progress)
587*f6dc9357SAndroid Build Coastguard Worker {
588*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(inStream, position))
589*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> streamSpec;
590*f6dc9357SAndroid Build Coastguard Worker streamSpec->SetStream(inStream);
591*f6dc9357SAndroid Build Coastguard Worker streamSpec->Init(size);
592*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
593*f6dc9357SAndroid Build Coastguard Worker RINOK(copyCoder.Interface()->Code(streamSpec, outStream, NULL, NULL, progress))
594*f6dc9357SAndroid Build Coastguard Worker return (copyCoder->TotalSize == size ? S_OK : E_FAIL);
595*f6dc9357SAndroid Build Coastguard Worker }
596*f6dc9357SAndroid Build Coastguard Worker
597*f6dc9357SAndroid Build Coastguard Worker /*
598*f6dc9357SAndroid Build Coastguard Worker unsigned CUpdateItem::GetExtensionPos() const
599*f6dc9357SAndroid Build Coastguard Worker {
600*f6dc9357SAndroid Build Coastguard Worker int slashPos = Name.ReverseFind_PathSepar();
601*f6dc9357SAndroid Build Coastguard Worker int dotPos = Name.ReverseFind_Dot();
602*f6dc9357SAndroid Build Coastguard Worker if (dotPos <= slashPos)
603*f6dc9357SAndroid Build Coastguard Worker return Name.Len();
604*f6dc9357SAndroid Build Coastguard Worker return dotPos + 1;
605*f6dc9357SAndroid Build Coastguard Worker }
606*f6dc9357SAndroid Build Coastguard Worker
607*f6dc9357SAndroid Build Coastguard Worker UString CUpdateItem::GetExtension() const
608*f6dc9357SAndroid Build Coastguard Worker {
609*f6dc9357SAndroid Build Coastguard Worker return Name.Ptr(GetExtensionPos());
610*f6dc9357SAndroid Build Coastguard Worker }
611*f6dc9357SAndroid Build Coastguard Worker */
612*f6dc9357SAndroid Build Coastguard Worker
613*f6dc9357SAndroid Build Coastguard Worker #define RINOZ(x) { const int _t_ = (x); if (_t_ != 0) return _t_; }
614*f6dc9357SAndroid Build Coastguard Worker
615*f6dc9357SAndroid Build Coastguard Worker #define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b))
616*f6dc9357SAndroid Build Coastguard Worker
617*f6dc9357SAndroid Build Coastguard Worker /*
618*f6dc9357SAndroid Build Coastguard Worker static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
619*f6dc9357SAndroid Build Coastguard Worker {
620*f6dc9357SAndroid Build Coastguard Worker size_t c1 = a1.GetCapacity();
621*f6dc9357SAndroid Build Coastguard Worker size_t c2 = a2.GetCapacity();
622*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(c1, c2);
623*f6dc9357SAndroid Build Coastguard Worker for (size_t i = 0; i < c1; i++)
624*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(a1[i], a2[i]);
625*f6dc9357SAndroid Build Coastguard Worker return 0;
626*f6dc9357SAndroid Build Coastguard Worker }
627*f6dc9357SAndroid Build Coastguard Worker
628*f6dc9357SAndroid Build Coastguard Worker static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2)
629*f6dc9357SAndroid Build Coastguard Worker {
630*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(c1.NumInStreams, c2.NumInStreams);
631*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(c1.NumOutStreams, c2.NumOutStreams);
632*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(c1.MethodID, c2.MethodID);
633*f6dc9357SAndroid Build Coastguard Worker return CompareBuffers(c1.Props, c2.Props);
634*f6dc9357SAndroid Build Coastguard Worker }
635*f6dc9357SAndroid Build Coastguard Worker
636*f6dc9357SAndroid Build Coastguard Worker static int CompareBonds(const CBond &b1, const CBond &b2)
637*f6dc9357SAndroid Build Coastguard Worker {
638*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(b1.InIndex, b2.InIndex);
639*f6dc9357SAndroid Build Coastguard Worker return MyCompare(b1.OutIndex, b2.OutIndex);
640*f6dc9357SAndroid Build Coastguard Worker }
641*f6dc9357SAndroid Build Coastguard Worker
642*f6dc9357SAndroid Build Coastguard Worker static int CompareFolders(const CFolder &f1, const CFolder &f2)
643*f6dc9357SAndroid Build Coastguard Worker {
644*f6dc9357SAndroid Build Coastguard Worker int s1 = f1.Coders.Size();
645*f6dc9357SAndroid Build Coastguard Worker int s2 = f2.Coders.Size();
646*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(s1, s2);
647*f6dc9357SAndroid Build Coastguard Worker int i;
648*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < s1; i++)
649*f6dc9357SAndroid Build Coastguard Worker RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i]));
650*f6dc9357SAndroid Build Coastguard Worker s1 = f1.Bonds.Size();
651*f6dc9357SAndroid Build Coastguard Worker s2 = f2.Bonds.Size();
652*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(s1, s2);
653*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < s1; i++)
654*f6dc9357SAndroid Build Coastguard Worker RINOZ(CompareBonds(f1.Bonds[i], f2.Bonds[i]));
655*f6dc9357SAndroid Build Coastguard Worker return 0;
656*f6dc9357SAndroid Build Coastguard Worker }
657*f6dc9357SAndroid Build Coastguard Worker */
658*f6dc9357SAndroid Build Coastguard Worker
659*f6dc9357SAndroid Build Coastguard Worker /*
660*f6dc9357SAndroid Build Coastguard Worker static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
661*f6dc9357SAndroid Build Coastguard Worker {
662*f6dc9357SAndroid Build Coastguard Worker return CompareFileNames(f1.Name, f2.Name);
663*f6dc9357SAndroid Build Coastguard Worker }
664*f6dc9357SAndroid Build Coastguard Worker */
665*f6dc9357SAndroid Build Coastguard Worker
666*f6dc9357SAndroid Build Coastguard Worker struct CFolderRepack
667*f6dc9357SAndroid Build Coastguard Worker {
668*f6dc9357SAndroid Build Coastguard Worker unsigned FolderIndex;
669*f6dc9357SAndroid Build Coastguard Worker CNum NumCopyFiles;
670*f6dc9357SAndroid Build Coastguard Worker };
671*f6dc9357SAndroid Build Coastguard Worker
672*f6dc9357SAndroid Build Coastguard Worker /*
673*f6dc9357SAndroid Build Coastguard Worker static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *)
674*f6dc9357SAndroid Build Coastguard Worker {
675*f6dc9357SAndroid Build Coastguard Worker int i1 = p1->FolderIndex;
676*f6dc9357SAndroid Build Coastguard Worker int i2 = p2->FolderIndex;
677*f6dc9357SAndroid Build Coastguard Worker // In that version we don't want to parse folders here, so we don't compare folders
678*f6dc9357SAndroid Build Coastguard Worker // probably it must be improved in future
679*f6dc9357SAndroid Build Coastguard Worker // const CDbEx &db = *(const CDbEx *)param;
680*f6dc9357SAndroid Build Coastguard Worker // RINOZ(CompareFolders(
681*f6dc9357SAndroid Build Coastguard Worker // db.Folders[i1],
682*f6dc9357SAndroid Build Coastguard Worker // db.Folders[i2]));
683*f6dc9357SAndroid Build Coastguard Worker
684*f6dc9357SAndroid Build Coastguard Worker return MyCompare(i1, i2);
685*f6dc9357SAndroid Build Coastguard Worker
686*f6dc9357SAndroid Build Coastguard Worker // RINOZ_COMP(
687*f6dc9357SAndroid Build Coastguard Worker // db.NumUnpackStreamsVector[i1],
688*f6dc9357SAndroid Build Coastguard Worker // db.NumUnpackStreamsVector[i2]);
689*f6dc9357SAndroid Build Coastguard Worker // if (db.NumUnpackStreamsVector[i1] == 0)
690*f6dc9357SAndroid Build Coastguard Worker // return 0;
691*f6dc9357SAndroid Build Coastguard Worker // return CompareFiles(
692*f6dc9357SAndroid Build Coastguard Worker // db.Files[db.FolderStartFileIndex[i1]],
693*f6dc9357SAndroid Build Coastguard Worker // db.Files[db.FolderStartFileIndex[i2]]);
694*f6dc9357SAndroid Build Coastguard Worker }
695*f6dc9357SAndroid Build Coastguard Worker */
696*f6dc9357SAndroid Build Coastguard Worker
697*f6dc9357SAndroid Build Coastguard Worker /*
698*f6dc9357SAndroid Build Coastguard Worker we sort empty files and dirs in such order:
699*f6dc9357SAndroid Build Coastguard Worker - Dir.NonAnti (name sorted)
700*f6dc9357SAndroid Build Coastguard Worker - File.NonAnti (name sorted)
701*f6dc9357SAndroid Build Coastguard Worker - File.Anti (name sorted)
702*f6dc9357SAndroid Build Coastguard Worker - Dir.Anti (reverse name sorted)
703*f6dc9357SAndroid Build Coastguard Worker */
704*f6dc9357SAndroid Build Coastguard Worker
CompareEmptyItems(const unsigned * p1,const unsigned * p2,void * param)705*f6dc9357SAndroid Build Coastguard Worker static int CompareEmptyItems(const unsigned *p1, const unsigned *p2, void *param)
706*f6dc9357SAndroid Build Coastguard Worker {
707*f6dc9357SAndroid Build Coastguard Worker const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
708*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &u1 = updateItems[*p1];
709*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &u2 = updateItems[*p2];
710*f6dc9357SAndroid Build Coastguard Worker // NonAnti < Anti
711*f6dc9357SAndroid Build Coastguard Worker if (u1.IsAnti != u2.IsAnti)
712*f6dc9357SAndroid Build Coastguard Worker return (u1.IsAnti ? 1 : -1);
713*f6dc9357SAndroid Build Coastguard Worker if (u1.IsDir != u2.IsDir)
714*f6dc9357SAndroid Build Coastguard Worker {
715*f6dc9357SAndroid Build Coastguard Worker // Dir.NonAnti < File < Dir.Anti
716*f6dc9357SAndroid Build Coastguard Worker if (u1.IsDir)
717*f6dc9357SAndroid Build Coastguard Worker return (u1.IsAnti ? 1 : -1);
718*f6dc9357SAndroid Build Coastguard Worker return (u2.IsAnti ? -1 : 1);
719*f6dc9357SAndroid Build Coastguard Worker }
720*f6dc9357SAndroid Build Coastguard Worker int n = CompareFileNames(u1.Name, u2.Name);
721*f6dc9357SAndroid Build Coastguard Worker return (u1.IsDir && u1.IsAnti) ? -n : n;
722*f6dc9357SAndroid Build Coastguard Worker }
723*f6dc9357SAndroid Build Coastguard Worker
724*f6dc9357SAndroid Build Coastguard Worker static const char *g_Exts =
725*f6dc9357SAndroid Build Coastguard Worker " 7z xz lzma ace arc arj bz tbz bz2 tbz2 cab deb gz tgz ha lha lzh lzo lzx pak rar rpm sit zoo"
726*f6dc9357SAndroid Build Coastguard Worker " zip jar ear war msi"
727*f6dc9357SAndroid Build Coastguard Worker " 3gp avi mov mpeg mpg mpe wmv"
728*f6dc9357SAndroid Build Coastguard Worker " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
729*f6dc9357SAndroid Build Coastguard Worker " swf"
730*f6dc9357SAndroid Build Coastguard Worker " chm hxi hxs"
731*f6dc9357SAndroid Build Coastguard Worker " gif jpeg jpg jp2 png tiff bmp ico psd psp"
732*f6dc9357SAndroid Build Coastguard Worker " awg ps eps cgm dxf svg vrml wmf emf ai md"
733*f6dc9357SAndroid Build Coastguard Worker " cad dwg pps key sxi"
734*f6dc9357SAndroid Build Coastguard Worker " max 3ds"
735*f6dc9357SAndroid Build Coastguard Worker " iso bin nrg mdf img pdi tar cpio xpi"
736*f6dc9357SAndroid Build Coastguard Worker " vfd vhd vud vmc vsv"
737*f6dc9357SAndroid Build Coastguard Worker " vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
738*f6dc9357SAndroid Build Coastguard Worker " inl inc idl acf asa"
739*f6dc9357SAndroid Build Coastguard Worker " h hpp hxx c cpp cxx m mm go swift"
740*f6dc9357SAndroid Build Coastguard Worker " rc java cs rs pas bas vb cls ctl frm dlg def"
741*f6dc9357SAndroid Build Coastguard Worker " f77 f f90 f95"
742*f6dc9357SAndroid Build Coastguard Worker " asm s"
743*f6dc9357SAndroid Build Coastguard Worker " sql manifest dep"
744*f6dc9357SAndroid Build Coastguard Worker " mak clw csproj vcproj sln dsp dsw"
745*f6dc9357SAndroid Build Coastguard Worker " class"
746*f6dc9357SAndroid Build Coastguard Worker " bat cmd bash sh"
747*f6dc9357SAndroid Build Coastguard Worker " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
748*f6dc9357SAndroid Build Coastguard Worker " awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs"
749*f6dc9357SAndroid Build Coastguard Worker " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
750*f6dc9357SAndroid Build Coastguard Worker " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
751*f6dc9357SAndroid Build Coastguard Worker " abw afp cwk lwp wpd wps wpt wrf wri"
752*f6dc9357SAndroid Build Coastguard Worker " abf afm bdf fon mgf otf pcf pfa snf ttf"
753*f6dc9357SAndroid Build Coastguard Worker " dbf mdb nsf ntf wdb db fdb gdb"
754*f6dc9357SAndroid Build Coastguard Worker " exe dll ocx vbx sfx sys tlb awx com obj lib out o so"
755*f6dc9357SAndroid Build Coastguard Worker " pdb pch idb ncb opt";
756*f6dc9357SAndroid Build Coastguard Worker
GetExtIndex(const char * ext)757*f6dc9357SAndroid Build Coastguard Worker static unsigned GetExtIndex(const char *ext)
758*f6dc9357SAndroid Build Coastguard Worker {
759*f6dc9357SAndroid Build Coastguard Worker unsigned extIndex = 1;
760*f6dc9357SAndroid Build Coastguard Worker const char *p = g_Exts;
761*f6dc9357SAndroid Build Coastguard Worker for (;;)
762*f6dc9357SAndroid Build Coastguard Worker {
763*f6dc9357SAndroid Build Coastguard Worker char c = *p++;
764*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
765*f6dc9357SAndroid Build Coastguard Worker return extIndex;
766*f6dc9357SAndroid Build Coastguard Worker if (c == ' ')
767*f6dc9357SAndroid Build Coastguard Worker continue;
768*f6dc9357SAndroid Build Coastguard Worker unsigned pos = 0;
769*f6dc9357SAndroid Build Coastguard Worker for (;;)
770*f6dc9357SAndroid Build Coastguard Worker {
771*f6dc9357SAndroid Build Coastguard Worker char c2 = ext[pos++];
772*f6dc9357SAndroid Build Coastguard Worker if (c2 == 0 && (c == 0 || c == ' '))
773*f6dc9357SAndroid Build Coastguard Worker return extIndex;
774*f6dc9357SAndroid Build Coastguard Worker if (c != c2)
775*f6dc9357SAndroid Build Coastguard Worker break;
776*f6dc9357SAndroid Build Coastguard Worker c = *p++;
777*f6dc9357SAndroid Build Coastguard Worker }
778*f6dc9357SAndroid Build Coastguard Worker extIndex++;
779*f6dc9357SAndroid Build Coastguard Worker for (;;)
780*f6dc9357SAndroid Build Coastguard Worker {
781*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
782*f6dc9357SAndroid Build Coastguard Worker return extIndex;
783*f6dc9357SAndroid Build Coastguard Worker if (c == ' ')
784*f6dc9357SAndroid Build Coastguard Worker break;
785*f6dc9357SAndroid Build Coastguard Worker c = *p++;
786*f6dc9357SAndroid Build Coastguard Worker }
787*f6dc9357SAndroid Build Coastguard Worker }
788*f6dc9357SAndroid Build Coastguard Worker }
789*f6dc9357SAndroid Build Coastguard Worker
790*f6dc9357SAndroid Build Coastguard Worker struct CRefItem
791*f6dc9357SAndroid Build Coastguard Worker {
792*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem *UpdateItem;
793*f6dc9357SAndroid Build Coastguard Worker UInt32 Index;
794*f6dc9357SAndroid Build Coastguard Worker unsigned ExtensionPos;
795*f6dc9357SAndroid Build Coastguard Worker unsigned NamePos;
796*f6dc9357SAndroid Build Coastguard Worker unsigned ExtensionIndex;
797*f6dc9357SAndroid Build Coastguard Worker
CRefItemNArchive::N7z::CRefItem798*f6dc9357SAndroid Build Coastguard Worker CRefItem() {}
CRefItemNArchive::N7z::CRefItem799*f6dc9357SAndroid Build Coastguard Worker CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):
800*f6dc9357SAndroid Build Coastguard Worker UpdateItem(&ui),
801*f6dc9357SAndroid Build Coastguard Worker Index(index),
802*f6dc9357SAndroid Build Coastguard Worker ExtensionPos(0),
803*f6dc9357SAndroid Build Coastguard Worker NamePos(0),
804*f6dc9357SAndroid Build Coastguard Worker ExtensionIndex(0)
805*f6dc9357SAndroid Build Coastguard Worker {
806*f6dc9357SAndroid Build Coastguard Worker if (sortByType)
807*f6dc9357SAndroid Build Coastguard Worker {
808*f6dc9357SAndroid Build Coastguard Worker const int slashPos = ui.Name.ReverseFind_PathSepar();
809*f6dc9357SAndroid Build Coastguard Worker NamePos = (unsigned)(slashPos + 1);
810*f6dc9357SAndroid Build Coastguard Worker const int dotPos = ui.Name.ReverseFind_Dot();
811*f6dc9357SAndroid Build Coastguard Worker if (dotPos <= slashPos)
812*f6dc9357SAndroid Build Coastguard Worker ExtensionPos = ui.Name.Len();
813*f6dc9357SAndroid Build Coastguard Worker else
814*f6dc9357SAndroid Build Coastguard Worker {
815*f6dc9357SAndroid Build Coastguard Worker ExtensionPos = (unsigned)(dotPos + 1);
816*f6dc9357SAndroid Build Coastguard Worker if (ExtensionPos != ui.Name.Len())
817*f6dc9357SAndroid Build Coastguard Worker {
818*f6dc9357SAndroid Build Coastguard Worker AString s;
819*f6dc9357SAndroid Build Coastguard Worker for (unsigned pos = ExtensionPos;; pos++)
820*f6dc9357SAndroid Build Coastguard Worker {
821*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = ui.Name[pos];
822*f6dc9357SAndroid Build Coastguard Worker if (c >= 0x80)
823*f6dc9357SAndroid Build Coastguard Worker break;
824*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
825*f6dc9357SAndroid Build Coastguard Worker {
826*f6dc9357SAndroid Build Coastguard Worker ExtensionIndex = GetExtIndex(s);
827*f6dc9357SAndroid Build Coastguard Worker break;
828*f6dc9357SAndroid Build Coastguard Worker }
829*f6dc9357SAndroid Build Coastguard Worker s.Add_Char((char)MyCharLower_Ascii((char)c));
830*f6dc9357SAndroid Build Coastguard Worker }
831*f6dc9357SAndroid Build Coastguard Worker }
832*f6dc9357SAndroid Build Coastguard Worker }
833*f6dc9357SAndroid Build Coastguard Worker }
834*f6dc9357SAndroid Build Coastguard Worker }
835*f6dc9357SAndroid Build Coastguard Worker };
836*f6dc9357SAndroid Build Coastguard Worker
837*f6dc9357SAndroid Build Coastguard Worker struct CSortParam
838*f6dc9357SAndroid Build Coastguard Worker {
839*f6dc9357SAndroid Build Coastguard Worker // const CObjectVector<CTreeFolder> *TreeFolders;
840*f6dc9357SAndroid Build Coastguard Worker bool SortByType;
841*f6dc9357SAndroid Build Coastguard Worker };
842*f6dc9357SAndroid Build Coastguard Worker
843*f6dc9357SAndroid Build Coastguard Worker /*
844*f6dc9357SAndroid Build Coastguard Worker we sort files in such order:
845*f6dc9357SAndroid Build Coastguard Worker - Dir.NonAnti (name sorted)
846*f6dc9357SAndroid Build Coastguard Worker - alt streams
847*f6dc9357SAndroid Build Coastguard Worker - Dirs
848*f6dc9357SAndroid Build Coastguard Worker - Dir.Anti (reverse name sorted)
849*f6dc9357SAndroid Build Coastguard Worker */
850*f6dc9357SAndroid Build Coastguard Worker
851*f6dc9357SAndroid Build Coastguard Worker
CompareUpdateItems(const CRefItem * p1,const CRefItem * p2,void * param)852*f6dc9357SAndroid Build Coastguard Worker static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
853*f6dc9357SAndroid Build Coastguard Worker {
854*f6dc9357SAndroid Build Coastguard Worker const CRefItem &a1 = *p1;
855*f6dc9357SAndroid Build Coastguard Worker const CRefItem &a2 = *p2;
856*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &u1 = *a1.UpdateItem;
857*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &u2 = *a2.UpdateItem;
858*f6dc9357SAndroid Build Coastguard Worker
859*f6dc9357SAndroid Build Coastguard Worker /*
860*f6dc9357SAndroid Build Coastguard Worker if (u1.IsAltStream != u2.IsAltStream)
861*f6dc9357SAndroid Build Coastguard Worker return u1.IsAltStream ? 1 : -1;
862*f6dc9357SAndroid Build Coastguard Worker */
863*f6dc9357SAndroid Build Coastguard Worker
864*f6dc9357SAndroid Build Coastguard Worker // Actually there are no dirs that time. They were stored in other steps
865*f6dc9357SAndroid Build Coastguard Worker // So that code is unused?
866*f6dc9357SAndroid Build Coastguard Worker if (u1.IsDir != u2.IsDir)
867*f6dc9357SAndroid Build Coastguard Worker return u1.IsDir ? 1 : -1;
868*f6dc9357SAndroid Build Coastguard Worker if (u1.IsDir)
869*f6dc9357SAndroid Build Coastguard Worker {
870*f6dc9357SAndroid Build Coastguard Worker if (u1.IsAnti != u2.IsAnti)
871*f6dc9357SAndroid Build Coastguard Worker return (u1.IsAnti ? 1 : -1);
872*f6dc9357SAndroid Build Coastguard Worker int n = CompareFileNames(u1.Name, u2.Name);
873*f6dc9357SAndroid Build Coastguard Worker return -n;
874*f6dc9357SAndroid Build Coastguard Worker }
875*f6dc9357SAndroid Build Coastguard Worker
876*f6dc9357SAndroid Build Coastguard Worker // bool sortByType = *(bool *)param;
877*f6dc9357SAndroid Build Coastguard Worker const CSortParam *sortParam = (const CSortParam *)param;
878*f6dc9357SAndroid Build Coastguard Worker const bool sortByType = sortParam->SortByType;
879*f6dc9357SAndroid Build Coastguard Worker if (sortByType)
880*f6dc9357SAndroid Build Coastguard Worker {
881*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex)
882*f6dc9357SAndroid Build Coastguard Worker RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos)))
883*f6dc9357SAndroid Build Coastguard Worker RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos)))
884*f6dc9357SAndroid Build Coastguard Worker if (!u1.MTimeDefined && u2.MTimeDefined) return 1;
885*f6dc9357SAndroid Build Coastguard Worker if (u1.MTimeDefined && !u2.MTimeDefined) return -1;
886*f6dc9357SAndroid Build Coastguard Worker if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime)
887*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(u1.Size, u2.Size)
888*f6dc9357SAndroid Build Coastguard Worker }
889*f6dc9357SAndroid Build Coastguard Worker /*
890*f6dc9357SAndroid Build Coastguard Worker int par1 = a1.UpdateItem->ParentFolderIndex;
891*f6dc9357SAndroid Build Coastguard Worker int par2 = a2.UpdateItem->ParentFolderIndex;
892*f6dc9357SAndroid Build Coastguard Worker const CTreeFolder &tf1 = (*sortParam->TreeFolders)[par1];
893*f6dc9357SAndroid Build Coastguard Worker const CTreeFolder &tf2 = (*sortParam->TreeFolders)[par2];
894*f6dc9357SAndroid Build Coastguard Worker
895*f6dc9357SAndroid Build Coastguard Worker int b1 = tf1.SortIndex, e1 = tf1.SortIndexEnd;
896*f6dc9357SAndroid Build Coastguard Worker int b2 = tf2.SortIndex, e2 = tf2.SortIndexEnd;
897*f6dc9357SAndroid Build Coastguard Worker if (b1 < b2)
898*f6dc9357SAndroid Build Coastguard Worker {
899*f6dc9357SAndroid Build Coastguard Worker if (e1 <= b2)
900*f6dc9357SAndroid Build Coastguard Worker return -1;
901*f6dc9357SAndroid Build Coastguard Worker // p2 in p1
902*f6dc9357SAndroid Build Coastguard Worker int par = par2;
903*f6dc9357SAndroid Build Coastguard Worker for (;;)
904*f6dc9357SAndroid Build Coastguard Worker {
905*f6dc9357SAndroid Build Coastguard Worker const CTreeFolder &tf = (*sortParam->TreeFolders)[par];
906*f6dc9357SAndroid Build Coastguard Worker par = tf.Parent;
907*f6dc9357SAndroid Build Coastguard Worker if (par == par1)
908*f6dc9357SAndroid Build Coastguard Worker {
909*f6dc9357SAndroid Build Coastguard Worker RINOZ(CompareFileNames(u1.Name, tf.Name));
910*f6dc9357SAndroid Build Coastguard Worker break;
911*f6dc9357SAndroid Build Coastguard Worker }
912*f6dc9357SAndroid Build Coastguard Worker }
913*f6dc9357SAndroid Build Coastguard Worker }
914*f6dc9357SAndroid Build Coastguard Worker else if (b2 < b1)
915*f6dc9357SAndroid Build Coastguard Worker {
916*f6dc9357SAndroid Build Coastguard Worker if (e2 <= b1)
917*f6dc9357SAndroid Build Coastguard Worker return 1;
918*f6dc9357SAndroid Build Coastguard Worker // p1 in p2
919*f6dc9357SAndroid Build Coastguard Worker int par = par1;
920*f6dc9357SAndroid Build Coastguard Worker for (;;)
921*f6dc9357SAndroid Build Coastguard Worker {
922*f6dc9357SAndroid Build Coastguard Worker const CTreeFolder &tf = (*sortParam->TreeFolders)[par];
923*f6dc9357SAndroid Build Coastguard Worker par = tf.Parent;
924*f6dc9357SAndroid Build Coastguard Worker if (par == par2)
925*f6dc9357SAndroid Build Coastguard Worker {
926*f6dc9357SAndroid Build Coastguard Worker RINOZ(CompareFileNames(tf.Name, u2.Name));
927*f6dc9357SAndroid Build Coastguard Worker break;
928*f6dc9357SAndroid Build Coastguard Worker }
929*f6dc9357SAndroid Build Coastguard Worker }
930*f6dc9357SAndroid Build Coastguard Worker }
931*f6dc9357SAndroid Build Coastguard Worker */
932*f6dc9357SAndroid Build Coastguard Worker // RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex);
933*f6dc9357SAndroid Build Coastguard Worker RINOK(CompareFileNames(u1.Name, u2.Name))
934*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient)
935*f6dc9357SAndroid Build Coastguard Worker RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive)
936*f6dc9357SAndroid Build Coastguard Worker return 0;
937*f6dc9357SAndroid Build Coastguard Worker }
938*f6dc9357SAndroid Build Coastguard Worker
939*f6dc9357SAndroid Build Coastguard Worker struct CSolidGroup
940*f6dc9357SAndroid Build Coastguard Worker {
941*f6dc9357SAndroid Build Coastguard Worker CRecordVector<UInt32> Indices;
942*f6dc9357SAndroid Build Coastguard Worker
943*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CFolderRepack> folderRefs;
944*f6dc9357SAndroid Build Coastguard Worker };
945*f6dc9357SAndroid Build Coastguard Worker
946*f6dc9357SAndroid Build Coastguard Worker static const char * const g_Exe_Exts[] =
947*f6dc9357SAndroid Build Coastguard Worker {
948*f6dc9357SAndroid Build Coastguard Worker "dll"
949*f6dc9357SAndroid Build Coastguard Worker , "exe"
950*f6dc9357SAndroid Build Coastguard Worker , "ocx"
951*f6dc9357SAndroid Build Coastguard Worker , "sfx"
952*f6dc9357SAndroid Build Coastguard Worker , "sys"
953*f6dc9357SAndroid Build Coastguard Worker };
954*f6dc9357SAndroid Build Coastguard Worker
955*f6dc9357SAndroid Build Coastguard Worker static const char * const g_ExeUnix_Exts[] =
956*f6dc9357SAndroid Build Coastguard Worker {
957*f6dc9357SAndroid Build Coastguard Worker "so"
958*f6dc9357SAndroid Build Coastguard Worker , "dylib"
959*f6dc9357SAndroid Build Coastguard Worker };
960*f6dc9357SAndroid Build Coastguard Worker
IsExt_Exe(const wchar_t * ext)961*f6dc9357SAndroid Build Coastguard Worker static bool IsExt_Exe(const wchar_t *ext)
962*f6dc9357SAndroid Build Coastguard Worker {
963*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Exe_Exts); i++)
964*f6dc9357SAndroid Build Coastguard Worker if (StringsAreEqualNoCase_Ascii(ext, g_Exe_Exts[i]))
965*f6dc9357SAndroid Build Coastguard Worker return true;
966*f6dc9357SAndroid Build Coastguard Worker return false;
967*f6dc9357SAndroid Build Coastguard Worker }
968*f6dc9357SAndroid Build Coastguard Worker
969*f6dc9357SAndroid Build Coastguard Worker /*
970*f6dc9357SAndroid Build Coastguard Worker static bool IsExt_ExeUnix(const wchar_t *ext)
971*f6dc9357SAndroid Build Coastguard Worker {
972*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++)
973*f6dc9357SAndroid Build Coastguard Worker if (StringsAreEqualNoCase_Ascii(ext, g_ExeUnix_Exts[i]))
974*f6dc9357SAndroid Build Coastguard Worker return true;
975*f6dc9357SAndroid Build Coastguard Worker return false;
976*f6dc9357SAndroid Build Coastguard Worker }
977*f6dc9357SAndroid Build Coastguard Worker */
978*f6dc9357SAndroid Build Coastguard Worker
979*f6dc9357SAndroid Build Coastguard Worker // we try to find "so" extension in such name: libstdc++.so.6.0.29
IsExt_ExeUnix_NumericAllowed(const UString & path)980*f6dc9357SAndroid Build Coastguard Worker static bool IsExt_ExeUnix_NumericAllowed(const UString &path)
981*f6dc9357SAndroid Build Coastguard Worker {
982*f6dc9357SAndroid Build Coastguard Worker unsigned pos = path.Len();
983*f6dc9357SAndroid Build Coastguard Worker unsigned dotPos = pos;
984*f6dc9357SAndroid Build Coastguard Worker for (;;)
985*f6dc9357SAndroid Build Coastguard Worker {
986*f6dc9357SAndroid Build Coastguard Worker if (pos == 0)
987*f6dc9357SAndroid Build Coastguard Worker return false;
988*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = path[--pos];
989*f6dc9357SAndroid Build Coastguard Worker if (IS_PATH_SEPAR(c))
990*f6dc9357SAndroid Build Coastguard Worker return false;
991*f6dc9357SAndroid Build Coastguard Worker if (c == '.')
992*f6dc9357SAndroid Build Coastguard Worker {
993*f6dc9357SAndroid Build Coastguard Worker const unsigned num = (dotPos - pos) - 1;
994*f6dc9357SAndroid Build Coastguard Worker if (num < 1)
995*f6dc9357SAndroid Build Coastguard Worker return false;
996*f6dc9357SAndroid Build Coastguard Worker const wchar_t *cur = path.Ptr(pos + 1);
997*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++)
998*f6dc9357SAndroid Build Coastguard Worker {
999*f6dc9357SAndroid Build Coastguard Worker const char *ext = g_ExeUnix_Exts[i];
1000*f6dc9357SAndroid Build Coastguard Worker if (num == MyStringLen(ext))
1001*f6dc9357SAndroid Build Coastguard Worker if (IsString1PrefixedByString2_NoCase_Ascii(cur, ext))
1002*f6dc9357SAndroid Build Coastguard Worker return true;
1003*f6dc9357SAndroid Build Coastguard Worker }
1004*f6dc9357SAndroid Build Coastguard Worker const wchar_t *end;
1005*f6dc9357SAndroid Build Coastguard Worker ConvertStringToUInt32(cur, &end);
1006*f6dc9357SAndroid Build Coastguard Worker if ((size_t)(end - cur) != num)
1007*f6dc9357SAndroid Build Coastguard Worker return false;
1008*f6dc9357SAndroid Build Coastguard Worker dotPos = pos;
1009*f6dc9357SAndroid Build Coastguard Worker }
1010*f6dc9357SAndroid Build Coastguard Worker }
1011*f6dc9357SAndroid Build Coastguard Worker }
1012*f6dc9357SAndroid Build Coastguard Worker
1013*f6dc9357SAndroid Build Coastguard Worker
1014*f6dc9357SAndroid Build Coastguard Worker struct CAnalysis
1015*f6dc9357SAndroid Build Coastguard Worker {
1016*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IArchiveUpdateCallbackFile> Callback;
1017*f6dc9357SAndroid Build Coastguard Worker CByteBuffer Buffer;
1018*f6dc9357SAndroid Build Coastguard Worker
1019*f6dc9357SAndroid Build Coastguard Worker bool ParseWav;
1020*f6dc9357SAndroid Build Coastguard Worker bool ParseExe;
1021*f6dc9357SAndroid Build Coastguard Worker bool ParseExeUnix;
1022*f6dc9357SAndroid Build Coastguard Worker bool ParseNoExt;
1023*f6dc9357SAndroid Build Coastguard Worker bool ParseAll;
1024*f6dc9357SAndroid Build Coastguard Worker
1025*f6dc9357SAndroid Build Coastguard Worker /*
1026*f6dc9357SAndroid Build Coastguard Worker bool Need_ATime;
1027*f6dc9357SAndroid Build Coastguard Worker bool ATime_Defined;
1028*f6dc9357SAndroid Build Coastguard Worker FILETIME ATime;
1029*f6dc9357SAndroid Build Coastguard Worker */
1030*f6dc9357SAndroid Build Coastguard Worker
CAnalysisNArchive::N7z::CAnalysis1031*f6dc9357SAndroid Build Coastguard Worker CAnalysis():
1032*f6dc9357SAndroid Build Coastguard Worker ParseWav(false),
1033*f6dc9357SAndroid Build Coastguard Worker ParseExe(false),
1034*f6dc9357SAndroid Build Coastguard Worker ParseExeUnix(false),
1035*f6dc9357SAndroid Build Coastguard Worker ParseNoExt(false),
1036*f6dc9357SAndroid Build Coastguard Worker ParseAll(false)
1037*f6dc9357SAndroid Build Coastguard Worker /*
1038*f6dc9357SAndroid Build Coastguard Worker , Need_ATime(false)
1039*f6dc9357SAndroid Build Coastguard Worker , ATime_Defined(false)
1040*f6dc9357SAndroid Build Coastguard Worker */
1041*f6dc9357SAndroid Build Coastguard Worker {}
1042*f6dc9357SAndroid Build Coastguard Worker
1043*f6dc9357SAndroid Build Coastguard Worker HRESULT GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode);
1044*f6dc9357SAndroid Build Coastguard Worker };
1045*f6dc9357SAndroid Build Coastguard Worker
1046*f6dc9357SAndroid Build Coastguard Worker static const size_t kAnalysisBufSize = 1 << 14;
1047*f6dc9357SAndroid Build Coastguard Worker
GetFilterGroup(UInt32 index,const CUpdateItem & ui,CFilterMode & filterMode)1048*f6dc9357SAndroid Build Coastguard Worker HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode)
1049*f6dc9357SAndroid Build Coastguard Worker {
1050*f6dc9357SAndroid Build Coastguard Worker filterMode.Id = 0;
1051*f6dc9357SAndroid Build Coastguard Worker filterMode.Delta = 0;
1052*f6dc9357SAndroid Build Coastguard Worker filterMode.Offset = 0;
1053*f6dc9357SAndroid Build Coastguard Worker
1054*f6dc9357SAndroid Build Coastguard Worker CFilterMode filterModeTemp = filterMode;
1055*f6dc9357SAndroid Build Coastguard Worker
1056*f6dc9357SAndroid Build Coastguard Worker const int slashPos = ui.Name.ReverseFind_PathSepar();
1057*f6dc9357SAndroid Build Coastguard Worker const int dotPos = ui.Name.ReverseFind_Dot();
1058*f6dc9357SAndroid Build Coastguard Worker
1059*f6dc9357SAndroid Build Coastguard Worker // if (dotPos > slashPos)
1060*f6dc9357SAndroid Build Coastguard Worker {
1061*f6dc9357SAndroid Build Coastguard Worker bool needReadFile = ParseAll;
1062*f6dc9357SAndroid Build Coastguard Worker /* if (Callback) is not supported by client,
1063*f6dc9357SAndroid Build Coastguard Worker we still try to use file name extension to detect executable file */
1064*f6dc9357SAndroid Build Coastguard Worker bool probablyIsSameIsa = false;
1065*f6dc9357SAndroid Build Coastguard Worker
1066*f6dc9357SAndroid Build Coastguard Worker if (!needReadFile || !Callback)
1067*f6dc9357SAndroid Build Coastguard Worker {
1068*f6dc9357SAndroid Build Coastguard Worker const wchar_t *ext = NULL;
1069*f6dc9357SAndroid Build Coastguard Worker if (dotPos > slashPos)
1070*f6dc9357SAndroid Build Coastguard Worker ext = ui.Name.Ptr((unsigned)(dotPos + 1));
1071*f6dc9357SAndroid Build Coastguard Worker // 7-zip stores posix attributes in high 16 bits and sets (0x8000) flag
1072*f6dc9357SAndroid Build Coastguard Worker if (ui.Attrib & 0x8000)
1073*f6dc9357SAndroid Build Coastguard Worker {
1074*f6dc9357SAndroid Build Coastguard Worker const unsigned st_mode = ui.Attrib >> 16;
1075*f6dc9357SAndroid Build Coastguard Worker /* note: executable ".so" can be without execute permission,
1076*f6dc9357SAndroid Build Coastguard Worker and symbolic link to such ".so" file is possible */
1077*f6dc9357SAndroid Build Coastguard Worker // st_mode = 00111; // for debug
1078*f6dc9357SAndroid Build Coastguard Worker /* in Linux we expect such permissions:
1079*f6dc9357SAndroid Build Coastguard Worker 0755 : for most executables
1080*f6dc9357SAndroid Build Coastguard Worker 0644 : for some ".so" files
1081*f6dc9357SAndroid Build Coastguard Worker 0777 : in WSL for all files.
1082*f6dc9357SAndroid Build Coastguard Worker We can try to exclude some such 0777 cases from analysis,
1083*f6dc9357SAndroid Build Coastguard Worker if there is non-executable extension.
1084*f6dc9357SAndroid Build Coastguard Worker */
1085*f6dc9357SAndroid Build Coastguard Worker
1086*f6dc9357SAndroid Build Coastguard Worker if ((st_mode & (
1087*f6dc9357SAndroid Build Coastguard Worker MY_LIN_S_IXUSR |
1088*f6dc9357SAndroid Build Coastguard Worker MY_LIN_S_IXGRP |
1089*f6dc9357SAndroid Build Coastguard Worker MY_LIN_S_IXOTH)) != 0
1090*f6dc9357SAndroid Build Coastguard Worker && MY_LIN_S_ISREG(st_mode)
1091*f6dc9357SAndroid Build Coastguard Worker && (ui.Size >= (1u << 11)))
1092*f6dc9357SAndroid Build Coastguard Worker {
1093*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
1094*f6dc9357SAndroid Build Coastguard Worker probablyIsSameIsa = true;
1095*f6dc9357SAndroid Build Coastguard Worker #endif
1096*f6dc9357SAndroid Build Coastguard Worker needReadFile = true;
1097*f6dc9357SAndroid Build Coastguard Worker }
1098*f6dc9357SAndroid Build Coastguard Worker }
1099*f6dc9357SAndroid Build Coastguard Worker
1100*f6dc9357SAndroid Build Coastguard Worker if (!needReadFile)
1101*f6dc9357SAndroid Build Coastguard Worker {
1102*f6dc9357SAndroid Build Coastguard Worker if (!ext)
1103*f6dc9357SAndroid Build Coastguard Worker needReadFile = ParseNoExt;
1104*f6dc9357SAndroid Build Coastguard Worker else
1105*f6dc9357SAndroid Build Coastguard Worker {
1106*f6dc9357SAndroid Build Coastguard Worker bool isUnixExt = false;
1107*f6dc9357SAndroid Build Coastguard Worker if (ParseExeUnix)
1108*f6dc9357SAndroid Build Coastguard Worker isUnixExt = IsExt_ExeUnix_NumericAllowed(ui.Name);
1109*f6dc9357SAndroid Build Coastguard Worker if (isUnixExt)
1110*f6dc9357SAndroid Build Coastguard Worker {
1111*f6dc9357SAndroid Build Coastguard Worker needReadFile = true;
1112*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
1113*f6dc9357SAndroid Build Coastguard Worker probablyIsSameIsa = true;
1114*f6dc9357SAndroid Build Coastguard Worker #endif
1115*f6dc9357SAndroid Build Coastguard Worker }
1116*f6dc9357SAndroid Build Coastguard Worker else if (IsExt_Exe(ext))
1117*f6dc9357SAndroid Build Coastguard Worker {
1118*f6dc9357SAndroid Build Coastguard Worker needReadFile = ParseExe;
1119*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
1120*f6dc9357SAndroid Build Coastguard Worker probablyIsSameIsa = true;
1121*f6dc9357SAndroid Build Coastguard Worker #endif
1122*f6dc9357SAndroid Build Coastguard Worker }
1123*f6dc9357SAndroid Build Coastguard Worker else if (StringsAreEqualNoCase_Ascii(ext, "wav"))
1124*f6dc9357SAndroid Build Coastguard Worker {
1125*f6dc9357SAndroid Build Coastguard Worker if (!needReadFile)
1126*f6dc9357SAndroid Build Coastguard Worker needReadFile = ParseWav;
1127*f6dc9357SAndroid Build Coastguard Worker }
1128*f6dc9357SAndroid Build Coastguard Worker }
1129*f6dc9357SAndroid Build Coastguard Worker }
1130*f6dc9357SAndroid Build Coastguard Worker }
1131*f6dc9357SAndroid Build Coastguard Worker
1132*f6dc9357SAndroid Build Coastguard Worker if (needReadFile)
1133*f6dc9357SAndroid Build Coastguard Worker {
1134*f6dc9357SAndroid Build Coastguard Worker BoolInt parseRes = false;
1135*f6dc9357SAndroid Build Coastguard Worker if (Callback)
1136*f6dc9357SAndroid Build Coastguard Worker {
1137*f6dc9357SAndroid Build Coastguard Worker if (Buffer.Size() != kAnalysisBufSize)
1138*f6dc9357SAndroid Build Coastguard Worker Buffer.Alloc(kAnalysisBufSize);
1139*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> stream;
1140*f6dc9357SAndroid Build Coastguard Worker HRESULT result = Callback->GetStream2(index, &stream, NUpdateNotifyOp::kAnalyze);
1141*f6dc9357SAndroid Build Coastguard Worker if (result == S_OK && stream)
1142*f6dc9357SAndroid Build Coastguard Worker {
1143*f6dc9357SAndroid Build Coastguard Worker /*
1144*f6dc9357SAndroid Build Coastguard Worker if (Need_ATime)
1145*f6dc9357SAndroid Build Coastguard Worker {
1146*f6dc9357SAndroid Build Coastguard Worker // access time could be changed in analysis pass
1147*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IStreamGetProps> getProps;
1148*f6dc9357SAndroid Build Coastguard Worker stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps);
1149*f6dc9357SAndroid Build Coastguard Worker if (getProps)
1150*f6dc9357SAndroid Build Coastguard Worker if (getProps->GetProps(NULL, NULL, &ATime, NULL, NULL) == S_OK)
1151*f6dc9357SAndroid Build Coastguard Worker ATime_Defined = true;
1152*f6dc9357SAndroid Build Coastguard Worker }
1153*f6dc9357SAndroid Build Coastguard Worker */
1154*f6dc9357SAndroid Build Coastguard Worker size_t size = kAnalysisBufSize;
1155*f6dc9357SAndroid Build Coastguard Worker result = ReadStream(stream, Buffer, &size);
1156*f6dc9357SAndroid Build Coastguard Worker stream.Release();
1157*f6dc9357SAndroid Build Coastguard Worker // RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK));
1158*f6dc9357SAndroid Build Coastguard Worker if (result == S_OK)
1159*f6dc9357SAndroid Build Coastguard Worker {
1160*f6dc9357SAndroid Build Coastguard Worker parseRes = ParseFile(Buffer, size, &filterModeTemp);
1161*f6dc9357SAndroid Build Coastguard Worker }
1162*f6dc9357SAndroid Build Coastguard Worker }
1163*f6dc9357SAndroid Build Coastguard Worker } // Callback
1164*f6dc9357SAndroid Build Coastguard Worker else if (probablyIsSameIsa)
1165*f6dc9357SAndroid Build Coastguard Worker {
1166*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_X86_OR_AMD64
1167*f6dc9357SAndroid Build Coastguard Worker filterModeTemp.Id = k_X86;
1168*f6dc9357SAndroid Build Coastguard Worker #endif
1169*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_ARM64
1170*f6dc9357SAndroid Build Coastguard Worker filterModeTemp.Id = k_ARM64;
1171*f6dc9357SAndroid Build Coastguard Worker #endif
1172*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_RISCV
1173*f6dc9357SAndroid Build Coastguard Worker filterModeTemp.Id = k_RISCV;
1174*f6dc9357SAndroid Build Coastguard Worker #endif
1175*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_SPARC
1176*f6dc9357SAndroid Build Coastguard Worker filterModeTemp.Id = k_SPARC;
1177*f6dc9357SAndroid Build Coastguard Worker #endif
1178*f6dc9357SAndroid Build Coastguard Worker parseRes = true;
1179*f6dc9357SAndroid Build Coastguard Worker }
1180*f6dc9357SAndroid Build Coastguard Worker
1181*f6dc9357SAndroid Build Coastguard Worker if (parseRes
1182*f6dc9357SAndroid Build Coastguard Worker && filterModeTemp.Id != k_Delta
1183*f6dc9357SAndroid Build Coastguard Worker && filterModeTemp.Delta == 0)
1184*f6dc9357SAndroid Build Coastguard Worker {
1185*f6dc9357SAndroid Build Coastguard Worker /* ParseFile() sets (filterModeTemp.Delta == 0) for all
1186*f6dc9357SAndroid Build Coastguard Worker methods except of k_Delta. */
1187*f6dc9357SAndroid Build Coastguard Worker // it's not k_Delta
1188*f6dc9357SAndroid Build Coastguard Worker // So we call SetDelta() to set Delta
1189*f6dc9357SAndroid Build Coastguard Worker filterModeTemp.SetDelta();
1190*f6dc9357SAndroid Build Coastguard Worker if (filterModeTemp.Delta > 1)
1191*f6dc9357SAndroid Build Coastguard Worker {
1192*f6dc9357SAndroid Build Coastguard Worker /* If file Size is not aligned, then branch filter
1193*f6dc9357SAndroid Build Coastguard Worker will not work for next file in solid block.
1194*f6dc9357SAndroid Build Coastguard Worker Maybe we should allow filter for non-aligned-size file in non-solid archives ?
1195*f6dc9357SAndroid Build Coastguard Worker */
1196*f6dc9357SAndroid Build Coastguard Worker if (ui.Size % filterModeTemp.Delta != 0)
1197*f6dc9357SAndroid Build Coastguard Worker parseRes = false;
1198*f6dc9357SAndroid Build Coastguard Worker // windows exe files are not aligned for 4 KiB.
1199*f6dc9357SAndroid Build Coastguard Worker /*
1200*f6dc9357SAndroid Build Coastguard Worker else if (filterModeTemp.Id == k_ARM64 && filterModeTemp.Offset != 0)
1201*f6dc9357SAndroid Build Coastguard Worker {
1202*f6dc9357SAndroid Build Coastguard Worker if (ui.Size % (1 << 12) != 0)
1203*f6dc9357SAndroid Build Coastguard Worker {
1204*f6dc9357SAndroid Build Coastguard Worker // If Size is not aligned for 4 KiB, then Offset will not work for next file in solid block.
1205*f6dc9357SAndroid Build Coastguard Worker // so we place such file in group with (Offset==0).
1206*f6dc9357SAndroid Build Coastguard Worker filterModeTemp.Offset = 0;
1207*f6dc9357SAndroid Build Coastguard Worker }
1208*f6dc9357SAndroid Build Coastguard Worker }
1209*f6dc9357SAndroid Build Coastguard Worker */
1210*f6dc9357SAndroid Build Coastguard Worker }
1211*f6dc9357SAndroid Build Coastguard Worker }
1212*f6dc9357SAndroid Build Coastguard Worker if (!parseRes)
1213*f6dc9357SAndroid Build Coastguard Worker filterModeTemp.ClearFilterMode();
1214*f6dc9357SAndroid Build Coastguard Worker }
1215*f6dc9357SAndroid Build Coastguard Worker }
1216*f6dc9357SAndroid Build Coastguard Worker
1217*f6dc9357SAndroid Build Coastguard Worker filterMode = filterModeTemp;
1218*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1219*f6dc9357SAndroid Build Coastguard Worker }
1220*f6dc9357SAndroid Build Coastguard Worker
GetMethodFull(UInt64 methodID,UInt32 numStreams,CMethodFull & m)1221*f6dc9357SAndroid Build Coastguard Worker static inline void GetMethodFull(UInt64 methodID, UInt32 numStreams, CMethodFull &m)
1222*f6dc9357SAndroid Build Coastguard Worker {
1223*f6dc9357SAndroid Build Coastguard Worker m.Id = methodID;
1224*f6dc9357SAndroid Build Coastguard Worker m.NumStreams = numStreams;
1225*f6dc9357SAndroid Build Coastguard Worker }
1226*f6dc9357SAndroid Build Coastguard Worker
1227*f6dc9357SAndroid Build Coastguard Worker
1228*f6dc9357SAndroid Build Coastguard Worker // we add bond for mode.Methods[0] that is filter
AddBondForFilter(CCompressionMethodMode & mode)1229*f6dc9357SAndroid Build Coastguard Worker static HRESULT AddBondForFilter(CCompressionMethodMode &mode)
1230*f6dc9357SAndroid Build Coastguard Worker {
1231*f6dc9357SAndroid Build Coastguard Worker for (unsigned c = 1; c < mode.Methods.Size(); c++)
1232*f6dc9357SAndroid Build Coastguard Worker {
1233*f6dc9357SAndroid Build Coastguard Worker if (!mode.IsThereBond_to_Coder(c))
1234*f6dc9357SAndroid Build Coastguard Worker {
1235*f6dc9357SAndroid Build Coastguard Worker CBond2 bond;
1236*f6dc9357SAndroid Build Coastguard Worker bond.OutCoder = 0;
1237*f6dc9357SAndroid Build Coastguard Worker bond.OutStream = 0;
1238*f6dc9357SAndroid Build Coastguard Worker bond.InCoder = c;
1239*f6dc9357SAndroid Build Coastguard Worker mode.Bonds.Add(bond);
1240*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1241*f6dc9357SAndroid Build Coastguard Worker }
1242*f6dc9357SAndroid Build Coastguard Worker }
1243*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
1244*f6dc9357SAndroid Build Coastguard Worker }
1245*f6dc9357SAndroid Build Coastguard Worker
1246*f6dc9357SAndroid Build Coastguard Worker /*
1247*f6dc9357SAndroid Build Coastguard Worker static HRESULT AddBondForFilter_if_ThereAreBonds(CCompressionMethodMode &mode)
1248*f6dc9357SAndroid Build Coastguard Worker {
1249*f6dc9357SAndroid Build Coastguard Worker if (!mode.Bonds.IsEmpty())
1250*f6dc9357SAndroid Build Coastguard Worker return AddBondForFilter(mode);
1251*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1252*f6dc9357SAndroid Build Coastguard Worker }
1253*f6dc9357SAndroid Build Coastguard Worker */
1254*f6dc9357SAndroid Build Coastguard Worker
AddBcj2Methods(CCompressionMethodMode & mode)1255*f6dc9357SAndroid Build Coastguard Worker static HRESULT AddBcj2Methods(CCompressionMethodMode &mode)
1256*f6dc9357SAndroid Build Coastguard Worker {
1257*f6dc9357SAndroid Build Coastguard Worker // mode.Methods[0] must be k_BCJ2 method !
1258*f6dc9357SAndroid Build Coastguard Worker // mode.Methods[1] : we expect that there is at least one method after BCJ2
1259*f6dc9357SAndroid Build Coastguard Worker
1260*f6dc9357SAndroid Build Coastguard Worker CMethodFull m;
1261*f6dc9357SAndroid Build Coastguard Worker GetMethodFull(k_LZMA, 1, m);
1262*f6dc9357SAndroid Build Coastguard Worker
1263*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(NCoderPropID::kDictionarySize, 1 << 20);
1264*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(NCoderPropID::kNumFastBytes, 128);
1265*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(NCoderPropID::kNumThreads, 1);
1266*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(NCoderPropID::kLitPosBits, 2);
1267*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(NCoderPropID::kLitContextBits, 0);
1268*f6dc9357SAndroid Build Coastguard Worker // m.AddProp_Ascii(NCoderPropID::kMatchFinder, "BT2");
1269*f6dc9357SAndroid Build Coastguard Worker
1270*f6dc9357SAndroid Build Coastguard Worker const unsigned methodIndex = mode.Methods.Size();
1271*f6dc9357SAndroid Build Coastguard Worker
1272*f6dc9357SAndroid Build Coastguard Worker if (mode.Bonds.IsEmpty())
1273*f6dc9357SAndroid Build Coastguard Worker {
1274*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 1; i + 1 < mode.Methods.Size(); i++)
1275*f6dc9357SAndroid Build Coastguard Worker {
1276*f6dc9357SAndroid Build Coastguard Worker CBond2 bond;
1277*f6dc9357SAndroid Build Coastguard Worker bond.OutCoder = i;
1278*f6dc9357SAndroid Build Coastguard Worker bond.OutStream = 0;
1279*f6dc9357SAndroid Build Coastguard Worker bond.InCoder = i + 1;
1280*f6dc9357SAndroid Build Coastguard Worker mode.Bonds.Add(bond);
1281*f6dc9357SAndroid Build Coastguard Worker }
1282*f6dc9357SAndroid Build Coastguard Worker }
1283*f6dc9357SAndroid Build Coastguard Worker
1284*f6dc9357SAndroid Build Coastguard Worker mode.Methods.Add(m);
1285*f6dc9357SAndroid Build Coastguard Worker mode.Methods.Add(m);
1286*f6dc9357SAndroid Build Coastguard Worker
1287*f6dc9357SAndroid Build Coastguard Worker RINOK(AddBondForFilter(mode))
1288*f6dc9357SAndroid Build Coastguard Worker CBond2 bond;
1289*f6dc9357SAndroid Build Coastguard Worker bond.OutCoder = 0; // index of BCJ2 coder
1290*f6dc9357SAndroid Build Coastguard Worker bond.InCoder = methodIndex; bond.OutStream = 1; mode.Bonds.Add(bond);
1291*f6dc9357SAndroid Build Coastguard Worker bond.InCoder = methodIndex + 1; bond.OutStream = 2; mode.Bonds.Add(bond);
1292*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1293*f6dc9357SAndroid Build Coastguard Worker }
1294*f6dc9357SAndroid Build Coastguard Worker
1295*f6dc9357SAndroid Build Coastguard Worker
MakeExeMethod(CCompressionMethodMode & mode,const CFilterMode & filterMode,const bool bcj2_IsAllowed,const CUIntVector & disabledFilterIDs)1296*f6dc9357SAndroid Build Coastguard Worker static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
1297*f6dc9357SAndroid Build Coastguard Worker const CFilterMode &filterMode,
1298*f6dc9357SAndroid Build Coastguard Worker const bool bcj2_IsAllowed,
1299*f6dc9357SAndroid Build Coastguard Worker const CUIntVector &disabledFilterIDs)
1300*f6dc9357SAndroid Build Coastguard Worker {
1301*f6dc9357SAndroid Build Coastguard Worker if (mode.Filter_was_Inserted)
1302*f6dc9357SAndroid Build Coastguard Worker {
1303*f6dc9357SAndroid Build Coastguard Worker // filter was inserted, but bond for that filter was not added still.
1304*f6dc9357SAndroid Build Coastguard Worker const CMethodFull &m = mode.Methods[0];
1305*f6dc9357SAndroid Build Coastguard Worker if (m.Id == k_BCJ2)
1306*f6dc9357SAndroid Build Coastguard Worker return AddBcj2Methods(mode);
1307*f6dc9357SAndroid Build Coastguard Worker if (!m.IsSimpleCoder())
1308*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
1309*f6dc9357SAndroid Build Coastguard Worker if (mode.Bonds.IsEmpty())
1310*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1311*f6dc9357SAndroid Build Coastguard Worker return AddBondForFilter(mode);
1312*f6dc9357SAndroid Build Coastguard Worker }
1313*f6dc9357SAndroid Build Coastguard Worker
1314*f6dc9357SAndroid Build Coastguard Worker if (filterMode.Id == 0)
1315*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1316*f6dc9357SAndroid Build Coastguard Worker
1317*f6dc9357SAndroid Build Coastguard Worker unsigned nextCoder;
1318*f6dc9357SAndroid Build Coastguard Worker
1319*f6dc9357SAndroid Build Coastguard Worker const bool useBcj2 = bcj2_IsAllowed
1320*f6dc9357SAndroid Build Coastguard Worker && Is86Filter(filterMode.Id)
1321*f6dc9357SAndroid Build Coastguard Worker && disabledFilterIDs.FindInSorted(k_BCJ2) < 0;
1322*f6dc9357SAndroid Build Coastguard Worker
1323*f6dc9357SAndroid Build Coastguard Worker if (!useBcj2 && disabledFilterIDs.FindInSorted(filterMode.Id) >= 0)
1324*f6dc9357SAndroid Build Coastguard Worker {
1325*f6dc9357SAndroid Build Coastguard Worker // required filter is disabled,
1326*f6dc9357SAndroid Build Coastguard Worker // but we still can use information about data alignment.
1327*f6dc9357SAndroid Build Coastguard Worker #if 0 // 1 for debug
1328*f6dc9357SAndroid Build Coastguard Worker // we can return here, if we want default lzma properties
1329*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1330*f6dc9357SAndroid Build Coastguard Worker #else
1331*f6dc9357SAndroid Build Coastguard Worker // we will try to change lzma/lzma2 properties
1332*f6dc9357SAndroid Build Coastguard Worker nextCoder = 0;
1333*f6dc9357SAndroid Build Coastguard Worker if (!mode.Bonds.IsEmpty())
1334*f6dc9357SAndroid Build Coastguard Worker for (unsigned c = 0;; c++)
1335*f6dc9357SAndroid Build Coastguard Worker {
1336*f6dc9357SAndroid Build Coastguard Worker if (c == mode.Methods.Size())
1337*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1338*f6dc9357SAndroid Build Coastguard Worker if (!mode.IsThereBond_to_Coder(c))
1339*f6dc9357SAndroid Build Coastguard Worker {
1340*f6dc9357SAndroid Build Coastguard Worker nextCoder = c;
1341*f6dc9357SAndroid Build Coastguard Worker break;
1342*f6dc9357SAndroid Build Coastguard Worker }
1343*f6dc9357SAndroid Build Coastguard Worker }
1344*f6dc9357SAndroid Build Coastguard Worker #endif
1345*f6dc9357SAndroid Build Coastguard Worker }
1346*f6dc9357SAndroid Build Coastguard Worker else
1347*f6dc9357SAndroid Build Coastguard Worker {
1348*f6dc9357SAndroid Build Coastguard Worker // we insert new filter method:
1349*f6dc9357SAndroid Build Coastguard Worker CMethodFull &m = mode.Methods.InsertNew(0); // 0 == index of new inserted item
1350*f6dc9357SAndroid Build Coastguard Worker {
1351*f6dc9357SAndroid Build Coastguard Worker // we move all coder indexes in bonds up for 1 position:
1352*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (k, mode.Bonds)
1353*f6dc9357SAndroid Build Coastguard Worker {
1354*f6dc9357SAndroid Build Coastguard Worker CBond2 &bond = mode.Bonds[k];
1355*f6dc9357SAndroid Build Coastguard Worker bond.InCoder++;
1356*f6dc9357SAndroid Build Coastguard Worker bond.OutCoder++;
1357*f6dc9357SAndroid Build Coastguard Worker }
1358*f6dc9357SAndroid Build Coastguard Worker }
1359*f6dc9357SAndroid Build Coastguard Worker if (useBcj2)
1360*f6dc9357SAndroid Build Coastguard Worker {
1361*f6dc9357SAndroid Build Coastguard Worker GetMethodFull(k_BCJ2, 4, m);
1362*f6dc9357SAndroid Build Coastguard Worker return AddBcj2Methods(mode);
1363*f6dc9357SAndroid Build Coastguard Worker }
1364*f6dc9357SAndroid Build Coastguard Worker
1365*f6dc9357SAndroid Build Coastguard Worker GetMethodFull(filterMode.Id, 1, m);
1366*f6dc9357SAndroid Build Coastguard Worker
1367*f6dc9357SAndroid Build Coastguard Worker if (filterMode.Id == k_Delta)
1368*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(NCoderPropID::kDefaultProp, filterMode.Delta);
1369*f6dc9357SAndroid Build Coastguard Worker else if (filterMode.Id == k_ARM64
1370*f6dc9357SAndroid Build Coastguard Worker || filterMode.Id == k_RISCV)
1371*f6dc9357SAndroid Build Coastguard Worker {
1372*f6dc9357SAndroid Build Coastguard Worker // if (filterMode.Offset != 0)
1373*f6dc9357SAndroid Build Coastguard Worker m.AddProp32(
1374*f6dc9357SAndroid Build Coastguard Worker NCoderPropID::kDefaultProp,
1375*f6dc9357SAndroid Build Coastguard Worker // NCoderPropID::kBranchOffset,
1376*f6dc9357SAndroid Build Coastguard Worker filterMode.Offset);
1377*f6dc9357SAndroid Build Coastguard Worker }
1378*f6dc9357SAndroid Build Coastguard Worker
1379*f6dc9357SAndroid Build Coastguard Worker nextCoder = 1;
1380*f6dc9357SAndroid Build Coastguard Worker if (!mode.Bonds.IsEmpty())
1381*f6dc9357SAndroid Build Coastguard Worker {
1382*f6dc9357SAndroid Build Coastguard Worker RINOK(AddBondForFilter(mode))
1383*f6dc9357SAndroid Build Coastguard Worker nextCoder = mode.Bonds.Back().InCoder;
1384*f6dc9357SAndroid Build Coastguard Worker }
1385*f6dc9357SAndroid Build Coastguard Worker }
1386*f6dc9357SAndroid Build Coastguard Worker
1387*f6dc9357SAndroid Build Coastguard Worker if (nextCoder >= mode.Methods.Size())
1388*f6dc9357SAndroid Build Coastguard Worker {
1389*f6dc9357SAndroid Build Coastguard Worker // we don't expect that case, if there was non-filter method.
1390*f6dc9357SAndroid Build Coastguard Worker // but we return S_OK to support filter-only case.
1391*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1392*f6dc9357SAndroid Build Coastguard Worker }
1393*f6dc9357SAndroid Build Coastguard Worker
1394*f6dc9357SAndroid Build Coastguard Worker int alignBits = -1;
1395*f6dc9357SAndroid Build Coastguard Worker {
1396*f6dc9357SAndroid Build Coastguard Worker const UInt32 delta = filterMode.Delta;
1397*f6dc9357SAndroid Build Coastguard Worker if (delta == 0 || delta > 16)
1398*f6dc9357SAndroid Build Coastguard Worker {
1399*f6dc9357SAndroid Build Coastguard Worker // if (delta == 0) alignBits = GetAlignForFilterMethod(filterMode.Id);
1400*f6dc9357SAndroid Build Coastguard Worker }
1401*f6dc9357SAndroid Build Coastguard Worker else if ((delta & ((1 << 4) - 1)) == 0) alignBits = 4;
1402*f6dc9357SAndroid Build Coastguard Worker else if ((delta & ((1 << 3) - 1)) == 0) alignBits = 3;
1403*f6dc9357SAndroid Build Coastguard Worker else if ((delta & ((1 << 2) - 1)) == 0) alignBits = 2;
1404*f6dc9357SAndroid Build Coastguard Worker else if ((delta & ((1 << 1) - 1)) == 0) alignBits = 1;
1405*f6dc9357SAndroid Build Coastguard Worker // else alignBits = 0;
1406*f6dc9357SAndroid Build Coastguard Worker /* alignBits=0 is default mode for lzma/lzma2.
1407*f6dc9357SAndroid Build Coastguard Worker So we don't set alignBits=0 here. */
1408*f6dc9357SAndroid Build Coastguard Worker }
1409*f6dc9357SAndroid Build Coastguard Worker if (alignBits <= 0)
1410*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1411*f6dc9357SAndroid Build Coastguard Worker // (alignBits > 0)
1412*f6dc9357SAndroid Build Coastguard Worker CMethodFull &nextMethod = mode.Methods[nextCoder];
1413*f6dc9357SAndroid Build Coastguard Worker if (nextMethod.Id == k_LZMA || nextMethod.Id == k_LZMA2)
1414*f6dc9357SAndroid Build Coastguard Worker if (!nextMethod.Are_Lzma_Model_Props_Defined())
1415*f6dc9357SAndroid Build Coastguard Worker {
1416*f6dc9357SAndroid Build Coastguard Worker if (alignBits > 2 || filterMode.Id == k_Delta)
1417*f6dc9357SAndroid Build Coastguard Worker nextMethod.AddProp32(NCoderPropID::kPosStateBits, (unsigned)alignBits);
1418*f6dc9357SAndroid Build Coastguard Worker const unsigned lc = (alignBits < 3) ? (unsigned)(3 - alignBits) : 0u;
1419*f6dc9357SAndroid Build Coastguard Worker nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc);
1420*f6dc9357SAndroid Build Coastguard Worker nextMethod.AddProp32(NCoderPropID::kLitPosBits, (unsigned)alignBits);
1421*f6dc9357SAndroid Build Coastguard Worker }
1422*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1423*f6dc9357SAndroid Build Coastguard Worker }
1424*f6dc9357SAndroid Build Coastguard Worker
1425*f6dc9357SAndroid Build Coastguard Worker
UpdateItem_To_FileItem2(const CUpdateItem & ui,CFileItem2 & file2)1426*f6dc9357SAndroid Build Coastguard Worker static void UpdateItem_To_FileItem2(const CUpdateItem &ui, CFileItem2 &file2)
1427*f6dc9357SAndroid Build Coastguard Worker {
1428*f6dc9357SAndroid Build Coastguard Worker file2.Attrib = ui.Attrib; file2.AttribDefined = ui.AttribDefined;
1429*f6dc9357SAndroid Build Coastguard Worker file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
1430*f6dc9357SAndroid Build Coastguard Worker file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
1431*f6dc9357SAndroid Build Coastguard Worker file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
1432*f6dc9357SAndroid Build Coastguard Worker file2.IsAnti = ui.IsAnti;
1433*f6dc9357SAndroid Build Coastguard Worker // file2.IsAux = false;
1434*f6dc9357SAndroid Build Coastguard Worker file2.StartPosDefined = false;
1435*f6dc9357SAndroid Build Coastguard Worker // file2.StartPos = 0;
1436*f6dc9357SAndroid Build Coastguard Worker }
1437*f6dc9357SAndroid Build Coastguard Worker
1438*f6dc9357SAndroid Build Coastguard Worker
UpdateItem_To_FileItem(const CUpdateItem & ui,CFileItem & file,CFileItem2 & file2)1439*f6dc9357SAndroid Build Coastguard Worker static void UpdateItem_To_FileItem(const CUpdateItem &ui,
1440*f6dc9357SAndroid Build Coastguard Worker CFileItem &file, CFileItem2 &file2)
1441*f6dc9357SAndroid Build Coastguard Worker {
1442*f6dc9357SAndroid Build Coastguard Worker UpdateItem_To_FileItem2(ui, file2);
1443*f6dc9357SAndroid Build Coastguard Worker
1444*f6dc9357SAndroid Build Coastguard Worker file.Size = ui.Size;
1445*f6dc9357SAndroid Build Coastguard Worker file.IsDir = ui.IsDir;
1446*f6dc9357SAndroid Build Coastguard Worker file.HasStream = ui.HasStream();
1447*f6dc9357SAndroid Build Coastguard Worker // file.IsAltStream = ui.IsAltStream;
1448*f6dc9357SAndroid Build Coastguard Worker }
1449*f6dc9357SAndroid Build Coastguard Worker
1450*f6dc9357SAndroid Build Coastguard Worker
1451*f6dc9357SAndroid Build Coastguard Worker
1452*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_2(
1453*f6dc9357SAndroid Build Coastguard Worker CRepackInStreamWithSizes
1454*f6dc9357SAndroid Build Coastguard Worker , ISequentialInStream
1455*f6dc9357SAndroid Build Coastguard Worker , ICompressGetSubStreamSize
1456*f6dc9357SAndroid Build Coastguard Worker )
1457*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> _stream;
1458*f6dc9357SAndroid Build Coastguard Worker UInt64 _size;
1459*f6dc9357SAndroid Build Coastguard Worker const CBoolVector *_extractStatuses;
1460*f6dc9357SAndroid Build Coastguard Worker UInt32 _startIndex;
1461*f6dc9357SAndroid Build Coastguard Worker public:
1462*f6dc9357SAndroid Build Coastguard Worker const CDbEx *_db;
1463*f6dc9357SAndroid Build Coastguard Worker
1464*f6dc9357SAndroid Build Coastguard Worker void Init(ISequentialInStream *stream, UInt32 startIndex, const CBoolVector *extractStatuses)
1465*f6dc9357SAndroid Build Coastguard Worker {
1466*f6dc9357SAndroid Build Coastguard Worker _startIndex = startIndex;
1467*f6dc9357SAndroid Build Coastguard Worker _extractStatuses = extractStatuses;
1468*f6dc9357SAndroid Build Coastguard Worker _size = 0;
1469*f6dc9357SAndroid Build Coastguard Worker _stream = stream;
1470*f6dc9357SAndroid Build Coastguard Worker }
1471*f6dc9357SAndroid Build Coastguard Worker UInt64 GetSize() const { return _size; }
1472*f6dc9357SAndroid Build Coastguard Worker };
1473*f6dc9357SAndroid Build Coastguard Worker
1474*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize))
1475*f6dc9357SAndroid Build Coastguard Worker {
1476*f6dc9357SAndroid Build Coastguard Worker UInt32 realProcessedSize;
1477*f6dc9357SAndroid Build Coastguard Worker const HRESULT result = _stream->Read(data, size, &realProcessedSize);
1478*f6dc9357SAndroid Build Coastguard Worker _size += realProcessedSize;
1479*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
1480*f6dc9357SAndroid Build Coastguard Worker *processedSize = realProcessedSize;
1481*f6dc9357SAndroid Build Coastguard Worker return result;
1482*f6dc9357SAndroid Build Coastguard Worker }
1483*f6dc9357SAndroid Build Coastguard Worker
1484*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value))
1485*f6dc9357SAndroid Build Coastguard Worker {
1486*f6dc9357SAndroid Build Coastguard Worker *value = 0;
1487*f6dc9357SAndroid Build Coastguard Worker if (subStream >= _extractStatuses->Size())
1488*f6dc9357SAndroid Build Coastguard Worker return S_FALSE; // E_FAIL;
1489*f6dc9357SAndroid Build Coastguard Worker const unsigned index = (unsigned)subStream;
1490*f6dc9357SAndroid Build Coastguard Worker if ((*_extractStatuses)[index])
1491*f6dc9357SAndroid Build Coastguard Worker {
1492*f6dc9357SAndroid Build Coastguard Worker const CFileItem &fi = _db->Files[_startIndex + index];
1493*f6dc9357SAndroid Build Coastguard Worker if (fi.HasStream)
1494*f6dc9357SAndroid Build Coastguard Worker *value = fi.Size;
1495*f6dc9357SAndroid Build Coastguard Worker }
1496*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1497*f6dc9357SAndroid Build Coastguard Worker }
1498*f6dc9357SAndroid Build Coastguard Worker
1499*f6dc9357SAndroid Build Coastguard Worker
1500*f6dc9357SAndroid Build Coastguard Worker class CRepackStreamBase
1501*f6dc9357SAndroid Build Coastguard Worker {
1502*f6dc9357SAndroid Build Coastguard Worker protected:
1503*f6dc9357SAndroid Build Coastguard Worker bool _needWrite;
1504*f6dc9357SAndroid Build Coastguard Worker bool _fileIsOpen;
1505*f6dc9357SAndroid Build Coastguard Worker bool _calcCrc;
1506*f6dc9357SAndroid Build Coastguard Worker UInt32 _crc;
1507*f6dc9357SAndroid Build Coastguard Worker UInt64 _rem;
1508*f6dc9357SAndroid Build Coastguard Worker
1509*f6dc9357SAndroid Build Coastguard Worker const CBoolVector *_extractStatuses;
1510*f6dc9357SAndroid Build Coastguard Worker UInt32 _startIndex;
1511*f6dc9357SAndroid Build Coastguard Worker unsigned _currentIndex;
1512*f6dc9357SAndroid Build Coastguard Worker
1513*f6dc9357SAndroid Build Coastguard Worker HRESULT OpenFile();
1514*f6dc9357SAndroid Build Coastguard Worker HRESULT CloseFile();
1515*f6dc9357SAndroid Build Coastguard Worker HRESULT ProcessEmptyFiles();
1516*f6dc9357SAndroid Build Coastguard Worker
1517*f6dc9357SAndroid Build Coastguard Worker public:
1518*f6dc9357SAndroid Build Coastguard Worker const CDbEx *_db;
1519*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IArchiveUpdateCallbackFile> _opCallback;
1520*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IArchiveExtractCallbackMessage2> _extractCallback;
1521*f6dc9357SAndroid Build Coastguard Worker
1522*f6dc9357SAndroid Build Coastguard Worker HRESULT Init(UInt32 startIndex, const CBoolVector *extractStatuses);
1523*f6dc9357SAndroid Build Coastguard Worker HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; }
1524*f6dc9357SAndroid Build Coastguard Worker };
1525*f6dc9357SAndroid Build Coastguard Worker
1526*f6dc9357SAndroid Build Coastguard Worker HRESULT CRepackStreamBase::Init(UInt32 startIndex, const CBoolVector *extractStatuses)
1527*f6dc9357SAndroid Build Coastguard Worker {
1528*f6dc9357SAndroid Build Coastguard Worker _startIndex = startIndex;
1529*f6dc9357SAndroid Build Coastguard Worker _extractStatuses = extractStatuses;
1530*f6dc9357SAndroid Build Coastguard Worker
1531*f6dc9357SAndroid Build Coastguard Worker _currentIndex = 0;
1532*f6dc9357SAndroid Build Coastguard Worker _fileIsOpen = false;
1533*f6dc9357SAndroid Build Coastguard Worker
1534*f6dc9357SAndroid Build Coastguard Worker return ProcessEmptyFiles();
1535*f6dc9357SAndroid Build Coastguard Worker }
1536*f6dc9357SAndroid Build Coastguard Worker
1537*f6dc9357SAndroid Build Coastguard Worker HRESULT CRepackStreamBase::OpenFile()
1538*f6dc9357SAndroid Build Coastguard Worker {
1539*f6dc9357SAndroid Build Coastguard Worker UInt32 arcIndex = _startIndex + _currentIndex;
1540*f6dc9357SAndroid Build Coastguard Worker const CFileItem &fi = _db->Files[arcIndex];
1541*f6dc9357SAndroid Build Coastguard Worker
1542*f6dc9357SAndroid Build Coastguard Worker _needWrite = (*_extractStatuses)[_currentIndex];
1543*f6dc9357SAndroid Build Coastguard Worker if (_opCallback)
1544*f6dc9357SAndroid Build Coastguard Worker {
1545*f6dc9357SAndroid Build Coastguard Worker RINOK(_opCallback->ReportOperation(
1546*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kInArcIndex, arcIndex,
1547*f6dc9357SAndroid Build Coastguard Worker _needWrite ?
1548*f6dc9357SAndroid Build Coastguard Worker NUpdateNotifyOp::kRepack :
1549*f6dc9357SAndroid Build Coastguard Worker NUpdateNotifyOp::kSkip))
1550*f6dc9357SAndroid Build Coastguard Worker }
1551*f6dc9357SAndroid Build Coastguard Worker
1552*f6dc9357SAndroid Build Coastguard Worker _crc = CRC_INIT_VAL;
1553*f6dc9357SAndroid Build Coastguard Worker _calcCrc = (fi.CrcDefined && !fi.IsDir);
1554*f6dc9357SAndroid Build Coastguard Worker
1555*f6dc9357SAndroid Build Coastguard Worker _fileIsOpen = true;
1556*f6dc9357SAndroid Build Coastguard Worker _rem = fi.Size;
1557*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1558*f6dc9357SAndroid Build Coastguard Worker }
1559*f6dc9357SAndroid Build Coastguard Worker
1560*f6dc9357SAndroid Build Coastguard Worker const HRESULT k_My_HRESULT_CRC_ERROR = 0x20000002;
1561*f6dc9357SAndroid Build Coastguard Worker
1562*f6dc9357SAndroid Build Coastguard Worker HRESULT CRepackStreamBase::CloseFile()
1563*f6dc9357SAndroid Build Coastguard Worker {
1564*f6dc9357SAndroid Build Coastguard Worker UInt32 arcIndex = _startIndex + _currentIndex;
1565*f6dc9357SAndroid Build Coastguard Worker const CFileItem &fi = _db->Files[arcIndex];
1566*f6dc9357SAndroid Build Coastguard Worker _fileIsOpen = false;
1567*f6dc9357SAndroid Build Coastguard Worker _currentIndex++;
1568*f6dc9357SAndroid Build Coastguard Worker if (!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc))
1569*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1570*f6dc9357SAndroid Build Coastguard Worker
1571*f6dc9357SAndroid Build Coastguard Worker if (_extractCallback)
1572*f6dc9357SAndroid Build Coastguard Worker {
1573*f6dc9357SAndroid Build Coastguard Worker RINOK(_extractCallback->ReportExtractResult(
1574*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kInArcIndex, arcIndex,
1575*f6dc9357SAndroid Build Coastguard Worker NExtract::NOperationResult::kCRCError))
1576*f6dc9357SAndroid Build Coastguard Worker }
1577*f6dc9357SAndroid Build Coastguard Worker // return S_FALSE;
1578*f6dc9357SAndroid Build Coastguard Worker return k_My_HRESULT_CRC_ERROR;
1579*f6dc9357SAndroid Build Coastguard Worker }
1580*f6dc9357SAndroid Build Coastguard Worker
1581*f6dc9357SAndroid Build Coastguard Worker HRESULT CRepackStreamBase::ProcessEmptyFiles()
1582*f6dc9357SAndroid Build Coastguard Worker {
1583*f6dc9357SAndroid Build Coastguard Worker while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0)
1584*f6dc9357SAndroid Build Coastguard Worker {
1585*f6dc9357SAndroid Build Coastguard Worker RINOK(OpenFile())
1586*f6dc9357SAndroid Build Coastguard Worker RINOK(CloseFile())
1587*f6dc9357SAndroid Build Coastguard Worker }
1588*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1589*f6dc9357SAndroid Build Coastguard Worker }
1590*f6dc9357SAndroid Build Coastguard Worker
1591*f6dc9357SAndroid Build Coastguard Worker
1592*f6dc9357SAndroid Build Coastguard Worker
1593*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1594*f6dc9357SAndroid Build Coastguard Worker
1595*f6dc9357SAndroid Build Coastguard Worker class CFolderOutStream2 Z7_final:
1596*f6dc9357SAndroid Build Coastguard Worker public CRepackStreamBase,
1597*f6dc9357SAndroid Build Coastguard Worker public ISequentialOutStream,
1598*f6dc9357SAndroid Build Coastguard Worker public CMyUnknownImp
1599*f6dc9357SAndroid Build Coastguard Worker {
1600*f6dc9357SAndroid Build Coastguard Worker Z7_COM_UNKNOWN_IMP_0
1601*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_COM7_IMP(ISequentialOutStream)
1602*f6dc9357SAndroid Build Coastguard Worker public:
1603*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> _stream;
1604*f6dc9357SAndroid Build Coastguard Worker };
1605*f6dc9357SAndroid Build Coastguard Worker
1606*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize))
1607*f6dc9357SAndroid Build Coastguard Worker {
1608*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
1609*f6dc9357SAndroid Build Coastguard Worker *processedSize = 0;
1610*f6dc9357SAndroid Build Coastguard Worker
1611*f6dc9357SAndroid Build Coastguard Worker while (size != 0)
1612*f6dc9357SAndroid Build Coastguard Worker {
1613*f6dc9357SAndroid Build Coastguard Worker if (_fileIsOpen)
1614*f6dc9357SAndroid Build Coastguard Worker {
1615*f6dc9357SAndroid Build Coastguard Worker UInt32 cur = (size < _rem ? size : (UInt32)_rem);
1616*f6dc9357SAndroid Build Coastguard Worker HRESULT result = S_OK;
1617*f6dc9357SAndroid Build Coastguard Worker if (_needWrite)
1618*f6dc9357SAndroid Build Coastguard Worker result = _stream->Write(data, cur, &cur);
1619*f6dc9357SAndroid Build Coastguard Worker if (_calcCrc)
1620*f6dc9357SAndroid Build Coastguard Worker _crc = CrcUpdate(_crc, data, cur);
1621*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
1622*f6dc9357SAndroid Build Coastguard Worker *processedSize += cur;
1623*f6dc9357SAndroid Build Coastguard Worker data = (const Byte *)data + cur;
1624*f6dc9357SAndroid Build Coastguard Worker size -= cur;
1625*f6dc9357SAndroid Build Coastguard Worker _rem -= cur;
1626*f6dc9357SAndroid Build Coastguard Worker if (_rem == 0)
1627*f6dc9357SAndroid Build Coastguard Worker {
1628*f6dc9357SAndroid Build Coastguard Worker RINOK(CloseFile())
1629*f6dc9357SAndroid Build Coastguard Worker RINOK(ProcessEmptyFiles())
1630*f6dc9357SAndroid Build Coastguard Worker }
1631*f6dc9357SAndroid Build Coastguard Worker RINOK(result)
1632*f6dc9357SAndroid Build Coastguard Worker if (cur == 0)
1633*f6dc9357SAndroid Build Coastguard Worker break;
1634*f6dc9357SAndroid Build Coastguard Worker continue;
1635*f6dc9357SAndroid Build Coastguard Worker }
1636*f6dc9357SAndroid Build Coastguard Worker
1637*f6dc9357SAndroid Build Coastguard Worker RINOK(ProcessEmptyFiles())
1638*f6dc9357SAndroid Build Coastguard Worker if (_currentIndex == _extractStatuses->Size())
1639*f6dc9357SAndroid Build Coastguard Worker {
1640*f6dc9357SAndroid Build Coastguard Worker // we don't support write cut here
1641*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1642*f6dc9357SAndroid Build Coastguard Worker }
1643*f6dc9357SAndroid Build Coastguard Worker RINOK(OpenFile())
1644*f6dc9357SAndroid Build Coastguard Worker }
1645*f6dc9357SAndroid Build Coastguard Worker
1646*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1647*f6dc9357SAndroid Build Coastguard Worker }
1648*f6dc9357SAndroid Build Coastguard Worker
1649*f6dc9357SAndroid Build Coastguard Worker #endif
1650*f6dc9357SAndroid Build Coastguard Worker
1651*f6dc9357SAndroid Build Coastguard Worker
1652*f6dc9357SAndroid Build Coastguard Worker
1653*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kTempBufSize = 1 << 16;
1654*f6dc9357SAndroid Build Coastguard Worker
1655*f6dc9357SAndroid Build Coastguard Worker class CFolderInStream2 Z7_final:
1656*f6dc9357SAndroid Build Coastguard Worker public CRepackStreamBase,
1657*f6dc9357SAndroid Build Coastguard Worker public ISequentialInStream,
1658*f6dc9357SAndroid Build Coastguard Worker public CMyUnknownImp
1659*f6dc9357SAndroid Build Coastguard Worker {
1660*f6dc9357SAndroid Build Coastguard Worker Z7_COM_UNKNOWN_IMP_0
1661*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_COM7_IMP(ISequentialInStream)
1662*f6dc9357SAndroid Build Coastguard Worker
1663*f6dc9357SAndroid Build Coastguard Worker Byte *_buf;
1664*f6dc9357SAndroid Build Coastguard Worker public:
1665*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> _inStream;
1666*f6dc9357SAndroid Build Coastguard Worker HRESULT Result;
1667*f6dc9357SAndroid Build Coastguard Worker
1668*f6dc9357SAndroid Build Coastguard Worker CFolderInStream2():
1669*f6dc9357SAndroid Build Coastguard Worker Result(S_OK)
1670*f6dc9357SAndroid Build Coastguard Worker {
1671*f6dc9357SAndroid Build Coastguard Worker _buf = new Byte[kTempBufSize];
1672*f6dc9357SAndroid Build Coastguard Worker }
1673*f6dc9357SAndroid Build Coastguard Worker
1674*f6dc9357SAndroid Build Coastguard Worker ~CFolderInStream2()
1675*f6dc9357SAndroid Build Coastguard Worker {
1676*f6dc9357SAndroid Build Coastguard Worker delete []_buf;
1677*f6dc9357SAndroid Build Coastguard Worker }
1678*f6dc9357SAndroid Build Coastguard Worker
1679*f6dc9357SAndroid Build Coastguard Worker void Init() { Result = S_OK; }
1680*f6dc9357SAndroid Build Coastguard Worker };
1681*f6dc9357SAndroid Build Coastguard Worker
1682*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize))
1683*f6dc9357SAndroid Build Coastguard Worker {
1684*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
1685*f6dc9357SAndroid Build Coastguard Worker *processedSize = 0;
1686*f6dc9357SAndroid Build Coastguard Worker
1687*f6dc9357SAndroid Build Coastguard Worker while (size != 0)
1688*f6dc9357SAndroid Build Coastguard Worker {
1689*f6dc9357SAndroid Build Coastguard Worker if (_fileIsOpen)
1690*f6dc9357SAndroid Build Coastguard Worker {
1691*f6dc9357SAndroid Build Coastguard Worker UInt32 cur = (size < _rem ? size : (UInt32)_rem);
1692*f6dc9357SAndroid Build Coastguard Worker
1693*f6dc9357SAndroid Build Coastguard Worker void *buf;
1694*f6dc9357SAndroid Build Coastguard Worker if (_needWrite)
1695*f6dc9357SAndroid Build Coastguard Worker buf = data;
1696*f6dc9357SAndroid Build Coastguard Worker else
1697*f6dc9357SAndroid Build Coastguard Worker {
1698*f6dc9357SAndroid Build Coastguard Worker buf = _buf;
1699*f6dc9357SAndroid Build Coastguard Worker if (cur > kTempBufSize)
1700*f6dc9357SAndroid Build Coastguard Worker cur = kTempBufSize;
1701*f6dc9357SAndroid Build Coastguard Worker }
1702*f6dc9357SAndroid Build Coastguard Worker
1703*f6dc9357SAndroid Build Coastguard Worker const HRESULT result = _inStream->Read(buf, cur, &cur);
1704*f6dc9357SAndroid Build Coastguard Worker _crc = CrcUpdate(_crc, buf, cur);
1705*f6dc9357SAndroid Build Coastguard Worker _rem -= cur;
1706*f6dc9357SAndroid Build Coastguard Worker
1707*f6dc9357SAndroid Build Coastguard Worker if (_needWrite)
1708*f6dc9357SAndroid Build Coastguard Worker {
1709*f6dc9357SAndroid Build Coastguard Worker data = (Byte *)data + cur;
1710*f6dc9357SAndroid Build Coastguard Worker size -= cur;
1711*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
1712*f6dc9357SAndroid Build Coastguard Worker *processedSize += cur;
1713*f6dc9357SAndroid Build Coastguard Worker }
1714*f6dc9357SAndroid Build Coastguard Worker
1715*f6dc9357SAndroid Build Coastguard Worker if (result != S_OK)
1716*f6dc9357SAndroid Build Coastguard Worker Result = result;
1717*f6dc9357SAndroid Build Coastguard Worker
1718*f6dc9357SAndroid Build Coastguard Worker if (_rem == 0)
1719*f6dc9357SAndroid Build Coastguard Worker {
1720*f6dc9357SAndroid Build Coastguard Worker RINOK(CloseFile())
1721*f6dc9357SAndroid Build Coastguard Worker RINOK(ProcessEmptyFiles())
1722*f6dc9357SAndroid Build Coastguard Worker }
1723*f6dc9357SAndroid Build Coastguard Worker
1724*f6dc9357SAndroid Build Coastguard Worker RINOK(result)
1725*f6dc9357SAndroid Build Coastguard Worker
1726*f6dc9357SAndroid Build Coastguard Worker if (cur == 0)
1727*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
1728*f6dc9357SAndroid Build Coastguard Worker
1729*f6dc9357SAndroid Build Coastguard Worker continue;
1730*f6dc9357SAndroid Build Coastguard Worker }
1731*f6dc9357SAndroid Build Coastguard Worker
1732*f6dc9357SAndroid Build Coastguard Worker RINOK(ProcessEmptyFiles())
1733*f6dc9357SAndroid Build Coastguard Worker if (_currentIndex == _extractStatuses->Size())
1734*f6dc9357SAndroid Build Coastguard Worker {
1735*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1736*f6dc9357SAndroid Build Coastguard Worker }
1737*f6dc9357SAndroid Build Coastguard Worker RINOK(OpenFile())
1738*f6dc9357SAndroid Build Coastguard Worker }
1739*f6dc9357SAndroid Build Coastguard Worker
1740*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1741*f6dc9357SAndroid Build Coastguard Worker }
1742*f6dc9357SAndroid Build Coastguard Worker
1743*f6dc9357SAndroid Build Coastguard Worker
1744*f6dc9357SAndroid Build Coastguard Worker class CThreadDecoder Z7_final
1745*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1746*f6dc9357SAndroid Build Coastguard Worker : public CVirtThread
1747*f6dc9357SAndroid Build Coastguard Worker #endif
1748*f6dc9357SAndroid Build Coastguard Worker {
1749*f6dc9357SAndroid Build Coastguard Worker public:
1750*f6dc9357SAndroid Build Coastguard Worker CDecoder Decoder;
1751*f6dc9357SAndroid Build Coastguard Worker
1752*f6dc9357SAndroid Build Coastguard Worker CThreadDecoder(bool multiThreadMixer):
1753*f6dc9357SAndroid Build Coastguard Worker Decoder(multiThreadMixer)
1754*f6dc9357SAndroid Build Coastguard Worker {
1755*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1756*f6dc9357SAndroid Build Coastguard Worker if (multiThreadMixer)
1757*f6dc9357SAndroid Build Coastguard Worker {
1758*f6dc9357SAndroid Build Coastguard Worker MtMode = false;
1759*f6dc9357SAndroid Build Coastguard Worker NumThreads = 1;
1760*f6dc9357SAndroid Build Coastguard Worker FosSpec = new CFolderOutStream2;
1761*f6dc9357SAndroid Build Coastguard Worker Fos = FosSpec;
1762*f6dc9357SAndroid Build Coastguard Worker Result = E_FAIL;
1763*f6dc9357SAndroid Build Coastguard Worker }
1764*f6dc9357SAndroid Build Coastguard Worker #endif
1765*f6dc9357SAndroid Build Coastguard Worker // UnpackSize = 0;
1766*f6dc9357SAndroid Build Coastguard Worker // send_UnpackSize = false;
1767*f6dc9357SAndroid Build Coastguard Worker }
1768*f6dc9357SAndroid Build Coastguard Worker
1769*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1770*f6dc9357SAndroid Build Coastguard Worker
1771*f6dc9357SAndroid Build Coastguard Worker bool dataAfterEnd_Error;
1772*f6dc9357SAndroid Build Coastguard Worker HRESULT Result;
1773*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IInStream> InStream;
1774*f6dc9357SAndroid Build Coastguard Worker
1775*f6dc9357SAndroid Build Coastguard Worker CFolderOutStream2 *FosSpec;
1776*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> Fos;
1777*f6dc9357SAndroid Build Coastguard Worker
1778*f6dc9357SAndroid Build Coastguard Worker UInt64 StartPos;
1779*f6dc9357SAndroid Build Coastguard Worker const CFolders *Folders;
1780*f6dc9357SAndroid Build Coastguard Worker unsigned FolderIndex;
1781*f6dc9357SAndroid Build Coastguard Worker
1782*f6dc9357SAndroid Build Coastguard Worker // bool send_UnpackSize;
1783*f6dc9357SAndroid Build Coastguard Worker // UInt64 UnpackSize;
1784*f6dc9357SAndroid Build Coastguard Worker
1785*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
1786*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICryptoGetTextPassword> getTextPassword;
1787*f6dc9357SAndroid Build Coastguard Worker #endif
1788*f6dc9357SAndroid Build Coastguard Worker
1789*f6dc9357SAndroid Build Coastguard Worker DECL_EXTERNAL_CODECS_LOC_VARS_DECL
1790*f6dc9357SAndroid Build Coastguard Worker
1791*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1792*f6dc9357SAndroid Build Coastguard Worker bool MtMode;
1793*f6dc9357SAndroid Build Coastguard Worker UInt32 NumThreads;
1794*f6dc9357SAndroid Build Coastguard Worker #endif
1795*f6dc9357SAndroid Build Coastguard Worker
1796*f6dc9357SAndroid Build Coastguard Worker
1797*f6dc9357SAndroid Build Coastguard Worker ~CThreadDecoder() Z7_DESTRUCTOR_override
1798*f6dc9357SAndroid Build Coastguard Worker {
1799*f6dc9357SAndroid Build Coastguard Worker /* WaitThreadFinish() will be called in ~CVirtThread().
1800*f6dc9357SAndroid Build Coastguard Worker But we need WaitThreadFinish() call before
1801*f6dc9357SAndroid Build Coastguard Worker destructors of this class members.
1802*f6dc9357SAndroid Build Coastguard Worker */
1803*f6dc9357SAndroid Build Coastguard Worker CVirtThread::WaitThreadFinish();
1804*f6dc9357SAndroid Build Coastguard Worker }
1805*f6dc9357SAndroid Build Coastguard Worker private:
1806*f6dc9357SAndroid Build Coastguard Worker virtual void Execute() Z7_override;
1807*f6dc9357SAndroid Build Coastguard Worker
1808*f6dc9357SAndroid Build Coastguard Worker #endif
1809*f6dc9357SAndroid Build Coastguard Worker };
1810*f6dc9357SAndroid Build Coastguard Worker
1811*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1812*f6dc9357SAndroid Build Coastguard Worker
1813*f6dc9357SAndroid Build Coastguard Worker void CThreadDecoder::Execute()
1814*f6dc9357SAndroid Build Coastguard Worker {
1815*f6dc9357SAndroid Build Coastguard Worker try
1816*f6dc9357SAndroid Build Coastguard Worker {
1817*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
1818*f6dc9357SAndroid Build Coastguard Worker bool isEncrypted = false;
1819*f6dc9357SAndroid Build Coastguard Worker bool passwordIsDefined = false;
1820*f6dc9357SAndroid Build Coastguard Worker UString password;
1821*f6dc9357SAndroid Build Coastguard Worker #endif
1822*f6dc9357SAndroid Build Coastguard Worker
1823*f6dc9357SAndroid Build Coastguard Worker dataAfterEnd_Error = false;
1824*f6dc9357SAndroid Build Coastguard Worker
1825*f6dc9357SAndroid Build Coastguard Worker Result = Decoder.Decode(
1826*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_LOC_VARS
1827*f6dc9357SAndroid Build Coastguard Worker InStream,
1828*f6dc9357SAndroid Build Coastguard Worker StartPos,
1829*f6dc9357SAndroid Build Coastguard Worker *Folders, FolderIndex,
1830*f6dc9357SAndroid Build Coastguard Worker
1831*f6dc9357SAndroid Build Coastguard Worker // send_UnpackSize ? &UnpackSize : NULL,
1832*f6dc9357SAndroid Build Coastguard Worker NULL, // unpackSize : FULL unpack
1833*f6dc9357SAndroid Build Coastguard Worker
1834*f6dc9357SAndroid Build Coastguard Worker Fos,
1835*f6dc9357SAndroid Build Coastguard Worker NULL, // compressProgress
1836*f6dc9357SAndroid Build Coastguard Worker
1837*f6dc9357SAndroid Build Coastguard Worker NULL // *inStreamMainRes
1838*f6dc9357SAndroid Build Coastguard Worker , dataAfterEnd_Error
1839*f6dc9357SAndroid Build Coastguard Worker
1840*f6dc9357SAndroid Build Coastguard Worker Z7_7Z_DECODER_CRYPRO_VARS
1841*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1842*f6dc9357SAndroid Build Coastguard Worker , MtMode, NumThreads,
1843*f6dc9357SAndroid Build Coastguard Worker 0 // MemUsage
1844*f6dc9357SAndroid Build Coastguard Worker #endif
1845*f6dc9357SAndroid Build Coastguard Worker
1846*f6dc9357SAndroid Build Coastguard Worker );
1847*f6dc9357SAndroid Build Coastguard Worker }
1848*f6dc9357SAndroid Build Coastguard Worker catch(...)
1849*f6dc9357SAndroid Build Coastguard Worker {
1850*f6dc9357SAndroid Build Coastguard Worker Result = E_FAIL;
1851*f6dc9357SAndroid Build Coastguard Worker }
1852*f6dc9357SAndroid Build Coastguard Worker
1853*f6dc9357SAndroid Build Coastguard Worker /*
1854*f6dc9357SAndroid Build Coastguard Worker if (Result == S_OK)
1855*f6dc9357SAndroid Build Coastguard Worker Result = FosSpec->CheckFinishedState();
1856*f6dc9357SAndroid Build Coastguard Worker */
1857*f6dc9357SAndroid Build Coastguard Worker FosSpec->_stream.Release();
1858*f6dc9357SAndroid Build Coastguard Worker }
1859*f6dc9357SAndroid Build Coastguard Worker
1860*f6dc9357SAndroid Build Coastguard Worker #endif
1861*f6dc9357SAndroid Build Coastguard Worker
1862*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
1863*f6dc9357SAndroid Build Coastguard Worker
1864*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_NOQIB_1(
1865*f6dc9357SAndroid Build Coastguard Worker CCryptoGetTextPassword
1866*f6dc9357SAndroid Build Coastguard Worker , ICryptoGetTextPassword
1867*f6dc9357SAndroid Build Coastguard Worker )
1868*f6dc9357SAndroid Build Coastguard Worker public:
1869*f6dc9357SAndroid Build Coastguard Worker UString Password;
1870*f6dc9357SAndroid Build Coastguard Worker };
1871*f6dc9357SAndroid Build Coastguard Worker
1872*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password))
1873*f6dc9357SAndroid Build Coastguard Worker {
1874*f6dc9357SAndroid Build Coastguard Worker return StringToBstr(Password, password);
1875*f6dc9357SAndroid Build Coastguard Worker }
1876*f6dc9357SAndroid Build Coastguard Worker
1877*f6dc9357SAndroid Build Coastguard Worker #endif
1878*f6dc9357SAndroid Build Coastguard Worker
1879*f6dc9357SAndroid Build Coastguard Worker
1880*f6dc9357SAndroid Build Coastguard Worker static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFileItem2 &file2)
1881*f6dc9357SAndroid Build Coastguard Worker {
1882*f6dc9357SAndroid Build Coastguard Worker file = inDb.Files[index];
1883*f6dc9357SAndroid Build Coastguard Worker file2.CTimeDefined = inDb.CTime.GetItem(index, file2.CTime);
1884*f6dc9357SAndroid Build Coastguard Worker file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime);
1885*f6dc9357SAndroid Build Coastguard Worker file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime);
1886*f6dc9357SAndroid Build Coastguard Worker file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos);
1887*f6dc9357SAndroid Build Coastguard Worker file2.AttribDefined = inDb.Attrib.GetItem(index, file2.Attrib);
1888*f6dc9357SAndroid Build Coastguard Worker file2.IsAnti = inDb.IsItemAnti(index);
1889*f6dc9357SAndroid Build Coastguard Worker // file2.IsAux = inDb.IsItemAux(index);
1890*f6dc9357SAndroid Build Coastguard Worker }
1891*f6dc9357SAndroid Build Coastguard Worker
1892*f6dc9357SAndroid Build Coastguard Worker HRESULT Update(
1893*f6dc9357SAndroid Build Coastguard Worker DECL_EXTERNAL_CODECS_LOC_VARS
1894*f6dc9357SAndroid Build Coastguard Worker IInStream *inStream,
1895*f6dc9357SAndroid Build Coastguard Worker const CDbEx *db,
1896*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CUpdateItem> &updateItems,
1897*f6dc9357SAndroid Build Coastguard Worker // const CObjectVector<CTreeFolder> &treeFolders,
1898*f6dc9357SAndroid Build Coastguard Worker // const CUniqBlocks &secureBlocks,
1899*f6dc9357SAndroid Build Coastguard Worker ISequentialOutStream *seqOutStream,
1900*f6dc9357SAndroid Build Coastguard Worker IArchiveUpdateCallback *updateCallback,
1901*f6dc9357SAndroid Build Coastguard Worker const CUpdateOptions &options)
1902*f6dc9357SAndroid Build Coastguard Worker {
1903*f6dc9357SAndroid Build Coastguard Worker UInt64 numSolidFiles = options.NumSolidFiles;
1904*f6dc9357SAndroid Build Coastguard Worker if (numSolidFiles == 0)
1905*f6dc9357SAndroid Build Coastguard Worker numSolidFiles = 1;
1906*f6dc9357SAndroid Build Coastguard Worker
1907*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
1908*f6dc9357SAndroid Build Coastguard Worker IArchiveUpdateCallbackFile,
1909*f6dc9357SAndroid Build Coastguard Worker opCallback, updateCallback)
1910*f6dc9357SAndroid Build Coastguard Worker
1911*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
1912*f6dc9357SAndroid Build Coastguard Worker IArchiveExtractCallbackMessage2,
1913*f6dc9357SAndroid Build Coastguard Worker extractCallback, updateCallback)
1914*f6dc9357SAndroid Build Coastguard Worker
1915*f6dc9357SAndroid Build Coastguard Worker /*
1916*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
1917*f6dc9357SAndroid Build Coastguard Worker IArchiveUpdateCallbackArcProp,
1918*f6dc9357SAndroid Build Coastguard Worker reportArcProp, updateCallback)
1919*f6dc9357SAndroid Build Coastguard Worker */
1920*f6dc9357SAndroid Build Coastguard Worker
1921*f6dc9357SAndroid Build Coastguard Worker // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes();
1922*f6dc9357SAndroid Build Coastguard Worker
1923*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IStreamSetRestriction> v_StreamSetRestriction;
1924*f6dc9357SAndroid Build Coastguard Worker {
1925*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
1926*f6dc9357SAndroid Build Coastguard Worker IOutStream,
1927*f6dc9357SAndroid Build Coastguard Worker outStream, seqOutStream)
1928*f6dc9357SAndroid Build Coastguard Worker if (!outStream)
1929*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
1930*f6dc9357SAndroid Build Coastguard Worker const UInt64 sfxBlockSize = (db && !options.RemoveSfxBlock) ?
1931*f6dc9357SAndroid Build Coastguard Worker db->ArcInfo.StartPosition: 0;
1932*f6dc9357SAndroid Build Coastguard Worker seqOutStream->QueryInterface(IID_IStreamSetRestriction, (void **)&v_StreamSetRestriction);
1933*f6dc9357SAndroid Build Coastguard Worker if (v_StreamSetRestriction)
1934*f6dc9357SAndroid Build Coastguard Worker {
1935*f6dc9357SAndroid Build Coastguard Worker UInt64 offset = 0;
1936*f6dc9357SAndroid Build Coastguard Worker RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &offset))
1937*f6dc9357SAndroid Build Coastguard Worker RINOK(v_StreamSetRestriction->SetRestriction(
1938*f6dc9357SAndroid Build Coastguard Worker outStream ? offset + sfxBlockSize : 0,
1939*f6dc9357SAndroid Build Coastguard Worker outStream ? offset + sfxBlockSize + k_StartHeadersRewriteSize : 0))
1940*f6dc9357SAndroid Build Coastguard Worker }
1941*f6dc9357SAndroid Build Coastguard Worker outStream.Release();
1942*f6dc9357SAndroid Build Coastguard Worker if (sfxBlockSize != 0)
1943*f6dc9357SAndroid Build Coastguard Worker {
1944*f6dc9357SAndroid Build Coastguard Worker RINOK(WriteRange(inStream, seqOutStream, 0, sfxBlockSize, NULL))
1945*f6dc9357SAndroid Build Coastguard Worker }
1946*f6dc9357SAndroid Build Coastguard Worker }
1947*f6dc9357SAndroid Build Coastguard Worker
1948*f6dc9357SAndroid Build Coastguard Worker CIntArr fileIndexToUpdateIndexMap;
1949*f6dc9357SAndroid Build Coastguard Worker UInt64 complexity = 0;
1950*f6dc9357SAndroid Build Coastguard Worker bool isThere_UnknownSize = false;
1951*f6dc9357SAndroid Build Coastguard Worker UInt64 inSizeForReduce2 = 0;
1952*f6dc9357SAndroid Build Coastguard Worker
1953*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
1954*f6dc9357SAndroid Build Coastguard Worker bool needEncryptedRepack = false;
1955*f6dc9357SAndroid Build Coastguard Worker #endif
1956*f6dc9357SAndroid Build Coastguard Worker
1957*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CFilterMode2> filters;
1958*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CSolidGroup> groups;
1959*f6dc9357SAndroid Build Coastguard Worker
1960*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1961*f6dc9357SAndroid Build Coastguard Worker bool thereAreRepacks = false;
1962*f6dc9357SAndroid Build Coastguard Worker #endif
1963*f6dc9357SAndroid Build Coastguard Worker
1964*f6dc9357SAndroid Build Coastguard Worker bool useFilters = options.UseFilters;
1965*f6dc9357SAndroid Build Coastguard Worker if (useFilters)
1966*f6dc9357SAndroid Build Coastguard Worker {
1967*f6dc9357SAndroid Build Coastguard Worker const CCompressionMethodMode &method = *options.Method;
1968*f6dc9357SAndroid Build Coastguard Worker
1969*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, method.Methods)
1970*f6dc9357SAndroid Build Coastguard Worker {
1971*f6dc9357SAndroid Build Coastguard Worker /* IsFilterMethod() knows only built-in codecs
1972*f6dc9357SAndroid Build Coastguard Worker FIXME: we should check IsFilter status for external filters too */
1973*f6dc9357SAndroid Build Coastguard Worker if (IsFilterMethod(method.Methods[i].Id))
1974*f6dc9357SAndroid Build Coastguard Worker {
1975*f6dc9357SAndroid Build Coastguard Worker useFilters = false;
1976*f6dc9357SAndroid Build Coastguard Worker break;
1977*f6dc9357SAndroid Build Coastguard Worker }
1978*f6dc9357SAndroid Build Coastguard Worker }
1979*f6dc9357SAndroid Build Coastguard Worker }
1980*f6dc9357SAndroid Build Coastguard Worker
1981*f6dc9357SAndroid Build Coastguard Worker if (db)
1982*f6dc9357SAndroid Build Coastguard Worker {
1983*f6dc9357SAndroid Build Coastguard Worker fileIndexToUpdateIndexMap.Alloc(db->Files.Size());
1984*f6dc9357SAndroid Build Coastguard Worker unsigned i;
1985*f6dc9357SAndroid Build Coastguard Worker
1986*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < db->Files.Size(); i++)
1987*f6dc9357SAndroid Build Coastguard Worker fileIndexToUpdateIndexMap[i] = -1;
1988*f6dc9357SAndroid Build Coastguard Worker
1989*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < updateItems.Size(); i++)
1990*f6dc9357SAndroid Build Coastguard Worker {
1991*f6dc9357SAndroid Build Coastguard Worker int index = updateItems[i].IndexInArchive;
1992*f6dc9357SAndroid Build Coastguard Worker if (index != -1)
1993*f6dc9357SAndroid Build Coastguard Worker fileIndexToUpdateIndexMap[(unsigned)index] = (int)i;
1994*f6dc9357SAndroid Build Coastguard Worker }
1995*f6dc9357SAndroid Build Coastguard Worker
1996*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < db->NumFolders; i++)
1997*f6dc9357SAndroid Build Coastguard Worker {
1998*f6dc9357SAndroid Build Coastguard Worker CNum indexInFolder = 0;
1999*f6dc9357SAndroid Build Coastguard Worker CNum numCopyItems = 0;
2000*f6dc9357SAndroid Build Coastguard Worker const CNum numUnpackStreams = db->NumUnpackStreamsVector[i];
2001*f6dc9357SAndroid Build Coastguard Worker UInt64 repackSize = 0;
2002*f6dc9357SAndroid Build Coastguard Worker
2003*f6dc9357SAndroid Build Coastguard Worker for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++)
2004*f6dc9357SAndroid Build Coastguard Worker {
2005*f6dc9357SAndroid Build Coastguard Worker if (fi >= db->Files.Size())
2006*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2007*f6dc9357SAndroid Build Coastguard Worker
2008*f6dc9357SAndroid Build Coastguard Worker const CFileItem &file = db->Files[fi];
2009*f6dc9357SAndroid Build Coastguard Worker if (file.HasStream)
2010*f6dc9357SAndroid Build Coastguard Worker {
2011*f6dc9357SAndroid Build Coastguard Worker indexInFolder++;
2012*f6dc9357SAndroid Build Coastguard Worker const int updateIndex = fileIndexToUpdateIndexMap[fi];
2013*f6dc9357SAndroid Build Coastguard Worker if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData)
2014*f6dc9357SAndroid Build Coastguard Worker {
2015*f6dc9357SAndroid Build Coastguard Worker numCopyItems++;
2016*f6dc9357SAndroid Build Coastguard Worker repackSize += file.Size;
2017*f6dc9357SAndroid Build Coastguard Worker }
2018*f6dc9357SAndroid Build Coastguard Worker }
2019*f6dc9357SAndroid Build Coastguard Worker }
2020*f6dc9357SAndroid Build Coastguard Worker
2021*f6dc9357SAndroid Build Coastguard Worker if (numCopyItems == 0)
2022*f6dc9357SAndroid Build Coastguard Worker continue;
2023*f6dc9357SAndroid Build Coastguard Worker
2024*f6dc9357SAndroid Build Coastguard Worker CFolderRepack rep;
2025*f6dc9357SAndroid Build Coastguard Worker rep.FolderIndex = i;
2026*f6dc9357SAndroid Build Coastguard Worker rep.NumCopyFiles = numCopyItems;
2027*f6dc9357SAndroid Build Coastguard Worker CFolderEx f;
2028*f6dc9357SAndroid Build Coastguard Worker db->ParseFolderEx(i, f);
2029*f6dc9357SAndroid Build Coastguard Worker
2030*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
2031*f6dc9357SAndroid Build Coastguard Worker const bool isEncrypted = f.IsEncrypted();
2032*f6dc9357SAndroid Build Coastguard Worker #endif
2033*f6dc9357SAndroid Build Coastguard Worker const bool needCopy = (numCopyItems == numUnpackStreams);
2034*f6dc9357SAndroid Build Coastguard Worker const bool extractFilter = (useFilters || needCopy);
2035*f6dc9357SAndroid Build Coastguard Worker
2036*f6dc9357SAndroid Build Coastguard Worker const unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter);
2037*f6dc9357SAndroid Build Coastguard Worker
2038*f6dc9357SAndroid Build Coastguard Worker while (groupIndex >= groups.Size())
2039*f6dc9357SAndroid Build Coastguard Worker groups.AddNew();
2040*f6dc9357SAndroid Build Coastguard Worker
2041*f6dc9357SAndroid Build Coastguard Worker groups[groupIndex].folderRefs.Add(rep);
2042*f6dc9357SAndroid Build Coastguard Worker
2043*f6dc9357SAndroid Build Coastguard Worker if (needCopy)
2044*f6dc9357SAndroid Build Coastguard Worker complexity += db->GetFolderFullPackSize(i);
2045*f6dc9357SAndroid Build Coastguard Worker else
2046*f6dc9357SAndroid Build Coastguard Worker {
2047*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2048*f6dc9357SAndroid Build Coastguard Worker thereAreRepacks = true;
2049*f6dc9357SAndroid Build Coastguard Worker #endif
2050*f6dc9357SAndroid Build Coastguard Worker complexity += repackSize;
2051*f6dc9357SAndroid Build Coastguard Worker if (inSizeForReduce2 < repackSize)
2052*f6dc9357SAndroid Build Coastguard Worker inSizeForReduce2 = repackSize;
2053*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
2054*f6dc9357SAndroid Build Coastguard Worker if (isEncrypted)
2055*f6dc9357SAndroid Build Coastguard Worker needEncryptedRepack = true;
2056*f6dc9357SAndroid Build Coastguard Worker #endif
2057*f6dc9357SAndroid Build Coastguard Worker }
2058*f6dc9357SAndroid Build Coastguard Worker }
2059*f6dc9357SAndroid Build Coastguard Worker }
2060*f6dc9357SAndroid Build Coastguard Worker
2061*f6dc9357SAndroid Build Coastguard Worker UInt64 inSizeForReduce = 0;
2062*f6dc9357SAndroid Build Coastguard Worker {
2063*f6dc9357SAndroid Build Coastguard Worker const bool isSolid = (numSolidFiles > 1 && options.NumSolidBytes != 0);
2064*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, updateItems)
2065*f6dc9357SAndroid Build Coastguard Worker {
2066*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[i];
2067*f6dc9357SAndroid Build Coastguard Worker if (ui.NewData)
2068*f6dc9357SAndroid Build Coastguard Worker {
2069*f6dc9357SAndroid Build Coastguard Worker if (ui.Size == (UInt64)(Int64)-1)
2070*f6dc9357SAndroid Build Coastguard Worker isThere_UnknownSize = true;
2071*f6dc9357SAndroid Build Coastguard Worker else
2072*f6dc9357SAndroid Build Coastguard Worker {
2073*f6dc9357SAndroid Build Coastguard Worker complexity += ui.Size;
2074*f6dc9357SAndroid Build Coastguard Worker if (isSolid)
2075*f6dc9357SAndroid Build Coastguard Worker inSizeForReduce += ui.Size;
2076*f6dc9357SAndroid Build Coastguard Worker else if (inSizeForReduce < ui.Size)
2077*f6dc9357SAndroid Build Coastguard Worker inSizeForReduce = ui.Size;
2078*f6dc9357SAndroid Build Coastguard Worker }
2079*f6dc9357SAndroid Build Coastguard Worker }
2080*f6dc9357SAndroid Build Coastguard Worker }
2081*f6dc9357SAndroid Build Coastguard Worker }
2082*f6dc9357SAndroid Build Coastguard Worker
2083*f6dc9357SAndroid Build Coastguard Worker if (isThere_UnknownSize)
2084*f6dc9357SAndroid Build Coastguard Worker inSizeForReduce = (UInt64)(Int64)-1;
2085*f6dc9357SAndroid Build Coastguard Worker else
2086*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->SetTotal(complexity))
2087*f6dc9357SAndroid Build Coastguard Worker
2088*f6dc9357SAndroid Build Coastguard Worker if (inSizeForReduce < inSizeForReduce2)
2089*f6dc9357SAndroid Build Coastguard Worker inSizeForReduce = inSizeForReduce2;
2090*f6dc9357SAndroid Build Coastguard Worker
2091*f6dc9357SAndroid Build Coastguard Worker
2092*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
2093*f6dc9357SAndroid Build Coastguard Worker lps->Init(updateCallback, true);
2094*f6dc9357SAndroid Build Coastguard Worker
2095*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2096*f6dc9357SAndroid Build Coastguard Worker
2097*f6dc9357SAndroid Build Coastguard Worker CStreamBinder sb;
2098*f6dc9357SAndroid Build Coastguard Worker /*
2099*f6dc9357SAndroid Build Coastguard Worker if (options.MultiThreadMixer)
2100*f6dc9357SAndroid Build Coastguard Worker {
2101*f6dc9357SAndroid Build Coastguard Worker RINOK(sb.CreateEvents());
2102*f6dc9357SAndroid Build Coastguard Worker }
2103*f6dc9357SAndroid Build Coastguard Worker */
2104*f6dc9357SAndroid Build Coastguard Worker
2105*f6dc9357SAndroid Build Coastguard Worker #endif
2106*f6dc9357SAndroid Build Coastguard Worker
2107*f6dc9357SAndroid Build Coastguard Worker CThreadDecoder threadDecoder(options.MultiThreadMixer);
2108*f6dc9357SAndroid Build Coastguard Worker
2109*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2110*f6dc9357SAndroid Build Coastguard Worker if (options.MultiThreadMixer && thereAreRepacks)
2111*f6dc9357SAndroid Build Coastguard Worker {
2112*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_EXTERNAL_CODECS
2113*f6dc9357SAndroid Build Coastguard Worker threadDecoder._externalCodecs = _externalCodecs;
2114*f6dc9357SAndroid Build Coastguard Worker #endif
2115*f6dc9357SAndroid Build Coastguard Worker const WRes wres = threadDecoder.Create();
2116*f6dc9357SAndroid Build Coastguard Worker if (wres != 0)
2117*f6dc9357SAndroid Build Coastguard Worker return HRESULT_FROM_WIN32(wres);
2118*f6dc9357SAndroid Build Coastguard Worker }
2119*f6dc9357SAndroid Build Coastguard Worker #endif
2120*f6dc9357SAndroid Build Coastguard Worker
2121*f6dc9357SAndroid Build Coastguard Worker {
2122*f6dc9357SAndroid Build Coastguard Worker CAnalysis analysis;
2123*f6dc9357SAndroid Build Coastguard Worker // analysis.Need_ATime = options.Need_ATime;
2124*f6dc9357SAndroid Build Coastguard Worker int analysisLevel = options.AnalysisLevel;
2125*f6dc9357SAndroid Build Coastguard Worker // (analysisLevel < 0) means default level (5)
2126*f6dc9357SAndroid Build Coastguard Worker if (analysisLevel < 0)
2127*f6dc9357SAndroid Build Coastguard Worker analysisLevel = 5;
2128*f6dc9357SAndroid Build Coastguard Worker if (analysisLevel != 0)
2129*f6dc9357SAndroid Build Coastguard Worker {
2130*f6dc9357SAndroid Build Coastguard Worker analysis.Callback = opCallback;
2131*f6dc9357SAndroid Build Coastguard Worker analysis.ParseWav = true;
2132*f6dc9357SAndroid Build Coastguard Worker if (analysisLevel >= 5)
2133*f6dc9357SAndroid Build Coastguard Worker {
2134*f6dc9357SAndroid Build Coastguard Worker analysis.ParseExe = true;
2135*f6dc9357SAndroid Build Coastguard Worker analysis.ParseExeUnix = true;
2136*f6dc9357SAndroid Build Coastguard Worker // analysis.ParseNoExt = true;
2137*f6dc9357SAndroid Build Coastguard Worker if (analysisLevel >= 7)
2138*f6dc9357SAndroid Build Coastguard Worker {
2139*f6dc9357SAndroid Build Coastguard Worker analysis.ParseNoExt = true;
2140*f6dc9357SAndroid Build Coastguard Worker if (analysisLevel >= 9)
2141*f6dc9357SAndroid Build Coastguard Worker analysis.ParseAll = true;
2142*f6dc9357SAndroid Build Coastguard Worker }
2143*f6dc9357SAndroid Build Coastguard Worker }
2144*f6dc9357SAndroid Build Coastguard Worker }
2145*f6dc9357SAndroid Build Coastguard Worker
2146*f6dc9357SAndroid Build Coastguard Worker // ---------- Split files to groups ----------
2147*f6dc9357SAndroid Build Coastguard Worker
2148*f6dc9357SAndroid Build Coastguard Worker const CCompressionMethodMode &method = *options.Method;
2149*f6dc9357SAndroid Build Coastguard Worker
2150*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, updateItems)
2151*f6dc9357SAndroid Build Coastguard Worker {
2152*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[i];
2153*f6dc9357SAndroid Build Coastguard Worker if (!ui.NewData || !ui.HasStream())
2154*f6dc9357SAndroid Build Coastguard Worker continue;
2155*f6dc9357SAndroid Build Coastguard Worker
2156*f6dc9357SAndroid Build Coastguard Worker CFilterMode2 fm;
2157*f6dc9357SAndroid Build Coastguard Worker if (useFilters)
2158*f6dc9357SAndroid Build Coastguard Worker {
2159*f6dc9357SAndroid Build Coastguard Worker // analysis.ATime_Defined = false;
2160*f6dc9357SAndroid Build Coastguard Worker RINOK(analysis.GetFilterGroup(i, ui, fm))
2161*f6dc9357SAndroid Build Coastguard Worker /*
2162*f6dc9357SAndroid Build Coastguard Worker if (analysis.ATime_Defined)
2163*f6dc9357SAndroid Build Coastguard Worker {
2164*f6dc9357SAndroid Build Coastguard Worker ui.ATime = FILETIME_To_UInt64(analysis.ATime);
2165*f6dc9357SAndroid Build Coastguard Worker ui.ATime_WasReadByAnalysis = true;
2166*f6dc9357SAndroid Build Coastguard Worker }
2167*f6dc9357SAndroid Build Coastguard Worker */
2168*f6dc9357SAndroid Build Coastguard Worker }
2169*f6dc9357SAndroid Build Coastguard Worker fm.Encrypted = method.PasswordIsDefined;
2170*f6dc9357SAndroid Build Coastguard Worker
2171*f6dc9357SAndroid Build Coastguard Worker const unsigned groupIndex = GetGroup(filters, fm);
2172*f6dc9357SAndroid Build Coastguard Worker while (groupIndex >= groups.Size())
2173*f6dc9357SAndroid Build Coastguard Worker groups.AddNew();
2174*f6dc9357SAndroid Build Coastguard Worker groups[groupIndex].Indices.Add(i);
2175*f6dc9357SAndroid Build Coastguard Worker }
2176*f6dc9357SAndroid Build Coastguard Worker }
2177*f6dc9357SAndroid Build Coastguard Worker
2178*f6dc9357SAndroid Build Coastguard Worker
2179*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
2180*f6dc9357SAndroid Build Coastguard Worker
2181*f6dc9357SAndroid Build Coastguard Worker CCryptoGetTextPassword *getPasswordSpec = NULL;
2182*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ICryptoGetTextPassword> getTextPassword;
2183*f6dc9357SAndroid Build Coastguard Worker if (needEncryptedRepack)
2184*f6dc9357SAndroid Build Coastguard Worker {
2185*f6dc9357SAndroid Build Coastguard Worker getPasswordSpec = new CCryptoGetTextPassword;
2186*f6dc9357SAndroid Build Coastguard Worker getTextPassword = getPasswordSpec;
2187*f6dc9357SAndroid Build Coastguard Worker
2188*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2189*f6dc9357SAndroid Build Coastguard Worker threadDecoder.getTextPassword = getPasswordSpec;
2190*f6dc9357SAndroid Build Coastguard Worker #endif
2191*f6dc9357SAndroid Build Coastguard Worker
2192*f6dc9357SAndroid Build Coastguard Worker if (options.Method->PasswordIsDefined)
2193*f6dc9357SAndroid Build Coastguard Worker getPasswordSpec->Password = options.Method->Password;
2194*f6dc9357SAndroid Build Coastguard Worker else
2195*f6dc9357SAndroid Build Coastguard Worker {
2196*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
2197*f6dc9357SAndroid Build Coastguard Worker ICryptoGetTextPassword,
2198*f6dc9357SAndroid Build Coastguard Worker getDecoderPassword, updateCallback)
2199*f6dc9357SAndroid Build Coastguard Worker if (!getDecoderPassword)
2200*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
2201*f6dc9357SAndroid Build Coastguard Worker CMyComBSTR password;
2202*f6dc9357SAndroid Build Coastguard Worker RINOK(getDecoderPassword->CryptoGetTextPassword(&password))
2203*f6dc9357SAndroid Build Coastguard Worker if (password)
2204*f6dc9357SAndroid Build Coastguard Worker getPasswordSpec->Password = password;
2205*f6dc9357SAndroid Build Coastguard Worker }
2206*f6dc9357SAndroid Build Coastguard Worker }
2207*f6dc9357SAndroid Build Coastguard Worker
2208*f6dc9357SAndroid Build Coastguard Worker #endif
2209*f6dc9357SAndroid Build Coastguard Worker
2210*f6dc9357SAndroid Build Coastguard Worker // ---------- Compress ----------
2211*f6dc9357SAndroid Build Coastguard Worker
2212*f6dc9357SAndroid Build Coastguard Worker COutArchive archive;
2213*f6dc9357SAndroid Build Coastguard Worker CArchiveDatabaseOut newDatabase;
2214*f6dc9357SAndroid Build Coastguard Worker
2215*f6dc9357SAndroid Build Coastguard Worker RINOK(archive.Create_and_WriteStartPrefix(seqOutStream))
2216*f6dc9357SAndroid Build Coastguard Worker
2217*f6dc9357SAndroid Build Coastguard Worker /*
2218*f6dc9357SAndroid Build Coastguard Worker CIntVector treeFolderToArcIndex;
2219*f6dc9357SAndroid Build Coastguard Worker treeFolderToArcIndex.Reserve(treeFolders.Size());
2220*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < treeFolders.Size(); i++)
2221*f6dc9357SAndroid Build Coastguard Worker treeFolderToArcIndex.Add(-1);
2222*f6dc9357SAndroid Build Coastguard Worker // ---------- Write Tree (only AUX dirs) ----------
2223*f6dc9357SAndroid Build Coastguard Worker for (i = 1; i < treeFolders.Size(); i++)
2224*f6dc9357SAndroid Build Coastguard Worker {
2225*f6dc9357SAndroid Build Coastguard Worker const CTreeFolder &treeFolder = treeFolders[i];
2226*f6dc9357SAndroid Build Coastguard Worker CFileItem file;
2227*f6dc9357SAndroid Build Coastguard Worker CFileItem2 file2;
2228*f6dc9357SAndroid Build Coastguard Worker file2.Init();
2229*f6dc9357SAndroid Build Coastguard Worker int secureID = 0;
2230*f6dc9357SAndroid Build Coastguard Worker if (treeFolder.UpdateItemIndex < 0)
2231*f6dc9357SAndroid Build Coastguard Worker {
2232*f6dc9357SAndroid Build Coastguard Worker // we can store virtual dir item wuthout attrib, but we want all items have attrib.
2233*f6dc9357SAndroid Build Coastguard Worker file.SetAttrib(FILE_ATTRIBUTE_DIRECTORY);
2234*f6dc9357SAndroid Build Coastguard Worker file2.IsAux = true;
2235*f6dc9357SAndroid Build Coastguard Worker }
2236*f6dc9357SAndroid Build Coastguard Worker else
2237*f6dc9357SAndroid Build Coastguard Worker {
2238*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[treeFolder.UpdateItemIndex];
2239*f6dc9357SAndroid Build Coastguard Worker // if item is not dir, then it's parent for alt streams.
2240*f6dc9357SAndroid Build Coastguard Worker // we will write such items later
2241*f6dc9357SAndroid Build Coastguard Worker if (!ui.IsDir)
2242*f6dc9357SAndroid Build Coastguard Worker continue;
2243*f6dc9357SAndroid Build Coastguard Worker secureID = ui.SecureIndex;
2244*f6dc9357SAndroid Build Coastguard Worker if (ui.NewProps)
2245*f6dc9357SAndroid Build Coastguard Worker UpdateItem_To_FileItem(ui, file, file2);
2246*f6dc9357SAndroid Build Coastguard Worker else
2247*f6dc9357SAndroid Build Coastguard Worker GetFile(*db, ui.IndexInArchive, file, file2);
2248*f6dc9357SAndroid Build Coastguard Worker }
2249*f6dc9357SAndroid Build Coastguard Worker file.Size = 0;
2250*f6dc9357SAndroid Build Coastguard Worker file.HasStream = false;
2251*f6dc9357SAndroid Build Coastguard Worker file.IsDir = true;
2252*f6dc9357SAndroid Build Coastguard Worker file.Parent = treeFolder.Parent;
2253*f6dc9357SAndroid Build Coastguard Worker
2254*f6dc9357SAndroid Build Coastguard Worker treeFolderToArcIndex[i] = newDatabase.Files.Size();
2255*f6dc9357SAndroid Build Coastguard Worker newDatabase.AddFile(file, file2, treeFolder.Name);
2256*f6dc9357SAndroid Build Coastguard Worker
2257*f6dc9357SAndroid Build Coastguard Worker if (totalSecureDataSize != 0)
2258*f6dc9357SAndroid Build Coastguard Worker newDatabase.SecureIDs.Add(secureID);
2259*f6dc9357SAndroid Build Coastguard Worker }
2260*f6dc9357SAndroid Build Coastguard Worker */
2261*f6dc9357SAndroid Build Coastguard Worker
2262*f6dc9357SAndroid Build Coastguard Worker {
2263*f6dc9357SAndroid Build Coastguard Worker /* ---------- Write non-AUX dirs and Empty files ---------- */
2264*f6dc9357SAndroid Build Coastguard Worker CUIntVector emptyRefs;
2265*f6dc9357SAndroid Build Coastguard Worker
2266*f6dc9357SAndroid Build Coastguard Worker unsigned i;
2267*f6dc9357SAndroid Build Coastguard Worker
2268*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < updateItems.Size(); i++)
2269*f6dc9357SAndroid Build Coastguard Worker {
2270*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[i];
2271*f6dc9357SAndroid Build Coastguard Worker if (ui.NewData)
2272*f6dc9357SAndroid Build Coastguard Worker {
2273*f6dc9357SAndroid Build Coastguard Worker if (ui.HasStream())
2274*f6dc9357SAndroid Build Coastguard Worker continue;
2275*f6dc9357SAndroid Build Coastguard Worker }
2276*f6dc9357SAndroid Build Coastguard Worker else if (ui.IndexInArchive != -1 && db->Files[(unsigned)ui.IndexInArchive].HasStream)
2277*f6dc9357SAndroid Build Coastguard Worker continue;
2278*f6dc9357SAndroid Build Coastguard Worker /*
2279*f6dc9357SAndroid Build Coastguard Worker if (ui.TreeFolderIndex >= 0)
2280*f6dc9357SAndroid Build Coastguard Worker continue;
2281*f6dc9357SAndroid Build Coastguard Worker */
2282*f6dc9357SAndroid Build Coastguard Worker emptyRefs.Add(i);
2283*f6dc9357SAndroid Build Coastguard Worker }
2284*f6dc9357SAndroid Build Coastguard Worker
2285*f6dc9357SAndroid Build Coastguard Worker emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
2286*f6dc9357SAndroid Build Coastguard Worker
2287*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < emptyRefs.Size(); i++)
2288*f6dc9357SAndroid Build Coastguard Worker {
2289*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[emptyRefs[i]];
2290*f6dc9357SAndroid Build Coastguard Worker CFileItem file;
2291*f6dc9357SAndroid Build Coastguard Worker CFileItem2 file2;
2292*f6dc9357SAndroid Build Coastguard Worker UString name;
2293*f6dc9357SAndroid Build Coastguard Worker if (ui.NewProps)
2294*f6dc9357SAndroid Build Coastguard Worker {
2295*f6dc9357SAndroid Build Coastguard Worker UpdateItem_To_FileItem(ui, file, file2);
2296*f6dc9357SAndroid Build Coastguard Worker file.CrcDefined = false;
2297*f6dc9357SAndroid Build Coastguard Worker name = ui.Name;
2298*f6dc9357SAndroid Build Coastguard Worker }
2299*f6dc9357SAndroid Build Coastguard Worker else
2300*f6dc9357SAndroid Build Coastguard Worker {
2301*f6dc9357SAndroid Build Coastguard Worker GetFile(*db, (unsigned)ui.IndexInArchive, file, file2);
2302*f6dc9357SAndroid Build Coastguard Worker db->GetPath((unsigned)ui.IndexInArchive, name);
2303*f6dc9357SAndroid Build Coastguard Worker }
2304*f6dc9357SAndroid Build Coastguard Worker
2305*f6dc9357SAndroid Build Coastguard Worker /*
2306*f6dc9357SAndroid Build Coastguard Worker if (totalSecureDataSize != 0)
2307*f6dc9357SAndroid Build Coastguard Worker newDatabase.SecureIDs.Add(ui.SecureIndex);
2308*f6dc9357SAndroid Build Coastguard Worker file.Parent = ui.ParentFolderIndex;
2309*f6dc9357SAndroid Build Coastguard Worker */
2310*f6dc9357SAndroid Build Coastguard Worker newDatabase.AddFile(file, file2, name);
2311*f6dc9357SAndroid Build Coastguard Worker }
2312*f6dc9357SAndroid Build Coastguard Worker }
2313*f6dc9357SAndroid Build Coastguard Worker
2314*f6dc9357SAndroid Build Coastguard Worker lps->ProgressOffset = 0;
2315*f6dc9357SAndroid Build Coastguard Worker
2316*f6dc9357SAndroid Build Coastguard Worker {
2317*f6dc9357SAndroid Build Coastguard Worker // ---------- Sort Filters ----------
2318*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, filters)
2319*f6dc9357SAndroid Build Coastguard Worker {
2320*f6dc9357SAndroid Build Coastguard Worker filters[i].GroupIndex = i;
2321*f6dc9357SAndroid Build Coastguard Worker }
2322*f6dc9357SAndroid Build Coastguard Worker filters.Sort2();
2323*f6dc9357SAndroid Build Coastguard Worker }
2324*f6dc9357SAndroid Build Coastguard Worker
2325*f6dc9357SAndroid Build Coastguard Worker for (unsigned groupIndex = 0; groupIndex < filters.Size(); groupIndex++)
2326*f6dc9357SAndroid Build Coastguard Worker {
2327*f6dc9357SAndroid Build Coastguard Worker const CFilterMode2 &filterMode = filters[groupIndex];
2328*f6dc9357SAndroid Build Coastguard Worker
2329*f6dc9357SAndroid Build Coastguard Worker CCompressionMethodMode method = *options.Method;
2330*f6dc9357SAndroid Build Coastguard Worker {
2331*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = MakeExeMethod(method, filterMode,
2332*f6dc9357SAndroid Build Coastguard Worker // bcj2_IsAllowed:
2333*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ST
2334*f6dc9357SAndroid Build Coastguard Worker false
2335*f6dc9357SAndroid Build Coastguard Worker #else
2336*f6dc9357SAndroid Build Coastguard Worker options.MaxFilter && options.MultiThreadMixer
2337*f6dc9357SAndroid Build Coastguard Worker #endif
2338*f6dc9357SAndroid Build Coastguard Worker , options.DisabledFilterIDs);
2339*f6dc9357SAndroid Build Coastguard Worker
2340*f6dc9357SAndroid Build Coastguard Worker RINOK(res)
2341*f6dc9357SAndroid Build Coastguard Worker }
2342*f6dc9357SAndroid Build Coastguard Worker
2343*f6dc9357SAndroid Build Coastguard Worker if (filterMode.Encrypted)
2344*f6dc9357SAndroid Build Coastguard Worker {
2345*f6dc9357SAndroid Build Coastguard Worker if (!method.PasswordIsDefined)
2346*f6dc9357SAndroid Build Coastguard Worker {
2347*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
2348*f6dc9357SAndroid Build Coastguard Worker if (getPasswordSpec)
2349*f6dc9357SAndroid Build Coastguard Worker method.Password = getPasswordSpec->Password;
2350*f6dc9357SAndroid Build Coastguard Worker #endif
2351*f6dc9357SAndroid Build Coastguard Worker method.PasswordIsDefined = true;
2352*f6dc9357SAndroid Build Coastguard Worker }
2353*f6dc9357SAndroid Build Coastguard Worker }
2354*f6dc9357SAndroid Build Coastguard Worker else
2355*f6dc9357SAndroid Build Coastguard Worker {
2356*f6dc9357SAndroid Build Coastguard Worker method.PasswordIsDefined = false;
2357*f6dc9357SAndroid Build Coastguard Worker method.Password.Empty();
2358*f6dc9357SAndroid Build Coastguard Worker }
2359*f6dc9357SAndroid Build Coastguard Worker
2360*f6dc9357SAndroid Build Coastguard Worker CEncoder encoder(method);
2361*f6dc9357SAndroid Build Coastguard Worker
2362*f6dc9357SAndroid Build Coastguard Worker // ---------- Repack and copy old solid blocks ----------
2363*f6dc9357SAndroid Build Coastguard Worker
2364*f6dc9357SAndroid Build Coastguard Worker const CSolidGroup &group = groups[filterMode.GroupIndex];
2365*f6dc9357SAndroid Build Coastguard Worker
2366*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (folderRefIndex, group.folderRefs)
2367*f6dc9357SAndroid Build Coastguard Worker {
2368*f6dc9357SAndroid Build Coastguard Worker const CFolderRepack &rep = group.folderRefs[folderRefIndex];
2369*f6dc9357SAndroid Build Coastguard Worker
2370*f6dc9357SAndroid Build Coastguard Worker const unsigned folderIndex = rep.FolderIndex;
2371*f6dc9357SAndroid Build Coastguard Worker
2372*f6dc9357SAndroid Build Coastguard Worker const CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
2373*f6dc9357SAndroid Build Coastguard Worker
2374*f6dc9357SAndroid Build Coastguard Worker if (rep.NumCopyFiles == numUnpackStreams)
2375*f6dc9357SAndroid Build Coastguard Worker {
2376*f6dc9357SAndroid Build Coastguard Worker if (opCallback)
2377*f6dc9357SAndroid Build Coastguard Worker {
2378*f6dc9357SAndroid Build Coastguard Worker RINOK(opCallback->ReportOperation(
2379*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex,
2380*f6dc9357SAndroid Build Coastguard Worker NUpdateNotifyOp::kReplicate))
2381*f6dc9357SAndroid Build Coastguard Worker
2382*f6dc9357SAndroid Build Coastguard Worker // ---------- Copy old solid block ----------
2383*f6dc9357SAndroid Build Coastguard Worker {
2384*f6dc9357SAndroid Build Coastguard Worker CNum indexInFolder = 0;
2385*f6dc9357SAndroid Build Coastguard Worker for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
2386*f6dc9357SAndroid Build Coastguard Worker {
2387*f6dc9357SAndroid Build Coastguard Worker if (db->Files[fi].HasStream)
2388*f6dc9357SAndroid Build Coastguard Worker {
2389*f6dc9357SAndroid Build Coastguard Worker indexInFolder++;
2390*f6dc9357SAndroid Build Coastguard Worker RINOK(opCallback->ReportOperation(
2391*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kInArcIndex, (UInt32)fi,
2392*f6dc9357SAndroid Build Coastguard Worker NUpdateNotifyOp::kReplicate))
2393*f6dc9357SAndroid Build Coastguard Worker }
2394*f6dc9357SAndroid Build Coastguard Worker }
2395*f6dc9357SAndroid Build Coastguard Worker }
2396*f6dc9357SAndroid Build Coastguard Worker }
2397*f6dc9357SAndroid Build Coastguard Worker
2398*f6dc9357SAndroid Build Coastguard Worker const UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
2399*f6dc9357SAndroid Build Coastguard Worker RINOK(WriteRange(inStream, archive.SeqStream,
2400*f6dc9357SAndroid Build Coastguard Worker db->GetFolderStreamPos(folderIndex, 0), packSize, lps))
2401*f6dc9357SAndroid Build Coastguard Worker lps->ProgressOffset += packSize;
2402*f6dc9357SAndroid Build Coastguard Worker
2403*f6dc9357SAndroid Build Coastguard Worker const unsigned folderIndex_New = newDatabase.Folders.Size();
2404*f6dc9357SAndroid Build Coastguard Worker CFolder &folder = newDatabase.Folders.AddNew();
2405*f6dc9357SAndroid Build Coastguard Worker // v23.01: we copy FolderCrc, if FolderCrc was used
2406*f6dc9357SAndroid Build Coastguard Worker if (db->FolderCRCs.ValidAndDefined(folderIndex))
2407*f6dc9357SAndroid Build Coastguard Worker newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New,
2408*f6dc9357SAndroid Build Coastguard Worker true, db->FolderCRCs.Vals[folderIndex]);
2409*f6dc9357SAndroid Build Coastguard Worker
2410*f6dc9357SAndroid Build Coastguard Worker db->ParseFolderInfo(folderIndex, folder);
2411*f6dc9357SAndroid Build Coastguard Worker const CNum startIndex = db->FoStartPackStreamIndex[folderIndex];
2412*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (j, folder.PackStreams)
2413*f6dc9357SAndroid Build Coastguard Worker {
2414*f6dc9357SAndroid Build Coastguard Worker newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j));
2415*f6dc9357SAndroid Build Coastguard Worker // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);
2416*f6dc9357SAndroid Build Coastguard Worker // newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]);
2417*f6dc9357SAndroid Build Coastguard Worker }
2418*f6dc9357SAndroid Build Coastguard Worker
2419*f6dc9357SAndroid Build Coastguard Worker size_t indexStart = db->FoToCoderUnpackSizes[folderIndex];
2420*f6dc9357SAndroid Build Coastguard Worker const size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1];
2421*f6dc9357SAndroid Build Coastguard Worker for (; indexStart < indexEnd; indexStart++)
2422*f6dc9357SAndroid Build Coastguard Worker newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes.ConstData()[indexStart]);
2423*f6dc9357SAndroid Build Coastguard Worker }
2424*f6dc9357SAndroid Build Coastguard Worker else
2425*f6dc9357SAndroid Build Coastguard Worker {
2426*f6dc9357SAndroid Build Coastguard Worker // ---------- Repack old solid block ----------
2427*f6dc9357SAndroid Build Coastguard Worker
2428*f6dc9357SAndroid Build Coastguard Worker CBoolVector extractStatuses;
2429*f6dc9357SAndroid Build Coastguard Worker
2430*f6dc9357SAndroid Build Coastguard Worker CNum indexInFolder = 0;
2431*f6dc9357SAndroid Build Coastguard Worker
2432*f6dc9357SAndroid Build Coastguard Worker if (opCallback)
2433*f6dc9357SAndroid Build Coastguard Worker {
2434*f6dc9357SAndroid Build Coastguard Worker RINOK(opCallback->ReportOperation(
2435*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex,
2436*f6dc9357SAndroid Build Coastguard Worker NUpdateNotifyOp::kRepack))
2437*f6dc9357SAndroid Build Coastguard Worker }
2438*f6dc9357SAndroid Build Coastguard Worker
2439*f6dc9357SAndroid Build Coastguard Worker /* We could reduce data size of decoded folder, if we don't need to repack
2440*f6dc9357SAndroid Build Coastguard Worker last files in folder. But the gain in speed is small in most cases.
2441*f6dc9357SAndroid Build Coastguard Worker So we unpack full folder. */
2442*f6dc9357SAndroid Build Coastguard Worker
2443*f6dc9357SAndroid Build Coastguard Worker UInt64 sizeToEncode = 0;
2444*f6dc9357SAndroid Build Coastguard Worker
2445*f6dc9357SAndroid Build Coastguard Worker /*
2446*f6dc9357SAndroid Build Coastguard Worker UInt64 importantUnpackSize = 0;
2447*f6dc9357SAndroid Build Coastguard Worker unsigned numImportantFiles = 0;
2448*f6dc9357SAndroid Build Coastguard Worker UInt64 decodeSize = 0;
2449*f6dc9357SAndroid Build Coastguard Worker */
2450*f6dc9357SAndroid Build Coastguard Worker
2451*f6dc9357SAndroid Build Coastguard Worker for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
2452*f6dc9357SAndroid Build Coastguard Worker {
2453*f6dc9357SAndroid Build Coastguard Worker bool needExtract = false;
2454*f6dc9357SAndroid Build Coastguard Worker const CFileItem &file = db->Files[fi];
2455*f6dc9357SAndroid Build Coastguard Worker
2456*f6dc9357SAndroid Build Coastguard Worker if (file.HasStream)
2457*f6dc9357SAndroid Build Coastguard Worker {
2458*f6dc9357SAndroid Build Coastguard Worker indexInFolder++;
2459*f6dc9357SAndroid Build Coastguard Worker const int updateIndex = fileIndexToUpdateIndexMap[fi];
2460*f6dc9357SAndroid Build Coastguard Worker if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData)
2461*f6dc9357SAndroid Build Coastguard Worker needExtract = true;
2462*f6dc9357SAndroid Build Coastguard Worker // decodeSize += file.Size;
2463*f6dc9357SAndroid Build Coastguard Worker }
2464*f6dc9357SAndroid Build Coastguard Worker
2465*f6dc9357SAndroid Build Coastguard Worker extractStatuses.Add(needExtract);
2466*f6dc9357SAndroid Build Coastguard Worker if (needExtract)
2467*f6dc9357SAndroid Build Coastguard Worker {
2468*f6dc9357SAndroid Build Coastguard Worker sizeToEncode += file.Size;
2469*f6dc9357SAndroid Build Coastguard Worker /*
2470*f6dc9357SAndroid Build Coastguard Worker numImportantFiles = extractStatuses.Size();
2471*f6dc9357SAndroid Build Coastguard Worker importantUnpackSize = decodeSize;
2472*f6dc9357SAndroid Build Coastguard Worker */
2473*f6dc9357SAndroid Build Coastguard Worker }
2474*f6dc9357SAndroid Build Coastguard Worker }
2475*f6dc9357SAndroid Build Coastguard Worker
2476*f6dc9357SAndroid Build Coastguard Worker // extractStatuses.DeleteFrom(numImportantFiles);
2477*f6dc9357SAndroid Build Coastguard Worker
2478*f6dc9357SAndroid Build Coastguard Worker unsigned startPackIndex = newDatabase.PackSizes.Size();
2479*f6dc9357SAndroid Build Coastguard Worker UInt64 curUnpackSize;
2480*f6dc9357SAndroid Build Coastguard Worker {
2481*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> sbInStream;
2482*f6dc9357SAndroid Build Coastguard Worker CRepackStreamBase *repackBase;
2483*f6dc9357SAndroid Build Coastguard Worker CFolderInStream2 *FosSpec2 = NULL;
2484*f6dc9357SAndroid Build Coastguard Worker
2485*f6dc9357SAndroid Build Coastguard Worker CRepackInStreamWithSizes *inStreamSizeCountSpec = new CRepackInStreamWithSizes;
2486*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
2487*f6dc9357SAndroid Build Coastguard Worker {
2488*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2489*f6dc9357SAndroid Build Coastguard Worker if (options.MultiThreadMixer)
2490*f6dc9357SAndroid Build Coastguard Worker {
2491*f6dc9357SAndroid Build Coastguard Worker repackBase = threadDecoder.FosSpec;
2492*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> sbOutStream;
2493*f6dc9357SAndroid Build Coastguard Worker sb.CreateStreams2(sbInStream, sbOutStream);
2494*f6dc9357SAndroid Build Coastguard Worker RINOK(sb.Create_ReInit())
2495*f6dc9357SAndroid Build Coastguard Worker
2496*f6dc9357SAndroid Build Coastguard Worker threadDecoder.FosSpec->_stream = sbOutStream;
2497*f6dc9357SAndroid Build Coastguard Worker
2498*f6dc9357SAndroid Build Coastguard Worker threadDecoder.InStream = inStream;
2499*f6dc9357SAndroid Build Coastguard Worker threadDecoder.StartPos = db->ArcInfo.DataStartPosition; // db->GetFolderStreamPos(folderIndex, 0);
2500*f6dc9357SAndroid Build Coastguard Worker threadDecoder.Folders = (const CFolders *)db;
2501*f6dc9357SAndroid Build Coastguard Worker threadDecoder.FolderIndex = folderIndex;
2502*f6dc9357SAndroid Build Coastguard Worker
2503*f6dc9357SAndroid Build Coastguard Worker // threadDecoder.UnpackSize = importantUnpackSize;
2504*f6dc9357SAndroid Build Coastguard Worker // threadDecoder.send_UnpackSize = true;
2505*f6dc9357SAndroid Build Coastguard Worker }
2506*f6dc9357SAndroid Build Coastguard Worker else
2507*f6dc9357SAndroid Build Coastguard Worker #endif
2508*f6dc9357SAndroid Build Coastguard Worker {
2509*f6dc9357SAndroid Build Coastguard Worker FosSpec2 = new CFolderInStream2;
2510*f6dc9357SAndroid Build Coastguard Worker FosSpec2->Init();
2511*f6dc9357SAndroid Build Coastguard Worker sbInStream = FosSpec2;
2512*f6dc9357SAndroid Build Coastguard Worker repackBase = FosSpec2;
2513*f6dc9357SAndroid Build Coastguard Worker
2514*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
2515*f6dc9357SAndroid Build Coastguard Worker bool isEncrypted = false;
2516*f6dc9357SAndroid Build Coastguard Worker bool passwordIsDefined = false;
2517*f6dc9357SAndroid Build Coastguard Worker UString password;
2518*f6dc9357SAndroid Build Coastguard Worker #endif
2519*f6dc9357SAndroid Build Coastguard Worker
2520*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> decodedStream;
2521*f6dc9357SAndroid Build Coastguard Worker bool dataAfterEnd_Error = false;
2522*f6dc9357SAndroid Build Coastguard Worker
2523*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = threadDecoder.Decoder.Decode(
2524*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_LOC_VARS
2525*f6dc9357SAndroid Build Coastguard Worker inStream,
2526*f6dc9357SAndroid Build Coastguard Worker db->ArcInfo.DataStartPosition, // db->GetFolderStreamPos(folderIndex, 0);,
2527*f6dc9357SAndroid Build Coastguard Worker *db, folderIndex,
2528*f6dc9357SAndroid Build Coastguard Worker // &importantUnpackSize, // *unpackSize
2529*f6dc9357SAndroid Build Coastguard Worker NULL, // *unpackSize : FULL unpack
2530*f6dc9357SAndroid Build Coastguard Worker
2531*f6dc9357SAndroid Build Coastguard Worker NULL, // *outStream
2532*f6dc9357SAndroid Build Coastguard Worker NULL, // *compressProgress
2533*f6dc9357SAndroid Build Coastguard Worker
2534*f6dc9357SAndroid Build Coastguard Worker &decodedStream
2535*f6dc9357SAndroid Build Coastguard Worker , dataAfterEnd_Error
2536*f6dc9357SAndroid Build Coastguard Worker
2537*f6dc9357SAndroid Build Coastguard Worker Z7_7Z_DECODER_CRYPRO_VARS
2538*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2539*f6dc9357SAndroid Build Coastguard Worker , false // mtMode
2540*f6dc9357SAndroid Build Coastguard Worker , 1 // numThreads
2541*f6dc9357SAndroid Build Coastguard Worker , 0 // memUsage
2542*f6dc9357SAndroid Build Coastguard Worker #endif
2543*f6dc9357SAndroid Build Coastguard Worker );
2544*f6dc9357SAndroid Build Coastguard Worker
2545*f6dc9357SAndroid Build Coastguard Worker RINOK(res)
2546*f6dc9357SAndroid Build Coastguard Worker if (!decodedStream)
2547*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2548*f6dc9357SAndroid Build Coastguard Worker
2549*f6dc9357SAndroid Build Coastguard Worker FosSpec2->_inStream = decodedStream;
2550*f6dc9357SAndroid Build Coastguard Worker }
2551*f6dc9357SAndroid Build Coastguard Worker
2552*f6dc9357SAndroid Build Coastguard Worker repackBase->_db = db;
2553*f6dc9357SAndroid Build Coastguard Worker repackBase->_opCallback = opCallback;
2554*f6dc9357SAndroid Build Coastguard Worker repackBase->_extractCallback = extractCallback;
2555*f6dc9357SAndroid Build Coastguard Worker
2556*f6dc9357SAndroid Build Coastguard Worker UInt32 startIndex = db->FolderStartFileIndex[folderIndex];
2557*f6dc9357SAndroid Build Coastguard Worker RINOK(repackBase->Init(startIndex, &extractStatuses))
2558*f6dc9357SAndroid Build Coastguard Worker
2559*f6dc9357SAndroid Build Coastguard Worker inStreamSizeCountSpec->_db = db;
2560*f6dc9357SAndroid Build Coastguard Worker inStreamSizeCountSpec->Init(sbInStream, startIndex, &extractStatuses);
2561*f6dc9357SAndroid Build Coastguard Worker
2562*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2563*f6dc9357SAndroid Build Coastguard Worker if (options.MultiThreadMixer)
2564*f6dc9357SAndroid Build Coastguard Worker {
2565*f6dc9357SAndroid Build Coastguard Worker WRes wres = threadDecoder.Start();
2566*f6dc9357SAndroid Build Coastguard Worker if (wres != 0)
2567*f6dc9357SAndroid Build Coastguard Worker return HRESULT_FROM_WIN32(wres);
2568*f6dc9357SAndroid Build Coastguard Worker }
2569*f6dc9357SAndroid Build Coastguard Worker #endif
2570*f6dc9357SAndroid Build Coastguard Worker }
2571*f6dc9357SAndroid Build Coastguard Worker
2572*f6dc9357SAndroid Build Coastguard Worker // curUnpackSize = sizeToEncode;
2573*f6dc9357SAndroid Build Coastguard Worker
2574*f6dc9357SAndroid Build Coastguard Worker HRESULT encodeRes = encoder.Encode1(
2575*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_LOC_VARS
2576*f6dc9357SAndroid Build Coastguard Worker inStreamSizeCount,
2577*f6dc9357SAndroid Build Coastguard Worker // NULL,
2578*f6dc9357SAndroid Build Coastguard Worker &inSizeForReduce,
2579*f6dc9357SAndroid Build Coastguard Worker sizeToEncode, // expectedDataSize
2580*f6dc9357SAndroid Build Coastguard Worker newDatabase.Folders.AddNew(),
2581*f6dc9357SAndroid Build Coastguard Worker // newDatabase.CoderUnpackSizes, curUnpackSize,
2582*f6dc9357SAndroid Build Coastguard Worker archive.SeqStream, newDatabase.PackSizes, lps);
2583*f6dc9357SAndroid Build Coastguard Worker
2584*f6dc9357SAndroid Build Coastguard Worker if (encodeRes == k_My_HRESULT_CRC_ERROR)
2585*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2586*f6dc9357SAndroid Build Coastguard Worker
2587*f6dc9357SAndroid Build Coastguard Worker curUnpackSize = inStreamSizeCountSpec->GetSize();
2588*f6dc9357SAndroid Build Coastguard Worker
2589*f6dc9357SAndroid Build Coastguard Worker if (encodeRes == S_OK)
2590*f6dc9357SAndroid Build Coastguard Worker {
2591*f6dc9357SAndroid Build Coastguard Worker encoder.Encode_Post(curUnpackSize, newDatabase.CoderUnpackSizes);
2592*f6dc9357SAndroid Build Coastguard Worker }
2593*f6dc9357SAndroid Build Coastguard Worker
2594*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2595*f6dc9357SAndroid Build Coastguard Worker if (options.MultiThreadMixer)
2596*f6dc9357SAndroid Build Coastguard Worker {
2597*f6dc9357SAndroid Build Coastguard Worker // 16.00: hang was fixed : for case if decoding was not finished.
2598*f6dc9357SAndroid Build Coastguard Worker // We close CBinderInStream and it calls CStreamBinder::CloseRead()
2599*f6dc9357SAndroid Build Coastguard Worker inStreamSizeCount.Release();
2600*f6dc9357SAndroid Build Coastguard Worker sbInStream.Release();
2601*f6dc9357SAndroid Build Coastguard Worker
2602*f6dc9357SAndroid Build Coastguard Worker {
2603*f6dc9357SAndroid Build Coastguard Worker const WRes wres = threadDecoder.WaitExecuteFinish();
2604*f6dc9357SAndroid Build Coastguard Worker if (wres != 0)
2605*f6dc9357SAndroid Build Coastguard Worker return HRESULT_FROM_WIN32(wres);
2606*f6dc9357SAndroid Build Coastguard Worker }
2607*f6dc9357SAndroid Build Coastguard Worker
2608*f6dc9357SAndroid Build Coastguard Worker const HRESULT decodeRes = threadDecoder.Result;
2609*f6dc9357SAndroid Build Coastguard Worker // if (res == k_My_HRESULT_CRC_ERROR)
2610*f6dc9357SAndroid Build Coastguard Worker if (decodeRes == S_FALSE || threadDecoder.dataAfterEnd_Error)
2611*f6dc9357SAndroid Build Coastguard Worker {
2612*f6dc9357SAndroid Build Coastguard Worker if (extractCallback)
2613*f6dc9357SAndroid Build Coastguard Worker {
2614*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->ReportExtractResult(
2615*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex],
2616*f6dc9357SAndroid Build Coastguard Worker // NEventIndexType::kBlockIndex, (UInt32)folderIndex,
2617*f6dc9357SAndroid Build Coastguard Worker (decodeRes != S_OK ?
2618*f6dc9357SAndroid Build Coastguard Worker NExtract::NOperationResult::kDataError :
2619*f6dc9357SAndroid Build Coastguard Worker NExtract::NOperationResult::kDataAfterEnd)))
2620*f6dc9357SAndroid Build Coastguard Worker }
2621*f6dc9357SAndroid Build Coastguard Worker if (decodeRes != S_OK)
2622*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2623*f6dc9357SAndroid Build Coastguard Worker }
2624*f6dc9357SAndroid Build Coastguard Worker RINOK(decodeRes)
2625*f6dc9357SAndroid Build Coastguard Worker if (encodeRes == S_OK)
2626*f6dc9357SAndroid Build Coastguard Worker if (sb.ProcessedSize != sizeToEncode)
2627*f6dc9357SAndroid Build Coastguard Worker encodeRes = E_FAIL;
2628*f6dc9357SAndroid Build Coastguard Worker }
2629*f6dc9357SAndroid Build Coastguard Worker else
2630*f6dc9357SAndroid Build Coastguard Worker #endif
2631*f6dc9357SAndroid Build Coastguard Worker {
2632*f6dc9357SAndroid Build Coastguard Worker if (FosSpec2->Result == S_FALSE)
2633*f6dc9357SAndroid Build Coastguard Worker {
2634*f6dc9357SAndroid Build Coastguard Worker if (extractCallback)
2635*f6dc9357SAndroid Build Coastguard Worker {
2636*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->ReportExtractResult(
2637*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex,
2638*f6dc9357SAndroid Build Coastguard Worker NExtract::NOperationResult::kDataError))
2639*f6dc9357SAndroid Build Coastguard Worker }
2640*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2641*f6dc9357SAndroid Build Coastguard Worker }
2642*f6dc9357SAndroid Build Coastguard Worker RINOK(FosSpec2->Result)
2643*f6dc9357SAndroid Build Coastguard Worker }
2644*f6dc9357SAndroid Build Coastguard Worker
2645*f6dc9357SAndroid Build Coastguard Worker RINOK(encodeRes)
2646*f6dc9357SAndroid Build Coastguard Worker RINOK(repackBase->CheckFinishedState())
2647*f6dc9357SAndroid Build Coastguard Worker
2648*f6dc9357SAndroid Build Coastguard Worker if (curUnpackSize != sizeToEncode)
2649*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2650*f6dc9357SAndroid Build Coastguard Worker }
2651*f6dc9357SAndroid Build Coastguard Worker
2652*f6dc9357SAndroid Build Coastguard Worker for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
2653*f6dc9357SAndroid Build Coastguard Worker lps->OutSize += newDatabase.PackSizes[startPackIndex];
2654*f6dc9357SAndroid Build Coastguard Worker lps->InSize += curUnpackSize;
2655*f6dc9357SAndroid Build Coastguard Worker }
2656*f6dc9357SAndroid Build Coastguard Worker
2657*f6dc9357SAndroid Build Coastguard Worker newDatabase.NumUnpackStreamsVector.Add(rep.NumCopyFiles);
2658*f6dc9357SAndroid Build Coastguard Worker
2659*f6dc9357SAndroid Build Coastguard Worker CNum indexInFolder = 0;
2660*f6dc9357SAndroid Build Coastguard Worker for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
2661*f6dc9357SAndroid Build Coastguard Worker {
2662*f6dc9357SAndroid Build Coastguard Worker if (db->Files[fi].HasStream)
2663*f6dc9357SAndroid Build Coastguard Worker {
2664*f6dc9357SAndroid Build Coastguard Worker indexInFolder++;
2665*f6dc9357SAndroid Build Coastguard Worker const int updateIndex = fileIndexToUpdateIndexMap[fi];
2666*f6dc9357SAndroid Build Coastguard Worker if (updateIndex >= 0)
2667*f6dc9357SAndroid Build Coastguard Worker {
2668*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[(unsigned)updateIndex];
2669*f6dc9357SAndroid Build Coastguard Worker if (ui.NewData)
2670*f6dc9357SAndroid Build Coastguard Worker continue;
2671*f6dc9357SAndroid Build Coastguard Worker
2672*f6dc9357SAndroid Build Coastguard Worker UString name;
2673*f6dc9357SAndroid Build Coastguard Worker CFileItem file;
2674*f6dc9357SAndroid Build Coastguard Worker CFileItem2 file2;
2675*f6dc9357SAndroid Build Coastguard Worker GetFile(*db, fi, file, file2);
2676*f6dc9357SAndroid Build Coastguard Worker
2677*f6dc9357SAndroid Build Coastguard Worker if (ui.NewProps)
2678*f6dc9357SAndroid Build Coastguard Worker {
2679*f6dc9357SAndroid Build Coastguard Worker UpdateItem_To_FileItem2(ui, file2);
2680*f6dc9357SAndroid Build Coastguard Worker file.IsDir = ui.IsDir;
2681*f6dc9357SAndroid Build Coastguard Worker name = ui.Name;
2682*f6dc9357SAndroid Build Coastguard Worker }
2683*f6dc9357SAndroid Build Coastguard Worker else
2684*f6dc9357SAndroid Build Coastguard Worker db->GetPath(fi, name);
2685*f6dc9357SAndroid Build Coastguard Worker
2686*f6dc9357SAndroid Build Coastguard Worker /*
2687*f6dc9357SAndroid Build Coastguard Worker file.Parent = ui.ParentFolderIndex;
2688*f6dc9357SAndroid Build Coastguard Worker if (ui.TreeFolderIndex >= 0)
2689*f6dc9357SAndroid Build Coastguard Worker treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size();
2690*f6dc9357SAndroid Build Coastguard Worker if (totalSecureDataSize != 0)
2691*f6dc9357SAndroid Build Coastguard Worker newDatabase.SecureIDs.Add(ui.SecureIndex);
2692*f6dc9357SAndroid Build Coastguard Worker */
2693*f6dc9357SAndroid Build Coastguard Worker newDatabase.AddFile(file, file2, name);
2694*f6dc9357SAndroid Build Coastguard Worker }
2695*f6dc9357SAndroid Build Coastguard Worker }
2696*f6dc9357SAndroid Build Coastguard Worker }
2697*f6dc9357SAndroid Build Coastguard Worker }
2698*f6dc9357SAndroid Build Coastguard Worker
2699*f6dc9357SAndroid Build Coastguard Worker
2700*f6dc9357SAndroid Build Coastguard Worker // ---------- Compress files to new solid blocks ----------
2701*f6dc9357SAndroid Build Coastguard Worker
2702*f6dc9357SAndroid Build Coastguard Worker const unsigned numFiles = group.Indices.Size();
2703*f6dc9357SAndroid Build Coastguard Worker if (numFiles == 0)
2704*f6dc9357SAndroid Build Coastguard Worker continue;
2705*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CRefItem> refItems;
2706*f6dc9357SAndroid Build Coastguard Worker refItems.ClearAndSetSize(numFiles);
2707*f6dc9357SAndroid Build Coastguard Worker // bool sortByType = (options.UseTypeSorting && isSoid); // numSolidFiles > 1
2708*f6dc9357SAndroid Build Coastguard Worker const bool sortByType = options.UseTypeSorting;
2709*f6dc9357SAndroid Build Coastguard Worker
2710*f6dc9357SAndroid Build Coastguard Worker unsigned i;
2711*f6dc9357SAndroid Build Coastguard Worker
2712*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numFiles; i++)
2713*f6dc9357SAndroid Build Coastguard Worker refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType);
2714*f6dc9357SAndroid Build Coastguard Worker
2715*f6dc9357SAndroid Build Coastguard Worker CSortParam sortParam;
2716*f6dc9357SAndroid Build Coastguard Worker // sortParam.TreeFolders = &treeFolders;
2717*f6dc9357SAndroid Build Coastguard Worker sortParam.SortByType = sortByType;
2718*f6dc9357SAndroid Build Coastguard Worker refItems.Sort(CompareUpdateItems, (void *)&sortParam);
2719*f6dc9357SAndroid Build Coastguard Worker
2720*f6dc9357SAndroid Build Coastguard Worker CObjArray<UInt32> indices(numFiles);
2721*f6dc9357SAndroid Build Coastguard Worker
2722*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numFiles; i++)
2723*f6dc9357SAndroid Build Coastguard Worker {
2724*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = refItems[i].Index;
2725*f6dc9357SAndroid Build Coastguard Worker indices[i] = index;
2726*f6dc9357SAndroid Build Coastguard Worker /*
2727*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[index];
2728*f6dc9357SAndroid Build Coastguard Worker CFileItem file;
2729*f6dc9357SAndroid Build Coastguard Worker if (ui.NewProps)
2730*f6dc9357SAndroid Build Coastguard Worker UpdateItem_To_FileItem(ui, file);
2731*f6dc9357SAndroid Build Coastguard Worker else
2732*f6dc9357SAndroid Build Coastguard Worker file = db.Files[ui.IndexInArchive];
2733*f6dc9357SAndroid Build Coastguard Worker if (file.IsAnti || file.IsDir)
2734*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2735*f6dc9357SAndroid Build Coastguard Worker newDatabase.Files.Add(file);
2736*f6dc9357SAndroid Build Coastguard Worker */
2737*f6dc9357SAndroid Build Coastguard Worker }
2738*f6dc9357SAndroid Build Coastguard Worker
2739*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numFiles;)
2740*f6dc9357SAndroid Build Coastguard Worker {
2741*f6dc9357SAndroid Build Coastguard Worker UInt64 totalSize = 0;
2742*f6dc9357SAndroid Build Coastguard Worker unsigned numSubFiles;
2743*f6dc9357SAndroid Build Coastguard Worker
2744*f6dc9357SAndroid Build Coastguard Worker const wchar_t *prevExtension = NULL;
2745*f6dc9357SAndroid Build Coastguard Worker
2746*f6dc9357SAndroid Build Coastguard Worker for (numSubFiles = 0; i + numSubFiles < numFiles && numSubFiles < numSolidFiles; numSubFiles++)
2747*f6dc9357SAndroid Build Coastguard Worker {
2748*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[indices[i + numSubFiles]];
2749*f6dc9357SAndroid Build Coastguard Worker totalSize += ui.Size;
2750*f6dc9357SAndroid Build Coastguard Worker if (totalSize > options.NumSolidBytes)
2751*f6dc9357SAndroid Build Coastguard Worker break;
2752*f6dc9357SAndroid Build Coastguard Worker if (options.SolidExtension)
2753*f6dc9357SAndroid Build Coastguard Worker {
2754*f6dc9357SAndroid Build Coastguard Worker const int slashPos = ui.Name.ReverseFind_PathSepar();
2755*f6dc9357SAndroid Build Coastguard Worker const int dotPos = ui.Name.ReverseFind_Dot();
2756*f6dc9357SAndroid Build Coastguard Worker const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : (unsigned)(dotPos + 1));
2757*f6dc9357SAndroid Build Coastguard Worker if (numSubFiles == 0)
2758*f6dc9357SAndroid Build Coastguard Worker prevExtension = ext;
2759*f6dc9357SAndroid Build Coastguard Worker else if (!StringsAreEqualNoCase(ext, prevExtension))
2760*f6dc9357SAndroid Build Coastguard Worker break;
2761*f6dc9357SAndroid Build Coastguard Worker }
2762*f6dc9357SAndroid Build Coastguard Worker }
2763*f6dc9357SAndroid Build Coastguard Worker
2764*f6dc9357SAndroid Build Coastguard Worker if (numSubFiles < 1)
2765*f6dc9357SAndroid Build Coastguard Worker numSubFiles = 1;
2766*f6dc9357SAndroid Build Coastguard Worker
2767*f6dc9357SAndroid Build Coastguard Worker RINOK(lps->SetCur())
2768*f6dc9357SAndroid Build Coastguard Worker
2769*f6dc9357SAndroid Build Coastguard Worker /*
2770*f6dc9357SAndroid Build Coastguard Worker const unsigned folderIndex = newDatabase.NumUnpackStreamsVector.Size();
2771*f6dc9357SAndroid Build Coastguard Worker
2772*f6dc9357SAndroid Build Coastguard Worker if (opCallback)
2773*f6dc9357SAndroid Build Coastguard Worker {
2774*f6dc9357SAndroid Build Coastguard Worker RINOK(opCallback->ReportOperation(
2775*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex,
2776*f6dc9357SAndroid Build Coastguard Worker NUpdateNotifyOp::kAdd));
2777*f6dc9357SAndroid Build Coastguard Worker }
2778*f6dc9357SAndroid Build Coastguard Worker */
2779*f6dc9357SAndroid Build Coastguard Worker
2780*f6dc9357SAndroid Build Coastguard Worker
2781*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ISequentialInStream, CFolderInStream> inStreamSpec; // solidInStream;
2782*f6dc9357SAndroid Build Coastguard Worker
2783*f6dc9357SAndroid Build Coastguard Worker // inStreamSpec->_reportArcProp = reportArcProp;
2784*f6dc9357SAndroid Build Coastguard Worker
2785*f6dc9357SAndroid Build Coastguard Worker inStreamSpec->Need_CTime = options.Need_CTime;
2786*f6dc9357SAndroid Build Coastguard Worker inStreamSpec->Need_ATime = options.Need_ATime;
2787*f6dc9357SAndroid Build Coastguard Worker inStreamSpec->Need_MTime = options.Need_MTime;
2788*f6dc9357SAndroid Build Coastguard Worker inStreamSpec->Need_Attrib = options.Need_Attrib;
2789*f6dc9357SAndroid Build Coastguard Worker // inStreamSpec->Need_Crc = options.Need_Crc;
2790*f6dc9357SAndroid Build Coastguard Worker
2791*f6dc9357SAndroid Build Coastguard Worker inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
2792*f6dc9357SAndroid Build Coastguard Worker
2793*f6dc9357SAndroid Build Coastguard Worker unsigned startPackIndex = newDatabase.PackSizes.Size();
2794*f6dc9357SAndroid Build Coastguard Worker // UInt64 curFolderUnpackSize = totalSize;
2795*f6dc9357SAndroid Build Coastguard Worker // curFolderUnpackSize = (UInt64)(Int64)-1; // for debug
2796*f6dc9357SAndroid Build Coastguard Worker const UInt64 expectedDataSize = totalSize;
2797*f6dc9357SAndroid Build Coastguard Worker
2798*f6dc9357SAndroid Build Coastguard Worker // const unsigned folderIndex_New = newDatabase.Folders.Size();
2799*f6dc9357SAndroid Build Coastguard Worker
2800*f6dc9357SAndroid Build Coastguard Worker RINOK(encoder.Encode1(
2801*f6dc9357SAndroid Build Coastguard Worker EXTERNAL_CODECS_LOC_VARS
2802*f6dc9357SAndroid Build Coastguard Worker inStreamSpec,
2803*f6dc9357SAndroid Build Coastguard Worker // NULL,
2804*f6dc9357SAndroid Build Coastguard Worker &inSizeForReduce,
2805*f6dc9357SAndroid Build Coastguard Worker expectedDataSize, // expected size
2806*f6dc9357SAndroid Build Coastguard Worker newDatabase.Folders.AddNew(),
2807*f6dc9357SAndroid Build Coastguard Worker // newDatabase.CoderUnpackSizes, curFolderUnpackSize,
2808*f6dc9357SAndroid Build Coastguard Worker archive.SeqStream, newDatabase.PackSizes, lps))
2809*f6dc9357SAndroid Build Coastguard Worker
2810*f6dc9357SAndroid Build Coastguard Worker if (!inStreamSpec->WasFinished())
2811*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2812*f6dc9357SAndroid Build Coastguard Worker
2813*f6dc9357SAndroid Build Coastguard Worker /*
2814*f6dc9357SAndroid Build Coastguard Worker if (inStreamSpec->Need_FolderCrc)
2815*f6dc9357SAndroid Build Coastguard Worker newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New,
2816*f6dc9357SAndroid Build Coastguard Worker true, inStreamSpec->GetFolderCrc());
2817*f6dc9357SAndroid Build Coastguard Worker */
2818*f6dc9357SAndroid Build Coastguard Worker
2819*f6dc9357SAndroid Build Coastguard Worker const UInt64 curFolderUnpackSize = inStreamSpec->Get_TotalSize_for_Coder();
2820*f6dc9357SAndroid Build Coastguard Worker encoder.Encode_Post(curFolderUnpackSize, newDatabase.CoderUnpackSizes);
2821*f6dc9357SAndroid Build Coastguard Worker
2822*f6dc9357SAndroid Build Coastguard Worker UInt64 packSize = 0;
2823*f6dc9357SAndroid Build Coastguard Worker // const UInt32 numStreams = newDatabase.PackSizes.Size() - startPackIndex;
2824*f6dc9357SAndroid Build Coastguard Worker for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
2825*f6dc9357SAndroid Build Coastguard Worker packSize += newDatabase.PackSizes[startPackIndex];
2826*f6dc9357SAndroid Build Coastguard Worker lps->OutSize += packSize;
2827*f6dc9357SAndroid Build Coastguard Worker
2828*f6dc9357SAndroid Build Coastguard Worker // for ()
2829*f6dc9357SAndroid Build Coastguard Worker // newDatabase.PackCRCsDefined.Add(false);
2830*f6dc9357SAndroid Build Coastguard Worker // newDatabase.PackCRCs.Add(0);
2831*f6dc9357SAndroid Build Coastguard Worker
2832*f6dc9357SAndroid Build Coastguard Worker CNum numUnpackStreams = 0;
2833*f6dc9357SAndroid Build Coastguard Worker UInt64 skippedSize = 0;
2834*f6dc9357SAndroid Build Coastguard Worker UInt64 procSize = 0;
2835*f6dc9357SAndroid Build Coastguard Worker // unsigned numProcessedFiles = 0;
2836*f6dc9357SAndroid Build Coastguard Worker
2837*f6dc9357SAndroid Build Coastguard Worker for (unsigned subIndex = 0; subIndex < numSubFiles; subIndex++)
2838*f6dc9357SAndroid Build Coastguard Worker {
2839*f6dc9357SAndroid Build Coastguard Worker const CUpdateItem &ui = updateItems[indices[i + subIndex]];
2840*f6dc9357SAndroid Build Coastguard Worker CFileItem file;
2841*f6dc9357SAndroid Build Coastguard Worker CFileItem2 file2;
2842*f6dc9357SAndroid Build Coastguard Worker UString name;
2843*f6dc9357SAndroid Build Coastguard Worker if (ui.NewProps)
2844*f6dc9357SAndroid Build Coastguard Worker {
2845*f6dc9357SAndroid Build Coastguard Worker UpdateItem_To_FileItem(ui, file, file2);
2846*f6dc9357SAndroid Build Coastguard Worker name = ui.Name;
2847*f6dc9357SAndroid Build Coastguard Worker }
2848*f6dc9357SAndroid Build Coastguard Worker else
2849*f6dc9357SAndroid Build Coastguard Worker {
2850*f6dc9357SAndroid Build Coastguard Worker GetFile(*db, (unsigned)ui.IndexInArchive, file, file2);
2851*f6dc9357SAndroid Build Coastguard Worker db->GetPath((unsigned)ui.IndexInArchive, name);
2852*f6dc9357SAndroid Build Coastguard Worker }
2853*f6dc9357SAndroid Build Coastguard Worker if (file2.IsAnti || file.IsDir)
2854*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2855*f6dc9357SAndroid Build Coastguard Worker
2856*f6dc9357SAndroid Build Coastguard Worker /*
2857*f6dc9357SAndroid Build Coastguard Worker CFileItem &file = newDatabase.Files[
2858*f6dc9357SAndroid Build Coastguard Worker startFileIndexInDatabase + i + subIndex];
2859*f6dc9357SAndroid Build Coastguard Worker */
2860*f6dc9357SAndroid Build Coastguard Worker if (!inStreamSpec->Processed[subIndex])
2861*f6dc9357SAndroid Build Coastguard Worker {
2862*f6dc9357SAndroid Build Coastguard Worker // we don't add file here
2863*f6dc9357SAndroid Build Coastguard Worker skippedSize += ui.Size;
2864*f6dc9357SAndroid Build Coastguard Worker continue; // comment it for debug
2865*f6dc9357SAndroid Build Coastguard Worker // name += ".locked"; // for debug
2866*f6dc9357SAndroid Build Coastguard Worker }
2867*f6dc9357SAndroid Build Coastguard Worker
2868*f6dc9357SAndroid Build Coastguard Worker // if (inStreamSpec->Need_Crc)
2869*f6dc9357SAndroid Build Coastguard Worker file.Crc = inStreamSpec->CRCs[subIndex];
2870*f6dc9357SAndroid Build Coastguard Worker file.Size = inStreamSpec->Sizes[subIndex];
2871*f6dc9357SAndroid Build Coastguard Worker
2872*f6dc9357SAndroid Build Coastguard Worker procSize += file.Size;
2873*f6dc9357SAndroid Build Coastguard Worker // if (file.Size >= 0) // for debug: test purposes
2874*f6dc9357SAndroid Build Coastguard Worker if (file.Size != 0)
2875*f6dc9357SAndroid Build Coastguard Worker {
2876*f6dc9357SAndroid Build Coastguard Worker file.CrcDefined = true; // inStreamSpec->Need_Crc;
2877*f6dc9357SAndroid Build Coastguard Worker file.HasStream = true;
2878*f6dc9357SAndroid Build Coastguard Worker numUnpackStreams++;
2879*f6dc9357SAndroid Build Coastguard Worker }
2880*f6dc9357SAndroid Build Coastguard Worker else
2881*f6dc9357SAndroid Build Coastguard Worker {
2882*f6dc9357SAndroid Build Coastguard Worker file.CrcDefined = false;
2883*f6dc9357SAndroid Build Coastguard Worker file.HasStream = false;
2884*f6dc9357SAndroid Build Coastguard Worker }
2885*f6dc9357SAndroid Build Coastguard Worker
2886*f6dc9357SAndroid Build Coastguard Worker if (inStreamSpec->TimesDefined[subIndex])
2887*f6dc9357SAndroid Build Coastguard Worker {
2888*f6dc9357SAndroid Build Coastguard Worker if (inStreamSpec->Need_CTime)
2889*f6dc9357SAndroid Build Coastguard Worker { file2.CTimeDefined = true; file2.CTime = inStreamSpec->CTimes[subIndex]; }
2890*f6dc9357SAndroid Build Coastguard Worker if (inStreamSpec->Need_ATime
2891*f6dc9357SAndroid Build Coastguard Worker // && !ui.ATime_WasReadByAnalysis
2892*f6dc9357SAndroid Build Coastguard Worker )
2893*f6dc9357SAndroid Build Coastguard Worker { file2.ATimeDefined = true; file2.ATime = inStreamSpec->ATimes[subIndex]; }
2894*f6dc9357SAndroid Build Coastguard Worker if (inStreamSpec->Need_MTime)
2895*f6dc9357SAndroid Build Coastguard Worker { file2.MTimeDefined = true; file2.MTime = inStreamSpec->MTimes[subIndex]; }
2896*f6dc9357SAndroid Build Coastguard Worker if (inStreamSpec->Need_Attrib)
2897*f6dc9357SAndroid Build Coastguard Worker {
2898*f6dc9357SAndroid Build Coastguard Worker file2.AttribDefined = true;
2899*f6dc9357SAndroid Build Coastguard Worker file2.Attrib = inStreamSpec->Attribs[subIndex];
2900*f6dc9357SAndroid Build Coastguard Worker }
2901*f6dc9357SAndroid Build Coastguard Worker }
2902*f6dc9357SAndroid Build Coastguard Worker
2903*f6dc9357SAndroid Build Coastguard Worker /*
2904*f6dc9357SAndroid Build Coastguard Worker file.Parent = ui.ParentFolderIndex;
2905*f6dc9357SAndroid Build Coastguard Worker if (ui.TreeFolderIndex >= 0)
2906*f6dc9357SAndroid Build Coastguard Worker treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size();
2907*f6dc9357SAndroid Build Coastguard Worker if (totalSecureDataSize != 0)
2908*f6dc9357SAndroid Build Coastguard Worker newDatabase.SecureIDs.Add(ui.SecureIndex);
2909*f6dc9357SAndroid Build Coastguard Worker */
2910*f6dc9357SAndroid Build Coastguard Worker /*
2911*f6dc9357SAndroid Build Coastguard Worker if (reportArcProp)
2912*f6dc9357SAndroid Build Coastguard Worker {
2913*f6dc9357SAndroid Build Coastguard Worker RINOK(ReportItemProps(reportArcProp, ui.IndexInClient, file.Size,
2914*f6dc9357SAndroid Build Coastguard Worker file.CrcDefined ? &file.Crc : NULL))
2915*f6dc9357SAndroid Build Coastguard Worker }
2916*f6dc9357SAndroid Build Coastguard Worker */
2917*f6dc9357SAndroid Build Coastguard Worker
2918*f6dc9357SAndroid Build Coastguard Worker // numProcessedFiles++;
2919*f6dc9357SAndroid Build Coastguard Worker newDatabase.AddFile(file, file2, name);
2920*f6dc9357SAndroid Build Coastguard Worker }
2921*f6dc9357SAndroid Build Coastguard Worker
2922*f6dc9357SAndroid Build Coastguard Worker /*
2923*f6dc9357SAndroid Build Coastguard Worker // for debug:
2924*f6dc9357SAndroid Build Coastguard Worker // we can write crc to folders area, if folder contains only one file
2925*f6dc9357SAndroid Build Coastguard Worker if (numUnpackStreams == 1 && numSubFiles == 1)
2926*f6dc9357SAndroid Build Coastguard Worker {
2927*f6dc9357SAndroid Build Coastguard Worker const CFileItem &file = newDatabase.Files.Back();
2928*f6dc9357SAndroid Build Coastguard Worker if (file.CrcDefined)
2929*f6dc9357SAndroid Build Coastguard Worker newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, true, file.Crc);
2930*f6dc9357SAndroid Build Coastguard Worker }
2931*f6dc9357SAndroid Build Coastguard Worker */
2932*f6dc9357SAndroid Build Coastguard Worker
2933*f6dc9357SAndroid Build Coastguard Worker /*
2934*f6dc9357SAndroid Build Coastguard Worker // it's optional check to ensure that sizes are correct
2935*f6dc9357SAndroid Build Coastguard Worker if (inStreamSpec->TotalSize_for_Coder != curFolderUnpackSize)
2936*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2937*f6dc9357SAndroid Build Coastguard Worker */
2938*f6dc9357SAndroid Build Coastguard Worker // if (inStreamSpec->AlignLog == 0)
2939*f6dc9357SAndroid Build Coastguard Worker {
2940*f6dc9357SAndroid Build Coastguard Worker if (procSize != curFolderUnpackSize)
2941*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
2942*f6dc9357SAndroid Build Coastguard Worker }
2943*f6dc9357SAndroid Build Coastguard Worker // else
2944*f6dc9357SAndroid Build Coastguard Worker {
2945*f6dc9357SAndroid Build Coastguard Worker /*
2946*f6dc9357SAndroid Build Coastguard Worker {
2947*f6dc9357SAndroid Build Coastguard Worker const CFolder &old = newDatabase.Folders.Back();
2948*f6dc9357SAndroid Build Coastguard Worker CFolder &folder = newDatabase.Folders.AddNew();
2949*f6dc9357SAndroid Build Coastguard Worker {
2950*f6dc9357SAndroid Build Coastguard Worker const unsigned numBonds = old.Bonds.Size();
2951*f6dc9357SAndroid Build Coastguard Worker folder.Bonds.SetSize(numBonds + 1);
2952*f6dc9357SAndroid Build Coastguard Worker for (unsigned k = 0; k < numBonds; k++)
2953*f6dc9357SAndroid Build Coastguard Worker folder.Bonds[k] = old.Bonds[k];
2954*f6dc9357SAndroid Build Coastguard Worker CBond &bond = folder.Bonds[numBonds];
2955*f6dc9357SAndroid Build Coastguard Worker bond.PackIndex = 0;
2956*f6dc9357SAndroid Build Coastguard Worker bond.UnpackIndex = 0;
2957*f6dc9357SAndroid Build Coastguard Worker }
2958*f6dc9357SAndroid Build Coastguard Worker {
2959*f6dc9357SAndroid Build Coastguard Worker const unsigned numCoders = old.Coders.Size();
2960*f6dc9357SAndroid Build Coastguard Worker folder.Coders.SetSize(numCoders + 1);
2961*f6dc9357SAndroid Build Coastguard Worker for (unsigned k = 0; k < numCoders; k++)
2962*f6dc9357SAndroid Build Coastguard Worker folder.Coders[k] = old.Coders[k];
2963*f6dc9357SAndroid Build Coastguard Worker CCoderInfo &cod = folder.Coders[numCoders];
2964*f6dc9357SAndroid Build Coastguard Worker cod.Props.Alloc(1);
2965*f6dc9357SAndroid Build Coastguard Worker cod.Props[0] = (Byte)inStreamSpec->AlignLog;
2966*f6dc9357SAndroid Build Coastguard Worker cod.NumStreams = 1;
2967*f6dc9357SAndroid Build Coastguard Worker }
2968*f6dc9357SAndroid Build Coastguard Worker {
2969*f6dc9357SAndroid Build Coastguard Worker const unsigned numPackStreams = old.Coders.Size();
2970*f6dc9357SAndroid Build Coastguard Worker folder.Coders.SetSize(numPackStreams);
2971*f6dc9357SAndroid Build Coastguard Worker for (unsigned k = 0; k < numPackStreams; k++)
2972*f6dc9357SAndroid Build Coastguard Worker folder.PackStreams[k] = old.PackStreams[k];
2973*f6dc9357SAndroid Build Coastguard Worker }
2974*f6dc9357SAndroid Build Coastguard Worker }
2975*f6dc9357SAndroid Build Coastguard Worker newDatabase.Folders.Delete(newDatabase.Folders.Size() - 2);
2976*f6dc9357SAndroid Build Coastguard Worker */
2977*f6dc9357SAndroid Build Coastguard Worker }
2978*f6dc9357SAndroid Build Coastguard Worker
2979*f6dc9357SAndroid Build Coastguard Worker
2980*f6dc9357SAndroid Build Coastguard Worker lps->InSize += procSize;
2981*f6dc9357SAndroid Build Coastguard Worker // lps->InSize += curFolderUnpackSize;
2982*f6dc9357SAndroid Build Coastguard Worker
2983*f6dc9357SAndroid Build Coastguard Worker // numUnpackStreams = 0 is very bad case for locked files
2984*f6dc9357SAndroid Build Coastguard Worker // v3.13 doesn't understand it.
2985*f6dc9357SAndroid Build Coastguard Worker newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
2986*f6dc9357SAndroid Build Coastguard Worker i += numSubFiles;
2987*f6dc9357SAndroid Build Coastguard Worker
2988*f6dc9357SAndroid Build Coastguard Worker if (skippedSize != 0 && complexity >= skippedSize)
2989*f6dc9357SAndroid Build Coastguard Worker {
2990*f6dc9357SAndroid Build Coastguard Worker complexity -= skippedSize;
2991*f6dc9357SAndroid Build Coastguard Worker RINOK(updateCallback->SetTotal(complexity))
2992*f6dc9357SAndroid Build Coastguard Worker }
2993*f6dc9357SAndroid Build Coastguard Worker
2994*f6dc9357SAndroid Build Coastguard Worker /*
2995*f6dc9357SAndroid Build Coastguard Worker if (reportArcProp)
2996*f6dc9357SAndroid Build Coastguard Worker {
2997*f6dc9357SAndroid Build Coastguard Worker PROPVARIANT prop;
2998*f6dc9357SAndroid Build Coastguard Worker prop.vt = VT_EMPTY;
2999*f6dc9357SAndroid Build Coastguard Worker prop.wReserved1 = 0;
3000*f6dc9357SAndroid Build Coastguard Worker {
3001*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::PropVarEm_Set_UInt32(&prop, numProcessedFiles);
3002*f6dc9357SAndroid Build Coastguard Worker RINOK(reportArcProp->ReportProp(
3003*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidNumSubFiles, &prop));
3004*f6dc9357SAndroid Build Coastguard Worker }
3005*f6dc9357SAndroid Build Coastguard Worker {
3006*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::PropVarEm_Set_UInt64(&prop, curFolderUnpackSize);
3007*f6dc9357SAndroid Build Coastguard Worker RINOK(reportArcProp->ReportProp(
3008*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidSize, &prop));
3009*f6dc9357SAndroid Build Coastguard Worker }
3010*f6dc9357SAndroid Build Coastguard Worker {
3011*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::PropVarEm_Set_UInt64(&prop, packSize);
3012*f6dc9357SAndroid Build Coastguard Worker RINOK(reportArcProp->ReportProp(
3013*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidPackSize, &prop));
3014*f6dc9357SAndroid Build Coastguard Worker }
3015*f6dc9357SAndroid Build Coastguard Worker {
3016*f6dc9357SAndroid Build Coastguard Worker NWindows::NCOM::PropVarEm_Set_UInt32(&prop, numStreams);
3017*f6dc9357SAndroid Build Coastguard Worker RINOK(reportArcProp->ReportProp(
3018*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidNumStreams, &prop));
3019*f6dc9357SAndroid Build Coastguard Worker }
3020*f6dc9357SAndroid Build Coastguard Worker RINOK(reportArcProp->ReportFinished(NEventIndexType::kBlockIndex, (UInt32)folderIndex, NUpdate::NOperationResult::kOK));
3021*f6dc9357SAndroid Build Coastguard Worker }
3022*f6dc9357SAndroid Build Coastguard Worker */
3023*f6dc9357SAndroid Build Coastguard Worker /*
3024*f6dc9357SAndroid Build Coastguard Worker if (opCallback)
3025*f6dc9357SAndroid Build Coastguard Worker {
3026*f6dc9357SAndroid Build Coastguard Worker RINOK(opCallback->ReportOperation(
3027*f6dc9357SAndroid Build Coastguard Worker NEventIndexType::kBlockIndex, (UInt32)folderIndex,
3028*f6dc9357SAndroid Build Coastguard Worker NUpdateNotifyOp::kOpFinished));
3029*f6dc9357SAndroid Build Coastguard Worker }
3030*f6dc9357SAndroid Build Coastguard Worker */
3031*f6dc9357SAndroid Build Coastguard Worker }
3032*f6dc9357SAndroid Build Coastguard Worker }
3033*f6dc9357SAndroid Build Coastguard Worker
3034*f6dc9357SAndroid Build Coastguard Worker RINOK(lps->SetCur())
3035*f6dc9357SAndroid Build Coastguard Worker
3036*f6dc9357SAndroid Build Coastguard Worker /*
3037*f6dc9357SAndroid Build Coastguard Worker fileIndexToUpdateIndexMap.ClearAndFree();
3038*f6dc9357SAndroid Build Coastguard Worker groups.ClearAndFree();
3039*f6dc9357SAndroid Build Coastguard Worker */
3040*f6dc9357SAndroid Build Coastguard Worker
3041*f6dc9357SAndroid Build Coastguard Worker /*
3042*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < newDatabase.Files.Size(); i++)
3043*f6dc9357SAndroid Build Coastguard Worker {
3044*f6dc9357SAndroid Build Coastguard Worker CFileItem &file = newDatabase.Files[i];
3045*f6dc9357SAndroid Build Coastguard Worker file.Parent = treeFolderToArcIndex[file.Parent];
3046*f6dc9357SAndroid Build Coastguard Worker }
3047*f6dc9357SAndroid Build Coastguard Worker
3048*f6dc9357SAndroid Build Coastguard Worker if (totalSecureDataSize != 0)
3049*f6dc9357SAndroid Build Coastguard Worker {
3050*f6dc9357SAndroid Build Coastguard Worker newDatabase.SecureBuf.SetCapacity(totalSecureDataSize);
3051*f6dc9357SAndroid Build Coastguard Worker size_t pos = 0;
3052*f6dc9357SAndroid Build Coastguard Worker newDatabase.SecureSizes.Reserve(secureBlocks.Sorted.Size());
3053*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < secureBlocks.Sorted.Size(); i++)
3054*f6dc9357SAndroid Build Coastguard Worker {
3055*f6dc9357SAndroid Build Coastguard Worker const CByteBuffer &buf = secureBlocks.Bufs[secureBlocks.Sorted[i]];
3056*f6dc9357SAndroid Build Coastguard Worker size_t size = buf.GetCapacity();
3057*f6dc9357SAndroid Build Coastguard Worker if (size != 0)
3058*f6dc9357SAndroid Build Coastguard Worker memcpy(newDatabase.SecureBuf + pos, buf, size);
3059*f6dc9357SAndroid Build Coastguard Worker newDatabase.SecureSizes.Add((UInt32)size);
3060*f6dc9357SAndroid Build Coastguard Worker pos += size;
3061*f6dc9357SAndroid Build Coastguard Worker }
3062*f6dc9357SAndroid Build Coastguard Worker }
3063*f6dc9357SAndroid Build Coastguard Worker */
3064*f6dc9357SAndroid Build Coastguard Worker
3065*f6dc9357SAndroid Build Coastguard Worker {
3066*f6dc9357SAndroid Build Coastguard Worker const unsigned numFolders = newDatabase.Folders.Size();
3067*f6dc9357SAndroid Build Coastguard Worker if (newDatabase.NumUnpackStreamsVector.Size() != numFolders
3068*f6dc9357SAndroid Build Coastguard Worker || newDatabase.FolderUnpackCRCs.Defs.Size() > numFolders)
3069*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
3070*f6dc9357SAndroid Build Coastguard Worker newDatabase.FolderUnpackCRCs.if_NonEmpty_FillResidue_with_false(numFolders);
3071*f6dc9357SAndroid Build Coastguard Worker }
3072*f6dc9357SAndroid Build Coastguard Worker
3073*f6dc9357SAndroid Build Coastguard Worker updateItems.ClearAndFree();
3074*f6dc9357SAndroid Build Coastguard Worker newDatabase.ReserveDown();
3075*f6dc9357SAndroid Build Coastguard Worker
3076*f6dc9357SAndroid Build Coastguard Worker if (opCallback)
3077*f6dc9357SAndroid Build Coastguard Worker RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader))
3078*f6dc9357SAndroid Build Coastguard Worker
3079*f6dc9357SAndroid Build Coastguard Worker RINOK(archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS
3080*f6dc9357SAndroid Build Coastguard Worker newDatabase, options.HeaderMethod, options.HeaderOptions))
3081*f6dc9357SAndroid Build Coastguard Worker
3082*f6dc9357SAndroid Build Coastguard Worker if (v_StreamSetRestriction)
3083*f6dc9357SAndroid Build Coastguard Worker RINOK(v_StreamSetRestriction->SetRestriction(0, 0))
3084*f6dc9357SAndroid Build Coastguard Worker
3085*f6dc9357SAndroid Build Coastguard Worker return S_OK;
3086*f6dc9357SAndroid Build Coastguard Worker }
3087*f6dc9357SAndroid Build Coastguard Worker
3088*f6dc9357SAndroid Build Coastguard Worker }}
3089