1*f6dc9357SAndroid Build Coastguard Worker // Archive/UdfIn.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker // #define SHOW_DEBUG_INFO
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
8*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
9*f6dc9357SAndroid Build Coastguard Worker #endif
10*f6dc9357SAndroid Build Coastguard Worker
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/CpuArch.h"
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariantUtils.h"
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/RegisterArc.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker #include "UdfIn.h"
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
21*f6dc9357SAndroid Build Coastguard Worker #define PRF(x) x
22*f6dc9357SAndroid Build Coastguard Worker #else
23*f6dc9357SAndroid Build Coastguard Worker #define PRF(x)
24*f6dc9357SAndroid Build Coastguard Worker #endif
25*f6dc9357SAndroid Build Coastguard Worker
26*f6dc9357SAndroid Build Coastguard Worker #define Get16(p) GetUi16(p)
27*f6dc9357SAndroid Build Coastguard Worker #define Get32(p) GetUi32(p)
28*f6dc9357SAndroid Build Coastguard Worker #define Get64(p) GetUi64(p)
29*f6dc9357SAndroid Build Coastguard Worker
30*f6dc9357SAndroid Build Coastguard Worker #define G16(_offs_, dest) dest = Get16(p + (_offs_))
31*f6dc9357SAndroid Build Coastguard Worker #define G32(_offs_, dest) dest = Get32(p + (_offs_))
32*f6dc9357SAndroid Build Coastguard Worker #define G64(_offs_, dest) dest = Get64(p + (_offs_))
33*f6dc9357SAndroid Build Coastguard Worker
34*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
35*f6dc9357SAndroid Build Coastguard Worker namespace NUdf {
36*f6dc9357SAndroid Build Coastguard Worker
37*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumPartitionsMax = 64;
38*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumLogVolumesMax = 64;
39*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumRecursionLevelsMax = 1 << 10;
40*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumItemsMax = 1 << 27;
41*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumFilesMax = 1 << 28;
42*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumRefsMax = 1 << 28;
43*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kNumExtentsMax = (UInt32)1 << 30;
44*f6dc9357SAndroid Build Coastguard Worker static const UInt64 kFileNameLengthTotalMax = (UInt64)1 << 33;
45*f6dc9357SAndroid Build Coastguard Worker static const UInt64 kInlineExtentsSizeMax = (UInt64)1 << 33;
46*f6dc9357SAndroid Build Coastguard Worker
47*f6dc9357SAndroid Build Coastguard Worker #define CRC16_INIT_VAL 0
48*f6dc9357SAndroid Build Coastguard Worker #define CRC16_UPDATE_BYTE(crc, b) ((UInt16)(g_Crc16Table[(((crc) >> 8) ^ (b)) & 0xFF] ^ ((crc) << 8)))
49*f6dc9357SAndroid Build Coastguard Worker
50*f6dc9357SAndroid Build Coastguard Worker #define kCrc16Poly 0x1021
51*f6dc9357SAndroid Build Coastguard Worker static UInt16 g_Crc16Table[256];
52*f6dc9357SAndroid Build Coastguard Worker
Crc16GenerateTable(void)53*f6dc9357SAndroid Build Coastguard Worker static void Z7_FASTCALL Crc16GenerateTable(void)
54*f6dc9357SAndroid Build Coastguard Worker {
55*f6dc9357SAndroid Build Coastguard Worker UInt32 i;
56*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < 256; i++)
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker UInt32 r = (i << 8);
59*f6dc9357SAndroid Build Coastguard Worker for (unsigned j = 0; j < 8; j++)
60*f6dc9357SAndroid Build Coastguard Worker r = ((r << 1) ^ (kCrc16Poly & ((UInt32)0 - (r >> 15)))) & 0xFFFF;
61*f6dc9357SAndroid Build Coastguard Worker g_Crc16Table[i] = (UInt16)r;
62*f6dc9357SAndroid Build Coastguard Worker }
63*f6dc9357SAndroid Build Coastguard Worker }
64*f6dc9357SAndroid Build Coastguard Worker
Crc16Calc(const void * data,size_t size)65*f6dc9357SAndroid Build Coastguard Worker static UInt32 Z7_FASTCALL Crc16Calc(const void *data, size_t size)
66*f6dc9357SAndroid Build Coastguard Worker {
67*f6dc9357SAndroid Build Coastguard Worker UInt32 v = CRC16_INIT_VAL;
68*f6dc9357SAndroid Build Coastguard Worker const Byte *p = (const Byte *)data;
69*f6dc9357SAndroid Build Coastguard Worker const Byte *pEnd = p + size;
70*f6dc9357SAndroid Build Coastguard Worker for (; p != pEnd; p++)
71*f6dc9357SAndroid Build Coastguard Worker v = CRC16_UPDATE_BYTE(v, *p);
72*f6dc9357SAndroid Build Coastguard Worker return v;
73*f6dc9357SAndroid Build Coastguard Worker }
74*f6dc9357SAndroid Build Coastguard Worker
CCrc16TableInitNArchive::NUdf::CCrc16TableInit75*f6dc9357SAndroid Build Coastguard Worker static struct CCrc16TableInit { CCrc16TableInit() { Crc16GenerateTable(); } } g_Crc16TableInit;
76*f6dc9357SAndroid Build Coastguard Worker
77*f6dc9357SAndroid Build Coastguard Worker
78*f6dc9357SAndroid Build Coastguard Worker // ---------- ECMA Part 1 ----------
79*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p,unsigned size)80*f6dc9357SAndroid Build Coastguard Worker void CDString::Parse(const Byte *p, unsigned size)
81*f6dc9357SAndroid Build Coastguard Worker {
82*f6dc9357SAndroid Build Coastguard Worker Data.CopyFrom(p, size);
83*f6dc9357SAndroid Build Coastguard Worker }
84*f6dc9357SAndroid Build Coastguard Worker
ParseDString(const Byte * data,unsigned size)85*f6dc9357SAndroid Build Coastguard Worker static UString ParseDString(const Byte *data, unsigned size)
86*f6dc9357SAndroid Build Coastguard Worker {
87*f6dc9357SAndroid Build Coastguard Worker UString res;
88*f6dc9357SAndroid Build Coastguard Worker if (size != 0)
89*f6dc9357SAndroid Build Coastguard Worker {
90*f6dc9357SAndroid Build Coastguard Worker wchar_t *p;
91*f6dc9357SAndroid Build Coastguard Worker const Byte type = *data++;
92*f6dc9357SAndroid Build Coastguard Worker size--;
93*f6dc9357SAndroid Build Coastguard Worker if (type == 8)
94*f6dc9357SAndroid Build Coastguard Worker {
95*f6dc9357SAndroid Build Coastguard Worker p = res.GetBuf(size);
96*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
97*f6dc9357SAndroid Build Coastguard Worker {
98*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = data[i];
99*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
100*f6dc9357SAndroid Build Coastguard Worker break;
101*f6dc9357SAndroid Build Coastguard Worker *p++ = c;
102*f6dc9357SAndroid Build Coastguard Worker }
103*f6dc9357SAndroid Build Coastguard Worker }
104*f6dc9357SAndroid Build Coastguard Worker else if (type == 16)
105*f6dc9357SAndroid Build Coastguard Worker {
106*f6dc9357SAndroid Build Coastguard Worker size &= ~(unsigned)1;
107*f6dc9357SAndroid Build Coastguard Worker p = res.GetBuf(size / 2);
108*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i += 2)
109*f6dc9357SAndroid Build Coastguard Worker {
110*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = GetBe16(data + i);
111*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
112*f6dc9357SAndroid Build Coastguard Worker break;
113*f6dc9357SAndroid Build Coastguard Worker *p++ = c;
114*f6dc9357SAndroid Build Coastguard Worker }
115*f6dc9357SAndroid Build Coastguard Worker }
116*f6dc9357SAndroid Build Coastguard Worker else
117*f6dc9357SAndroid Build Coastguard Worker return UString("[unknown]");
118*f6dc9357SAndroid Build Coastguard Worker *p = 0;
119*f6dc9357SAndroid Build Coastguard Worker res.ReleaseBuf_SetLen((unsigned)(p - (const wchar_t *)res));
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker return res;
122*f6dc9357SAndroid Build Coastguard Worker }
123*f6dc9357SAndroid Build Coastguard Worker
GetString() const124*f6dc9357SAndroid Build Coastguard Worker UString CDString32::GetString() const
125*f6dc9357SAndroid Build Coastguard Worker {
126*f6dc9357SAndroid Build Coastguard Worker const unsigned size = Data[sizeof(Data) - 1];
127*f6dc9357SAndroid Build Coastguard Worker return ParseDString(Data, MyMin(size, (unsigned)(sizeof(Data) - 1)));
128*f6dc9357SAndroid Build Coastguard Worker }
129*f6dc9357SAndroid Build Coastguard Worker
GetString() const130*f6dc9357SAndroid Build Coastguard Worker UString CDString128::GetString() const
131*f6dc9357SAndroid Build Coastguard Worker {
132*f6dc9357SAndroid Build Coastguard Worker const unsigned size = Data[sizeof(Data) - 1];
133*f6dc9357SAndroid Build Coastguard Worker return ParseDString(Data, MyMin(size, (unsigned)(sizeof(Data) - 1)));
134*f6dc9357SAndroid Build Coastguard Worker }
135*f6dc9357SAndroid Build Coastguard Worker
GetString() const136*f6dc9357SAndroid Build Coastguard Worker UString CDString::GetString() const { return ParseDString(Data, (unsigned)Data.Size()); }
137*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)138*f6dc9357SAndroid Build Coastguard Worker void CTime::Parse(const Byte *p) { memcpy(Data, p, sizeof(Data)); }
139*f6dc9357SAndroid Build Coastguard Worker
140*f6dc9357SAndroid Build Coastguard Worker
AddCommentChars(UString & dest,const char * s,size_t size)141*f6dc9357SAndroid Build Coastguard Worker static void AddCommentChars(UString &dest, const char *s, size_t size)
142*f6dc9357SAndroid Build Coastguard Worker {
143*f6dc9357SAndroid Build Coastguard Worker for (size_t i = 0; i < size; i++)
144*f6dc9357SAndroid Build Coastguard Worker {
145*f6dc9357SAndroid Build Coastguard Worker char c = s[i];
146*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
147*f6dc9357SAndroid Build Coastguard Worker break;
148*f6dc9357SAndroid Build Coastguard Worker if (c < 0x20)
149*f6dc9357SAndroid Build Coastguard Worker c = '_';
150*f6dc9357SAndroid Build Coastguard Worker dest += (wchar_t)c;
151*f6dc9357SAndroid Build Coastguard Worker }
152*f6dc9357SAndroid Build Coastguard Worker }
153*f6dc9357SAndroid Build Coastguard Worker
154*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)155*f6dc9357SAndroid Build Coastguard Worker void CRegId::Parse(const Byte *p)
156*f6dc9357SAndroid Build Coastguard Worker {
157*f6dc9357SAndroid Build Coastguard Worker Flags = p[0];
158*f6dc9357SAndroid Build Coastguard Worker memcpy(Id, p + 1, sizeof(Id));
159*f6dc9357SAndroid Build Coastguard Worker memcpy(Suffix, p + 24, sizeof(Suffix));
160*f6dc9357SAndroid Build Coastguard Worker }
161*f6dc9357SAndroid Build Coastguard Worker
AddCommentTo(UString & s) const162*f6dc9357SAndroid Build Coastguard Worker void CRegId::AddCommentTo(UString &s) const
163*f6dc9357SAndroid Build Coastguard Worker {
164*f6dc9357SAndroid Build Coastguard Worker AddCommentChars(s, Id, sizeof(Id));
165*f6dc9357SAndroid Build Coastguard Worker }
166*f6dc9357SAndroid Build Coastguard Worker
AddUdfVersionTo(UString & s) const167*f6dc9357SAndroid Build Coastguard Worker void CRegId::AddUdfVersionTo(UString &s) const
168*f6dc9357SAndroid Build Coastguard Worker {
169*f6dc9357SAndroid Build Coastguard Worker // use it only for "Domain Identifier Suffix" and "UDF Identifier Suffix"
170*f6dc9357SAndroid Build Coastguard Worker // UDF 2.1.5.3
171*f6dc9357SAndroid Build Coastguard Worker // Revision in hex (3 digits)
172*f6dc9357SAndroid Build Coastguard Worker const Byte minor = Suffix[0];
173*f6dc9357SAndroid Build Coastguard Worker const Byte major = Suffix[1];
174*f6dc9357SAndroid Build Coastguard Worker if (major != 0 || minor != 0)
175*f6dc9357SAndroid Build Coastguard Worker {
176*f6dc9357SAndroid Build Coastguard Worker char temp[16];
177*f6dc9357SAndroid Build Coastguard Worker ConvertUInt32ToHex(major, temp);
178*f6dc9357SAndroid Build Coastguard Worker s += temp;
179*f6dc9357SAndroid Build Coastguard Worker s.Add_Dot();
180*f6dc9357SAndroid Build Coastguard Worker ConvertUInt32ToHex8Digits(minor, temp);
181*f6dc9357SAndroid Build Coastguard Worker s += &temp[8 - 2];
182*f6dc9357SAndroid Build Coastguard Worker }
183*f6dc9357SAndroid Build Coastguard Worker }
184*f6dc9357SAndroid Build Coastguard Worker
185*f6dc9357SAndroid Build Coastguard Worker
186*f6dc9357SAndroid Build Coastguard Worker // ---------- ECMA Part 3: Volume Structure ----------
187*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)188*f6dc9357SAndroid Build Coastguard Worker void CExtent::Parse(const Byte *p)
189*f6dc9357SAndroid Build Coastguard Worker {
190*f6dc9357SAndroid Build Coastguard Worker /* Len shall be less than < 2^30.
191*f6dc9357SAndroid Build Coastguard Worker Unless otherwise specified, the length shall be an integral multiple of the logical sector size.
192*f6dc9357SAndroid Build Coastguard Worker If (Len == 0), no extent is specified and (Pos) shall contain 0 */
193*f6dc9357SAndroid Build Coastguard Worker G32 (0, Len);
194*f6dc9357SAndroid Build Coastguard Worker G32 (4, Pos);
195*f6dc9357SAndroid Build Coastguard Worker }
196*f6dc9357SAndroid Build Coastguard Worker
197*f6dc9357SAndroid Build Coastguard Worker
198*f6dc9357SAndroid Build Coastguard Worker // ECMA 3/7.2
199*f6dc9357SAndroid Build Coastguard Worker
200*f6dc9357SAndroid Build Coastguard Worker struct CTag
201*f6dc9357SAndroid Build Coastguard Worker {
202*f6dc9357SAndroid Build Coastguard Worker UInt16 Id;
203*f6dc9357SAndroid Build Coastguard Worker // UInt16 Version;
204*f6dc9357SAndroid Build Coastguard Worker // Byte Checksum;
205*f6dc9357SAndroid Build Coastguard Worker // UInt16 SerialNumber;
206*f6dc9357SAndroid Build Coastguard Worker // UInt16 Crc;
207*f6dc9357SAndroid Build Coastguard Worker UInt16 CrcLen;
208*f6dc9357SAndroid Build Coastguard Worker // UInt32 TagLocation; // the number of the logical sector
209*f6dc9357SAndroid Build Coastguard Worker
210*f6dc9357SAndroid Build Coastguard Worker HRESULT Parse(const Byte *p, size_t size);
211*f6dc9357SAndroid Build Coastguard Worker };
212*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p,size_t size)213*f6dc9357SAndroid Build Coastguard Worker HRESULT CTag::Parse(const Byte *p, size_t size)
214*f6dc9357SAndroid Build Coastguard Worker {
215*f6dc9357SAndroid Build Coastguard Worker if (size < 16)
216*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
217*f6dc9357SAndroid Build Coastguard Worker {
218*f6dc9357SAndroid Build Coastguard Worker unsigned sum = 0;
219*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < 16; i++)
220*f6dc9357SAndroid Build Coastguard Worker sum = sum + p[i];
221*f6dc9357SAndroid Build Coastguard Worker if ((Byte)(sum - p[4]) != p[4] || p[5] != 0)
222*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
223*f6dc9357SAndroid Build Coastguard Worker }
224*f6dc9357SAndroid Build Coastguard Worker Id = Get16(p);
225*f6dc9357SAndroid Build Coastguard Worker const UInt16 Version = Get16(p + 2);
226*f6dc9357SAndroid Build Coastguard Worker if (Version != 2 && Version != 3)
227*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
228*f6dc9357SAndroid Build Coastguard Worker // SerialNumber = Get16(p + 6);
229*f6dc9357SAndroid Build Coastguard Worker const UInt32 crc = Get16(p + 8);
230*f6dc9357SAndroid Build Coastguard Worker CrcLen = Get16(p + 10);
231*f6dc9357SAndroid Build Coastguard Worker // TagLocation = Get32(p + 12);
232*f6dc9357SAndroid Build Coastguard Worker
233*f6dc9357SAndroid Build Coastguard Worker if (size >= 16 + (size_t)CrcLen)
234*f6dc9357SAndroid Build Coastguard Worker if (crc == Crc16Calc(p + 16, (size_t)CrcLen))
235*f6dc9357SAndroid Build Coastguard Worker return S_OK;
236*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
237*f6dc9357SAndroid Build Coastguard Worker }
238*f6dc9357SAndroid Build Coastguard Worker
239*f6dc9357SAndroid Build Coastguard Worker // ECMA 3/7.2.1
240*f6dc9357SAndroid Build Coastguard Worker
241*f6dc9357SAndroid Build Coastguard Worker enum EDescriptorType
242*f6dc9357SAndroid Build Coastguard Worker {
243*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_SpoaringTable = 0, // UDF
244*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_PrimVol = 1,
245*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_AnchorVolPtr = 2,
246*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_VolPtr = 3,
247*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_ImplUseVol = 4,
248*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_Partition = 5,
249*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_LogicalVol = 6,
250*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_UnallocSpace = 7,
251*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_Terminating = 8,
252*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_LogicalVolIntegrity = 9,
253*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_FileSet = 256,
254*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_FileId = 257,
255*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_AllocationExtent = 258,
256*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_Indirect = 259,
257*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_Terminal = 260,
258*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_File = 261,
259*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_ExtendedAttrHeader = 262,
260*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_UnallocatedSpaceEntry = 263,
261*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_SpaceBitmap = 264,
262*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_PartitionIntegrity = 265,
263*f6dc9357SAndroid Build Coastguard Worker DESC_TYPE_ExtendedFile = 266
264*f6dc9357SAndroid Build Coastguard Worker };
265*f6dc9357SAndroid Build Coastguard Worker
266*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)267*f6dc9357SAndroid Build Coastguard Worker void CLogBlockAddr::Parse(const Byte *p)
268*f6dc9357SAndroid Build Coastguard Worker {
269*f6dc9357SAndroid Build Coastguard Worker G32 (0, Pos);
270*f6dc9357SAndroid Build Coastguard Worker G16 (4, PartitionRef);
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)273*f6dc9357SAndroid Build Coastguard Worker void CShortAllocDesc::Parse(const Byte *p)
274*f6dc9357SAndroid Build Coastguard Worker {
275*f6dc9357SAndroid Build Coastguard Worker G32 (0, Len);
276*f6dc9357SAndroid Build Coastguard Worker G32 (4, Pos);
277*f6dc9357SAndroid Build Coastguard Worker }
278*f6dc9357SAndroid Build Coastguard Worker
279*f6dc9357SAndroid Build Coastguard Worker /*
280*f6dc9357SAndroid Build Coastguard Worker void CADImpUse::Parse(const Byte *p)
281*f6dc9357SAndroid Build Coastguard Worker {
282*f6dc9357SAndroid Build Coastguard Worker G16 (0, Flags);
283*f6dc9357SAndroid Build Coastguard Worker G32 (2, UdfUniqueId);
284*f6dc9357SAndroid Build Coastguard Worker }
285*f6dc9357SAndroid Build Coastguard Worker */
286*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)287*f6dc9357SAndroid Build Coastguard Worker void CLongAllocDesc::Parse(const Byte *p)
288*f6dc9357SAndroid Build Coastguard Worker {
289*f6dc9357SAndroid Build Coastguard Worker G32 (0, Len);
290*f6dc9357SAndroid Build Coastguard Worker Location.Parse(p + 4);
291*f6dc9357SAndroid Build Coastguard Worker // memcpy(ImplUse, p + 10, sizeof(ImplUse));
292*f6dc9357SAndroid Build Coastguard Worker // adImpUse.Parse(ImplUse);
293*f6dc9357SAndroid Build Coastguard Worker }
294*f6dc9357SAndroid Build Coastguard Worker
295*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)296*f6dc9357SAndroid Build Coastguard Worker void CPrimeVol::Parse(const Byte *p)
297*f6dc9357SAndroid Build Coastguard Worker {
298*f6dc9357SAndroid Build Coastguard Worker // G32 (16, VolumeDescriptorSequenceNumber);
299*f6dc9357SAndroid Build Coastguard Worker G32 (20, PrimaryVolumeDescriptorNumber);
300*f6dc9357SAndroid Build Coastguard Worker VolumeId.Parse(p + 24);
301*f6dc9357SAndroid Build Coastguard Worker G16 (56, VolumeSequenceNumber);
302*f6dc9357SAndroid Build Coastguard Worker G16 (58, MaximumVolumeSequenceNumber);
303*f6dc9357SAndroid Build Coastguard Worker // G16 (60, InterchangeLevel);
304*f6dc9357SAndroid Build Coastguard Worker // G16 (62, MaximumInterchangeLevel);
305*f6dc9357SAndroid Build Coastguard Worker // G32 (64, CharacterSetList)
306*f6dc9357SAndroid Build Coastguard Worker // G32 (68, MaximumCharacterSetList)
307*f6dc9357SAndroid Build Coastguard Worker VolumeSetId.Parse(p + 72);
308*f6dc9357SAndroid Build Coastguard Worker // 200 64 Descriptor Character Set charspec (1/7.2.1)
309*f6dc9357SAndroid Build Coastguard Worker // 264 64 Explanatory Character Set charspec (1/7.2.1)
310*f6dc9357SAndroid Build Coastguard Worker // VolumeAbstract.Parse(p + 328);
311*f6dc9357SAndroid Build Coastguard Worker // VolumeCopyrightNotice.Parse(p + 336);
312*f6dc9357SAndroid Build Coastguard Worker ApplicationId.Parse(p + 344);
313*f6dc9357SAndroid Build Coastguard Worker RecordingTime.Parse(p + 376);
314*f6dc9357SAndroid Build Coastguard Worker ImplId.Parse(p + 388);
315*f6dc9357SAndroid Build Coastguard Worker // 420 64 Implementation Use bytes
316*f6dc9357SAndroid Build Coastguard Worker // G32 (484, PredecessorVolumeDescriptorSequenceLocation);
317*f6dc9357SAndroid Build Coastguard Worker // G16 (488, Flags);
318*f6dc9357SAndroid Build Coastguard Worker }
319*f6dc9357SAndroid Build Coastguard Worker
320*f6dc9357SAndroid Build Coastguard Worker
321*f6dc9357SAndroid Build Coastguard Worker
CheckExtent(unsigned volIndex,unsigned partitionRef,UInt32 blockPos,UInt32 len) const322*f6dc9357SAndroid Build Coastguard Worker bool CInArchive::CheckExtent(unsigned volIndex, unsigned partitionRef, UInt32 blockPos, UInt32 len) const
323*f6dc9357SAndroid Build Coastguard Worker {
324*f6dc9357SAndroid Build Coastguard Worker const CLogVol &vol = LogVols[volIndex];
325*f6dc9357SAndroid Build Coastguard Worker if (partitionRef >= vol.PartitionMaps.Size())
326*f6dc9357SAndroid Build Coastguard Worker return false;
327*f6dc9357SAndroid Build Coastguard Worker const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex];
328*f6dc9357SAndroid Build Coastguard Worker return ((UInt64)blockPos * vol.BlockSize + len) <= ((UInt64)partition.Len << SecLogSize);
329*f6dc9357SAndroid Build Coastguard Worker }
330*f6dc9357SAndroid Build Coastguard Worker
CheckItemExtents(unsigned volIndex,const CItem & item) const331*f6dc9357SAndroid Build Coastguard Worker bool CInArchive::CheckItemExtents(unsigned volIndex, const CItem &item) const
332*f6dc9357SAndroid Build Coastguard Worker {
333*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, item.Extents)
334*f6dc9357SAndroid Build Coastguard Worker {
335*f6dc9357SAndroid Build Coastguard Worker const CMyExtent &e = item.Extents[i];
336*f6dc9357SAndroid Build Coastguard Worker if (!CheckExtent(volIndex, e.PartitionRef, e.Pos, e.GetLen()))
337*f6dc9357SAndroid Build Coastguard Worker return false;
338*f6dc9357SAndroid Build Coastguard Worker }
339*f6dc9357SAndroid Build Coastguard Worker return true;
340*f6dc9357SAndroid Build Coastguard Worker }
341*f6dc9357SAndroid Build Coastguard Worker
Read(unsigned volIndex,unsigned partitionRef,UInt32 blockPos,UInt32 len,Byte * buf)342*f6dc9357SAndroid Build Coastguard Worker HRESULT CInArchive::Read(unsigned volIndex, unsigned partitionRef, UInt32 blockPos, UInt32 len, Byte *buf)
343*f6dc9357SAndroid Build Coastguard Worker {
344*f6dc9357SAndroid Build Coastguard Worker if (!CheckExtent(volIndex, partitionRef, blockPos, len))
345*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
346*f6dc9357SAndroid Build Coastguard Worker const CLogVol &vol = LogVols[volIndex];
347*f6dc9357SAndroid Build Coastguard Worker const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex];
348*f6dc9357SAndroid Build Coastguard Worker UInt64 offset = ((UInt64)partition.Pos << SecLogSize) + (UInt64)blockPos * vol.BlockSize;
349*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_stream, offset))
350*f6dc9357SAndroid Build Coastguard Worker offset += len;
351*f6dc9357SAndroid Build Coastguard Worker UpdatePhySize(offset);
352*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = ReadStream_FALSE(_stream, buf, len);
353*f6dc9357SAndroid Build Coastguard Worker if (res == S_FALSE && offset > FileSize)
354*f6dc9357SAndroid Build Coastguard Worker UnexpectedEnd = true;
355*f6dc9357SAndroid Build Coastguard Worker return res;
356*f6dc9357SAndroid Build Coastguard Worker }
357*f6dc9357SAndroid Build Coastguard Worker
ReadLad(unsigned volIndex,const CLongAllocDesc & lad,Byte * buf)358*f6dc9357SAndroid Build Coastguard Worker HRESULT CInArchive::ReadLad(unsigned volIndex, const CLongAllocDesc &lad, Byte *buf)
359*f6dc9357SAndroid Build Coastguard Worker {
360*f6dc9357SAndroid Build Coastguard Worker return Read(volIndex, lad.Location.PartitionRef, lad.Location.Pos, lad.GetLen(), (Byte *)buf);
361*f6dc9357SAndroid Build Coastguard Worker }
362*f6dc9357SAndroid Build Coastguard Worker
ReadFromFile(unsigned volIndex,const CItem & item,CByteBuffer & buf)363*f6dc9357SAndroid Build Coastguard Worker HRESULT CInArchive::ReadFromFile(unsigned volIndex, const CItem &item, CByteBuffer &buf)
364*f6dc9357SAndroid Build Coastguard Worker {
365*f6dc9357SAndroid Build Coastguard Worker if (item.Size >= (UInt32)1 << 30)
366*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
367*f6dc9357SAndroid Build Coastguard Worker if (item.IsInline)
368*f6dc9357SAndroid Build Coastguard Worker {
369*f6dc9357SAndroid Build Coastguard Worker buf = item.InlineData;
370*f6dc9357SAndroid Build Coastguard Worker return S_OK;
371*f6dc9357SAndroid Build Coastguard Worker }
372*f6dc9357SAndroid Build Coastguard Worker buf.Alloc((size_t)item.Size);
373*f6dc9357SAndroid Build Coastguard Worker size_t pos = 0;
374*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, item.Extents)
375*f6dc9357SAndroid Build Coastguard Worker {
376*f6dc9357SAndroid Build Coastguard Worker const CMyExtent &e = item.Extents[i];
377*f6dc9357SAndroid Build Coastguard Worker const UInt32 len = e.GetLen();
378*f6dc9357SAndroid Build Coastguard Worker RINOK(Read(volIndex, e.PartitionRef, e.Pos, len, (Byte *)buf + pos))
379*f6dc9357SAndroid Build Coastguard Worker pos += len;
380*f6dc9357SAndroid Build Coastguard Worker }
381*f6dc9357SAndroid Build Coastguard Worker return S_OK;
382*f6dc9357SAndroid Build Coastguard Worker }
383*f6dc9357SAndroid Build Coastguard Worker
384*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)385*f6dc9357SAndroid Build Coastguard Worker void CIcbTag::Parse(const Byte *p)
386*f6dc9357SAndroid Build Coastguard Worker {
387*f6dc9357SAndroid Build Coastguard Worker // G32 (0, PriorDirectNum);
388*f6dc9357SAndroid Build Coastguard Worker // G16 (4, StrategyType);
389*f6dc9357SAndroid Build Coastguard Worker // G16 (6, StrategyParam);
390*f6dc9357SAndroid Build Coastguard Worker // G16 (8, MaxNumOfEntries);
391*f6dc9357SAndroid Build Coastguard Worker FileType = p[11];
392*f6dc9357SAndroid Build Coastguard Worker // ParentIcb.Parse(p + 12);
393*f6dc9357SAndroid Build Coastguard Worker G16 (18, Flags);
394*f6dc9357SAndroid Build Coastguard Worker }
395*f6dc9357SAndroid Build Coastguard Worker
396*f6dc9357SAndroid Build Coastguard Worker
397*f6dc9357SAndroid Build Coastguard Worker // ECMA 4/14.9 File Entry
398*f6dc9357SAndroid Build Coastguard Worker // UDF FileEntry 2.3.6
399*f6dc9357SAndroid Build Coastguard Worker
400*f6dc9357SAndroid Build Coastguard Worker // ECMA 4/14.17 Extended File Entry
401*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)402*f6dc9357SAndroid Build Coastguard Worker void CItem::Parse(const Byte *p)
403*f6dc9357SAndroid Build Coastguard Worker {
404*f6dc9357SAndroid Build Coastguard Worker // (-1) can be stored in Uid/Gid.
405*f6dc9357SAndroid Build Coastguard Worker // G32 (36, Uid);
406*f6dc9357SAndroid Build Coastguard Worker // G32 (40, Gid);
407*f6dc9357SAndroid Build Coastguard Worker // G32 (44, Permissions);
408*f6dc9357SAndroid Build Coastguard Worker G16 (48, FileLinkCount);
409*f6dc9357SAndroid Build Coastguard Worker // RecordFormat = p[50];
410*f6dc9357SAndroid Build Coastguard Worker // RecordDisplayAttr = p[51];
411*f6dc9357SAndroid Build Coastguard Worker // G32 (52, RecordLen);
412*f6dc9357SAndroid Build Coastguard Worker G64 (56, Size);
413*f6dc9357SAndroid Build Coastguard Worker if (IsExtended)
414*f6dc9357SAndroid Build Coastguard Worker {
415*f6dc9357SAndroid Build Coastguard Worker // The sum of all Information Length fields for all streams of a file (including the default stream). If this file has no
416*f6dc9357SAndroid Build Coastguard Worker // streams, the Object Size shall be equal to the Information Length.
417*f6dc9357SAndroid Build Coastguard Worker // G64 (64, ObjectSize);
418*f6dc9357SAndroid Build Coastguard Worker p += 8;
419*f6dc9357SAndroid Build Coastguard Worker }
420*f6dc9357SAndroid Build Coastguard Worker G64 (64, NumLogBlockRecorded);
421*f6dc9357SAndroid Build Coastguard Worker ATime.Parse(p + 72);
422*f6dc9357SAndroid Build Coastguard Worker MTime.Parse(p + 84);
423*f6dc9357SAndroid Build Coastguard Worker if (IsExtended)
424*f6dc9357SAndroid Build Coastguard Worker {
425*f6dc9357SAndroid Build Coastguard Worker CreateTime.Parse(p + 96);
426*f6dc9357SAndroid Build Coastguard Worker p += 12;
427*f6dc9357SAndroid Build Coastguard Worker }
428*f6dc9357SAndroid Build Coastguard Worker AttribTime.Parse(p + 96);
429*f6dc9357SAndroid Build Coastguard Worker // G32 (108, CheckPoint);
430*f6dc9357SAndroid Build Coastguard Worker /*
431*f6dc9357SAndroid Build Coastguard Worker if (IsExtended)
432*f6dc9357SAndroid Build Coastguard Worker {
433*f6dc9357SAndroid Build Coastguard Worker // Get32(p + 112); // reserved
434*f6dc9357SAndroid Build Coastguard Worker p += 4;
435*f6dc9357SAndroid Build Coastguard Worker }
436*f6dc9357SAndroid Build Coastguard Worker // ExtendedAttrIcb.Parse(p + 112);
437*f6dc9357SAndroid Build Coastguard Worker if (IsExtended)
438*f6dc9357SAndroid Build Coastguard Worker {
439*f6dc9357SAndroid Build Coastguard Worker StreamDirectoryIcb.Parse(p + 128);
440*f6dc9357SAndroid Build Coastguard Worker p += 16;
441*f6dc9357SAndroid Build Coastguard Worker }
442*f6dc9357SAndroid Build Coastguard Worker */
443*f6dc9357SAndroid Build Coastguard Worker
444*f6dc9357SAndroid Build Coastguard Worker // ImplId.Parse(p + 128);
445*f6dc9357SAndroid Build Coastguard Worker // G64 (160, UniqueId);
446*f6dc9357SAndroid Build Coastguard Worker }
447*f6dc9357SAndroid Build Coastguard Worker
448*f6dc9357SAndroid Build Coastguard Worker
449*f6dc9357SAndroid Build Coastguard Worker // ECMA 4/14.4
450*f6dc9357SAndroid Build Coastguard Worker // UDF 2.3.4
451*f6dc9357SAndroid Build Coastguard Worker
452*f6dc9357SAndroid Build Coastguard Worker /*
453*f6dc9357SAndroid Build Coastguard Worker File Characteristics:
454*f6dc9357SAndroid Build Coastguard Worker Deleted bit:
455*f6dc9357SAndroid Build Coastguard Worker ECMA: If set to ONE, shall mean this File Identifier Descriptor
456*f6dc9357SAndroid Build Coastguard Worker identifies a file that has been deleted;
457*f6dc9357SAndroid Build Coastguard Worker UDF: If the space for the file or directory is deallocated,
458*f6dc9357SAndroid Build Coastguard Worker the implementation shall set the ICB field to zero.
459*f6dc9357SAndroid Build Coastguard Worker ECMA 167 4/8.6 requires that the File Identifiers of all FIDs in a directory shall be unique.
460*f6dc9357SAndroid Build Coastguard Worker The implementations shall follow these rules when a Deleted bit is set:
461*f6dc9357SAndroid Build Coastguard Worker rewrire the compression ID of the File Identifier: 8 -> 254, 16 -> 255.
462*f6dc9357SAndroid Build Coastguard Worker */
463*f6dc9357SAndroid Build Coastguard Worker
464*f6dc9357SAndroid Build Coastguard Worker struct CFileId
465*f6dc9357SAndroid Build Coastguard Worker {
466*f6dc9357SAndroid Build Coastguard Worker // UInt16 FileVersion;
467*f6dc9357SAndroid Build Coastguard Worker Byte FileCharacteristics;
468*f6dc9357SAndroid Build Coastguard Worker // CByteBuffer ImplUse;
469*f6dc9357SAndroid Build Coastguard Worker CDString Id;
470*f6dc9357SAndroid Build Coastguard Worker CLongAllocDesc Icb;
471*f6dc9357SAndroid Build Coastguard Worker
IsItLink_DirNArchive::NUdf::CFileId472*f6dc9357SAndroid Build Coastguard Worker bool IsItLink_Dir () const { return (FileCharacteristics & FILEID_CHARACS_Dir) != 0; }
IsItLink_DeletedNArchive::NUdf::CFileId473*f6dc9357SAndroid Build Coastguard Worker bool IsItLink_Deleted() const { return (FileCharacteristics & FILEID_CHARACS_Deleted) != 0; }
IsItLink_ParentNArchive::NUdf::CFileId474*f6dc9357SAndroid Build Coastguard Worker bool IsItLink_Parent () const { return (FileCharacteristics & FILEID_CHARACS_Parent) != 0; }
475*f6dc9357SAndroid Build Coastguard Worker
476*f6dc9357SAndroid Build Coastguard Worker size_t Parse(const Byte *p, size_t size);
477*f6dc9357SAndroid Build Coastguard Worker };
478*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p,size_t size)479*f6dc9357SAndroid Build Coastguard Worker size_t CFileId::Parse(const Byte *p, size_t size)
480*f6dc9357SAndroid Build Coastguard Worker {
481*f6dc9357SAndroid Build Coastguard Worker size_t processed = 0;
482*f6dc9357SAndroid Build Coastguard Worker if (size < 38)
483*f6dc9357SAndroid Build Coastguard Worker return 0;
484*f6dc9357SAndroid Build Coastguard Worker CTag tag;
485*f6dc9357SAndroid Build Coastguard Worker if (tag.Parse(p, size) != S_OK)
486*f6dc9357SAndroid Build Coastguard Worker return 0;
487*f6dc9357SAndroid Build Coastguard Worker if (tag.Id != DESC_TYPE_FileId)
488*f6dc9357SAndroid Build Coastguard Worker return 0;
489*f6dc9357SAndroid Build Coastguard Worker // FileVersion = Get16(p + 16);
490*f6dc9357SAndroid Build Coastguard Worker // UDF: There shall be only one version of a file as specified below with the value being set to 1.
491*f6dc9357SAndroid Build Coastguard Worker
492*f6dc9357SAndroid Build Coastguard Worker FileCharacteristics = p[18];
493*f6dc9357SAndroid Build Coastguard Worker const unsigned idLen = p[19];
494*f6dc9357SAndroid Build Coastguard Worker Icb.Parse(p + 20);
495*f6dc9357SAndroid Build Coastguard Worker const unsigned impLen = Get16(p + 36);
496*f6dc9357SAndroid Build Coastguard Worker if (size < 38 + idLen + impLen)
497*f6dc9357SAndroid Build Coastguard Worker return 0;
498*f6dc9357SAndroid Build Coastguard Worker processed = 38;
499*f6dc9357SAndroid Build Coastguard Worker // ImplUse.CopyFrom(p + processed, impLen);
500*f6dc9357SAndroid Build Coastguard Worker processed += impLen;
501*f6dc9357SAndroid Build Coastguard Worker Id.Parse(p + processed, idLen);
502*f6dc9357SAndroid Build Coastguard Worker processed += idLen;
503*f6dc9357SAndroid Build Coastguard Worker for (;(processed & 3) != 0; processed++)
504*f6dc9357SAndroid Build Coastguard Worker if (p[processed] != 0)
505*f6dc9357SAndroid Build Coastguard Worker return 0;
506*f6dc9357SAndroid Build Coastguard Worker if ((size_t)tag.CrcLen + 16 != processed) return 0;
507*f6dc9357SAndroid Build Coastguard Worker return (processed <= size) ? processed : 0;
508*f6dc9357SAndroid Build Coastguard Worker }
509*f6dc9357SAndroid Build Coastguard Worker
510*f6dc9357SAndroid Build Coastguard Worker
511*f6dc9357SAndroid Build Coastguard Worker
ReadFileItem(unsigned volIndex,unsigned fsIndex,const CLongAllocDesc & lad,bool isDir,int numRecurseAllowed)512*f6dc9357SAndroid Build Coastguard Worker HRESULT CInArchive::ReadFileItem(unsigned volIndex, unsigned fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed)
513*f6dc9357SAndroid Build Coastguard Worker {
514*f6dc9357SAndroid Build Coastguard Worker if (Files.Size() % 100 == 0)
515*f6dc9357SAndroid Build Coastguard Worker RINOK(_progress->SetCompleted(Files.Size(), _processedProgressBytes))
516*f6dc9357SAndroid Build Coastguard Worker if (numRecurseAllowed-- == 0)
517*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
518*f6dc9357SAndroid Build Coastguard Worker CFile &file = Files.Back();
519*f6dc9357SAndroid Build Coastguard Worker const CLogVol &vol = LogVols[volIndex];
520*f6dc9357SAndroid Build Coastguard Worker const unsigned partitionRef = lad.Location.PartitionRef;
521*f6dc9357SAndroid Build Coastguard Worker if (partitionRef >= vol.PartitionMaps.Size())
522*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
523*f6dc9357SAndroid Build Coastguard Worker CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex];
524*f6dc9357SAndroid Build Coastguard Worker
525*f6dc9357SAndroid Build Coastguard Worker const UInt32 key = lad.Location.Pos;
526*f6dc9357SAndroid Build Coastguard Worker UInt32 value;
527*f6dc9357SAndroid Build Coastguard Worker const UInt32 kRecursedErrorValue = (UInt32)(Int32)-1;
528*f6dc9357SAndroid Build Coastguard Worker if (partition.Map.Find(key, value))
529*f6dc9357SAndroid Build Coastguard Worker {
530*f6dc9357SAndroid Build Coastguard Worker if (value == kRecursedErrorValue)
531*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
532*f6dc9357SAndroid Build Coastguard Worker file.ItemIndex = (int)(Int32)value;
533*f6dc9357SAndroid Build Coastguard Worker }
534*f6dc9357SAndroid Build Coastguard Worker else
535*f6dc9357SAndroid Build Coastguard Worker {
536*f6dc9357SAndroid Build Coastguard Worker value = Items.Size();
537*f6dc9357SAndroid Build Coastguard Worker file.ItemIndex = (int)(Int32)value;
538*f6dc9357SAndroid Build Coastguard Worker if (partition.Map.Set(key, kRecursedErrorValue))
539*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
540*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadItem(volIndex, (int)fsIndex, lad, isDir, numRecurseAllowed))
541*f6dc9357SAndroid Build Coastguard Worker if (!partition.Map.Set(key, value))
542*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
543*f6dc9357SAndroid Build Coastguard Worker }
544*f6dc9357SAndroid Build Coastguard Worker return S_OK;
545*f6dc9357SAndroid Build Coastguard Worker }
546*f6dc9357SAndroid Build Coastguard Worker
547*f6dc9357SAndroid Build Coastguard Worker
548*f6dc9357SAndroid Build Coastguard Worker // (fsIndex = -1) means that it's metadata file
549*f6dc9357SAndroid Build Coastguard Worker
ReadItem(unsigned volIndex,int fsIndex,const CLongAllocDesc & lad,bool isDir,int numRecurseAllowed)550*f6dc9357SAndroid Build Coastguard Worker HRESULT CInArchive::ReadItem(unsigned volIndex, int fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed)
551*f6dc9357SAndroid Build Coastguard Worker {
552*f6dc9357SAndroid Build Coastguard Worker if (Items.Size() >= kNumItemsMax)
553*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
554*f6dc9357SAndroid Build Coastguard Worker CItem &item = Items.AddNew();
555*f6dc9357SAndroid Build Coastguard Worker
556*f6dc9357SAndroid Build Coastguard Worker const CLogVol &vol = LogVols[volIndex];
557*f6dc9357SAndroid Build Coastguard Worker
558*f6dc9357SAndroid Build Coastguard Worker const size_t size = lad.GetLen();
559*f6dc9357SAndroid Build Coastguard Worker if (size != vol.BlockSize)
560*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
561*f6dc9357SAndroid Build Coastguard Worker
562*f6dc9357SAndroid Build Coastguard Worker CByteBuffer buf(size);
563*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadLad(volIndex, lad, buf))
564*f6dc9357SAndroid Build Coastguard Worker
565*f6dc9357SAndroid Build Coastguard Worker CTag tag;
566*f6dc9357SAndroid Build Coastguard Worker const Byte *p = buf;
567*f6dc9357SAndroid Build Coastguard Worker RINOK(tag.Parse(p, size))
568*f6dc9357SAndroid Build Coastguard Worker
569*f6dc9357SAndroid Build Coastguard Worker item.IsExtended = (tag.Id == DESC_TYPE_ExtendedFile);
570*f6dc9357SAndroid Build Coastguard Worker const size_t kExtendOffset = item.IsExtended ? 40 : 0;
571*f6dc9357SAndroid Build Coastguard Worker
572*f6dc9357SAndroid Build Coastguard Worker if (size < kExtendOffset + 176)
573*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
574*f6dc9357SAndroid Build Coastguard Worker if (tag.Id != DESC_TYPE_File &&
575*f6dc9357SAndroid Build Coastguard Worker tag.Id != DESC_TYPE_ExtendedFile)
576*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
577*f6dc9357SAndroid Build Coastguard Worker
578*f6dc9357SAndroid Build Coastguard Worker item.IcbTag.Parse(p + 16);
579*f6dc9357SAndroid Build Coastguard Worker
580*f6dc9357SAndroid Build Coastguard Worker if (fsIndex < 0)
581*f6dc9357SAndroid Build Coastguard Worker {
582*f6dc9357SAndroid Build Coastguard Worker if (item.IcbTag.FileType != ICB_FILE_TYPE_METADATA &&
583*f6dc9357SAndroid Build Coastguard Worker item.IcbTag.FileType != ICB_FILE_TYPE_METADATA_MIRROR)
584*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
585*f6dc9357SAndroid Build Coastguard Worker }
586*f6dc9357SAndroid Build Coastguard Worker else if (
587*f6dc9357SAndroid Build Coastguard Worker item.IcbTag.FileType != ICB_FILE_TYPE_DIR &&
588*f6dc9357SAndroid Build Coastguard Worker item.IcbTag.FileType != ICB_FILE_TYPE_FILE)
589*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
590*f6dc9357SAndroid Build Coastguard Worker
591*f6dc9357SAndroid Build Coastguard Worker item.Parse(p);
592*f6dc9357SAndroid Build Coastguard Worker
593*f6dc9357SAndroid Build Coastguard Worker _processedProgressBytes += (UInt64)item.NumLogBlockRecorded * vol.BlockSize + size;
594*f6dc9357SAndroid Build Coastguard Worker
595*f6dc9357SAndroid Build Coastguard Worker const UInt32 extendedAttrLen = Get32(p + 168 + kExtendOffset);
596*f6dc9357SAndroid Build Coastguard Worker const UInt32 allocDescriptorsLen = Get32(p + 172 + kExtendOffset);
597*f6dc9357SAndroid Build Coastguard Worker
598*f6dc9357SAndroid Build Coastguard Worker if ((extendedAttrLen & 3) != 0)
599*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
600*f6dc9357SAndroid Build Coastguard Worker size_t pos = 176 + kExtendOffset;
601*f6dc9357SAndroid Build Coastguard Worker if (extendedAttrLen > size - pos)
602*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
603*f6dc9357SAndroid Build Coastguard Worker /*
604*f6dc9357SAndroid Build Coastguard Worker if (extendedAttrLen != 16)
605*f6dc9357SAndroid Build Coastguard Worker {
606*f6dc9357SAndroid Build Coastguard Worker if (extendedAttrLen < 24)
607*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
608*f6dc9357SAndroid Build Coastguard Worker CTag attrTag;
609*f6dc9357SAndroid Build Coastguard Worker RINOK(attrTag.Parse(p + pos, size));
610*f6dc9357SAndroid Build Coastguard Worker if (attrTag.Id != DESC_TYPE_ExtendedAttrHeader)
611*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
612*f6dc9357SAndroid Build Coastguard Worker // UInt32 implAttrLocation = Get32(p + pos + 16);
613*f6dc9357SAndroid Build Coastguard Worker // UInt32 applicationlAttrLocation = Get32(p + pos + 20);
614*f6dc9357SAndroid Build Coastguard Worker }
615*f6dc9357SAndroid Build Coastguard Worker */
616*f6dc9357SAndroid Build Coastguard Worker pos += extendedAttrLen;
617*f6dc9357SAndroid Build Coastguard Worker
618*f6dc9357SAndroid Build Coastguard Worker const int descType = item.IcbTag.GetDescriptorType();
619*f6dc9357SAndroid Build Coastguard Worker if (allocDescriptorsLen > size - pos)
620*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
621*f6dc9357SAndroid Build Coastguard Worker if (descType == ICB_DESC_TYPE_INLINE)
622*f6dc9357SAndroid Build Coastguard Worker {
623*f6dc9357SAndroid Build Coastguard Worker item.IsInline = true;
624*f6dc9357SAndroid Build Coastguard Worker item.InlineData.CopyFrom(p + pos, allocDescriptorsLen);
625*f6dc9357SAndroid Build Coastguard Worker }
626*f6dc9357SAndroid Build Coastguard Worker else
627*f6dc9357SAndroid Build Coastguard Worker {
628*f6dc9357SAndroid Build Coastguard Worker item.IsInline = false;
629*f6dc9357SAndroid Build Coastguard Worker if (descType != ICB_DESC_TYPE_SHORT && descType != ICB_DESC_TYPE_LONG)
630*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
631*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < allocDescriptorsLen;)
632*f6dc9357SAndroid Build Coastguard Worker {
633*f6dc9357SAndroid Build Coastguard Worker CMyExtent e;
634*f6dc9357SAndroid Build Coastguard Worker if (descType == ICB_DESC_TYPE_SHORT)
635*f6dc9357SAndroid Build Coastguard Worker {
636*f6dc9357SAndroid Build Coastguard Worker if (i + 8 > allocDescriptorsLen)
637*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
638*f6dc9357SAndroid Build Coastguard Worker CShortAllocDesc sad;
639*f6dc9357SAndroid Build Coastguard Worker sad.Parse(p + pos + i);
640*f6dc9357SAndroid Build Coastguard Worker e.Pos = sad.Pos;
641*f6dc9357SAndroid Build Coastguard Worker e.Len = sad.Len;
642*f6dc9357SAndroid Build Coastguard Worker e.PartitionRef = lad.Location.PartitionRef;
643*f6dc9357SAndroid Build Coastguard Worker i += 8;
644*f6dc9357SAndroid Build Coastguard Worker }
645*f6dc9357SAndroid Build Coastguard Worker else
646*f6dc9357SAndroid Build Coastguard Worker {
647*f6dc9357SAndroid Build Coastguard Worker if (i + 16 > allocDescriptorsLen)
648*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
649*f6dc9357SAndroid Build Coastguard Worker CLongAllocDesc ladNew;
650*f6dc9357SAndroid Build Coastguard Worker ladNew.Parse(p + pos + i);
651*f6dc9357SAndroid Build Coastguard Worker e.Pos = ladNew.Location.Pos;
652*f6dc9357SAndroid Build Coastguard Worker e.PartitionRef = ladNew.Location.PartitionRef;
653*f6dc9357SAndroid Build Coastguard Worker e.Len = ladNew.Len;
654*f6dc9357SAndroid Build Coastguard Worker i += 16;
655*f6dc9357SAndroid Build Coastguard Worker }
656*f6dc9357SAndroid Build Coastguard Worker item.Extents.Add(e);
657*f6dc9357SAndroid Build Coastguard Worker }
658*f6dc9357SAndroid Build Coastguard Worker }
659*f6dc9357SAndroid Build Coastguard Worker
660*f6dc9357SAndroid Build Coastguard Worker if (isDir != item.IcbTag.IsDir())
661*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
662*f6dc9357SAndroid Build Coastguard Worker
663*f6dc9357SAndroid Build Coastguard Worker if (item.IcbTag.IsDir())
664*f6dc9357SAndroid Build Coastguard Worker {
665*f6dc9357SAndroid Build Coastguard Worker if (fsIndex < 0)
666*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
667*f6dc9357SAndroid Build Coastguard Worker
668*f6dc9357SAndroid Build Coastguard Worker if (!item.CheckChunkSizes() || !CheckItemExtents(volIndex, item))
669*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
670*f6dc9357SAndroid Build Coastguard Worker CByteBuffer buf2;
671*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadFromFile(volIndex, item, buf2))
672*f6dc9357SAndroid Build Coastguard Worker item.Size = 0;
673*f6dc9357SAndroid Build Coastguard Worker item.Extents.ClearAndFree();
674*f6dc9357SAndroid Build Coastguard Worker item.InlineData.Free();
675*f6dc9357SAndroid Build Coastguard Worker
676*f6dc9357SAndroid Build Coastguard Worker const Byte *p2 = buf2;
677*f6dc9357SAndroid Build Coastguard Worker size_t size2 = buf2.Size();
678*f6dc9357SAndroid Build Coastguard Worker while (size2 != 0)
679*f6dc9357SAndroid Build Coastguard Worker {
680*f6dc9357SAndroid Build Coastguard Worker CFileId fileId;
681*f6dc9357SAndroid Build Coastguard Worker {
682*f6dc9357SAndroid Build Coastguard Worker const size_t cur = fileId.Parse(p2, size2);
683*f6dc9357SAndroid Build Coastguard Worker if (cur == 0)
684*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
685*f6dc9357SAndroid Build Coastguard Worker p2 += cur;
686*f6dc9357SAndroid Build Coastguard Worker size2 -= cur;
687*f6dc9357SAndroid Build Coastguard Worker }
688*f6dc9357SAndroid Build Coastguard Worker if (fileId.IsItLink_Parent())
689*f6dc9357SAndroid Build Coastguard Worker continue;
690*f6dc9357SAndroid Build Coastguard Worker if (fileId.IsItLink_Deleted())
691*f6dc9357SAndroid Build Coastguard Worker continue;
692*f6dc9357SAndroid Build Coastguard Worker {
693*f6dc9357SAndroid Build Coastguard Worker CFile file;
694*f6dc9357SAndroid Build Coastguard Worker // file.FileVersion = fileId.FileVersion;
695*f6dc9357SAndroid Build Coastguard Worker // file.FileCharacteristics = fileId.FileCharacteristics;
696*f6dc9357SAndroid Build Coastguard Worker // file.ImplUse = fileId.ImplUse;
697*f6dc9357SAndroid Build Coastguard Worker file.Id = fileId.Id;
698*f6dc9357SAndroid Build Coastguard Worker
699*f6dc9357SAndroid Build Coastguard Worker _fileNameLengthTotal += file.Id.Data.Size();
700*f6dc9357SAndroid Build Coastguard Worker if (_fileNameLengthTotal > kFileNameLengthTotalMax)
701*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
702*f6dc9357SAndroid Build Coastguard Worker
703*f6dc9357SAndroid Build Coastguard Worker item.SubFiles.Add(Files.Size());
704*f6dc9357SAndroid Build Coastguard Worker if (Files.Size() >= kNumFilesMax)
705*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
706*f6dc9357SAndroid Build Coastguard Worker Files.Add(file);
707*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadFileItem(volIndex, (unsigned)fsIndex, fileId.Icb,
708*f6dc9357SAndroid Build Coastguard Worker fileId.IsItLink_Dir(), numRecurseAllowed))
709*f6dc9357SAndroid Build Coastguard Worker }
710*f6dc9357SAndroid Build Coastguard Worker }
711*f6dc9357SAndroid Build Coastguard Worker }
712*f6dc9357SAndroid Build Coastguard Worker else
713*f6dc9357SAndroid Build Coastguard Worker {
714*f6dc9357SAndroid Build Coastguard Worker if ((UInt32)item.Extents.Size() > kNumExtentsMax - _numExtents)
715*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
716*f6dc9357SAndroid Build Coastguard Worker _numExtents += item.Extents.Size();
717*f6dc9357SAndroid Build Coastguard Worker
718*f6dc9357SAndroid Build Coastguard Worker if (item.InlineData.Size() > kInlineExtentsSizeMax - _inlineExtentsSize)
719*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
720*f6dc9357SAndroid Build Coastguard Worker _inlineExtentsSize += item.InlineData.Size();
721*f6dc9357SAndroid Build Coastguard Worker }
722*f6dc9357SAndroid Build Coastguard Worker
723*f6dc9357SAndroid Build Coastguard Worker return S_OK;
724*f6dc9357SAndroid Build Coastguard Worker }
725*f6dc9357SAndroid Build Coastguard Worker
726*f6dc9357SAndroid Build Coastguard Worker
FillRefs(CFileSet & fs,unsigned fileIndex,int parent,int numRecurseAllowed)727*f6dc9357SAndroid Build Coastguard Worker HRESULT CInArchive::FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed)
728*f6dc9357SAndroid Build Coastguard Worker {
729*f6dc9357SAndroid Build Coastguard Worker if ((_numRefs & 0xFFF) == 0)
730*f6dc9357SAndroid Build Coastguard Worker {
731*f6dc9357SAndroid Build Coastguard Worker RINOK(_progress->SetCompleted())
732*f6dc9357SAndroid Build Coastguard Worker }
733*f6dc9357SAndroid Build Coastguard Worker if (numRecurseAllowed-- == 0)
734*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
735*f6dc9357SAndroid Build Coastguard Worker if (_numRefs >= kNumRefsMax)
736*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
737*f6dc9357SAndroid Build Coastguard Worker _numRefs++;
738*f6dc9357SAndroid Build Coastguard Worker CRef ref;
739*f6dc9357SAndroid Build Coastguard Worker ref.FileIndex = fileIndex;
740*f6dc9357SAndroid Build Coastguard Worker ref.Parent = parent;
741*f6dc9357SAndroid Build Coastguard Worker parent = (int)fs.Refs.Size();
742*f6dc9357SAndroid Build Coastguard Worker fs.Refs.Add(ref);
743*f6dc9357SAndroid Build Coastguard Worker const CItem &item = Items[Files[fileIndex].ItemIndex];
744*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, item.SubFiles)
745*f6dc9357SAndroid Build Coastguard Worker {
746*f6dc9357SAndroid Build Coastguard Worker RINOK(FillRefs(fs, item.SubFiles[i], parent, numRecurseAllowed))
747*f6dc9357SAndroid Build Coastguard Worker }
748*f6dc9357SAndroid Build Coastguard Worker return S_OK;
749*f6dc9357SAndroid Build Coastguard Worker }
750*f6dc9357SAndroid Build Coastguard Worker
751*f6dc9357SAndroid Build Coastguard Worker
IsArc_Udf(const Byte * p,size_t size)752*f6dc9357SAndroid Build Coastguard Worker API_FUNC_IsArc IsArc_Udf(const Byte *p, size_t size)
753*f6dc9357SAndroid Build Coastguard Worker {
754*f6dc9357SAndroid Build Coastguard Worker UInt32 res = k_IsArc_Res_NO;
755*f6dc9357SAndroid Build Coastguard Worker unsigned SecLogSize;
756*f6dc9357SAndroid Build Coastguard Worker for (SecLogSize = 11;; SecLogSize -= 2)
757*f6dc9357SAndroid Build Coastguard Worker {
758*f6dc9357SAndroid Build Coastguard Worker if (SecLogSize < 9)
759*f6dc9357SAndroid Build Coastguard Worker return res;
760*f6dc9357SAndroid Build Coastguard Worker const UInt32 offset = (UInt32)256 << SecLogSize;
761*f6dc9357SAndroid Build Coastguard Worker const UInt32 bufSize = (UInt32)1 << SecLogSize;
762*f6dc9357SAndroid Build Coastguard Worker if (offset + bufSize > size)
763*f6dc9357SAndroid Build Coastguard Worker res = k_IsArc_Res_NEED_MORE;
764*f6dc9357SAndroid Build Coastguard Worker else
765*f6dc9357SAndroid Build Coastguard Worker {
766*f6dc9357SAndroid Build Coastguard Worker CTag tag;
767*f6dc9357SAndroid Build Coastguard Worker if (tag.Parse(p + offset, bufSize) == S_OK)
768*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_AnchorVolPtr)
769*f6dc9357SAndroid Build Coastguard Worker {
770*f6dc9357SAndroid Build Coastguard Worker if (Get32(p + offset + 12) == 256 && // TagLocation
771*f6dc9357SAndroid Build Coastguard Worker tag.CrcLen >= 16)
772*f6dc9357SAndroid Build Coastguard Worker return k_IsArc_Res_YES;
773*f6dc9357SAndroid Build Coastguard Worker }
774*f6dc9357SAndroid Build Coastguard Worker }
775*f6dc9357SAndroid Build Coastguard Worker }
776*f6dc9357SAndroid Build Coastguard Worker }
777*f6dc9357SAndroid Build Coastguard Worker
778*f6dc9357SAndroid Build Coastguard Worker
Open2()779*f6dc9357SAndroid Build Coastguard Worker HRESULT CInArchive::Open2()
780*f6dc9357SAndroid Build Coastguard Worker {
781*f6dc9357SAndroid Build Coastguard Worker Clear();
782*f6dc9357SAndroid Build Coastguard Worker UInt64 fileSize;
783*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_GetSize_SeekToEnd(_stream, fileSize))
784*f6dc9357SAndroid Build Coastguard Worker FileSize = fileSize;
785*f6dc9357SAndroid Build Coastguard Worker
786*f6dc9357SAndroid Build Coastguard Worker // Some UDFs contain additional pad zeros (2 KB).
787*f6dc9357SAndroid Build Coastguard Worker // Seek to STREAM_SEEK_END for direct DVD reading can return 8 KB more, so we check last 16 KB.
788*f6dc9357SAndroid Build Coastguard Worker // And when we read last block, result read size can be smaller than required size.
789*f6dc9357SAndroid Build Coastguard Worker
790*f6dc9357SAndroid Build Coastguard Worker /*
791*f6dc9357SAndroid Build Coastguard Worker const size_t kBufSize = 1 << 14;
792*f6dc9357SAndroid Build Coastguard Worker Byte buf[kBufSize];
793*f6dc9357SAndroid Build Coastguard Worker size_t readSize = (fileSize < kBufSize) ? (size_t)fileSize : kBufSize;
794*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_stream, fileSize - readSize))
795*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream(_stream, buf, &readSize));
796*f6dc9357SAndroid Build Coastguard Worker size_t i = readSize;
797*f6dc9357SAndroid Build Coastguard Worker for (;;)
798*f6dc9357SAndroid Build Coastguard Worker {
799*f6dc9357SAndroid Build Coastguard Worker const size_t kSecSizeMin = 1 << 8;
800*f6dc9357SAndroid Build Coastguard Worker if (i < kSecSizeMin)
801*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
802*f6dc9357SAndroid Build Coastguard Worker i -= kSecSizeMin;
803*f6dc9357SAndroid Build Coastguard Worker SecLogSize = (readSize - i < ((size_t)1 << 11)) ? 8 : 11;
804*f6dc9357SAndroid Build Coastguard Worker CTag tag;
805*f6dc9357SAndroid Build Coastguard Worker if (tag.Parse(buf + i, (1 << SecLogSize)) == S_OK)
806*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_AnchorVolPtr)
807*f6dc9357SAndroid Build Coastguard Worker break;
808*f6dc9357SAndroid Build Coastguard Worker }
809*f6dc9357SAndroid Build Coastguard Worker PhySize = fileSize;
810*f6dc9357SAndroid Build Coastguard Worker CExtent extentVDS;
811*f6dc9357SAndroid Build Coastguard Worker extentVDS.Parse(buf + i + 16);
812*f6dc9357SAndroid Build Coastguard Worker */
813*f6dc9357SAndroid Build Coastguard Worker
814*f6dc9357SAndroid Build Coastguard Worker /*
815*f6dc9357SAndroid Build Coastguard Worker An Anchor Volume Descriptor Pointer structure shall be recorded in at
816*f6dc9357SAndroid Build Coastguard Worker least 2 of the following 3 locations on the media:
817*f6dc9357SAndroid Build Coastguard Worker Logical Sector 256.
818*f6dc9357SAndroid Build Coastguard Worker Logical Sector (N - 256).
819*f6dc9357SAndroid Build Coastguard Worker N
820*f6dc9357SAndroid Build Coastguard Worker */
821*f6dc9357SAndroid Build Coastguard Worker
822*f6dc9357SAndroid Build Coastguard Worker const size_t kBufSize = 1 << 11;
823*f6dc9357SAndroid Build Coastguard Worker Byte buf[kBufSize];
824*f6dc9357SAndroid Build Coastguard Worker
825*f6dc9357SAndroid Build Coastguard Worker for (SecLogSize = 11;; SecLogSize -= 2)
826*f6dc9357SAndroid Build Coastguard Worker {
827*f6dc9357SAndroid Build Coastguard Worker // Windows 10 uses unusual (SecLogSize = 9)
828*f6dc9357SAndroid Build Coastguard Worker if (SecLogSize < 9)
829*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
830*f6dc9357SAndroid Build Coastguard Worker const UInt32 offset = (UInt32)256 << SecLogSize;
831*f6dc9357SAndroid Build Coastguard Worker if (offset >= fileSize)
832*f6dc9357SAndroid Build Coastguard Worker continue;
833*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_stream, offset))
834*f6dc9357SAndroid Build Coastguard Worker const size_t bufSize = (size_t)1 << SecLogSize;
835*f6dc9357SAndroid Build Coastguard Worker size_t readSize = bufSize;
836*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream(_stream, buf, &readSize))
837*f6dc9357SAndroid Build Coastguard Worker if (readSize == bufSize)
838*f6dc9357SAndroid Build Coastguard Worker {
839*f6dc9357SAndroid Build Coastguard Worker CTag tag;
840*f6dc9357SAndroid Build Coastguard Worker if (tag.Parse(buf, readSize) == S_OK)
841*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_AnchorVolPtr)
842*f6dc9357SAndroid Build Coastguard Worker {
843*f6dc9357SAndroid Build Coastguard Worker if (Get32(buf + 12) == 256 &&
844*f6dc9357SAndroid Build Coastguard Worker tag.CrcLen >= 16) // TagLocation
845*f6dc9357SAndroid Build Coastguard Worker break;
846*f6dc9357SAndroid Build Coastguard Worker }
847*f6dc9357SAndroid Build Coastguard Worker }
848*f6dc9357SAndroid Build Coastguard Worker }
849*f6dc9357SAndroid Build Coastguard Worker
850*f6dc9357SAndroid Build Coastguard Worker PhySize = (UInt32)(256 + 1) << SecLogSize;
851*f6dc9357SAndroid Build Coastguard Worker IsArc = true;
852*f6dc9357SAndroid Build Coastguard Worker
853*f6dc9357SAndroid Build Coastguard Worker // UDF 2.2.3 AnchorVolumeDescriptorPointer
854*f6dc9357SAndroid Build Coastguard Worker
855*f6dc9357SAndroid Build Coastguard Worker CExtent extentVDS;
856*f6dc9357SAndroid Build Coastguard Worker extentVDS.Parse(buf + 16);
857*f6dc9357SAndroid Build Coastguard Worker {
858*f6dc9357SAndroid Build Coastguard Worker CExtent extentVDS2;
859*f6dc9357SAndroid Build Coastguard Worker extentVDS2.Parse(buf + 24);
860*f6dc9357SAndroid Build Coastguard Worker UpdatePhySize(extentVDS);
861*f6dc9357SAndroid Build Coastguard Worker UpdatePhySize(extentVDS2);
862*f6dc9357SAndroid Build Coastguard Worker }
863*f6dc9357SAndroid Build Coastguard Worker
864*f6dc9357SAndroid Build Coastguard Worker for (UInt32 location = 0; ; location++)
865*f6dc9357SAndroid Build Coastguard Worker {
866*f6dc9357SAndroid Build Coastguard Worker if (location >= (extentVDS.Len >> SecLogSize))
867*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
868*f6dc9357SAndroid Build Coastguard Worker
869*f6dc9357SAndroid Build Coastguard Worker const size_t bufSize = (size_t)1 << SecLogSize;
870*f6dc9357SAndroid Build Coastguard Worker {
871*f6dc9357SAndroid Build Coastguard Worker const UInt64 offs = ((UInt64)extentVDS.Pos + location) << SecLogSize;
872*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_stream, offs))
873*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = ReadStream_FALSE(_stream, buf, bufSize);
874*f6dc9357SAndroid Build Coastguard Worker if (res == S_FALSE && offs + bufSize > FileSize)
875*f6dc9357SAndroid Build Coastguard Worker UnexpectedEnd = true;
876*f6dc9357SAndroid Build Coastguard Worker RINOK(res)
877*f6dc9357SAndroid Build Coastguard Worker }
878*f6dc9357SAndroid Build Coastguard Worker
879*f6dc9357SAndroid Build Coastguard Worker CTag tag;
880*f6dc9357SAndroid Build Coastguard Worker RINOK(tag.Parse(buf, bufSize))
881*f6dc9357SAndroid Build Coastguard Worker
882*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_Terminating)
883*f6dc9357SAndroid Build Coastguard Worker break;
884*f6dc9357SAndroid Build Coastguard Worker
885*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_PrimVol)
886*f6dc9357SAndroid Build Coastguard Worker {
887*f6dc9357SAndroid Build Coastguard Worker CPrimeVol &pm = PrimeVols.AddNew();
888*f6dc9357SAndroid Build Coastguard Worker pm.Parse(buf);
889*f6dc9357SAndroid Build Coastguard Worker continue;
890*f6dc9357SAndroid Build Coastguard Worker }
891*f6dc9357SAndroid Build Coastguard Worker
892*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_Partition)
893*f6dc9357SAndroid Build Coastguard Worker {
894*f6dc9357SAndroid Build Coastguard Worker // Partition Descriptor
895*f6dc9357SAndroid Build Coastguard Worker // ECMA 3/10.5
896*f6dc9357SAndroid Build Coastguard Worker // UDF 2.2.14
897*f6dc9357SAndroid Build Coastguard Worker if (Partitions.Size() >= kNumPartitionsMax)
898*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
899*f6dc9357SAndroid Build Coastguard Worker CPartition partition;
900*f6dc9357SAndroid Build Coastguard Worker // const UInt32 volDescSeqNumer = Get32(buf + 16);
901*f6dc9357SAndroid Build Coastguard Worker partition.Flags = Get16(buf + 20);
902*f6dc9357SAndroid Build Coastguard Worker partition.Number = Get16(buf + 22);
903*f6dc9357SAndroid Build Coastguard Worker partition.ContentsId.Parse(buf + 24);
904*f6dc9357SAndroid Build Coastguard Worker
905*f6dc9357SAndroid Build Coastguard Worker // memcpy(partition.ContentsUse, buf + 56, sizeof(partition.ContentsUse));
906*f6dc9357SAndroid Build Coastguard Worker // ContentsUse contains Partition Header Description.
907*f6dc9357SAndroid Build Coastguard Worker // ECMA 4/14.3
908*f6dc9357SAndroid Build Coastguard Worker // UDF PartitionHeaderDescriptor 2.3.3
909*f6dc9357SAndroid Build Coastguard Worker
910*f6dc9357SAndroid Build Coastguard Worker partition.AccessType = Get32(buf + 184);
911*f6dc9357SAndroid Build Coastguard Worker partition.Pos = Get32(buf + 188);
912*f6dc9357SAndroid Build Coastguard Worker partition.Len = Get32(buf + 192);
913*f6dc9357SAndroid Build Coastguard Worker partition.ImplId.Parse(buf + 196);
914*f6dc9357SAndroid Build Coastguard Worker // memcpy(partition.ImplUse, buf + 228, sizeof(partition.ImplUse));
915*f6dc9357SAndroid Build Coastguard Worker
916*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\nPartition number = %2d pos = %d len = %d", partition.Number, partition.Pos, partition.Len));
917*f6dc9357SAndroid Build Coastguard Worker Partitions.Add(partition);
918*f6dc9357SAndroid Build Coastguard Worker continue;
919*f6dc9357SAndroid Build Coastguard Worker }
920*f6dc9357SAndroid Build Coastguard Worker
921*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_LogicalVol)
922*f6dc9357SAndroid Build Coastguard Worker {
923*f6dc9357SAndroid Build Coastguard Worker /* Logical Volume Descriptor
924*f6dc9357SAndroid Build Coastguard Worker ECMA 3/10.6
925*f6dc9357SAndroid Build Coastguard Worker UDF 2.60 2.2.4 */
926*f6dc9357SAndroid Build Coastguard Worker
927*f6dc9357SAndroid Build Coastguard Worker if (LogVols.Size() >= kNumLogVolumesMax)
928*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
929*f6dc9357SAndroid Build Coastguard Worker CLogVol &vol = LogVols.AddNew();
930*f6dc9357SAndroid Build Coastguard Worker
931*f6dc9357SAndroid Build Coastguard Worker vol.Id.Parse(buf + 84);
932*f6dc9357SAndroid Build Coastguard Worker vol.BlockSize = Get32(buf + 212);
933*f6dc9357SAndroid Build Coastguard Worker if (vol.BlockSize != ((UInt32)1 << SecLogSize))
934*f6dc9357SAndroid Build Coastguard Worker {
935*f6dc9357SAndroid Build Coastguard Worker // UDF 2.2.4.2 LogicalBlockSize
936*f6dc9357SAndroid Build Coastguard Worker // UDF probably doesn't allow different sizes
937*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
938*f6dc9357SAndroid Build Coastguard Worker }
939*f6dc9357SAndroid Build Coastguard Worker /*
940*f6dc9357SAndroid Build Coastguard Worker if (vol.BlockSize < 512 || vol.BlockSize > ((UInt32)1 << 30))
941*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
942*f6dc9357SAndroid Build Coastguard Worker */
943*f6dc9357SAndroid Build Coastguard Worker
944*f6dc9357SAndroid Build Coastguard Worker vol.DomainId.Parse(buf + 216);
945*f6dc9357SAndroid Build Coastguard Worker
946*f6dc9357SAndroid Build Coastguard Worker // ECMA 4/3.1
947*f6dc9357SAndroid Build Coastguard Worker // UDF 2.2.4.4 LogicalVolumeContentsUse
948*f6dc9357SAndroid Build Coastguard Worker /* the extent in which the first File Set Descriptor Sequence
949*f6dc9357SAndroid Build Coastguard Worker of the logical volume is recorded */
950*f6dc9357SAndroid Build Coastguard Worker vol.FileSetLocation.Parse(buf + 248);
951*f6dc9357SAndroid Build Coastguard Worker // memcpy(vol.ContentsUse, buf + 248, sizeof(vol.ContentsUse));
952*f6dc9357SAndroid Build Coastguard Worker
953*f6dc9357SAndroid Build Coastguard Worker vol.ImplId.Parse(buf + 272);
954*f6dc9357SAndroid Build Coastguard Worker // memcpy(vol.ImplUse, buf + 304, sizeof(vol.ImplUse));
955*f6dc9357SAndroid Build Coastguard Worker // vol.IntegritySequenceExtent.Parse(buf + 432);
956*f6dc9357SAndroid Build Coastguard Worker
957*f6dc9357SAndroid Build Coastguard Worker const UInt32 mapTableLen = Get32(buf + 264);
958*f6dc9357SAndroid Build Coastguard Worker const UInt32 numPartitionMaps = Get32(buf + 268);
959*f6dc9357SAndroid Build Coastguard Worker if (numPartitionMaps > kNumPartitionsMax)
960*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
961*f6dc9357SAndroid Build Coastguard Worker
962*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\nLogicalVol numPartitionMaps = %2d", numPartitionMaps));
963*f6dc9357SAndroid Build Coastguard Worker
964*f6dc9357SAndroid Build Coastguard Worker size_t pos = 440;
965*f6dc9357SAndroid Build Coastguard Worker if (mapTableLen > bufSize - pos)
966*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
967*f6dc9357SAndroid Build Coastguard Worker const size_t posLimit = pos + mapTableLen;
968*f6dc9357SAndroid Build Coastguard Worker
969*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numPartitionMaps; i++)
970*f6dc9357SAndroid Build Coastguard Worker {
971*f6dc9357SAndroid Build Coastguard Worker // ECMA 3/10.7 Partition maps
972*f6dc9357SAndroid Build Coastguard Worker if (pos + 2 > posLimit)
973*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
974*f6dc9357SAndroid Build Coastguard Worker CPartitionMap pm;
975*f6dc9357SAndroid Build Coastguard Worker pm.Type = buf[pos + 0];
976*f6dc9357SAndroid Build Coastguard Worker // pm.Length = buf[pos + 1];
977*f6dc9357SAndroid Build Coastguard Worker const Byte len = buf[pos + 1];
978*f6dc9357SAndroid Build Coastguard Worker if (pos + len > posLimit)
979*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
980*f6dc9357SAndroid Build Coastguard Worker
981*f6dc9357SAndroid Build Coastguard Worker // memcpy(pm.Data, buf + pos + 2, pm.Length - 2);
982*f6dc9357SAndroid Build Coastguard Worker if (pm.Type == 1)
983*f6dc9357SAndroid Build Coastguard Worker {
984*f6dc9357SAndroid Build Coastguard Worker // ECMA 3/10.7.2
985*f6dc9357SAndroid Build Coastguard Worker if (len != 6)
986*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
987*f6dc9357SAndroid Build Coastguard Worker pm.VolumeSequenceNumber = Get16(buf + pos + 2);
988*f6dc9357SAndroid Build Coastguard Worker pm.PartitionNumber = Get16(buf + pos + 4);
989*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\nPartitionMap type 1 PartitionNumber = %2d", pm.PartitionNumber));
990*f6dc9357SAndroid Build Coastguard Worker }
991*f6dc9357SAndroid Build Coastguard Worker else if (pm.Type == 2)
992*f6dc9357SAndroid Build Coastguard Worker {
993*f6dc9357SAndroid Build Coastguard Worker if (len != 64)
994*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
995*f6dc9357SAndroid Build Coastguard Worker /* ECMA 10.7.3 / Type 2 Partition Map
996*f6dc9357SAndroid Build Coastguard Worker 62 bytes: Partition Identifier. */
997*f6dc9357SAndroid Build Coastguard Worker
998*f6dc9357SAndroid Build Coastguard Worker /* UDF
999*f6dc9357SAndroid Build Coastguard Worker 2.2.8 "*UDF Virtual Partition"
1000*f6dc9357SAndroid Build Coastguard Worker 2.2.9 "*UDF Sparable Partition"
1001*f6dc9357SAndroid Build Coastguard Worker 2.2.10 "*UDF Metadata Partition"
1002*f6dc9357SAndroid Build Coastguard Worker */
1003*f6dc9357SAndroid Build Coastguard Worker
1004*f6dc9357SAndroid Build Coastguard Worker if (Get16(buf + pos + 2) != 0) // reserved
1005*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1006*f6dc9357SAndroid Build Coastguard Worker
1007*f6dc9357SAndroid Build Coastguard Worker pm.PartitionTypeId.Parse(buf + pos + 4);
1008*f6dc9357SAndroid Build Coastguard Worker pm.VolumeSequenceNumber = Get16(buf + pos + 36);
1009*f6dc9357SAndroid Build Coastguard Worker pm.PartitionNumber = Get16(buf + pos + 38);
1010*f6dc9357SAndroid Build Coastguard Worker
1011*f6dc9357SAndroid Build Coastguard Worker if (memcmp(pm.PartitionTypeId.Id, "*UDF Metadata Partition", 23) != 0)
1012*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1013*f6dc9357SAndroid Build Coastguard Worker
1014*f6dc9357SAndroid Build Coastguard Worker // UDF 2.2.10 Metadata Partition Map
1015*f6dc9357SAndroid Build Coastguard Worker pm.MetadataFileLocation = Get32(buf + pos + 40);
1016*f6dc9357SAndroid Build Coastguard Worker // pm.MetadataMirrorFileLocation = Get32(buf + pos + 44);
1017*f6dc9357SAndroid Build Coastguard Worker // pm.MetadataBitmapFileLocation = Get32(buf + pos + 48);
1018*f6dc9357SAndroid Build Coastguard Worker // pm.AllocationUnitSize = Get32(buf + pos + 52);
1019*f6dc9357SAndroid Build Coastguard Worker // pm.AlignmentUnitSize = Get16(buf + pos + 56);
1020*f6dc9357SAndroid Build Coastguard Worker // pm.Flags = buf[pos + 58];
1021*f6dc9357SAndroid Build Coastguard Worker
1022*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\nPartitionMap type 2 PartitionNumber = %2d", pm.PartitionNumber));
1023*f6dc9357SAndroid Build Coastguard Worker // Unsupported = true;
1024*f6dc9357SAndroid Build Coastguard Worker // return S_FALSE;
1025*f6dc9357SAndroid Build Coastguard Worker }
1026*f6dc9357SAndroid Build Coastguard Worker else
1027*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1028*f6dc9357SAndroid Build Coastguard Worker pos += len;
1029*f6dc9357SAndroid Build Coastguard Worker vol.PartitionMaps.Add(pm);
1030*f6dc9357SAndroid Build Coastguard Worker }
1031*f6dc9357SAndroid Build Coastguard Worker continue;
1032*f6dc9357SAndroid Build Coastguard Worker }
1033*f6dc9357SAndroid Build Coastguard Worker
1034*f6dc9357SAndroid Build Coastguard Worker /*
1035*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_UnallocSpace)
1036*f6dc9357SAndroid Build Coastguard Worker {
1037*f6dc9357SAndroid Build Coastguard Worker // UInt32 volDescSeqNumer = Get32(buf + 16);
1038*f6dc9357SAndroid Build Coastguard Worker const UInt32 numAlocDescs = Get32(buf + 20);
1039*f6dc9357SAndroid Build Coastguard Worker // we need examples for (numAlocDescs != 0) case
1040*f6dc9357SAndroid Build Coastguard Worker if (numAlocDescs > (bufSize - 24) / 8)
1041*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1042*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numAlocDescs; i++)
1043*f6dc9357SAndroid Build Coastguard Worker {
1044*f6dc9357SAndroid Build Coastguard Worker CExtent e;
1045*f6dc9357SAndroid Build Coastguard Worker e.Parse(buf + 24 + i * 8);
1046*f6dc9357SAndroid Build Coastguard Worker }
1047*f6dc9357SAndroid Build Coastguard Worker continue;
1048*f6dc9357SAndroid Build Coastguard Worker }
1049*f6dc9357SAndroid Build Coastguard Worker else
1050*f6dc9357SAndroid Build Coastguard Worker continue;
1051*f6dc9357SAndroid Build Coastguard Worker */
1052*f6dc9357SAndroid Build Coastguard Worker }
1053*f6dc9357SAndroid Build Coastguard Worker
1054*f6dc9357SAndroid Build Coastguard Worker UInt64 totalSize = 0;
1055*f6dc9357SAndroid Build Coastguard Worker
1056*f6dc9357SAndroid Build Coastguard Worker unsigned volIndex;
1057*f6dc9357SAndroid Build Coastguard Worker for (volIndex = 0; volIndex < LogVols.Size(); volIndex++)
1058*f6dc9357SAndroid Build Coastguard Worker {
1059*f6dc9357SAndroid Build Coastguard Worker CLogVol &vol = LogVols[volIndex];
1060*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (pmIndex, vol.PartitionMaps)
1061*f6dc9357SAndroid Build Coastguard Worker {
1062*f6dc9357SAndroid Build Coastguard Worker CPartitionMap &pm = vol.PartitionMaps[pmIndex];
1063*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0;; i++)
1064*f6dc9357SAndroid Build Coastguard Worker {
1065*f6dc9357SAndroid Build Coastguard Worker if (i == Partitions.Size())
1066*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1067*f6dc9357SAndroid Build Coastguard Worker CPartition &part = Partitions[i];
1068*f6dc9357SAndroid Build Coastguard Worker if (part.Number == pm.PartitionNumber)
1069*f6dc9357SAndroid Build Coastguard Worker {
1070*f6dc9357SAndroid Build Coastguard Worker pm.PartitionIndex = i;
1071*f6dc9357SAndroid Build Coastguard Worker if (pm.Type == 2)
1072*f6dc9357SAndroid Build Coastguard Worker break;
1073*f6dc9357SAndroid Build Coastguard Worker
1074*f6dc9357SAndroid Build Coastguard Worker /*
1075*f6dc9357SAndroid Build Coastguard Worker if (part.VolIndex >= 0)
1076*f6dc9357SAndroid Build Coastguard Worker {
1077*f6dc9357SAndroid Build Coastguard Worker // it's for 2.60. Fix it
1078*f6dc9357SAndroid Build Coastguard Worker if (part.VolIndex != (int)volIndex)
1079*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1080*f6dc9357SAndroid Build Coastguard Worker // return S_FALSE;
1081*f6dc9357SAndroid Build Coastguard Worker }
1082*f6dc9357SAndroid Build Coastguard Worker part.VolIndex = volIndex;
1083*f6dc9357SAndroid Build Coastguard Worker */
1084*f6dc9357SAndroid Build Coastguard Worker
1085*f6dc9357SAndroid Build Coastguard Worker totalSize += (UInt64)part.Len << SecLogSize;
1086*f6dc9357SAndroid Build Coastguard Worker break;
1087*f6dc9357SAndroid Build Coastguard Worker }
1088*f6dc9357SAndroid Build Coastguard Worker }
1089*f6dc9357SAndroid Build Coastguard Worker }
1090*f6dc9357SAndroid Build Coastguard Worker }
1091*f6dc9357SAndroid Build Coastguard Worker
1092*f6dc9357SAndroid Build Coastguard Worker for (volIndex = 0; volIndex < LogVols.Size(); volIndex++)
1093*f6dc9357SAndroid Build Coastguard Worker {
1094*f6dc9357SAndroid Build Coastguard Worker CLogVol &vol = LogVols[volIndex];
1095*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (pmIndex, vol.PartitionMaps)
1096*f6dc9357SAndroid Build Coastguard Worker {
1097*f6dc9357SAndroid Build Coastguard Worker CPartitionMap &pm = vol.PartitionMaps[pmIndex];
1098*f6dc9357SAndroid Build Coastguard Worker if (pm.Type != 2)
1099*f6dc9357SAndroid Build Coastguard Worker continue;
1100*f6dc9357SAndroid Build Coastguard Worker
1101*f6dc9357SAndroid Build Coastguard Worker {
1102*f6dc9357SAndroid Build Coastguard Worker CLongAllocDesc lad;
1103*f6dc9357SAndroid Build Coastguard Worker lad.Len = vol.BlockSize;
1104*f6dc9357SAndroid Build Coastguard Worker lad.Location.Pos = pm.MetadataFileLocation;
1105*f6dc9357SAndroid Build Coastguard Worker // lad.Location.Pos = pm.MetadataMirrorFileLocation;
1106*f6dc9357SAndroid Build Coastguard Worker
1107*f6dc9357SAndroid Build Coastguard Worker lad.Location.PartitionRef = (UInt16)pmIndex;
1108*f6dc9357SAndroid Build Coastguard Worker
1109*f6dc9357SAndroid Build Coastguard Worker /* we need correct PartitionMaps[lad.Location.PartitionRef].PartitionIndex.
1110*f6dc9357SAndroid Build Coastguard Worker so we can use pmIndex or find (Type==1) PartitionMap */
1111*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (pmIndex2, vol.PartitionMaps)
1112*f6dc9357SAndroid Build Coastguard Worker {
1113*f6dc9357SAndroid Build Coastguard Worker const CPartitionMap &pm2 = vol.PartitionMaps[pmIndex2];
1114*f6dc9357SAndroid Build Coastguard Worker if (pm2.PartitionNumber == pm.PartitionNumber && pm2.Type == 1)
1115*f6dc9357SAndroid Build Coastguard Worker {
1116*f6dc9357SAndroid Build Coastguard Worker lad.Location.PartitionRef = (UInt16)pmIndex2;
1117*f6dc9357SAndroid Build Coastguard Worker break;
1118*f6dc9357SAndroid Build Coastguard Worker }
1119*f6dc9357SAndroid Build Coastguard Worker }
1120*f6dc9357SAndroid Build Coastguard Worker
1121*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadItem(volIndex,
1122*f6dc9357SAndroid Build Coastguard Worker -1, // (fsIndex = -1) means that it's metadata
1123*f6dc9357SAndroid Build Coastguard Worker lad,
1124*f6dc9357SAndroid Build Coastguard Worker false, // isDir
1125*f6dc9357SAndroid Build Coastguard Worker 1)) // numRecurseAllowed
1126*f6dc9357SAndroid Build Coastguard Worker }
1127*f6dc9357SAndroid Build Coastguard Worker {
1128*f6dc9357SAndroid Build Coastguard Worker const CItem &item = Items.Back();
1129*f6dc9357SAndroid Build Coastguard Worker if (!CheckItemExtents(volIndex, item))
1130*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1131*f6dc9357SAndroid Build Coastguard Worker if (item.Extents.Size() != 1)
1132*f6dc9357SAndroid Build Coastguard Worker {
1133*f6dc9357SAndroid Build Coastguard Worker if (item.Extents.Size() < 1)
1134*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1135*f6dc9357SAndroid Build Coastguard Worker /* Windows 10 writes empty record item.Extents[1].
1136*f6dc9357SAndroid Build Coastguard Worker we ignore such extent here */
1137*f6dc9357SAndroid Build Coastguard Worker for (unsigned k = 1; k < item.Extents.Size(); k++)
1138*f6dc9357SAndroid Build Coastguard Worker {
1139*f6dc9357SAndroid Build Coastguard Worker const CMyExtent &e = item.Extents[k];
1140*f6dc9357SAndroid Build Coastguard Worker if (e.GetLen() != 0)
1141*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1142*f6dc9357SAndroid Build Coastguard Worker }
1143*f6dc9357SAndroid Build Coastguard Worker }
1144*f6dc9357SAndroid Build Coastguard Worker
1145*f6dc9357SAndroid Build Coastguard Worker const CMyExtent &e = item.Extents[0];
1146*f6dc9357SAndroid Build Coastguard Worker const CPartition &part = Partitions[pm.PartitionIndex];
1147*f6dc9357SAndroid Build Coastguard Worker CPartition mp = part;
1148*f6dc9357SAndroid Build Coastguard Worker mp.IsMetadata = true;
1149*f6dc9357SAndroid Build Coastguard Worker // mp.Number = part.Number;
1150*f6dc9357SAndroid Build Coastguard Worker mp.Pos = part.Pos + e.Pos;
1151*f6dc9357SAndroid Build Coastguard Worker mp.Len = e.Len >> SecLogSize;
1152*f6dc9357SAndroid Build Coastguard Worker pm.PartitionIndex = Partitions.Add(mp);
1153*f6dc9357SAndroid Build Coastguard Worker }
1154*f6dc9357SAndroid Build Coastguard Worker // Items.DeleteBack(); // we can delete that metadata item
1155*f6dc9357SAndroid Build Coastguard Worker
1156*f6dc9357SAndroid Build Coastguard Worker /*
1157*f6dc9357SAndroid Build Coastguard Worker // short version of code to read metadata file.
1158*f6dc9357SAndroid Build Coastguard Worker RINOK(CInArchive::Read(volIndex, pmIndex, pm.MetadataFileLocation, 224, buf));
1159*f6dc9357SAndroid Build Coastguard Worker CTag tag;
1160*f6dc9357SAndroid Build Coastguard Worker RINOK(tag.Parse(buf, 224));
1161*f6dc9357SAndroid Build Coastguard Worker if (tag.Id != DESC_TYPE_ExtendedFile)
1162*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1163*f6dc9357SAndroid Build Coastguard Worker CShortAllocDesc sad;
1164*f6dc9357SAndroid Build Coastguard Worker sad.Parse(buf + 216);
1165*f6dc9357SAndroid Build Coastguard Worker const CPartition &part = Partitions[pm.PartitionIndex];
1166*f6dc9357SAndroid Build Coastguard Worker CPartition mp = part;
1167*f6dc9357SAndroid Build Coastguard Worker mp.IsMetadata = true;
1168*f6dc9357SAndroid Build Coastguard Worker // mp.Number = part.Number;
1169*f6dc9357SAndroid Build Coastguard Worker mp.Pos = part.Pos + sad.Pos;
1170*f6dc9357SAndroid Build Coastguard Worker mp.Len = sad.Len >> SecLogSize;
1171*f6dc9357SAndroid Build Coastguard Worker pm.PartitionIndex = Partitions.Add(mp);
1172*f6dc9357SAndroid Build Coastguard Worker */
1173*f6dc9357SAndroid Build Coastguard Worker }
1174*f6dc9357SAndroid Build Coastguard Worker }
1175*f6dc9357SAndroid Build Coastguard Worker
1176*f6dc9357SAndroid Build Coastguard Worker RINOK(_progress->SetTotal(totalSize))
1177*f6dc9357SAndroid Build Coastguard Worker
1178*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\n Read files"));
1179*f6dc9357SAndroid Build Coastguard Worker
1180*f6dc9357SAndroid Build Coastguard Worker for (volIndex = 0; volIndex < LogVols.Size(); volIndex++)
1181*f6dc9357SAndroid Build Coastguard Worker {
1182*f6dc9357SAndroid Build Coastguard Worker CLogVol &vol = LogVols[volIndex];
1183*f6dc9357SAndroid Build Coastguard Worker
1184*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\nLogVol %2d", volIndex));
1185*f6dc9357SAndroid Build Coastguard Worker
1186*f6dc9357SAndroid Build Coastguard Worker CLongAllocDesc nextExtent = vol.FileSetLocation;
1187*f6dc9357SAndroid Build Coastguard Worker // while (nextExtent.ExtentLen != 0)
1188*f6dc9357SAndroid Build Coastguard Worker // for (int i = 0; i < 1; i++)
1189*f6dc9357SAndroid Build Coastguard Worker {
1190*f6dc9357SAndroid Build Coastguard Worker if (nextExtent.GetLen() < 512)
1191*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1192*f6dc9357SAndroid Build Coastguard Worker CByteBuffer buf2(nextExtent.GetLen());
1193*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadLad(volIndex, nextExtent, buf2))
1194*f6dc9357SAndroid Build Coastguard Worker const Byte *p = buf2;
1195*f6dc9357SAndroid Build Coastguard Worker const size_t size = nextExtent.GetLen();
1196*f6dc9357SAndroid Build Coastguard Worker
1197*f6dc9357SAndroid Build Coastguard Worker CTag tag;
1198*f6dc9357SAndroid Build Coastguard Worker RINOK(tag.Parse(p, size))
1199*f6dc9357SAndroid Build Coastguard Worker
1200*f6dc9357SAndroid Build Coastguard Worker /*
1201*f6dc9357SAndroid Build Coastguard Worker // commented in 22.01
1202*f6dc9357SAndroid Build Coastguard Worker if (tag.Id == DESC_TYPE_ExtendedFile)
1203*f6dc9357SAndroid Build Coastguard Worker {
1204*f6dc9357SAndroid Build Coastguard Worker // ECMA 4 / 14.17
1205*f6dc9357SAndroid Build Coastguard Worker // 2.60 ??
1206*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1207*f6dc9357SAndroid Build Coastguard Worker }
1208*f6dc9357SAndroid Build Coastguard Worker */
1209*f6dc9357SAndroid Build Coastguard Worker
1210*f6dc9357SAndroid Build Coastguard Worker if (tag.Id != DESC_TYPE_FileSet)
1211*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1212*f6dc9357SAndroid Build Coastguard Worker
1213*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\n FileSet", volIndex));
1214*f6dc9357SAndroid Build Coastguard Worker CFileSet fs;
1215*f6dc9357SAndroid Build Coastguard Worker fs.RecordingTime.Parse(p + 16);
1216*f6dc9357SAndroid Build Coastguard Worker // fs.InterchangeLevel = Get16(p + 18);
1217*f6dc9357SAndroid Build Coastguard Worker // fs.MaxInterchangeLevel = Get16(p + 20);
1218*f6dc9357SAndroid Build Coastguard Worker fs.FileSetNumber = Get32(p + 40);
1219*f6dc9357SAndroid Build Coastguard Worker fs.FileSetDescNumber = Get32(p + 44);
1220*f6dc9357SAndroid Build Coastguard Worker
1221*f6dc9357SAndroid Build Coastguard Worker fs.LogicalVolumeId.Parse(p + 112);
1222*f6dc9357SAndroid Build Coastguard Worker fs.Id.Parse(p + 304);
1223*f6dc9357SAndroid Build Coastguard Worker fs.CopyrightId.Parse(p + 336);
1224*f6dc9357SAndroid Build Coastguard Worker fs.AbstractId.Parse(p + 368);
1225*f6dc9357SAndroid Build Coastguard Worker
1226*f6dc9357SAndroid Build Coastguard Worker fs.RootDirICB.Parse(p + 400);
1227*f6dc9357SAndroid Build Coastguard Worker fs.DomainId.Parse(p + 416);
1228*f6dc9357SAndroid Build Coastguard Worker
1229*f6dc9357SAndroid Build Coastguard Worker // fs.SystemStreamDirICB.Parse(p + 464);
1230*f6dc9357SAndroid Build Coastguard Worker
1231*f6dc9357SAndroid Build Coastguard Worker vol.FileSets.Add(fs);
1232*f6dc9357SAndroid Build Coastguard Worker
1233*f6dc9357SAndroid Build Coastguard Worker // nextExtent.Parse(p + 448);
1234*f6dc9357SAndroid Build Coastguard Worker }
1235*f6dc9357SAndroid Build Coastguard Worker
1236*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (fsIndex, vol.FileSets)
1237*f6dc9357SAndroid Build Coastguard Worker {
1238*f6dc9357SAndroid Build Coastguard Worker CFileSet &fs = vol.FileSets[fsIndex];
1239*f6dc9357SAndroid Build Coastguard Worker const unsigned fileIndex = Files.Size();
1240*f6dc9357SAndroid Build Coastguard Worker Files.AddNew();
1241*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadFileItem(volIndex, fsIndex, fs.RootDirICB,
1242*f6dc9357SAndroid Build Coastguard Worker true, // isDir
1243*f6dc9357SAndroid Build Coastguard Worker kNumRecursionLevelsMax))
1244*f6dc9357SAndroid Build Coastguard Worker RINOK(FillRefs(fs, fileIndex, -1, kNumRecursionLevelsMax))
1245*f6dc9357SAndroid Build Coastguard Worker }
1246*f6dc9357SAndroid Build Coastguard Worker }
1247*f6dc9357SAndroid Build Coastguard Worker
1248*f6dc9357SAndroid Build Coastguard Worker
1249*f6dc9357SAndroid Build Coastguard Worker for (volIndex = 0; volIndex < LogVols.Size(); volIndex++)
1250*f6dc9357SAndroid Build Coastguard Worker {
1251*f6dc9357SAndroid Build Coastguard Worker const CLogVol &vol = LogVols[volIndex];
1252*f6dc9357SAndroid Build Coastguard Worker // bool showFileSetName = (vol.FileSets.Size() > 1);
1253*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (fsIndex, vol.FileSets)
1254*f6dc9357SAndroid Build Coastguard Worker {
1255*f6dc9357SAndroid Build Coastguard Worker const CFileSet &fs = vol.FileSets[fsIndex];
1256*f6dc9357SAndroid Build Coastguard Worker for (unsigned i =
1257*f6dc9357SAndroid Build Coastguard Worker // ((showVolName || showFileSetName) ? 0 : 1)
1258*f6dc9357SAndroid Build Coastguard Worker 0; i < fs.Refs.Size(); i++)
1259*f6dc9357SAndroid Build Coastguard Worker {
1260*f6dc9357SAndroid Build Coastguard Worker const CRef &ref = vol.FileSets[fsIndex].Refs[i];
1261*f6dc9357SAndroid Build Coastguard Worker const CFile &file = Files[ref.FileIndex];
1262*f6dc9357SAndroid Build Coastguard Worker const CItem &item = Items[file.ItemIndex];
1263*f6dc9357SAndroid Build Coastguard Worker UInt64 size = item.Size;
1264*f6dc9357SAndroid Build Coastguard Worker
1265*f6dc9357SAndroid Build Coastguard Worker if (!item.IsRecAndAlloc() || !item.CheckChunkSizes() || !CheckItemExtents(volIndex, item))
1266*f6dc9357SAndroid Build Coastguard Worker continue;
1267*f6dc9357SAndroid Build Coastguard Worker
1268*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (extentIndex, item.Extents)
1269*f6dc9357SAndroid Build Coastguard Worker {
1270*f6dc9357SAndroid Build Coastguard Worker const CMyExtent &extent = item.Extents[extentIndex];
1271*f6dc9357SAndroid Build Coastguard Worker const UInt32 len = extent.GetLen();
1272*f6dc9357SAndroid Build Coastguard Worker if (len == 0)
1273*f6dc9357SAndroid Build Coastguard Worker continue;
1274*f6dc9357SAndroid Build Coastguard Worker if (size < len)
1275*f6dc9357SAndroid Build Coastguard Worker break;
1276*f6dc9357SAndroid Build Coastguard Worker
1277*f6dc9357SAndroid Build Coastguard Worker const unsigned partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex;
1278*f6dc9357SAndroid Build Coastguard Worker const UInt32 logBlockNumber = extent.Pos;
1279*f6dc9357SAndroid Build Coastguard Worker const CPartition &partition = Partitions[partitionIndex];
1280*f6dc9357SAndroid Build Coastguard Worker const UInt64 offset = ((UInt64)partition.Pos << SecLogSize) +
1281*f6dc9357SAndroid Build Coastguard Worker (UInt64)logBlockNumber * vol.BlockSize;
1282*f6dc9357SAndroid Build Coastguard Worker UpdatePhySize(offset + len);
1283*f6dc9357SAndroid Build Coastguard Worker }
1284*f6dc9357SAndroid Build Coastguard Worker }
1285*f6dc9357SAndroid Build Coastguard Worker }
1286*f6dc9357SAndroid Build Coastguard Worker }
1287*f6dc9357SAndroid Build Coastguard Worker
1288*f6dc9357SAndroid Build Coastguard Worker {
1289*f6dc9357SAndroid Build Coastguard Worker const UInt32 secMask = ((UInt32)1 << SecLogSize) - 1;
1290*f6dc9357SAndroid Build Coastguard Worker PhySize = (PhySize + secMask) & ~(UInt64)secMask;
1291*f6dc9357SAndroid Build Coastguard Worker }
1292*f6dc9357SAndroid Build Coastguard Worker
1293*f6dc9357SAndroid Build Coastguard Worker NoEndAnchor = true;
1294*f6dc9357SAndroid Build Coastguard Worker
1295*f6dc9357SAndroid Build Coastguard Worker if (PhySize < fileSize)
1296*f6dc9357SAndroid Build Coastguard Worker {
1297*f6dc9357SAndroid Build Coastguard Worker UInt64 rem = fileSize - PhySize;
1298*f6dc9357SAndroid Build Coastguard Worker const size_t secSize = (size_t)1 << SecLogSize;
1299*f6dc9357SAndroid Build Coastguard Worker
1300*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_stream, PhySize))
1301*f6dc9357SAndroid Build Coastguard Worker
1302*f6dc9357SAndroid Build Coastguard Worker // some UDF images contain ZEROs before "Anchor Volume Descriptor Pointer" at the end
1303*f6dc9357SAndroid Build Coastguard Worker
1304*f6dc9357SAndroid Build Coastguard Worker for (unsigned sec = 0; sec < 1024; sec++)
1305*f6dc9357SAndroid Build Coastguard Worker {
1306*f6dc9357SAndroid Build Coastguard Worker if (rem == 0)
1307*f6dc9357SAndroid Build Coastguard Worker break;
1308*f6dc9357SAndroid Build Coastguard Worker
1309*f6dc9357SAndroid Build Coastguard Worker size_t readSize = secSize;
1310*f6dc9357SAndroid Build Coastguard Worker if (readSize > rem)
1311*f6dc9357SAndroid Build Coastguard Worker readSize = (size_t)rem;
1312*f6dc9357SAndroid Build Coastguard Worker
1313*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream(_stream, buf, &readSize))
1314*f6dc9357SAndroid Build Coastguard Worker
1315*f6dc9357SAndroid Build Coastguard Worker if (readSize == 0)
1316*f6dc9357SAndroid Build Coastguard Worker break;
1317*f6dc9357SAndroid Build Coastguard Worker
1318*f6dc9357SAndroid Build Coastguard Worker // some udf contain many EndAnchors
1319*f6dc9357SAndroid Build Coastguard Worker if (readSize == secSize /* && NoEndAnchor */)
1320*f6dc9357SAndroid Build Coastguard Worker {
1321*f6dc9357SAndroid Build Coastguard Worker CTag tag;
1322*f6dc9357SAndroid Build Coastguard Worker if (tag.Parse(buf, readSize) == S_OK
1323*f6dc9357SAndroid Build Coastguard Worker && tag.Id == DESC_TYPE_AnchorVolPtr
1324*f6dc9357SAndroid Build Coastguard Worker && Get32(buf + 12) == (UInt32)((fileSize - rem) >> SecLogSize))
1325*f6dc9357SAndroid Build Coastguard Worker {
1326*f6dc9357SAndroid Build Coastguard Worker NoEndAnchor = false;
1327*f6dc9357SAndroid Build Coastguard Worker rem -= readSize;
1328*f6dc9357SAndroid Build Coastguard Worker PhySize = fileSize - rem;
1329*f6dc9357SAndroid Build Coastguard Worker continue;
1330*f6dc9357SAndroid Build Coastguard Worker }
1331*f6dc9357SAndroid Build Coastguard Worker }
1332*f6dc9357SAndroid Build Coastguard Worker
1333*f6dc9357SAndroid Build Coastguard Worker size_t i;
1334*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < readSize && buf[i] == 0; i++);
1335*f6dc9357SAndroid Build Coastguard Worker if (i != readSize)
1336*f6dc9357SAndroid Build Coastguard Worker break;
1337*f6dc9357SAndroid Build Coastguard Worker rem -= readSize;
1338*f6dc9357SAndroid Build Coastguard Worker }
1339*f6dc9357SAndroid Build Coastguard Worker
1340*f6dc9357SAndroid Build Coastguard Worker if (rem == 0)
1341*f6dc9357SAndroid Build Coastguard Worker PhySize = fileSize;
1342*f6dc9357SAndroid Build Coastguard Worker }
1343*f6dc9357SAndroid Build Coastguard Worker
1344*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1345*f6dc9357SAndroid Build Coastguard Worker }
1346*f6dc9357SAndroid Build Coastguard Worker
1347*f6dc9357SAndroid Build Coastguard Worker
Open(IInStream * inStream,CProgressVirt * progress)1348*f6dc9357SAndroid Build Coastguard Worker HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress)
1349*f6dc9357SAndroid Build Coastguard Worker {
1350*f6dc9357SAndroid Build Coastguard Worker _progress = progress;
1351*f6dc9357SAndroid Build Coastguard Worker _stream = inStream;
1352*f6dc9357SAndroid Build Coastguard Worker HRESULT res = Open2();
1353*f6dc9357SAndroid Build Coastguard Worker if (res == S_FALSE && IsArc && !UnexpectedEnd)
1354*f6dc9357SAndroid Build Coastguard Worker Unsupported = true;
1355*f6dc9357SAndroid Build Coastguard Worker return res;
1356*f6dc9357SAndroid Build Coastguard Worker
1357*f6dc9357SAndroid Build Coastguard Worker /*
1358*f6dc9357SAndroid Build Coastguard Worker HRESULT res;
1359*f6dc9357SAndroid Build Coastguard Worker try
1360*f6dc9357SAndroid Build Coastguard Worker {
1361*f6dc9357SAndroid Build Coastguard Worker res = Open2();
1362*f6dc9357SAndroid Build Coastguard Worker }
1363*f6dc9357SAndroid Build Coastguard Worker catch(...)
1364*f6dc9357SAndroid Build Coastguard Worker {
1365*f6dc9357SAndroid Build Coastguard Worker // Clear();
1366*f6dc9357SAndroid Build Coastguard Worker // res = S_FALSE;
1367*f6dc9357SAndroid Build Coastguard Worker _stream.Release();
1368*f6dc9357SAndroid Build Coastguard Worker throw;
1369*f6dc9357SAndroid Build Coastguard Worker }
1370*f6dc9357SAndroid Build Coastguard Worker _stream.Release();
1371*f6dc9357SAndroid Build Coastguard Worker return res;
1372*f6dc9357SAndroid Build Coastguard Worker */
1373*f6dc9357SAndroid Build Coastguard Worker }
1374*f6dc9357SAndroid Build Coastguard Worker
Clear()1375*f6dc9357SAndroid Build Coastguard Worker void CInArchive::Clear()
1376*f6dc9357SAndroid Build Coastguard Worker {
1377*f6dc9357SAndroid Build Coastguard Worker IsArc = false;
1378*f6dc9357SAndroid Build Coastguard Worker Unsupported = false;
1379*f6dc9357SAndroid Build Coastguard Worker UnexpectedEnd = false;
1380*f6dc9357SAndroid Build Coastguard Worker NoEndAnchor = false;
1381*f6dc9357SAndroid Build Coastguard Worker
1382*f6dc9357SAndroid Build Coastguard Worker PhySize = 0;
1383*f6dc9357SAndroid Build Coastguard Worker FileSize = 0;
1384*f6dc9357SAndroid Build Coastguard Worker
1385*f6dc9357SAndroid Build Coastguard Worker Partitions.Clear();
1386*f6dc9357SAndroid Build Coastguard Worker LogVols.Clear();
1387*f6dc9357SAndroid Build Coastguard Worker PrimeVols.Clear();
1388*f6dc9357SAndroid Build Coastguard Worker Items.Clear();
1389*f6dc9357SAndroid Build Coastguard Worker Files.Clear();
1390*f6dc9357SAndroid Build Coastguard Worker _fileNameLengthTotal = 0;
1391*f6dc9357SAndroid Build Coastguard Worker _numRefs = 0;
1392*f6dc9357SAndroid Build Coastguard Worker _numExtents = 0;
1393*f6dc9357SAndroid Build Coastguard Worker _inlineExtentsSize = 0;
1394*f6dc9357SAndroid Build Coastguard Worker _processedProgressBytes = 0;
1395*f6dc9357SAndroid Build Coastguard Worker }
1396*f6dc9357SAndroid Build Coastguard Worker
1397*f6dc9357SAndroid Build Coastguard Worker
1398*f6dc9357SAndroid Build Coastguard Worker static const char * const g_PartitionTypes[] =
1399*f6dc9357SAndroid Build Coastguard Worker {
1400*f6dc9357SAndroid Build Coastguard Worker "Pseudo-Overwritable" // UDF
1401*f6dc9357SAndroid Build Coastguard Worker , "Read-Only"
1402*f6dc9357SAndroid Build Coastguard Worker , "Write-Once"
1403*f6dc9357SAndroid Build Coastguard Worker , "Rewritable"
1404*f6dc9357SAndroid Build Coastguard Worker , "Overwritable"
1405*f6dc9357SAndroid Build Coastguard Worker };
1406*f6dc9357SAndroid Build Coastguard Worker
1407*f6dc9357SAndroid Build Coastguard Worker
AddComment_Align(UString & s)1408*f6dc9357SAndroid Build Coastguard Worker static void AddComment_Align(UString &s)
1409*f6dc9357SAndroid Build Coastguard Worker {
1410*f6dc9357SAndroid Build Coastguard Worker s += " ";
1411*f6dc9357SAndroid Build Coastguard Worker }
1412*f6dc9357SAndroid Build Coastguard Worker
AddComment_PropName(UString & s,const char * name)1413*f6dc9357SAndroid Build Coastguard Worker static void AddComment_PropName(UString &s, const char *name)
1414*f6dc9357SAndroid Build Coastguard Worker {
1415*f6dc9357SAndroid Build Coastguard Worker AddComment_Align(s);
1416*f6dc9357SAndroid Build Coastguard Worker s += name;
1417*f6dc9357SAndroid Build Coastguard Worker s += ": ";
1418*f6dc9357SAndroid Build Coastguard Worker }
1419*f6dc9357SAndroid Build Coastguard Worker
AddComment_UInt32(UString & s,const char * name,UInt32 val)1420*f6dc9357SAndroid Build Coastguard Worker static void AddComment_UInt32(UString &s, const char *name, UInt32 val)
1421*f6dc9357SAndroid Build Coastguard Worker {
1422*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, name);
1423*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(val);
1424*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1425*f6dc9357SAndroid Build Coastguard Worker }
1426*f6dc9357SAndroid Build Coastguard Worker
AddComment_UInt32_2(UString & s,const char * name,UInt32 val)1427*f6dc9357SAndroid Build Coastguard Worker static void AddComment_UInt32_2(UString &s, const char *name, UInt32 val)
1428*f6dc9357SAndroid Build Coastguard Worker {
1429*f6dc9357SAndroid Build Coastguard Worker AddComment_Align(s);
1430*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, name, val);
1431*f6dc9357SAndroid Build Coastguard Worker }
1432*f6dc9357SAndroid Build Coastguard Worker
1433*f6dc9357SAndroid Build Coastguard Worker
AddComment_UInt64(UString & s,const char * name,UInt64 val)1434*f6dc9357SAndroid Build Coastguard Worker static void AddComment_UInt64(UString &s, const char *name, UInt64 val)
1435*f6dc9357SAndroid Build Coastguard Worker {
1436*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, name);
1437*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt64(val);
1438*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1439*f6dc9357SAndroid Build Coastguard Worker }
1440*f6dc9357SAndroid Build Coastguard Worker
AddComment_RegId(UString & s,const char * name,const CRegId & ri)1441*f6dc9357SAndroid Build Coastguard Worker static void AddComment_RegId(UString &s, const char *name, const CRegId &ri)
1442*f6dc9357SAndroid Build Coastguard Worker {
1443*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, name);
1444*f6dc9357SAndroid Build Coastguard Worker ri.AddCommentTo(s);
1445*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1446*f6dc9357SAndroid Build Coastguard Worker }
1447*f6dc9357SAndroid Build Coastguard Worker
AddComment_RegId_Domain(UString & s,const char * name,const CRegId & ri)1448*f6dc9357SAndroid Build Coastguard Worker static void AddComment_RegId_Domain(UString &s, const char *name, const CRegId &ri)
1449*f6dc9357SAndroid Build Coastguard Worker {
1450*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, name);
1451*f6dc9357SAndroid Build Coastguard Worker ri.AddCommentTo(s);
1452*f6dc9357SAndroid Build Coastguard Worker {
1453*f6dc9357SAndroid Build Coastguard Worker UString s2;
1454*f6dc9357SAndroid Build Coastguard Worker ri.AddUdfVersionTo(s2);
1455*f6dc9357SAndroid Build Coastguard Worker if (!s2.IsEmpty())
1456*f6dc9357SAndroid Build Coastguard Worker {
1457*f6dc9357SAndroid Build Coastguard Worker s += "::";
1458*f6dc9357SAndroid Build Coastguard Worker s += s2;
1459*f6dc9357SAndroid Build Coastguard Worker }
1460*f6dc9357SAndroid Build Coastguard Worker }
1461*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1462*f6dc9357SAndroid Build Coastguard Worker }
1463*f6dc9357SAndroid Build Coastguard Worker
1464*f6dc9357SAndroid Build Coastguard Worker
1465*f6dc9357SAndroid Build Coastguard Worker // UDF 6.3.1 OS Class
1466*f6dc9357SAndroid Build Coastguard Worker
1467*f6dc9357SAndroid Build Coastguard Worker static const char * const g_OsClasses[] =
1468*f6dc9357SAndroid Build Coastguard Worker {
1469*f6dc9357SAndroid Build Coastguard Worker NULL
1470*f6dc9357SAndroid Build Coastguard Worker , "DOS"
1471*f6dc9357SAndroid Build Coastguard Worker , "OS/2"
1472*f6dc9357SAndroid Build Coastguard Worker , "Macintosh OS"
1473*f6dc9357SAndroid Build Coastguard Worker , "UNIX"
1474*f6dc9357SAndroid Build Coastguard Worker , "Windows 9x"
1475*f6dc9357SAndroid Build Coastguard Worker , "Windows NT"
1476*f6dc9357SAndroid Build Coastguard Worker , "OS/400"
1477*f6dc9357SAndroid Build Coastguard Worker , "BeOS"
1478*f6dc9357SAndroid Build Coastguard Worker , "Windows CE"
1479*f6dc9357SAndroid Build Coastguard Worker };
1480*f6dc9357SAndroid Build Coastguard Worker
1481*f6dc9357SAndroid Build Coastguard Worker // UDF 6.3.2 OS Identifier
1482*f6dc9357SAndroid Build Coastguard Worker
1483*f6dc9357SAndroid Build Coastguard Worker static const char * const g_OsIds_Unix[] =
1484*f6dc9357SAndroid Build Coastguard Worker {
1485*f6dc9357SAndroid Build Coastguard Worker NULL // "Generic"
1486*f6dc9357SAndroid Build Coastguard Worker , "AIX"
1487*f6dc9357SAndroid Build Coastguard Worker , "SUN OS / Solaris"
1488*f6dc9357SAndroid Build Coastguard Worker , "HP/UX"
1489*f6dc9357SAndroid Build Coastguard Worker , "Silicon Graphics Irix"
1490*f6dc9357SAndroid Build Coastguard Worker , "Linux"
1491*f6dc9357SAndroid Build Coastguard Worker , "MKLinux"
1492*f6dc9357SAndroid Build Coastguard Worker , "FreeBSD"
1493*f6dc9357SAndroid Build Coastguard Worker , "NetBSD"
1494*f6dc9357SAndroid Build Coastguard Worker };
1495*f6dc9357SAndroid Build Coastguard Worker
AddOs_Class_Id(UString & s,const Byte * p)1496*f6dc9357SAndroid Build Coastguard Worker static void AddOs_Class_Id(UString &s, const Byte *p)
1497*f6dc9357SAndroid Build Coastguard Worker {
1498*f6dc9357SAndroid Build Coastguard Worker // UDF 2.1.5.3 Implementation Identifier Suffix
1499*f6dc9357SAndroid Build Coastguard Worker // Appendix 6.3 Operating System Identifiers.
1500*f6dc9357SAndroid Build Coastguard Worker const Byte osClass = p[0];
1501*f6dc9357SAndroid Build Coastguard Worker if (osClass != 0)
1502*f6dc9357SAndroid Build Coastguard Worker {
1503*f6dc9357SAndroid Build Coastguard Worker s += "::";
1504*f6dc9357SAndroid Build Coastguard Worker s += TypeToString(g_OsClasses, Z7_ARRAY_SIZE(g_OsClasses), osClass);
1505*f6dc9357SAndroid Build Coastguard Worker }
1506*f6dc9357SAndroid Build Coastguard Worker const Byte osId = p[1];
1507*f6dc9357SAndroid Build Coastguard Worker if (osId != 0)
1508*f6dc9357SAndroid Build Coastguard Worker {
1509*f6dc9357SAndroid Build Coastguard Worker s += "::";
1510*f6dc9357SAndroid Build Coastguard Worker if (osClass == 4) // unix
1511*f6dc9357SAndroid Build Coastguard Worker {
1512*f6dc9357SAndroid Build Coastguard Worker s += TypeToString(g_OsIds_Unix, Z7_ARRAY_SIZE(g_OsIds_Unix), osId);
1513*f6dc9357SAndroid Build Coastguard Worker }
1514*f6dc9357SAndroid Build Coastguard Worker else
1515*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(osId);
1516*f6dc9357SAndroid Build Coastguard Worker }
1517*f6dc9357SAndroid Build Coastguard Worker }
1518*f6dc9357SAndroid Build Coastguard Worker
1519*f6dc9357SAndroid Build Coastguard Worker
AddComment_RegId_Impl(UString & s,const char * name,const CRegId & ri)1520*f6dc9357SAndroid Build Coastguard Worker static void AddComment_RegId_Impl(UString &s, const char *name, const CRegId &ri)
1521*f6dc9357SAndroid Build Coastguard Worker {
1522*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, name);
1523*f6dc9357SAndroid Build Coastguard Worker ri.AddCommentTo(s);
1524*f6dc9357SAndroid Build Coastguard Worker {
1525*f6dc9357SAndroid Build Coastguard Worker AddOs_Class_Id(s, ri.Suffix);
1526*f6dc9357SAndroid Build Coastguard Worker }
1527*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1528*f6dc9357SAndroid Build Coastguard Worker }
1529*f6dc9357SAndroid Build Coastguard Worker
1530*f6dc9357SAndroid Build Coastguard Worker
AddComment_RegId_UdfId(UString & s,const char * name,const CRegId & ri)1531*f6dc9357SAndroid Build Coastguard Worker static void AddComment_RegId_UdfId(UString &s, const char *name, const CRegId &ri)
1532*f6dc9357SAndroid Build Coastguard Worker {
1533*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, name);
1534*f6dc9357SAndroid Build Coastguard Worker ri.AddCommentTo(s);
1535*f6dc9357SAndroid Build Coastguard Worker {
1536*f6dc9357SAndroid Build Coastguard Worker // UDF 2.1.5.3
1537*f6dc9357SAndroid Build Coastguard Worker // UDF Identifier Suffix format
1538*f6dc9357SAndroid Build Coastguard Worker UString s2;
1539*f6dc9357SAndroid Build Coastguard Worker ri.AddUdfVersionTo(s2);
1540*f6dc9357SAndroid Build Coastguard Worker if (!s2.IsEmpty())
1541*f6dc9357SAndroid Build Coastguard Worker {
1542*f6dc9357SAndroid Build Coastguard Worker s += "::";
1543*f6dc9357SAndroid Build Coastguard Worker s += s2;
1544*f6dc9357SAndroid Build Coastguard Worker }
1545*f6dc9357SAndroid Build Coastguard Worker AddOs_Class_Id(s, &ri.Suffix[2]);
1546*f6dc9357SAndroid Build Coastguard Worker }
1547*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1548*f6dc9357SAndroid Build Coastguard Worker }
1549*f6dc9357SAndroid Build Coastguard Worker
AddComment_DString32(UString & s,const char * name,const CDString32 & d)1550*f6dc9357SAndroid Build Coastguard Worker static void AddComment_DString32(UString &s, const char *name, const CDString32 &d)
1551*f6dc9357SAndroid Build Coastguard Worker {
1552*f6dc9357SAndroid Build Coastguard Worker AddComment_Align(s);
1553*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, name);
1554*f6dc9357SAndroid Build Coastguard Worker s += d.GetString();
1555*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1556*f6dc9357SAndroid Build Coastguard Worker }
1557*f6dc9357SAndroid Build Coastguard Worker
GetComment() const1558*f6dc9357SAndroid Build Coastguard Worker UString CInArchive::GetComment() const
1559*f6dc9357SAndroid Build Coastguard Worker {
1560*f6dc9357SAndroid Build Coastguard Worker UString s;
1561*f6dc9357SAndroid Build Coastguard Worker {
1562*f6dc9357SAndroid Build Coastguard Worker s += "Primary Volumes:";
1563*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1564*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, PrimeVols)
1565*f6dc9357SAndroid Build Coastguard Worker {
1566*f6dc9357SAndroid Build Coastguard Worker if (i != 0)
1567*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1568*f6dc9357SAndroid Build Coastguard Worker const CPrimeVol &pv = PrimeVols[i];
1569*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt32(s, "VolumeDescriptorSequenceNumber", pv.VolumeDescriptorSequenceNumber);
1570*f6dc9357SAndroid Build Coastguard Worker // if (PrimeVols.Size() != 1 || pv.PrimaryVolumeDescriptorNumber != 0)
1571*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, "PrimaryVolumeDescriptorNumber", pv.PrimaryVolumeDescriptorNumber);
1572*f6dc9357SAndroid Build Coastguard Worker // if (pv.MaximumVolumeSequenceNumber != 1 || pv.VolumeSequenceNumber != 1)
1573*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, "VolumeSequenceNumber", pv.VolumeSequenceNumber);
1574*f6dc9357SAndroid Build Coastguard Worker if (pv.MaximumVolumeSequenceNumber != 1)
1575*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, "MaximumVolumeSequenceNumber", pv.MaximumVolumeSequenceNumber);
1576*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, "VolumeId");
1577*f6dc9357SAndroid Build Coastguard Worker s += pv.VolumeId.GetString();
1578*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1579*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, "VolumeSetId");
1580*f6dc9357SAndroid Build Coastguard Worker s += pv.VolumeSetId.GetString();
1581*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1582*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt32(s, "InterchangeLevel", pv.InterchangeLevel);
1583*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt32(s, "MaximumInterchangeLevel", pv.MaximumInterchangeLevel);
1584*f6dc9357SAndroid Build Coastguard Worker AddComment_RegId(s, "ApplicationId", pv.ApplicationId);
1585*f6dc9357SAndroid Build Coastguard Worker AddComment_RegId_Impl(s, "ImplementationId", pv.ImplId);
1586*f6dc9357SAndroid Build Coastguard Worker }
1587*f6dc9357SAndroid Build Coastguard Worker }
1588*f6dc9357SAndroid Build Coastguard Worker {
1589*f6dc9357SAndroid Build Coastguard Worker s += "Partitions:";
1590*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1591*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, Partitions)
1592*f6dc9357SAndroid Build Coastguard Worker {
1593*f6dc9357SAndroid Build Coastguard Worker if (i != 0)
1594*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1595*f6dc9357SAndroid Build Coastguard Worker const CPartition &part = Partitions[i];
1596*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, "PartitionIndex", i);
1597*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, "PartitionNumber", part.Number);
1598*f6dc9357SAndroid Build Coastguard Worker if (part.IsMetadata)
1599*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, "IsMetadata", 1);
1600*f6dc9357SAndroid Build Coastguard Worker else
1601*f6dc9357SAndroid Build Coastguard Worker {
1602*f6dc9357SAndroid Build Coastguard Worker AddComment_RegId(s, "ContentsId", part.ContentsId);
1603*f6dc9357SAndroid Build Coastguard Worker AddComment_RegId_Impl(s, "ImplementationId", part.ImplId);
1604*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, "AccessType");
1605*f6dc9357SAndroid Build Coastguard Worker s += TypeToString(g_PartitionTypes, Z7_ARRAY_SIZE(g_PartitionTypes), part.AccessType);
1606*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1607*f6dc9357SAndroid Build Coastguard Worker }
1608*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt64(s, "Size", (UInt64)part.Len << SecLogSize);
1609*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt64(s, "Pos", (UInt64)part.Pos << SecLogSize);
1610*f6dc9357SAndroid Build Coastguard Worker }
1611*f6dc9357SAndroid Build Coastguard Worker }
1612*f6dc9357SAndroid Build Coastguard Worker s += "Logical Volumes:";
1613*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1614*f6dc9357SAndroid Build Coastguard Worker {
1615*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, LogVols)
1616*f6dc9357SAndroid Build Coastguard Worker {
1617*f6dc9357SAndroid Build Coastguard Worker if (i != 0)
1618*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1619*f6dc9357SAndroid Build Coastguard Worker const CLogVol &vol = LogVols[i];
1620*f6dc9357SAndroid Build Coastguard Worker if (LogVols.Size() != 1)
1621*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, "Number", i);
1622*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, "Id");
1623*f6dc9357SAndroid Build Coastguard Worker s += vol.Id.GetString();
1624*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1625*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32(s, "BlockSize", vol.BlockSize);
1626*f6dc9357SAndroid Build Coastguard Worker AddComment_RegId_Domain(s, "DomainId", vol.DomainId);
1627*f6dc9357SAndroid Build Coastguard Worker AddComment_RegId_Impl(s, "ImplementationId", vol.ImplId);
1628*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt64(s, "IntegritySequenceExtent_Len", vol.IntegritySequenceExtent.Len);
1629*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt64(s, "IntegritySequenceExtent_Pos", (UInt64)vol.IntegritySequenceExtent.Pos << SecLogSize);
1630*f6dc9357SAndroid Build Coastguard Worker
1631*f6dc9357SAndroid Build Coastguard Worker s += " Partition Maps:";
1632*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1633*f6dc9357SAndroid Build Coastguard Worker {
1634*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (j, vol.PartitionMaps)
1635*f6dc9357SAndroid Build Coastguard Worker {
1636*f6dc9357SAndroid Build Coastguard Worker if (j != 0)
1637*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1638*f6dc9357SAndroid Build Coastguard Worker const CPartitionMap &pm = vol.PartitionMaps[j];
1639*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32_2(s, "PartitionMap", j);
1640*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32_2(s, "Type", pm.Type);
1641*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32_2(s, "VolumeSequenceNumber", pm.VolumeSequenceNumber);
1642*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32_2(s, "PartitionNumber", pm.PartitionNumber);
1643*f6dc9357SAndroid Build Coastguard Worker if (pm.Type == 2)
1644*f6dc9357SAndroid Build Coastguard Worker {
1645*f6dc9357SAndroid Build Coastguard Worker AddComment_UInt32_2(s, "MetadataFileLocation", pm.MetadataFileLocation);
1646*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt32_2(s, "MetadataMirrorFileLocation", pm.MetadataMirrorFileLocation);
1647*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt32_2(s, "MetadataBitmapFileLocation", pm.MetadataBitmapFileLocation);
1648*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt32_2(s, "AllocationUnitSize", pm.AllocationUnitSize);
1649*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt32_2(s, "AlignmentUnitSize", pm.AlignmentUnitSize);
1650*f6dc9357SAndroid Build Coastguard Worker // AddComment_UInt32_2(s, "Flags", pm.Flags);
1651*f6dc9357SAndroid Build Coastguard Worker AddComment_Align(s); AddComment_RegId_UdfId(s, "PartitionTypeId", pm.PartitionTypeId);
1652*f6dc9357SAndroid Build Coastguard Worker }
1653*f6dc9357SAndroid Build Coastguard Worker }
1654*f6dc9357SAndroid Build Coastguard Worker }
1655*f6dc9357SAndroid Build Coastguard Worker s += " File Sets:";
1656*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1657*f6dc9357SAndroid Build Coastguard Worker {
1658*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (j, vol.FileSets)
1659*f6dc9357SAndroid Build Coastguard Worker {
1660*f6dc9357SAndroid Build Coastguard Worker if (j != 0)
1661*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1662*f6dc9357SAndroid Build Coastguard Worker const CFileSet &fs = vol.FileSets[j];
1663*f6dc9357SAndroid Build Coastguard Worker AddComment_Align(s); AddComment_UInt32(s, "FileSetNumber", fs.FileSetNumber);
1664*f6dc9357SAndroid Build Coastguard Worker AddComment_Align(s); AddComment_UInt32(s, "FileSetDescNumber", fs.FileSetDescNumber);
1665*f6dc9357SAndroid Build Coastguard Worker
1666*f6dc9357SAndroid Build Coastguard Worker AddComment_Align(s);
1667*f6dc9357SAndroid Build Coastguard Worker AddComment_PropName(s, "LogicalVolumeId");
1668*f6dc9357SAndroid Build Coastguard Worker s += fs.LogicalVolumeId.GetString();
1669*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
1670*f6dc9357SAndroid Build Coastguard Worker
1671*f6dc9357SAndroid Build Coastguard Worker AddComment_DString32(s, "Id", fs.Id);
1672*f6dc9357SAndroid Build Coastguard Worker AddComment_DString32(s, "CopyrightId", fs.CopyrightId);
1673*f6dc9357SAndroid Build Coastguard Worker AddComment_DString32(s, "AbstractId", fs.AbstractId);
1674*f6dc9357SAndroid Build Coastguard Worker
1675*f6dc9357SAndroid Build Coastguard Worker AddComment_Align(s);
1676*f6dc9357SAndroid Build Coastguard Worker AddComment_RegId_Domain(s, "DomainId", fs.DomainId);
1677*f6dc9357SAndroid Build Coastguard Worker }
1678*f6dc9357SAndroid Build Coastguard Worker }
1679*f6dc9357SAndroid Build Coastguard Worker }
1680*f6dc9357SAndroid Build Coastguard Worker }
1681*f6dc9357SAndroid Build Coastguard Worker return s;
1682*f6dc9357SAndroid Build Coastguard Worker }
1683*f6dc9357SAndroid Build Coastguard Worker
GetSpecName(const UString & name)1684*f6dc9357SAndroid Build Coastguard Worker static UString GetSpecName(const UString &name)
1685*f6dc9357SAndroid Build Coastguard Worker {
1686*f6dc9357SAndroid Build Coastguard Worker UString name2 = name;
1687*f6dc9357SAndroid Build Coastguard Worker name2.Trim();
1688*f6dc9357SAndroid Build Coastguard Worker if (name2.IsEmpty())
1689*f6dc9357SAndroid Build Coastguard Worker return UString("[]");
1690*f6dc9357SAndroid Build Coastguard Worker return name;
1691*f6dc9357SAndroid Build Coastguard Worker }
1692*f6dc9357SAndroid Build Coastguard Worker
UpdateWithName(UString & res,const UString & addString)1693*f6dc9357SAndroid Build Coastguard Worker static void UpdateWithName(UString &res, const UString &addString)
1694*f6dc9357SAndroid Build Coastguard Worker {
1695*f6dc9357SAndroid Build Coastguard Worker if (res.IsEmpty())
1696*f6dc9357SAndroid Build Coastguard Worker res = addString;
1697*f6dc9357SAndroid Build Coastguard Worker else
1698*f6dc9357SAndroid Build Coastguard Worker res.Insert(0, addString + WCHAR_PATH_SEPARATOR);
1699*f6dc9357SAndroid Build Coastguard Worker }
1700*f6dc9357SAndroid Build Coastguard Worker
GetItemPath(unsigned volIndex,unsigned fsIndex,unsigned refIndex,bool showVolName,bool showFsName) const1701*f6dc9357SAndroid Build Coastguard Worker UString CInArchive::GetItemPath(unsigned volIndex, unsigned fsIndex, unsigned refIndex,
1702*f6dc9357SAndroid Build Coastguard Worker bool showVolName, bool showFsName) const
1703*f6dc9357SAndroid Build Coastguard Worker {
1704*f6dc9357SAndroid Build Coastguard Worker // showVolName = true;
1705*f6dc9357SAndroid Build Coastguard Worker const CLogVol &vol = LogVols[volIndex];
1706*f6dc9357SAndroid Build Coastguard Worker const CFileSet &fs = vol.FileSets[fsIndex];
1707*f6dc9357SAndroid Build Coastguard Worker
1708*f6dc9357SAndroid Build Coastguard Worker UString name;
1709*f6dc9357SAndroid Build Coastguard Worker
1710*f6dc9357SAndroid Build Coastguard Worker for (;;)
1711*f6dc9357SAndroid Build Coastguard Worker {
1712*f6dc9357SAndroid Build Coastguard Worker const CRef &ref = fs.Refs[refIndex];
1713*f6dc9357SAndroid Build Coastguard Worker // we break on root file (that probably has empty name)
1714*f6dc9357SAndroid Build Coastguard Worker if (ref.Parent < 0)
1715*f6dc9357SAndroid Build Coastguard Worker break;
1716*f6dc9357SAndroid Build Coastguard Worker refIndex = (unsigned)ref.Parent;
1717*f6dc9357SAndroid Build Coastguard Worker UpdateWithName(name, GetSpecName(Files[ref.FileIndex].GetName()));
1718*f6dc9357SAndroid Build Coastguard Worker }
1719*f6dc9357SAndroid Build Coastguard Worker
1720*f6dc9357SAndroid Build Coastguard Worker if (showFsName)
1721*f6dc9357SAndroid Build Coastguard Worker {
1722*f6dc9357SAndroid Build Coastguard Worker UString newName ("File Set ");
1723*f6dc9357SAndroid Build Coastguard Worker newName.Add_UInt32(fsIndex);
1724*f6dc9357SAndroid Build Coastguard Worker UpdateWithName(name, newName);
1725*f6dc9357SAndroid Build Coastguard Worker }
1726*f6dc9357SAndroid Build Coastguard Worker
1727*f6dc9357SAndroid Build Coastguard Worker if (showVolName)
1728*f6dc9357SAndroid Build Coastguard Worker {
1729*f6dc9357SAndroid Build Coastguard Worker UString newName;
1730*f6dc9357SAndroid Build Coastguard Worker newName.Add_UInt32(volIndex);
1731*f6dc9357SAndroid Build Coastguard Worker UString newName2 = vol.GetName();
1732*f6dc9357SAndroid Build Coastguard Worker if (newName2.IsEmpty())
1733*f6dc9357SAndroid Build Coastguard Worker newName2 = "Volume";
1734*f6dc9357SAndroid Build Coastguard Worker newName.Add_Minus();
1735*f6dc9357SAndroid Build Coastguard Worker newName += newName2;
1736*f6dc9357SAndroid Build Coastguard Worker UpdateWithName(name, newName);
1737*f6dc9357SAndroid Build Coastguard Worker }
1738*f6dc9357SAndroid Build Coastguard Worker return name;
1739*f6dc9357SAndroid Build Coastguard Worker }
1740*f6dc9357SAndroid Build Coastguard Worker
1741*f6dc9357SAndroid Build Coastguard Worker }}
1742