1*f6dc9357SAndroid Build Coastguard Worker // LvmHandler.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/7zCrc.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuArch.h"
7*f6dc9357SAndroid Build Coastguard Worker
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ComTry.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MyBuffer.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StringToInt.h"
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/PropVariantUtils.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/TimeUtils.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 "HandlerCont.h"
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker #define Get32(p) GetUi32(p)
21*f6dc9357SAndroid Build Coastguard Worker #define Get64(p) GetUi64(p)
22*f6dc9357SAndroid Build Coastguard Worker
23*f6dc9357SAndroid Build Coastguard Worker #define LE_32(offs, dest) dest = Get32(p + (offs))
24*f6dc9357SAndroid Build Coastguard Worker #define LE_64(offs, dest) dest = Get64(p + (offs))
25*f6dc9357SAndroid Build Coastguard Worker
26*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
27*f6dc9357SAndroid Build Coastguard Worker
28*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
29*f6dc9357SAndroid Build Coastguard Worker namespace NLvm {
30*f6dc9357SAndroid Build Coastguard Worker
31*f6dc9357SAndroid Build Coastguard Worker #define SIGNATURE { 'L', 'A', 'B', 'E', 'L', 'O', 'N', 'E' }
32*f6dc9357SAndroid Build Coastguard Worker
33*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_SignatureSize = 8;
34*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature[k_SignatureSize] = SIGNATURE;
35*f6dc9357SAndroid Build Coastguard Worker
36*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_Signature2Size = 8;
37*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature2[k_Signature2Size] =
38*f6dc9357SAndroid Build Coastguard Worker { 'L', 'V', 'M', '2', ' ', '0', '0', '1' };
39*f6dc9357SAndroid Build Coastguard Worker
40*f6dc9357SAndroid Build Coastguard Worker static const Byte FMTT_MAGIC[16] =
41*f6dc9357SAndroid Build Coastguard Worker { ' ', 'L', 'V', 'M', '2', ' ', 'x', '[', '5', 'A', '%', 'r', '0', 'N', '*', '>' };
42*f6dc9357SAndroid Build Coastguard Worker
43*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kSectorSize = 512;
44*f6dc9357SAndroid Build Coastguard Worker
45*f6dc9357SAndroid Build Coastguard Worker
46*f6dc9357SAndroid Build Coastguard Worker struct CPropVal
47*f6dc9357SAndroid Build Coastguard Worker {
48*f6dc9357SAndroid Build Coastguard Worker bool IsNumber;
49*f6dc9357SAndroid Build Coastguard Worker AString String;
50*f6dc9357SAndroid Build Coastguard Worker UInt64 Number;
51*f6dc9357SAndroid Build Coastguard Worker
CPropValNArchive::NLvm::CPropVal52*f6dc9357SAndroid Build Coastguard Worker CPropVal(): IsNumber(false), Number(0) {}
53*f6dc9357SAndroid Build Coastguard Worker };
54*f6dc9357SAndroid Build Coastguard Worker
55*f6dc9357SAndroid Build Coastguard Worker
56*f6dc9357SAndroid Build Coastguard Worker struct CConfigProp
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker AString Name;
59*f6dc9357SAndroid Build Coastguard Worker
60*f6dc9357SAndroid Build Coastguard Worker bool IsVector;
61*f6dc9357SAndroid Build Coastguard Worker CPropVal Val;
62*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CPropVal> Vector;
63*f6dc9357SAndroid Build Coastguard Worker
CConfigPropNArchive::NLvm::CConfigProp64*f6dc9357SAndroid Build Coastguard Worker CConfigProp(): IsVector(false) {}
65*f6dc9357SAndroid Build Coastguard Worker };
66*f6dc9357SAndroid Build Coastguard Worker
67*f6dc9357SAndroid Build Coastguard Worker
68*f6dc9357SAndroid Build Coastguard Worker class CConfigItem
69*f6dc9357SAndroid Build Coastguard Worker {
70*f6dc9357SAndroid Build Coastguard Worker public:
71*f6dc9357SAndroid Build Coastguard Worker AString Name;
72*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CConfigProp> Props;
73*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CConfigItem> Items;
74*f6dc9357SAndroid Build Coastguard Worker
75*f6dc9357SAndroid Build Coastguard Worker const char *ParseItem(const char *s, int numAllowedLevels);
76*f6dc9357SAndroid Build Coastguard Worker
77*f6dc9357SAndroid Build Coastguard Worker int FindProp(const char *name) const throw();
78*f6dc9357SAndroid Build Coastguard Worker bool GetPropVal_Number(const char *name, UInt64 &val) const throw();
79*f6dc9357SAndroid Build Coastguard Worker bool GetPropVal_String(const char *name, AString &val) const;
80*f6dc9357SAndroid Build Coastguard Worker
81*f6dc9357SAndroid Build Coastguard Worker int FindSubItem(const char *tag) const throw();
82*f6dc9357SAndroid Build Coastguard Worker };
83*f6dc9357SAndroid Build Coastguard Worker
84*f6dc9357SAndroid Build Coastguard Worker struct CConfig
85*f6dc9357SAndroid Build Coastguard Worker {
86*f6dc9357SAndroid Build Coastguard Worker CConfigItem Root;
87*f6dc9357SAndroid Build Coastguard Worker
88*f6dc9357SAndroid Build Coastguard Worker bool Parse(const char *s);
89*f6dc9357SAndroid Build Coastguard Worker };
90*f6dc9357SAndroid Build Coastguard Worker
91*f6dc9357SAndroid Build Coastguard Worker
IsSpaceChar(char c)92*f6dc9357SAndroid Build Coastguard Worker static bool IsSpaceChar(char c)
93*f6dc9357SAndroid Build Coastguard Worker {
94*f6dc9357SAndroid Build Coastguard Worker return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A);
95*f6dc9357SAndroid Build Coastguard Worker }
96*f6dc9357SAndroid Build Coastguard Worker
SkipSpaces(const char * s)97*f6dc9357SAndroid Build Coastguard Worker static const char *SkipSpaces(const char * s)
98*f6dc9357SAndroid Build Coastguard Worker {
99*f6dc9357SAndroid Build Coastguard Worker for (;; s++)
100*f6dc9357SAndroid Build Coastguard Worker {
101*f6dc9357SAndroid Build Coastguard Worker const char c = *s;
102*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
103*f6dc9357SAndroid Build Coastguard Worker return s;
104*f6dc9357SAndroid Build Coastguard Worker if (!IsSpaceChar(c))
105*f6dc9357SAndroid Build Coastguard Worker {
106*f6dc9357SAndroid Build Coastguard Worker if (c != '#')
107*f6dc9357SAndroid Build Coastguard Worker return s;
108*f6dc9357SAndroid Build Coastguard Worker s++;
109*f6dc9357SAndroid Build Coastguard Worker for (;;)
110*f6dc9357SAndroid Build Coastguard Worker {
111*f6dc9357SAndroid Build Coastguard Worker const char c2 = *s;
112*f6dc9357SAndroid Build Coastguard Worker if (c2 == 0)
113*f6dc9357SAndroid Build Coastguard Worker return s;
114*f6dc9357SAndroid Build Coastguard Worker if (c2 == '\n')
115*f6dc9357SAndroid Build Coastguard Worker break;
116*f6dc9357SAndroid Build Coastguard Worker s++;
117*f6dc9357SAndroid Build Coastguard Worker }
118*f6dc9357SAndroid Build Coastguard Worker }
119*f6dc9357SAndroid Build Coastguard Worker }
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker
122*f6dc9357SAndroid Build Coastguard Worker #define SKIP_SPACES(s) s = SkipSpaces(s);
123*f6dc9357SAndroid Build Coastguard Worker
FindProp(const char * name) const124*f6dc9357SAndroid Build Coastguard Worker int CConfigItem::FindProp(const char *name) const throw()
125*f6dc9357SAndroid Build Coastguard Worker {
126*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, Props)
127*f6dc9357SAndroid Build Coastguard Worker if (Props[i].Name == name)
128*f6dc9357SAndroid Build Coastguard Worker return (int)i;
129*f6dc9357SAndroid Build Coastguard Worker return -1;
130*f6dc9357SAndroid Build Coastguard Worker }
131*f6dc9357SAndroid Build Coastguard Worker
GetPropVal_Number(const char * name,UInt64 & val) const132*f6dc9357SAndroid Build Coastguard Worker bool CConfigItem::GetPropVal_Number(const char *name, UInt64 &val) const throw()
133*f6dc9357SAndroid Build Coastguard Worker {
134*f6dc9357SAndroid Build Coastguard Worker val = 0;
135*f6dc9357SAndroid Build Coastguard Worker int index = FindProp(name);
136*f6dc9357SAndroid Build Coastguard Worker if (index < 0)
137*f6dc9357SAndroid Build Coastguard Worker return false;
138*f6dc9357SAndroid Build Coastguard Worker const CConfigProp &prop = Props[index];
139*f6dc9357SAndroid Build Coastguard Worker if (prop.IsVector)
140*f6dc9357SAndroid Build Coastguard Worker return false;
141*f6dc9357SAndroid Build Coastguard Worker if (!prop.Val.IsNumber)
142*f6dc9357SAndroid Build Coastguard Worker return false;
143*f6dc9357SAndroid Build Coastguard Worker val = prop.Val.Number;
144*f6dc9357SAndroid Build Coastguard Worker return true;
145*f6dc9357SAndroid Build Coastguard Worker }
146*f6dc9357SAndroid Build Coastguard Worker
GetPropVal_String(const char * name,AString & val) const147*f6dc9357SAndroid Build Coastguard Worker bool CConfigItem::GetPropVal_String(const char *name, AString &val) const
148*f6dc9357SAndroid Build Coastguard Worker {
149*f6dc9357SAndroid Build Coastguard Worker val.Empty();
150*f6dc9357SAndroid Build Coastguard Worker int index = FindProp(name);
151*f6dc9357SAndroid Build Coastguard Worker if (index < 0)
152*f6dc9357SAndroid Build Coastguard Worker return false;
153*f6dc9357SAndroid Build Coastguard Worker const CConfigProp &prop = Props[index];
154*f6dc9357SAndroid Build Coastguard Worker if (prop.IsVector)
155*f6dc9357SAndroid Build Coastguard Worker return false;
156*f6dc9357SAndroid Build Coastguard Worker if (prop.Val.IsNumber)
157*f6dc9357SAndroid Build Coastguard Worker return false;
158*f6dc9357SAndroid Build Coastguard Worker val = prop.Val.String;
159*f6dc9357SAndroid Build Coastguard Worker return true;
160*f6dc9357SAndroid Build Coastguard Worker }
161*f6dc9357SAndroid Build Coastguard Worker
FindSubItem(const char * tag) const162*f6dc9357SAndroid Build Coastguard Worker int CConfigItem::FindSubItem(const char *tag) const throw()
163*f6dc9357SAndroid Build Coastguard Worker {
164*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, Items)
165*f6dc9357SAndroid Build Coastguard Worker if (Items[i].Name == tag)
166*f6dc9357SAndroid Build Coastguard Worker return (int)i;
167*f6dc9357SAndroid Build Coastguard Worker return -1;
168*f6dc9357SAndroid Build Coastguard Worker }
169*f6dc9357SAndroid Build Coastguard Worker
FillProp(const char * s,CPropVal & val)170*f6dc9357SAndroid Build Coastguard Worker static const char *FillProp(const char *s, CPropVal &val)
171*f6dc9357SAndroid Build Coastguard Worker {
172*f6dc9357SAndroid Build Coastguard Worker SKIP_SPACES(s)
173*f6dc9357SAndroid Build Coastguard Worker const char c = *s;
174*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
175*f6dc9357SAndroid Build Coastguard Worker return NULL;
176*f6dc9357SAndroid Build Coastguard Worker
177*f6dc9357SAndroid Build Coastguard Worker if (c == '\"')
178*f6dc9357SAndroid Build Coastguard Worker {
179*f6dc9357SAndroid Build Coastguard Worker s++;
180*f6dc9357SAndroid Build Coastguard Worker val.IsNumber = false;
181*f6dc9357SAndroid Build Coastguard Worker val.String.Empty();
182*f6dc9357SAndroid Build Coastguard Worker
183*f6dc9357SAndroid Build Coastguard Worker for (;;)
184*f6dc9357SAndroid Build Coastguard Worker {
185*f6dc9357SAndroid Build Coastguard Worker const char c2 = *s;
186*f6dc9357SAndroid Build Coastguard Worker if (c2 == 0)
187*f6dc9357SAndroid Build Coastguard Worker return NULL;
188*f6dc9357SAndroid Build Coastguard Worker s++;
189*f6dc9357SAndroid Build Coastguard Worker if (c2 == '\"')
190*f6dc9357SAndroid Build Coastguard Worker break;
191*f6dc9357SAndroid Build Coastguard Worker val.String += c2;
192*f6dc9357SAndroid Build Coastguard Worker }
193*f6dc9357SAndroid Build Coastguard Worker }
194*f6dc9357SAndroid Build Coastguard Worker else
195*f6dc9357SAndroid Build Coastguard Worker {
196*f6dc9357SAndroid Build Coastguard Worker const char *end;
197*f6dc9357SAndroid Build Coastguard Worker val.IsNumber = true;
198*f6dc9357SAndroid Build Coastguard Worker val.Number = ConvertStringToUInt64(s, &end);
199*f6dc9357SAndroid Build Coastguard Worker if (s == end)
200*f6dc9357SAndroid Build Coastguard Worker return NULL;
201*f6dc9357SAndroid Build Coastguard Worker s = end;
202*f6dc9357SAndroid Build Coastguard Worker }
203*f6dc9357SAndroid Build Coastguard Worker
204*f6dc9357SAndroid Build Coastguard Worker SKIP_SPACES(s)
205*f6dc9357SAndroid Build Coastguard Worker return s;
206*f6dc9357SAndroid Build Coastguard Worker }
207*f6dc9357SAndroid Build Coastguard Worker
208*f6dc9357SAndroid Build Coastguard Worker
ParseItem(const char * s,int numAllowedLevels)209*f6dc9357SAndroid Build Coastguard Worker const char *CConfigItem::ParseItem(const char *s, int numAllowedLevels)
210*f6dc9357SAndroid Build Coastguard Worker {
211*f6dc9357SAndroid Build Coastguard Worker if (numAllowedLevels < 0)
212*f6dc9357SAndroid Build Coastguard Worker return NULL;
213*f6dc9357SAndroid Build Coastguard Worker
214*f6dc9357SAndroid Build Coastguard Worker for (;;)
215*f6dc9357SAndroid Build Coastguard Worker {
216*f6dc9357SAndroid Build Coastguard Worker SKIP_SPACES(s)
217*f6dc9357SAndroid Build Coastguard Worker const char *beg = s;
218*f6dc9357SAndroid Build Coastguard Worker
219*f6dc9357SAndroid Build Coastguard Worker for (;; s++)
220*f6dc9357SAndroid Build Coastguard Worker {
221*f6dc9357SAndroid Build Coastguard Worker char c = *s;
222*f6dc9357SAndroid Build Coastguard Worker if (c == 0 || c == '}')
223*f6dc9357SAndroid Build Coastguard Worker {
224*f6dc9357SAndroid Build Coastguard Worker if (s != beg)
225*f6dc9357SAndroid Build Coastguard Worker return NULL;
226*f6dc9357SAndroid Build Coastguard Worker return s;
227*f6dc9357SAndroid Build Coastguard Worker }
228*f6dc9357SAndroid Build Coastguard Worker if (IsSpaceChar(c) || c == '=' || c == '{')
229*f6dc9357SAndroid Build Coastguard Worker break;
230*f6dc9357SAndroid Build Coastguard Worker }
231*f6dc9357SAndroid Build Coastguard Worker
232*f6dc9357SAndroid Build Coastguard Worker if (s == beg)
233*f6dc9357SAndroid Build Coastguard Worker return NULL;
234*f6dc9357SAndroid Build Coastguard Worker
235*f6dc9357SAndroid Build Coastguard Worker AString name;
236*f6dc9357SAndroid Build Coastguard Worker name.SetFrom(beg, (unsigned)(s - beg));
237*f6dc9357SAndroid Build Coastguard Worker
238*f6dc9357SAndroid Build Coastguard Worker SKIP_SPACES(s)
239*f6dc9357SAndroid Build Coastguard Worker
240*f6dc9357SAndroid Build Coastguard Worker if (*s == 0 || *s == '}')
241*f6dc9357SAndroid Build Coastguard Worker return NULL;
242*f6dc9357SAndroid Build Coastguard Worker
243*f6dc9357SAndroid Build Coastguard Worker if (*s == '{')
244*f6dc9357SAndroid Build Coastguard Worker {
245*f6dc9357SAndroid Build Coastguard Worker s++;
246*f6dc9357SAndroid Build Coastguard Worker CConfigItem &item = Items.AddNew();
247*f6dc9357SAndroid Build Coastguard Worker item.Name = name;
248*f6dc9357SAndroid Build Coastguard Worker s = item.ParseItem(s, numAllowedLevels - 1);
249*f6dc9357SAndroid Build Coastguard Worker if (!s)
250*f6dc9357SAndroid Build Coastguard Worker return NULL;
251*f6dc9357SAndroid Build Coastguard Worker if (*s != '}')
252*f6dc9357SAndroid Build Coastguard Worker return NULL;
253*f6dc9357SAndroid Build Coastguard Worker s++;
254*f6dc9357SAndroid Build Coastguard Worker continue;
255*f6dc9357SAndroid Build Coastguard Worker }
256*f6dc9357SAndroid Build Coastguard Worker
257*f6dc9357SAndroid Build Coastguard Worker if (*s != '=')
258*f6dc9357SAndroid Build Coastguard Worker continue;
259*f6dc9357SAndroid Build Coastguard Worker
260*f6dc9357SAndroid Build Coastguard Worker s++;
261*f6dc9357SAndroid Build Coastguard Worker SKIP_SPACES(s)
262*f6dc9357SAndroid Build Coastguard Worker if (*s == 0)
263*f6dc9357SAndroid Build Coastguard Worker return NULL;
264*f6dc9357SAndroid Build Coastguard Worker CConfigProp &prop = Props.AddNew();
265*f6dc9357SAndroid Build Coastguard Worker
266*f6dc9357SAndroid Build Coastguard Worker prop.Name = name;
267*f6dc9357SAndroid Build Coastguard Worker
268*f6dc9357SAndroid Build Coastguard Worker if (*s == '[')
269*f6dc9357SAndroid Build Coastguard Worker {
270*f6dc9357SAndroid Build Coastguard Worker s++;
271*f6dc9357SAndroid Build Coastguard Worker prop.IsVector = true;
272*f6dc9357SAndroid Build Coastguard Worker
273*f6dc9357SAndroid Build Coastguard Worker for (;;)
274*f6dc9357SAndroid Build Coastguard Worker {
275*f6dc9357SAndroid Build Coastguard Worker SKIP_SPACES(s)
276*f6dc9357SAndroid Build Coastguard Worker char c = *s;
277*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
278*f6dc9357SAndroid Build Coastguard Worker return NULL;
279*f6dc9357SAndroid Build Coastguard Worker if (c == ']')
280*f6dc9357SAndroid Build Coastguard Worker {
281*f6dc9357SAndroid Build Coastguard Worker s++;
282*f6dc9357SAndroid Build Coastguard Worker break;
283*f6dc9357SAndroid Build Coastguard Worker }
284*f6dc9357SAndroid Build Coastguard Worker
285*f6dc9357SAndroid Build Coastguard Worker CPropVal val;
286*f6dc9357SAndroid Build Coastguard Worker
287*f6dc9357SAndroid Build Coastguard Worker s = FillProp(s, val);
288*f6dc9357SAndroid Build Coastguard Worker if (!s)
289*f6dc9357SAndroid Build Coastguard Worker return NULL;
290*f6dc9357SAndroid Build Coastguard Worker prop.Vector.Add(val);
291*f6dc9357SAndroid Build Coastguard Worker SKIP_SPACES(s)
292*f6dc9357SAndroid Build Coastguard Worker
293*f6dc9357SAndroid Build Coastguard Worker if (*s == ',')
294*f6dc9357SAndroid Build Coastguard Worker {
295*f6dc9357SAndroid Build Coastguard Worker s++;
296*f6dc9357SAndroid Build Coastguard Worker continue;
297*f6dc9357SAndroid Build Coastguard Worker }
298*f6dc9357SAndroid Build Coastguard Worker if (*s != ']')
299*f6dc9357SAndroid Build Coastguard Worker return NULL;
300*f6dc9357SAndroid Build Coastguard Worker s++;
301*f6dc9357SAndroid Build Coastguard Worker break;
302*f6dc9357SAndroid Build Coastguard Worker }
303*f6dc9357SAndroid Build Coastguard Worker }
304*f6dc9357SAndroid Build Coastguard Worker else
305*f6dc9357SAndroid Build Coastguard Worker {
306*f6dc9357SAndroid Build Coastguard Worker prop.IsVector = false;
307*f6dc9357SAndroid Build Coastguard Worker s = FillProp(s, prop.Val);
308*f6dc9357SAndroid Build Coastguard Worker if (!s)
309*f6dc9357SAndroid Build Coastguard Worker return NULL;
310*f6dc9357SAndroid Build Coastguard Worker }
311*f6dc9357SAndroid Build Coastguard Worker }
312*f6dc9357SAndroid Build Coastguard Worker }
313*f6dc9357SAndroid Build Coastguard Worker
314*f6dc9357SAndroid Build Coastguard Worker
Parse(const char * s)315*f6dc9357SAndroid Build Coastguard Worker bool CConfig::Parse(const char *s)
316*f6dc9357SAndroid Build Coastguard Worker {
317*f6dc9357SAndroid Build Coastguard Worker s = Root.ParseItem(s, 10);
318*f6dc9357SAndroid Build Coastguard Worker if (!s)
319*f6dc9357SAndroid Build Coastguard Worker return false;
320*f6dc9357SAndroid Build Coastguard Worker SKIP_SPACES(s)
321*f6dc9357SAndroid Build Coastguard Worker return *s == 0;
322*f6dc9357SAndroid Build Coastguard Worker }
323*f6dc9357SAndroid Build Coastguard Worker
324*f6dc9357SAndroid Build Coastguard Worker
325*f6dc9357SAndroid Build Coastguard Worker /*
326*f6dc9357SAndroid Build Coastguard Worker static const CUInt32PCharPair g_PartitionFlags[] =
327*f6dc9357SAndroid Build Coastguard Worker {
328*f6dc9357SAndroid Build Coastguard Worker { 0, "Sys" },
329*f6dc9357SAndroid Build Coastguard Worker { 1, "Ignore" },
330*f6dc9357SAndroid Build Coastguard Worker { 2, "Legacy" },
331*f6dc9357SAndroid Build Coastguard Worker { 60, "Win-Read-only" },
332*f6dc9357SAndroid Build Coastguard Worker { 62, "Win-Hidden" },
333*f6dc9357SAndroid Build Coastguard Worker { 63, "Win-Not-Automount" }
334*f6dc9357SAndroid Build Coastguard Worker };
335*f6dc9357SAndroid Build Coastguard Worker */
336*f6dc9357SAndroid Build Coastguard Worker
337*f6dc9357SAndroid Build Coastguard Worker /*
338*f6dc9357SAndroid Build Coastguard Worker static inline char GetHex(unsigned t) { return (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); }
339*f6dc9357SAndroid Build Coastguard Worker
340*f6dc9357SAndroid Build Coastguard Worker static void PrintHex(unsigned v, char *s)
341*f6dc9357SAndroid Build Coastguard Worker {
342*f6dc9357SAndroid Build Coastguard Worker s[0] = GetHex((v >> 4) & 0xF);
343*f6dc9357SAndroid Build Coastguard Worker s[1] = GetHex(v & 0xF);
344*f6dc9357SAndroid Build Coastguard Worker }
345*f6dc9357SAndroid Build Coastguard Worker
346*f6dc9357SAndroid Build Coastguard Worker static void ConvertUInt16ToHex4Digits(UInt32 val, char *s) throw()
347*f6dc9357SAndroid Build Coastguard Worker {
348*f6dc9357SAndroid Build Coastguard Worker PrintHex(val >> 8, s);
349*f6dc9357SAndroid Build Coastguard Worker PrintHex(val & 0xFF, s + 2);
350*f6dc9357SAndroid Build Coastguard Worker }
351*f6dc9357SAndroid Build Coastguard Worker
352*f6dc9357SAndroid Build Coastguard Worker static void GuidToString(const Byte *g, char *s)
353*f6dc9357SAndroid Build Coastguard Worker {
354*f6dc9357SAndroid Build Coastguard Worker ConvertUInt32ToHex8Digits(Get32(g ), s); s += 8; *s++ = '-';
355*f6dc9357SAndroid Build Coastguard Worker ConvertUInt16ToHex4Digits(Get16(g + 4), s); s += 4; *s++ = '-';
356*f6dc9357SAndroid Build Coastguard Worker ConvertUInt16ToHex4Digits(Get16(g + 6), s); s += 4; *s++ = '-';
357*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < 8; i++)
358*f6dc9357SAndroid Build Coastguard Worker {
359*f6dc9357SAndroid Build Coastguard Worker if (i == 2)
360*f6dc9357SAndroid Build Coastguard Worker *s++ = '-';
361*f6dc9357SAndroid Build Coastguard Worker PrintHex(g[8 + i], s);
362*f6dc9357SAndroid Build Coastguard Worker s += 2;
363*f6dc9357SAndroid Build Coastguard Worker }
364*f6dc9357SAndroid Build Coastguard Worker *s = 0;
365*f6dc9357SAndroid Build Coastguard Worker }
366*f6dc9357SAndroid Build Coastguard Worker
367*f6dc9357SAndroid Build Coastguard Worker */
368*f6dc9357SAndroid Build Coastguard Worker
369*f6dc9357SAndroid Build Coastguard Worker struct CPhyVol
370*f6dc9357SAndroid Build Coastguard Worker {
371*f6dc9357SAndroid Build Coastguard Worker AString Name;
372*f6dc9357SAndroid Build Coastguard Worker
373*f6dc9357SAndroid Build Coastguard Worker // AString id;
374*f6dc9357SAndroid Build Coastguard Worker // AString device; // "/dev/sda2"
375*f6dc9357SAndroid Build Coastguard Worker // AString status; // ["ALLOCATABLE"]
376*f6dc9357SAndroid Build Coastguard Worker // AString flags; // []
377*f6dc9357SAndroid Build Coastguard Worker // UInt64 dev_size; // in sectors
378*f6dc9357SAndroid Build Coastguard Worker UInt64 pe_start; // in sectors
379*f6dc9357SAndroid Build Coastguard Worker UInt64 pe_count; // in extents
380*f6dc9357SAndroid Build Coastguard Worker
ParseNArchive::NLvm::CPhyVol381*f6dc9357SAndroid Build Coastguard Worker bool Parse(const CConfigItem &ci)
382*f6dc9357SAndroid Build Coastguard Worker {
383*f6dc9357SAndroid Build Coastguard Worker Name = ci.Name;
384*f6dc9357SAndroid Build Coastguard Worker // ci.GetPropVal_String("id", id);
385*f6dc9357SAndroid Build Coastguard Worker // ci.GetPropVal_String("device", device);
386*f6dc9357SAndroid Build Coastguard Worker bool res = true;
387*f6dc9357SAndroid Build Coastguard Worker // if (!ci.GetPropVal_Number("dev_size", dev_size)) res = false;
388*f6dc9357SAndroid Build Coastguard Worker if (!ci.GetPropVal_Number("pe_start", pe_start)) res = false;
389*f6dc9357SAndroid Build Coastguard Worker if (!ci.GetPropVal_Number("pe_count", pe_count)) res = false;
390*f6dc9357SAndroid Build Coastguard Worker return res;
391*f6dc9357SAndroid Build Coastguard Worker }
392*f6dc9357SAndroid Build Coastguard Worker };
393*f6dc9357SAndroid Build Coastguard Worker
394*f6dc9357SAndroid Build Coastguard Worker struct CStripe
395*f6dc9357SAndroid Build Coastguard Worker {
396*f6dc9357SAndroid Build Coastguard Worker AString Name; // "pv0";
397*f6dc9357SAndroid Build Coastguard Worker UInt64 ExtentOffset; // ????
398*f6dc9357SAndroid Build Coastguard Worker };
399*f6dc9357SAndroid Build Coastguard Worker
400*f6dc9357SAndroid Build Coastguard Worker struct CSegment
401*f6dc9357SAndroid Build Coastguard Worker {
402*f6dc9357SAndroid Build Coastguard Worker UInt64 start_extent;
403*f6dc9357SAndroid Build Coastguard Worker UInt64 extent_count;
404*f6dc9357SAndroid Build Coastguard Worker AString type;
405*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CStripe> stripes;
406*f6dc9357SAndroid Build Coastguard Worker
IsPosSizeOkNArchive::NLvm::CSegment407*f6dc9357SAndroid Build Coastguard Worker bool IsPosSizeOk() const
408*f6dc9357SAndroid Build Coastguard Worker {
409*f6dc9357SAndroid Build Coastguard Worker return
410*f6dc9357SAndroid Build Coastguard Worker (start_extent < ((UInt64)1 << 63)) &&
411*f6dc9357SAndroid Build Coastguard Worker (extent_count < ((UInt64)1 << 63));
412*f6dc9357SAndroid Build Coastguard Worker }
413*f6dc9357SAndroid Build Coastguard Worker
GetEndExtentNArchive::NLvm::CSegment414*f6dc9357SAndroid Build Coastguard Worker UInt64 GetEndExtent() const { return start_extent + extent_count; }
415*f6dc9357SAndroid Build Coastguard Worker
ParseNArchive::NLvm::CSegment416*f6dc9357SAndroid Build Coastguard Worker bool Parse(const CConfigItem &si)
417*f6dc9357SAndroid Build Coastguard Worker {
418*f6dc9357SAndroid Build Coastguard Worker UInt64 stripe_count;
419*f6dc9357SAndroid Build Coastguard Worker
420*f6dc9357SAndroid Build Coastguard Worker if (!si.GetPropVal_Number("start_extent", start_extent)) return false;
421*f6dc9357SAndroid Build Coastguard Worker if (!si.GetPropVal_Number("extent_count", extent_count)) return false;
422*f6dc9357SAndroid Build Coastguard Worker if (!si.GetPropVal_Number("stripe_count", stripe_count)) return false;
423*f6dc9357SAndroid Build Coastguard Worker if (!si.GetPropVal_String("type", type)) return false;
424*f6dc9357SAndroid Build Coastguard Worker
425*f6dc9357SAndroid Build Coastguard Worker //if (stripe_count != 1) return false;
426*f6dc9357SAndroid Build Coastguard Worker
427*f6dc9357SAndroid Build Coastguard Worker const int spi = si.FindProp("stripes");
428*f6dc9357SAndroid Build Coastguard Worker if (spi < 0)
429*f6dc9357SAndroid Build Coastguard Worker return false;
430*f6dc9357SAndroid Build Coastguard Worker
431*f6dc9357SAndroid Build Coastguard Worker const CConfigProp &prop = si.Props[spi];
432*f6dc9357SAndroid Build Coastguard Worker if (!prop.IsVector)
433*f6dc9357SAndroid Build Coastguard Worker return false;
434*f6dc9357SAndroid Build Coastguard Worker
435*f6dc9357SAndroid Build Coastguard Worker if (stripe_count > (1 << 20))
436*f6dc9357SAndroid Build Coastguard Worker return false;
437*f6dc9357SAndroid Build Coastguard Worker
438*f6dc9357SAndroid Build Coastguard Worker const unsigned numStripes = (unsigned)stripe_count;
439*f6dc9357SAndroid Build Coastguard Worker if (prop.Vector.Size() != numStripes * 2)
440*f6dc9357SAndroid Build Coastguard Worker return false;
441*f6dc9357SAndroid Build Coastguard Worker
442*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < numStripes; i++)
443*f6dc9357SAndroid Build Coastguard Worker {
444*f6dc9357SAndroid Build Coastguard Worker const CPropVal &v0 = prop.Vector[i * 2];
445*f6dc9357SAndroid Build Coastguard Worker const CPropVal &v1 = prop.Vector[i * 2 + 1];
446*f6dc9357SAndroid Build Coastguard Worker if (v0.IsNumber || !v1.IsNumber)
447*f6dc9357SAndroid Build Coastguard Worker return false;
448*f6dc9357SAndroid Build Coastguard Worker CStripe stripe;
449*f6dc9357SAndroid Build Coastguard Worker stripe.Name = v0.String;
450*f6dc9357SAndroid Build Coastguard Worker stripe.ExtentOffset = v1.Number;
451*f6dc9357SAndroid Build Coastguard Worker stripes.Add(stripe);
452*f6dc9357SAndroid Build Coastguard Worker }
453*f6dc9357SAndroid Build Coastguard Worker
454*f6dc9357SAndroid Build Coastguard Worker return true;
455*f6dc9357SAndroid Build Coastguard Worker }
456*f6dc9357SAndroid Build Coastguard Worker };
457*f6dc9357SAndroid Build Coastguard Worker
458*f6dc9357SAndroid Build Coastguard Worker
459*f6dc9357SAndroid Build Coastguard Worker struct CLogVol
460*f6dc9357SAndroid Build Coastguard Worker {
461*f6dc9357SAndroid Build Coastguard Worker bool IsSupported;
462*f6dc9357SAndroid Build Coastguard Worker
463*f6dc9357SAndroid Build Coastguard Worker AString Name;
464*f6dc9357SAndroid Build Coastguard Worker
465*f6dc9357SAndroid Build Coastguard Worker AString id;
466*f6dc9357SAndroid Build Coastguard Worker AString status; // ["READ", "WRITE", "VISIBLE"]
467*f6dc9357SAndroid Build Coastguard Worker AString flags; // []
468*f6dc9357SAndroid Build Coastguard Worker
469*f6dc9357SAndroid Build Coastguard Worker // UInt64 Pos;
470*f6dc9357SAndroid Build Coastguard Worker // UInt64 Size;
471*f6dc9357SAndroid Build Coastguard Worker
472*f6dc9357SAndroid Build Coastguard Worker // UInt64 GetSize() const { return Size; }
473*f6dc9357SAndroid Build Coastguard Worker // UInt64 GetPos() const { return Pos; }
474*f6dc9357SAndroid Build Coastguard Worker
475*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CSegment> Segments;
476*f6dc9357SAndroid Build Coastguard Worker
CLogVolNArchive::NLvm::CLogVol477*f6dc9357SAndroid Build Coastguard Worker CLogVol(): /* Pos(0), Size(0), */ IsSupported(false) {}
478*f6dc9357SAndroid Build Coastguard Worker
ParseNArchive::NLvm::CLogVol479*f6dc9357SAndroid Build Coastguard Worker bool Parse(const CConfigItem &ci)
480*f6dc9357SAndroid Build Coastguard Worker {
481*f6dc9357SAndroid Build Coastguard Worker Name = ci.Name;
482*f6dc9357SAndroid Build Coastguard Worker
483*f6dc9357SAndroid Build Coastguard Worker UInt64 segment_count;
484*f6dc9357SAndroid Build Coastguard Worker if (!ci.GetPropVal_Number("segment_count", segment_count))
485*f6dc9357SAndroid Build Coastguard Worker return false;
486*f6dc9357SAndroid Build Coastguard Worker
487*f6dc9357SAndroid Build Coastguard Worker if (ci.Items.Size() != segment_count)
488*f6dc9357SAndroid Build Coastguard Worker return false;
489*f6dc9357SAndroid Build Coastguard Worker
490*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (segIndex, ci.Items)
491*f6dc9357SAndroid Build Coastguard Worker {
492*f6dc9357SAndroid Build Coastguard Worker const CConfigItem &si = ci.Items[segIndex];
493*f6dc9357SAndroid Build Coastguard Worker {
494*f6dc9357SAndroid Build Coastguard Worker AString t ("segment");
495*f6dc9357SAndroid Build Coastguard Worker t.Add_UInt32(segIndex + 1);
496*f6dc9357SAndroid Build Coastguard Worker if (si.Name != t)
497*f6dc9357SAndroid Build Coastguard Worker return false;
498*f6dc9357SAndroid Build Coastguard Worker }
499*f6dc9357SAndroid Build Coastguard Worker
500*f6dc9357SAndroid Build Coastguard Worker CSegment segment;
501*f6dc9357SAndroid Build Coastguard Worker
502*f6dc9357SAndroid Build Coastguard Worker if (!segment.Parse(si))
503*f6dc9357SAndroid Build Coastguard Worker return false;
504*f6dc9357SAndroid Build Coastguard Worker
505*f6dc9357SAndroid Build Coastguard Worker // item.Size += (segment.extent_count * _extentSize) << 9;
506*f6dc9357SAndroid Build Coastguard Worker
507*f6dc9357SAndroid Build Coastguard Worker Segments.Add(segment);
508*f6dc9357SAndroid Build Coastguard Worker }
509*f6dc9357SAndroid Build Coastguard Worker
510*f6dc9357SAndroid Build Coastguard Worker IsSupported = true;
511*f6dc9357SAndroid Build Coastguard Worker return true;
512*f6dc9357SAndroid Build Coastguard Worker }
513*f6dc9357SAndroid Build Coastguard Worker
GetNumExtentsNArchive::NLvm::CLogVol514*f6dc9357SAndroid Build Coastguard Worker bool GetNumExtents(UInt64 &numExtents) const
515*f6dc9357SAndroid Build Coastguard Worker {
516*f6dc9357SAndroid Build Coastguard Worker numExtents = 0;
517*f6dc9357SAndroid Build Coastguard Worker if (Segments.IsEmpty())
518*f6dc9357SAndroid Build Coastguard Worker return true;
519*f6dc9357SAndroid Build Coastguard Worker unsigned i;
520*f6dc9357SAndroid Build Coastguard Worker for (i = 1; i < Segments.Size(); i++)
521*f6dc9357SAndroid Build Coastguard Worker if (!Segments[i].IsPosSizeOk())
522*f6dc9357SAndroid Build Coastguard Worker return false;
523*f6dc9357SAndroid Build Coastguard Worker for (i = 1; i < Segments.Size(); i++)
524*f6dc9357SAndroid Build Coastguard Worker if (Segments[i - 1].GetEndExtent() != Segments[i].start_extent)
525*f6dc9357SAndroid Build Coastguard Worker return false;
526*f6dc9357SAndroid Build Coastguard Worker numExtents = Segments.Back().GetEndExtent();
527*f6dc9357SAndroid Build Coastguard Worker return true;
528*f6dc9357SAndroid Build Coastguard Worker }
529*f6dc9357SAndroid Build Coastguard Worker };
530*f6dc9357SAndroid Build Coastguard Worker
531*f6dc9357SAndroid Build Coastguard Worker
532*f6dc9357SAndroid Build Coastguard Worker struct CItem
533*f6dc9357SAndroid Build Coastguard Worker {
534*f6dc9357SAndroid Build Coastguard Worker int LogVol;
535*f6dc9357SAndroid Build Coastguard Worker int PhyVol;
536*f6dc9357SAndroid Build Coastguard Worker UInt64 Pos;
537*f6dc9357SAndroid Build Coastguard Worker UInt64 Size;
538*f6dc9357SAndroid Build Coastguard Worker AString Name;
539*f6dc9357SAndroid Build Coastguard Worker bool IsSupported;
540*f6dc9357SAndroid Build Coastguard Worker
CItemNArchive::NLvm::CItem541*f6dc9357SAndroid Build Coastguard Worker CItem(): LogVol(-1), PhyVol(-1), Pos(0), Size(0), IsSupported(false) {}
542*f6dc9357SAndroid Build Coastguard Worker };
543*f6dc9357SAndroid Build Coastguard Worker
544*f6dc9357SAndroid Build Coastguard Worker
545*f6dc9357SAndroid Build Coastguard Worker struct CVolGroup
546*f6dc9357SAndroid Build Coastguard Worker {
547*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CLogVol> _logVols;
548*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CPhyVol> _phyVols;
549*f6dc9357SAndroid Build Coastguard Worker AString _id;
550*f6dc9357SAndroid Build Coastguard Worker int _extentSizeBits;
551*f6dc9357SAndroid Build Coastguard Worker
552*f6dc9357SAndroid Build Coastguard Worker /*
553*f6dc9357SAndroid Build Coastguard Worker UInt64 secno; // 3
554*f6dc9357SAndroid Build Coastguard Worker AString status; // ["RESIZEABLE", "READ", "WRITE"]
555*f6dc9357SAndroid Build Coastguard Worker AString flags; // []
556*f6dc9357SAndroid Build Coastguard Worker UInt64 max_lv; // 0
557*f6dc9357SAndroid Build Coastguard Worker UInt64 max_pv; // 0
558*f6dc9357SAndroid Build Coastguard Worker UInt64 metadata_copies; // 0
559*f6dc9357SAndroid Build Coastguard Worker */
560*f6dc9357SAndroid Build Coastguard Worker
ClearNArchive::NLvm::CVolGroup561*f6dc9357SAndroid Build Coastguard Worker void Clear()
562*f6dc9357SAndroid Build Coastguard Worker {
563*f6dc9357SAndroid Build Coastguard Worker _logVols.Clear();
564*f6dc9357SAndroid Build Coastguard Worker _phyVols.Clear();
565*f6dc9357SAndroid Build Coastguard Worker _id.Empty();
566*f6dc9357SAndroid Build Coastguard Worker _extentSizeBits = -1;
567*f6dc9357SAndroid Build Coastguard Worker }
568*f6dc9357SAndroid Build Coastguard Worker };
569*f6dc9357SAndroid Build Coastguard Worker
570*f6dc9357SAndroid Build Coastguard Worker
571*f6dc9357SAndroid Build Coastguard Worker Z7_class_CHandler_final: public CHandlerCont, public CVolGroup
572*f6dc9357SAndroid Build Coastguard Worker {
573*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_COM7_IMP(IInArchive_Cont)
574*f6dc9357SAndroid Build Coastguard Worker
575*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CItem> _items;
576*f6dc9357SAndroid Build Coastguard Worker
577*f6dc9357SAndroid Build Coastguard Worker UInt64 _cTime;
578*f6dc9357SAndroid Build Coastguard Worker
579*f6dc9357SAndroid Build Coastguard Worker bool _isArc;
580*f6dc9357SAndroid Build Coastguard Worker
581*f6dc9357SAndroid Build Coastguard Worker UInt64 _phySize;
582*f6dc9357SAndroid Build Coastguard Worker CByteBuffer _buffer;
583*f6dc9357SAndroid Build Coastguard Worker
584*f6dc9357SAndroid Build Coastguard Worker UInt64 _cfgPos;
585*f6dc9357SAndroid Build Coastguard Worker UInt64 _cfgSize;
586*f6dc9357SAndroid Build Coastguard Worker
587*f6dc9357SAndroid Build Coastguard Worker HRESULT Open2(IInStream *stream);
588*f6dc9357SAndroid Build Coastguard Worker
589*f6dc9357SAndroid Build Coastguard Worker virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override
590*f6dc9357SAndroid Build Coastguard Worker {
591*f6dc9357SAndroid Build Coastguard Worker if (index >= _items.Size())
592*f6dc9357SAndroid Build Coastguard Worker {
593*f6dc9357SAndroid Build Coastguard Worker pos = _cfgPos;
594*f6dc9357SAndroid Build Coastguard Worker size = _cfgSize;
595*f6dc9357SAndroid Build Coastguard Worker return NExtract::NOperationResult::kOK;
596*f6dc9357SAndroid Build Coastguard Worker }
597*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _items[index];
598*f6dc9357SAndroid Build Coastguard Worker if (!item.IsSupported)
599*f6dc9357SAndroid Build Coastguard Worker return NExtract::NOperationResult::kUnsupportedMethod;
600*f6dc9357SAndroid Build Coastguard Worker pos = item.Pos;
601*f6dc9357SAndroid Build Coastguard Worker size = item.Size;
602*f6dc9357SAndroid Build Coastguard Worker return NExtract::NOperationResult::kOK;
603*f6dc9357SAndroid Build Coastguard Worker }
604*f6dc9357SAndroid Build Coastguard Worker };
605*f6dc9357SAndroid Build Coastguard Worker
606*f6dc9357SAndroid Build Coastguard Worker static const UInt32 LVM_CRC_INIT_VAL = 0xf597a6cf;
607*f6dc9357SAndroid Build Coastguard Worker
608*f6dc9357SAndroid Build Coastguard Worker static UInt32 Z7_FASTCALL LvmCrcCalc(const void *data, size_t size)
609*f6dc9357SAndroid Build Coastguard Worker {
610*f6dc9357SAndroid Build Coastguard Worker return CrcUpdate(LVM_CRC_INIT_VAL, data, size);
611*f6dc9357SAndroid Build Coastguard Worker }
612*f6dc9357SAndroid Build Coastguard Worker
613*f6dc9357SAndroid Build Coastguard Worker struct CRawLocn
614*f6dc9357SAndroid Build Coastguard Worker {
615*f6dc9357SAndroid Build Coastguard Worker UInt64 Offset; /* Offset in bytes to start sector */
616*f6dc9357SAndroid Build Coastguard Worker UInt64 Size; /* Bytes */
617*f6dc9357SAndroid Build Coastguard Worker UInt32 Checksum;
618*f6dc9357SAndroid Build Coastguard Worker UInt32 Flags;
619*f6dc9357SAndroid Build Coastguard Worker
620*f6dc9357SAndroid Build Coastguard Worker bool IsEmpty() const { return Offset == 0 && Size == 0; }
621*f6dc9357SAndroid Build Coastguard Worker
622*f6dc9357SAndroid Build Coastguard Worker void Parse(const Byte *p)
623*f6dc9357SAndroid Build Coastguard Worker {
624*f6dc9357SAndroid Build Coastguard Worker LE_64(0x00, Offset);
625*f6dc9357SAndroid Build Coastguard Worker LE_64(0x08, Size);
626*f6dc9357SAndroid Build Coastguard Worker LE_32(0x10, Checksum);
627*f6dc9357SAndroid Build Coastguard Worker LE_32(0x14, Flags);
628*f6dc9357SAndroid Build Coastguard Worker }
629*f6dc9357SAndroid Build Coastguard Worker };
630*f6dc9357SAndroid Build Coastguard Worker
631*f6dc9357SAndroid Build Coastguard Worker // #define MDA_HEADER_SIZE 512
632*f6dc9357SAndroid Build Coastguard Worker
633*f6dc9357SAndroid Build Coastguard Worker struct mda_header
634*f6dc9357SAndroid Build Coastguard Worker {
635*f6dc9357SAndroid Build Coastguard Worker UInt64 Start; /* Absolute start byte of mda_header */
636*f6dc9357SAndroid Build Coastguard Worker UInt64 Size; /* Size of metadata area */
637*f6dc9357SAndroid Build Coastguard Worker
638*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CRawLocn> raw_locns;
639*f6dc9357SAndroid Build Coastguard Worker
640*f6dc9357SAndroid Build Coastguard Worker bool Parse(const Byte *p, size_t size)
641*f6dc9357SAndroid Build Coastguard Worker {
642*f6dc9357SAndroid Build Coastguard Worker if (memcmp(p + 4, FMTT_MAGIC, 16) != 0)
643*f6dc9357SAndroid Build Coastguard Worker return false;
644*f6dc9357SAndroid Build Coastguard Worker UInt32 version;
645*f6dc9357SAndroid Build Coastguard Worker LE_32(0x14, version);
646*f6dc9357SAndroid Build Coastguard Worker if (version != 1)
647*f6dc9357SAndroid Build Coastguard Worker return false;
648*f6dc9357SAndroid Build Coastguard Worker LE_64(0x18, Start);
649*f6dc9357SAndroid Build Coastguard Worker LE_64(0x20, Size);
650*f6dc9357SAndroid Build Coastguard Worker
651*f6dc9357SAndroid Build Coastguard Worker unsigned pos = 0x28;
652*f6dc9357SAndroid Build Coastguard Worker
653*f6dc9357SAndroid Build Coastguard Worker for (;;)
654*f6dc9357SAndroid Build Coastguard Worker {
655*f6dc9357SAndroid Build Coastguard Worker if (pos + 0x18 > size)
656*f6dc9357SAndroid Build Coastguard Worker return false;
657*f6dc9357SAndroid Build Coastguard Worker CRawLocn locn;
658*f6dc9357SAndroid Build Coastguard Worker locn.Parse(p + pos);
659*f6dc9357SAndroid Build Coastguard Worker if (locn.IsEmpty())
660*f6dc9357SAndroid Build Coastguard Worker break;
661*f6dc9357SAndroid Build Coastguard Worker pos += 0x18;
662*f6dc9357SAndroid Build Coastguard Worker raw_locns.Add(locn);
663*f6dc9357SAndroid Build Coastguard Worker }
664*f6dc9357SAndroid Build Coastguard Worker
665*f6dc9357SAndroid Build Coastguard Worker return true;
666*f6dc9357SAndroid Build Coastguard Worker }
667*f6dc9357SAndroid Build Coastguard Worker };
668*f6dc9357SAndroid Build Coastguard Worker
669*f6dc9357SAndroid Build Coastguard Worker
670*f6dc9357SAndroid Build Coastguard Worker static int inline GetLog(UInt64 num)
671*f6dc9357SAndroid Build Coastguard Worker {
672*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < 64; i++)
673*f6dc9357SAndroid Build Coastguard Worker if (((UInt64)1 << i) == num)
674*f6dc9357SAndroid Build Coastguard Worker return (int)i;
675*f6dc9357SAndroid Build Coastguard Worker return -1;
676*f6dc9357SAndroid Build Coastguard Worker }
677*f6dc9357SAndroid Build Coastguard Worker
678*f6dc9357SAndroid Build Coastguard Worker #define ID_LEN 32
679*f6dc9357SAndroid Build Coastguard Worker
680*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::Open2(IInStream *stream)
681*f6dc9357SAndroid Build Coastguard Worker {
682*f6dc9357SAndroid Build Coastguard Worker _buffer.Alloc(kSectorSize * 2);
683*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream_FALSE(stream, _buffer, kSectorSize * 2))
684*f6dc9357SAndroid Build Coastguard Worker
685*f6dc9357SAndroid Build Coastguard Worker const Byte *buf = _buffer;
686*f6dc9357SAndroid Build Coastguard Worker
687*f6dc9357SAndroid Build Coastguard Worker buf += kSectorSize;
688*f6dc9357SAndroid Build Coastguard Worker
689*f6dc9357SAndroid Build Coastguard Worker // label_header
690*f6dc9357SAndroid Build Coastguard Worker
691*f6dc9357SAndroid Build Coastguard Worker if (memcmp(buf, k_Signature, k_SignatureSize) != 0)
692*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
693*f6dc9357SAndroid Build Coastguard Worker const UInt64 sectorNumber = Get64(buf + 8);
694*f6dc9357SAndroid Build Coastguard Worker if (sectorNumber != 1)
695*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
696*f6dc9357SAndroid Build Coastguard Worker if (Get32(buf + 16) != LvmCrcCalc(buf + 20, kSectorSize - 20))
697*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
698*f6dc9357SAndroid Build Coastguard Worker
699*f6dc9357SAndroid Build Coastguard Worker const UInt32 offsetToCont = Get32(buf + 20);
700*f6dc9357SAndroid Build Coastguard Worker if (memcmp(buf + 24, k_Signature2, k_Signature2Size) != 0)
701*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
702*f6dc9357SAndroid Build Coastguard Worker
703*f6dc9357SAndroid Build Coastguard Worker if (offsetToCont != 32)
704*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
705*f6dc9357SAndroid Build Coastguard Worker
706*f6dc9357SAndroid Build Coastguard Worker // pv_header
707*f6dc9357SAndroid Build Coastguard Worker
708*f6dc9357SAndroid Build Coastguard Worker size_t pos = offsetToCont;
709*f6dc9357SAndroid Build Coastguard Worker const Byte *p = buf;
710*f6dc9357SAndroid Build Coastguard Worker
711*f6dc9357SAndroid Build Coastguard Worker /*
712*f6dc9357SAndroid Build Coastguard Worker {
713*f6dc9357SAndroid Build Coastguard Worker Byte id[ID_LEN];
714*f6dc9357SAndroid Build Coastguard Worker memcpy(id, p + pos, ID_LEN);
715*f6dc9357SAndroid Build Coastguard Worker }
716*f6dc9357SAndroid Build Coastguard Worker */
717*f6dc9357SAndroid Build Coastguard Worker
718*f6dc9357SAndroid Build Coastguard Worker pos += ID_LEN;
719*f6dc9357SAndroid Build Coastguard Worker const UInt64 device_size_xl = Get64(p + pos);
720*f6dc9357SAndroid Build Coastguard Worker pos += 8;
721*f6dc9357SAndroid Build Coastguard Worker
722*f6dc9357SAndroid Build Coastguard Worker _phySize = device_size_xl;
723*f6dc9357SAndroid Build Coastguard Worker _isArc = true;
724*f6dc9357SAndroid Build Coastguard Worker
725*f6dc9357SAndroid Build Coastguard Worker for (;;)
726*f6dc9357SAndroid Build Coastguard Worker {
727*f6dc9357SAndroid Build Coastguard Worker if (pos > kSectorSize - 16)
728*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
729*f6dc9357SAndroid Build Coastguard Worker // disk_locn (data areas)
730*f6dc9357SAndroid Build Coastguard Worker UInt64 offset = Get64(p + pos);
731*f6dc9357SAndroid Build Coastguard Worker UInt64 size = Get64(p + pos + 8);
732*f6dc9357SAndroid Build Coastguard Worker pos += 16;
733*f6dc9357SAndroid Build Coastguard Worker if (offset == 0 && size == 0)
734*f6dc9357SAndroid Build Coastguard Worker break;
735*f6dc9357SAndroid Build Coastguard Worker }
736*f6dc9357SAndroid Build Coastguard Worker
737*f6dc9357SAndroid Build Coastguard Worker CConfig cfg;
738*f6dc9357SAndroid Build Coastguard Worker // bool isFinded = false;
739*f6dc9357SAndroid Build Coastguard Worker
740*f6dc9357SAndroid Build Coastguard Worker // for (;;)
741*f6dc9357SAndroid Build Coastguard Worker {
742*f6dc9357SAndroid Build Coastguard Worker if (pos > kSectorSize - 16)
743*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
744*f6dc9357SAndroid Build Coastguard Worker // disk_locn (metadata area headers)
745*f6dc9357SAndroid Build Coastguard Worker UInt64 offset = Get64(p + pos);
746*f6dc9357SAndroid Build Coastguard Worker UInt64 size = Get64(p + pos + 8);
747*f6dc9357SAndroid Build Coastguard Worker pos += 16;
748*f6dc9357SAndroid Build Coastguard Worker if (offset == 0 && size == 0)
749*f6dc9357SAndroid Build Coastguard Worker {
750*f6dc9357SAndroid Build Coastguard Worker // break;
751*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
752*f6dc9357SAndroid Build Coastguard Worker }
753*f6dc9357SAndroid Build Coastguard Worker
754*f6dc9357SAndroid Build Coastguard Worker CByteBuffer meta;
755*f6dc9357SAndroid Build Coastguard Worker const size_t sizeT = (size_t)size;
756*f6dc9357SAndroid Build Coastguard Worker if (sizeT != size)
757*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
758*f6dc9357SAndroid Build Coastguard Worker meta.Alloc(sizeT);
759*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(stream, offset))
760*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream_FALSE(stream, meta, sizeT))
761*f6dc9357SAndroid Build Coastguard Worker if (Get32(meta) != LvmCrcCalc(meta + 4, kSectorSize - 4))
762*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
763*f6dc9357SAndroid Build Coastguard Worker mda_header mh;
764*f6dc9357SAndroid Build Coastguard Worker if (!mh.Parse(meta, kSectorSize))
765*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
766*f6dc9357SAndroid Build Coastguard Worker
767*f6dc9357SAndroid Build Coastguard Worker if (mh.raw_locns.Size() != 1)
768*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
769*f6dc9357SAndroid Build Coastguard Worker unsigned g = 0;
770*f6dc9357SAndroid Build Coastguard Worker // for (unsigned g = 0; g < mh.raw_locns.Size(); g++)
771*f6dc9357SAndroid Build Coastguard Worker {
772*f6dc9357SAndroid Build Coastguard Worker const CRawLocn &locn = mh.raw_locns[g];
773*f6dc9357SAndroid Build Coastguard Worker
774*f6dc9357SAndroid Build Coastguard Worker CByteBuffer vgBuf;
775*f6dc9357SAndroid Build Coastguard Worker if (locn.Size > ((UInt32)1 << 24))
776*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
777*f6dc9357SAndroid Build Coastguard Worker
778*f6dc9357SAndroid Build Coastguard Worker const size_t vgSize = (size_t)locn.Size;
779*f6dc9357SAndroid Build Coastguard Worker if (vgSize == 0)
780*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
781*f6dc9357SAndroid Build Coastguard Worker
782*f6dc9357SAndroid Build Coastguard Worker vgBuf.Alloc(vgSize);
783*f6dc9357SAndroid Build Coastguard Worker
784*f6dc9357SAndroid Build Coastguard Worker _cfgPos = offset + locn.Offset;
785*f6dc9357SAndroid Build Coastguard Worker _cfgSize = vgSize;
786*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(stream, _cfgPos))
787*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream_FALSE(stream, vgBuf, vgSize))
788*f6dc9357SAndroid Build Coastguard Worker if (locn.Checksum != LvmCrcCalc(vgBuf, vgSize))
789*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
790*f6dc9357SAndroid Build Coastguard Worker
791*f6dc9357SAndroid Build Coastguard Worker {
792*f6dc9357SAndroid Build Coastguard Worker AString s;
793*f6dc9357SAndroid Build Coastguard Worker s.SetFrom_CalcLen((const char *)(const Byte *)vgBuf, (unsigned)vgSize);
794*f6dc9357SAndroid Build Coastguard Worker _cfgSize = s.Len();
795*f6dc9357SAndroid Build Coastguard Worker if (!cfg.Parse(s))
796*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
797*f6dc9357SAndroid Build Coastguard Worker // isFinded = true;
798*f6dc9357SAndroid Build Coastguard Worker // break;
799*f6dc9357SAndroid Build Coastguard Worker }
800*f6dc9357SAndroid Build Coastguard Worker }
801*f6dc9357SAndroid Build Coastguard Worker
802*f6dc9357SAndroid Build Coastguard Worker // if (isFinded) break;
803*f6dc9357SAndroid Build Coastguard Worker }
804*f6dc9357SAndroid Build Coastguard Worker
805*f6dc9357SAndroid Build Coastguard Worker // if (!isFinded) return S_FALSE;
806*f6dc9357SAndroid Build Coastguard Worker
807*f6dc9357SAndroid Build Coastguard Worker if (cfg.Root.Items.Size() != 1)
808*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
809*f6dc9357SAndroid Build Coastguard Worker const CConfigItem &volGroup = cfg.Root.Items[0];
810*f6dc9357SAndroid Build Coastguard Worker if (volGroup.Name != "VolGroup00")
811*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
812*f6dc9357SAndroid Build Coastguard Worker
813*f6dc9357SAndroid Build Coastguard Worker volGroup.GetPropVal_String("id", _id);
814*f6dc9357SAndroid Build Coastguard Worker
815*f6dc9357SAndroid Build Coastguard Worker if (!cfg.Root.GetPropVal_Number("creation_time", _cTime))
816*f6dc9357SAndroid Build Coastguard Worker _cTime = 0;
817*f6dc9357SAndroid Build Coastguard Worker
818*f6dc9357SAndroid Build Coastguard Worker UInt64 extentSize;
819*f6dc9357SAndroid Build Coastguard Worker if (!volGroup.GetPropVal_Number("extent_size", extentSize))
820*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
821*f6dc9357SAndroid Build Coastguard Worker
822*f6dc9357SAndroid Build Coastguard Worker _extentSizeBits = GetLog(extentSize);
823*f6dc9357SAndroid Build Coastguard Worker if (_extentSizeBits < 0 || _extentSizeBits > (62 - 9))
824*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
825*f6dc9357SAndroid Build Coastguard Worker
826*f6dc9357SAndroid Build Coastguard Worker
827*f6dc9357SAndroid Build Coastguard Worker {
828*f6dc9357SAndroid Build Coastguard Worker int pvsIndex = volGroup.FindSubItem("physical_volumes");
829*f6dc9357SAndroid Build Coastguard Worker if (pvsIndex < 0)
830*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
831*f6dc9357SAndroid Build Coastguard Worker
832*f6dc9357SAndroid Build Coastguard Worker const CConfigItem &phyVols = volGroup.Items[pvsIndex];
833*f6dc9357SAndroid Build Coastguard Worker
834*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, phyVols.Items)
835*f6dc9357SAndroid Build Coastguard Worker {
836*f6dc9357SAndroid Build Coastguard Worker const CConfigItem &ci = phyVols.Items[i];
837*f6dc9357SAndroid Build Coastguard Worker CPhyVol pv;
838*f6dc9357SAndroid Build Coastguard Worker if (!pv.Parse(ci))
839*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
840*f6dc9357SAndroid Build Coastguard Worker _phyVols.Add(pv);
841*f6dc9357SAndroid Build Coastguard Worker }
842*f6dc9357SAndroid Build Coastguard Worker }
843*f6dc9357SAndroid Build Coastguard Worker
844*f6dc9357SAndroid Build Coastguard Worker {
845*f6dc9357SAndroid Build Coastguard Worker int lvIndex = volGroup.FindSubItem("logical_volumes");
846*f6dc9357SAndroid Build Coastguard Worker if (lvIndex < 0)
847*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
848*f6dc9357SAndroid Build Coastguard Worker
849*f6dc9357SAndroid Build Coastguard Worker const CConfigItem &logVolumes = volGroup.Items[lvIndex];
850*f6dc9357SAndroid Build Coastguard Worker
851*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, logVolumes.Items)
852*f6dc9357SAndroid Build Coastguard Worker {
853*f6dc9357SAndroid Build Coastguard Worker const CConfigItem &ci = logVolumes.Items[i];
854*f6dc9357SAndroid Build Coastguard Worker CLogVol &lv = _logVols.AddNew();
855*f6dc9357SAndroid Build Coastguard Worker lv.Parse(ci) ; // check error
856*f6dc9357SAndroid Build Coastguard Worker }
857*f6dc9357SAndroid Build Coastguard Worker }
858*f6dc9357SAndroid Build Coastguard Worker
859*f6dc9357SAndroid Build Coastguard Worker {
860*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, _logVols)
861*f6dc9357SAndroid Build Coastguard Worker {
862*f6dc9357SAndroid Build Coastguard Worker CLogVol &lv = _logVols[i];
863*f6dc9357SAndroid Build Coastguard Worker
864*f6dc9357SAndroid Build Coastguard Worker CItem item;
865*f6dc9357SAndroid Build Coastguard Worker
866*f6dc9357SAndroid Build Coastguard Worker item.LogVol = (int)i;
867*f6dc9357SAndroid Build Coastguard Worker item.Pos = 0;
868*f6dc9357SAndroid Build Coastguard Worker item.Size = 0;
869*f6dc9357SAndroid Build Coastguard Worker item.Name = lv.Name;
870*f6dc9357SAndroid Build Coastguard Worker
871*f6dc9357SAndroid Build Coastguard Worker if (lv.IsSupported)
872*f6dc9357SAndroid Build Coastguard Worker {
873*f6dc9357SAndroid Build Coastguard Worker UInt64 numExtents;
874*f6dc9357SAndroid Build Coastguard Worker lv.IsSupported = lv.GetNumExtents(numExtents);
875*f6dc9357SAndroid Build Coastguard Worker
876*f6dc9357SAndroid Build Coastguard Worker if (lv.IsSupported)
877*f6dc9357SAndroid Build Coastguard Worker {
878*f6dc9357SAndroid Build Coastguard Worker lv.IsSupported = false;
879*f6dc9357SAndroid Build Coastguard Worker item.Size = numExtents << (_extentSizeBits + 9);
880*f6dc9357SAndroid Build Coastguard Worker
881*f6dc9357SAndroid Build Coastguard Worker if (lv.Segments.Size() == 1)
882*f6dc9357SAndroid Build Coastguard Worker {
883*f6dc9357SAndroid Build Coastguard Worker const CSegment &segment = lv.Segments[0];
884*f6dc9357SAndroid Build Coastguard Worker if (segment.stripes.Size() == 1)
885*f6dc9357SAndroid Build Coastguard Worker {
886*f6dc9357SAndroid Build Coastguard Worker const CStripe &stripe = segment.stripes[0];
887*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (pvIndex, _phyVols)
888*f6dc9357SAndroid Build Coastguard Worker {
889*f6dc9357SAndroid Build Coastguard Worker const CPhyVol &pv = _phyVols[pvIndex];
890*f6dc9357SAndroid Build Coastguard Worker if (pv.Name == stripe.Name)
891*f6dc9357SAndroid Build Coastguard Worker {
892*f6dc9357SAndroid Build Coastguard Worker item.Pos = (pv.pe_start + (stripe.ExtentOffset << _extentSizeBits)) << 9;
893*f6dc9357SAndroid Build Coastguard Worker lv.IsSupported = true;
894*f6dc9357SAndroid Build Coastguard Worker item.IsSupported = true;
895*f6dc9357SAndroid Build Coastguard Worker break;
896*f6dc9357SAndroid Build Coastguard Worker }
897*f6dc9357SAndroid Build Coastguard Worker }
898*f6dc9357SAndroid Build Coastguard Worker }
899*f6dc9357SAndroid Build Coastguard Worker }
900*f6dc9357SAndroid Build Coastguard Worker }
901*f6dc9357SAndroid Build Coastguard Worker }
902*f6dc9357SAndroid Build Coastguard Worker
903*f6dc9357SAndroid Build Coastguard Worker _items.Add(item);
904*f6dc9357SAndroid Build Coastguard Worker }
905*f6dc9357SAndroid Build Coastguard Worker }
906*f6dc9357SAndroid Build Coastguard Worker
907*f6dc9357SAndroid Build Coastguard Worker {
908*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, _phyVols)
909*f6dc9357SAndroid Build Coastguard Worker {
910*f6dc9357SAndroid Build Coastguard Worker const CPhyVol &pv = _phyVols[i];
911*f6dc9357SAndroid Build Coastguard Worker
912*f6dc9357SAndroid Build Coastguard Worker if (pv.pe_start > (UInt64)1 << (62 - 9))
913*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
914*f6dc9357SAndroid Build Coastguard Worker if (pv.pe_count > (UInt64)1 << (62 - 9 - _extentSizeBits))
915*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
916*f6dc9357SAndroid Build Coastguard Worker
917*f6dc9357SAndroid Build Coastguard Worker CItem item;
918*f6dc9357SAndroid Build Coastguard Worker
919*f6dc9357SAndroid Build Coastguard Worker item.PhyVol = (int)i;
920*f6dc9357SAndroid Build Coastguard Worker item.Pos = pv.pe_start << 9;
921*f6dc9357SAndroid Build Coastguard Worker item.Size = pv.pe_count << (_extentSizeBits + 9);
922*f6dc9357SAndroid Build Coastguard Worker item.Name = pv.Name;
923*f6dc9357SAndroid Build Coastguard Worker item.IsSupported = true;
924*f6dc9357SAndroid Build Coastguard Worker
925*f6dc9357SAndroid Build Coastguard Worker _items.Add(item);
926*f6dc9357SAndroid Build Coastguard Worker }
927*f6dc9357SAndroid Build Coastguard Worker }
928*f6dc9357SAndroid Build Coastguard Worker
929*f6dc9357SAndroid Build Coastguard Worker return S_OK;
930*f6dc9357SAndroid Build Coastguard Worker }
931*f6dc9357SAndroid Build Coastguard Worker
932*f6dc9357SAndroid Build Coastguard Worker
933*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
934*f6dc9357SAndroid Build Coastguard Worker const UInt64 * /* maxCheckStartPosition */,
935*f6dc9357SAndroid Build Coastguard Worker IArchiveOpenCallback * /* openArchiveCallback */))
936*f6dc9357SAndroid Build Coastguard Worker {
937*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
938*f6dc9357SAndroid Build Coastguard Worker Close();
939*f6dc9357SAndroid Build Coastguard Worker RINOK(Open2(stream))
940*f6dc9357SAndroid Build Coastguard Worker _stream = stream;
941*f6dc9357SAndroid Build Coastguard Worker return S_OK;
942*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
943*f6dc9357SAndroid Build Coastguard Worker }
944*f6dc9357SAndroid Build Coastguard Worker
945*f6dc9357SAndroid Build Coastguard Worker
946*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
947*f6dc9357SAndroid Build Coastguard Worker {
948*f6dc9357SAndroid Build Coastguard Worker CVolGroup::Clear();
949*f6dc9357SAndroid Build Coastguard Worker
950*f6dc9357SAndroid Build Coastguard Worker _cfgPos = 0;
951*f6dc9357SAndroid Build Coastguard Worker _cfgSize = 0;
952*f6dc9357SAndroid Build Coastguard Worker _cTime = 0;
953*f6dc9357SAndroid Build Coastguard Worker _phySize = 0;
954*f6dc9357SAndroid Build Coastguard Worker _isArc = false;
955*f6dc9357SAndroid Build Coastguard Worker _items.Clear();
956*f6dc9357SAndroid Build Coastguard Worker
957*f6dc9357SAndroid Build Coastguard Worker _stream.Release();
958*f6dc9357SAndroid Build Coastguard Worker return S_OK;
959*f6dc9357SAndroid Build Coastguard Worker }
960*f6dc9357SAndroid Build Coastguard Worker
961*f6dc9357SAndroid Build Coastguard Worker
962*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
963*f6dc9357SAndroid Build Coastguard Worker {
964*f6dc9357SAndroid Build Coastguard Worker kpidPath,
965*f6dc9357SAndroid Build Coastguard Worker kpidSize,
966*f6dc9357SAndroid Build Coastguard Worker kpidFileSystem,
967*f6dc9357SAndroid Build Coastguard Worker kpidCharacts,
968*f6dc9357SAndroid Build Coastguard Worker kpidOffset,
969*f6dc9357SAndroid Build Coastguard Worker kpidId
970*f6dc9357SAndroid Build Coastguard Worker };
971*f6dc9357SAndroid Build Coastguard Worker
972*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
973*f6dc9357SAndroid Build Coastguard Worker {
974*f6dc9357SAndroid Build Coastguard Worker kpidId,
975*f6dc9357SAndroid Build Coastguard Worker kpidCTime,
976*f6dc9357SAndroid Build Coastguard Worker kpidClusterSize
977*f6dc9357SAndroid Build Coastguard Worker };
978*f6dc9357SAndroid Build Coastguard Worker
979*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
980*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
981*f6dc9357SAndroid Build Coastguard Worker
982*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
983*f6dc9357SAndroid Build Coastguard Worker {
984*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
985*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
986*f6dc9357SAndroid Build Coastguard Worker
987*f6dc9357SAndroid Build Coastguard Worker switch (propID)
988*f6dc9357SAndroid Build Coastguard Worker {
989*f6dc9357SAndroid Build Coastguard Worker case kpidMainSubfile:
990*f6dc9357SAndroid Build Coastguard Worker {
991*f6dc9357SAndroid Build Coastguard Worker /*
992*f6dc9357SAndroid Build Coastguard Worker if (_items.Size() == 1)
993*f6dc9357SAndroid Build Coastguard Worker prop = (UInt32)0;
994*f6dc9357SAndroid Build Coastguard Worker */
995*f6dc9357SAndroid Build Coastguard Worker break;
996*f6dc9357SAndroid Build Coastguard Worker }
997*f6dc9357SAndroid Build Coastguard Worker case kpidPhySize: if (_phySize != 0) prop = _phySize; break;
998*f6dc9357SAndroid Build Coastguard Worker case kpidId:
999*f6dc9357SAndroid Build Coastguard Worker {
1000*f6dc9357SAndroid Build Coastguard Worker prop = _id;
1001*f6dc9357SAndroid Build Coastguard Worker break;
1002*f6dc9357SAndroid Build Coastguard Worker }
1003*f6dc9357SAndroid Build Coastguard Worker case kpidClusterSize:
1004*f6dc9357SAndroid Build Coastguard Worker {
1005*f6dc9357SAndroid Build Coastguard Worker if (_extentSizeBits >= 0)
1006*f6dc9357SAndroid Build Coastguard Worker prop = ((UInt64)1 << (_extentSizeBits + 9));
1007*f6dc9357SAndroid Build Coastguard Worker break;
1008*f6dc9357SAndroid Build Coastguard Worker }
1009*f6dc9357SAndroid Build Coastguard Worker case kpidCTime:
1010*f6dc9357SAndroid Build Coastguard Worker {
1011*f6dc9357SAndroid Build Coastguard Worker if (_cTime != 0)
1012*f6dc9357SAndroid Build Coastguard Worker {
1013*f6dc9357SAndroid Build Coastguard Worker FILETIME ft;
1014*f6dc9357SAndroid Build Coastguard Worker NTime::UnixTime64_To_FileTime((Int64)_cTime, ft);
1015*f6dc9357SAndroid Build Coastguard Worker prop = ft;
1016*f6dc9357SAndroid Build Coastguard Worker }
1017*f6dc9357SAndroid Build Coastguard Worker break;
1018*f6dc9357SAndroid Build Coastguard Worker }
1019*f6dc9357SAndroid Build Coastguard Worker case kpidErrorFlags:
1020*f6dc9357SAndroid Build Coastguard Worker {
1021*f6dc9357SAndroid Build Coastguard Worker UInt32 v = 0;
1022*f6dc9357SAndroid Build Coastguard Worker if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
1023*f6dc9357SAndroid Build Coastguard Worker // if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
1024*f6dc9357SAndroid Build Coastguard Worker // if (_headerError) v |= kpv_ErrorFlags_HeadersError;
1025*f6dc9357SAndroid Build Coastguard Worker if (v == 0 && !_stream)
1026*f6dc9357SAndroid Build Coastguard Worker v |= kpv_ErrorFlags_UnsupportedMethod;
1027*f6dc9357SAndroid Build Coastguard Worker if (v != 0)
1028*f6dc9357SAndroid Build Coastguard Worker prop = v;
1029*f6dc9357SAndroid Build Coastguard Worker break;
1030*f6dc9357SAndroid Build Coastguard Worker }
1031*f6dc9357SAndroid Build Coastguard Worker }
1032*f6dc9357SAndroid Build Coastguard Worker
1033*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
1034*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1035*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
1036*f6dc9357SAndroid Build Coastguard Worker }
1037*f6dc9357SAndroid Build Coastguard Worker
1038*f6dc9357SAndroid Build Coastguard Worker
1039*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
1040*f6dc9357SAndroid Build Coastguard Worker {
1041*f6dc9357SAndroid Build Coastguard Worker *numItems = _items.Size() + (_cfgSize == 0 ? 0 : 1);
1042*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1043*f6dc9357SAndroid Build Coastguard Worker }
1044*f6dc9357SAndroid Build Coastguard Worker
1045*f6dc9357SAndroid Build Coastguard Worker
1046*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
1047*f6dc9357SAndroid Build Coastguard Worker {
1048*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
1049*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
1050*f6dc9357SAndroid Build Coastguard Worker
1051*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _items[index];
1052*f6dc9357SAndroid Build Coastguard Worker
1053*f6dc9357SAndroid Build Coastguard Worker // const CLogVol &item = _items[index];
1054*f6dc9357SAndroid Build Coastguard Worker
1055*f6dc9357SAndroid Build Coastguard Worker if (index >= _items.Size())
1056*f6dc9357SAndroid Build Coastguard Worker {
1057*f6dc9357SAndroid Build Coastguard Worker switch (propID)
1058*f6dc9357SAndroid Build Coastguard Worker {
1059*f6dc9357SAndroid Build Coastguard Worker case kpidPath:
1060*f6dc9357SAndroid Build Coastguard Worker {
1061*f6dc9357SAndroid Build Coastguard Worker prop = "meta.txt";
1062*f6dc9357SAndroid Build Coastguard Worker break;
1063*f6dc9357SAndroid Build Coastguard Worker }
1064*f6dc9357SAndroid Build Coastguard Worker
1065*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
1066*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize: prop = _cfgSize; break;
1067*f6dc9357SAndroid Build Coastguard Worker }
1068*f6dc9357SAndroid Build Coastguard Worker }
1069*f6dc9357SAndroid Build Coastguard Worker else
1070*f6dc9357SAndroid Build Coastguard Worker {
1071*f6dc9357SAndroid Build Coastguard Worker switch (propID)
1072*f6dc9357SAndroid Build Coastguard Worker {
1073*f6dc9357SAndroid Build Coastguard Worker case kpidPath:
1074*f6dc9357SAndroid Build Coastguard Worker {
1075*f6dc9357SAndroid Build Coastguard Worker AString s = item.Name;
1076*f6dc9357SAndroid Build Coastguard Worker s += ".img";
1077*f6dc9357SAndroid Build Coastguard Worker prop = s;
1078*f6dc9357SAndroid Build Coastguard Worker break;
1079*f6dc9357SAndroid Build Coastguard Worker }
1080*f6dc9357SAndroid Build Coastguard Worker
1081*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
1082*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize: prop = item.Size; break;
1083*f6dc9357SAndroid Build Coastguard Worker case kpidOffset: prop = item.Pos; break;
1084*f6dc9357SAndroid Build Coastguard Worker
1085*f6dc9357SAndroid Build Coastguard Worker case kpidId:
1086*f6dc9357SAndroid Build Coastguard Worker {
1087*f6dc9357SAndroid Build Coastguard Worker // prop = item.id;
1088*f6dc9357SAndroid Build Coastguard Worker break;
1089*f6dc9357SAndroid Build Coastguard Worker }
1090*f6dc9357SAndroid Build Coastguard Worker
1091*f6dc9357SAndroid Build Coastguard Worker // case kpidCharacts: FLAGS64_TO_PROP(g_PartitionFlags, item.Flags, prop); break;
1092*f6dc9357SAndroid Build Coastguard Worker }
1093*f6dc9357SAndroid Build Coastguard Worker }
1094*f6dc9357SAndroid Build Coastguard Worker
1095*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
1096*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1097*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
1098*f6dc9357SAndroid Build Coastguard Worker }
1099*f6dc9357SAndroid Build Coastguard Worker
1100*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I(
1101*f6dc9357SAndroid Build Coastguard Worker "LVM", "lvm", NULL, 0xBF,
1102*f6dc9357SAndroid Build Coastguard Worker k_Signature,
1103*f6dc9357SAndroid Build Coastguard Worker kSectorSize,
1104*f6dc9357SAndroid Build Coastguard Worker 0,
1105*f6dc9357SAndroid Build Coastguard Worker NULL)
1106*f6dc9357SAndroid Build Coastguard Worker
1107*f6dc9357SAndroid Build Coastguard Worker }}
1108