1*f6dc9357SAndroid Build Coastguard Worker // MbrHandler.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 "../../Common/ComTry.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/IntToString.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MyBuffer.h"
16*f6dc9357SAndroid Build Coastguard Worker
17*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/PropVariant.h"
18*f6dc9357SAndroid Build Coastguard Worker
19*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
20*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
21*f6dc9357SAndroid Build Coastguard Worker
22*f6dc9357SAndroid Build Coastguard Worker #include "HandlerCont.h"
23*f6dc9357SAndroid Build Coastguard Worker
24*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
25*f6dc9357SAndroid Build Coastguard Worker #define PRF(x) x
26*f6dc9357SAndroid Build Coastguard Worker #else
27*f6dc9357SAndroid Build Coastguard Worker #define PRF(x)
28*f6dc9357SAndroid Build Coastguard Worker #endif
29*f6dc9357SAndroid Build Coastguard Worker
30*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
31*f6dc9357SAndroid Build Coastguard Worker
32*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
33*f6dc9357SAndroid Build Coastguard Worker
34*f6dc9357SAndroid Build Coastguard Worker namespace NFat {
35*f6dc9357SAndroid Build Coastguard Worker API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size);
36*f6dc9357SAndroid Build Coastguard Worker }
37*f6dc9357SAndroid Build Coastguard Worker
38*f6dc9357SAndroid Build Coastguard Worker namespace NMbr {
39*f6dc9357SAndroid Build Coastguard Worker
40*f6dc9357SAndroid Build Coastguard Worker struct CChs
41*f6dc9357SAndroid Build Coastguard Worker {
42*f6dc9357SAndroid Build Coastguard Worker Byte Head;
43*f6dc9357SAndroid Build Coastguard Worker Byte SectCyl;
44*f6dc9357SAndroid Build Coastguard Worker Byte Cyl8;
45*f6dc9357SAndroid Build Coastguard Worker
GetSectorNArchive::NMbr::CChs46*f6dc9357SAndroid Build Coastguard Worker UInt32 GetSector() const { return SectCyl & 0x3F; }
GetCylNArchive::NMbr::CChs47*f6dc9357SAndroid Build Coastguard Worker UInt32 GetCyl() const { return ((UInt32)SectCyl >> 6 << 8) | Cyl8; }
48*f6dc9357SAndroid Build Coastguard Worker void ToString(NCOM::CPropVariant &prop) const;
49*f6dc9357SAndroid Build Coastguard Worker
ParseNArchive::NMbr::CChs50*f6dc9357SAndroid Build Coastguard Worker void Parse(const Byte *p)
51*f6dc9357SAndroid Build Coastguard Worker {
52*f6dc9357SAndroid Build Coastguard Worker Head = p[0];
53*f6dc9357SAndroid Build Coastguard Worker SectCyl = p[1];
54*f6dc9357SAndroid Build Coastguard Worker Cyl8 = p[2];
55*f6dc9357SAndroid Build Coastguard Worker }
CheckNArchive::NMbr::CChs56*f6dc9357SAndroid Build Coastguard Worker bool Check() const { return GetSector() > 0; }
57*f6dc9357SAndroid Build Coastguard Worker };
58*f6dc9357SAndroid Build Coastguard Worker
59*f6dc9357SAndroid Build Coastguard Worker
60*f6dc9357SAndroid Build Coastguard Worker // Chs in some MBRs contains only low bits of "Cyl number". So we disable check.
61*f6dc9357SAndroid Build Coastguard Worker /*
62*f6dc9357SAndroid Build Coastguard Worker #define RINOZ(x) { int _t_ = (x); if (_t_ != 0) return _t_; }
63*f6dc9357SAndroid Build Coastguard Worker static int CompareChs(const CChs &c1, const CChs &c2)
64*f6dc9357SAndroid Build Coastguard Worker {
65*f6dc9357SAndroid Build Coastguard Worker RINOZ(MyCompare(c1.GetCyl(), c2.GetCyl()));
66*f6dc9357SAndroid Build Coastguard Worker RINOZ(MyCompare(c1.Head, c2.Head));
67*f6dc9357SAndroid Build Coastguard Worker return MyCompare(c1.GetSector(), c2.GetSector());
68*f6dc9357SAndroid Build Coastguard Worker }
69*f6dc9357SAndroid Build Coastguard Worker */
70*f6dc9357SAndroid Build Coastguard Worker
ToString(NCOM::CPropVariant & prop) const71*f6dc9357SAndroid Build Coastguard Worker void CChs::ToString(NCOM::CPropVariant &prop) const
72*f6dc9357SAndroid Build Coastguard Worker {
73*f6dc9357SAndroid Build Coastguard Worker AString s;
74*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(GetCyl());
75*f6dc9357SAndroid Build Coastguard Worker s.Add_Minus();
76*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(Head);
77*f6dc9357SAndroid Build Coastguard Worker s.Add_Minus();
78*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(GetSector());
79*f6dc9357SAndroid Build Coastguard Worker prop = s;
80*f6dc9357SAndroid Build Coastguard Worker }
81*f6dc9357SAndroid Build Coastguard Worker
82*f6dc9357SAndroid Build Coastguard Worker struct CPartition
83*f6dc9357SAndroid Build Coastguard Worker {
84*f6dc9357SAndroid Build Coastguard Worker Byte Status;
85*f6dc9357SAndroid Build Coastguard Worker CChs BeginChs;
86*f6dc9357SAndroid Build Coastguard Worker Byte Type;
87*f6dc9357SAndroid Build Coastguard Worker CChs EndChs;
88*f6dc9357SAndroid Build Coastguard Worker UInt32 Lba;
89*f6dc9357SAndroid Build Coastguard Worker UInt32 NumBlocks;
90*f6dc9357SAndroid Build Coastguard Worker
CPartitionNArchive::NMbr::CPartition91*f6dc9357SAndroid Build Coastguard Worker CPartition() { memset (this, 0, sizeof(*this)); }
92*f6dc9357SAndroid Build Coastguard Worker
IsEmptyNArchive::NMbr::CPartition93*f6dc9357SAndroid Build Coastguard Worker bool IsEmpty() const { return Type == 0; }
IsExtendedNArchive::NMbr::CPartition94*f6dc9357SAndroid Build Coastguard Worker bool IsExtended() const { return Type == 5 || Type == 0xF; }
GetLimitNArchive::NMbr::CPartition95*f6dc9357SAndroid Build Coastguard Worker UInt32 GetLimit() const { return Lba + NumBlocks; }
96*f6dc9357SAndroid Build Coastguard Worker // bool IsActive() const { return Status == 0x80; }
GetPosNArchive::NMbr::CPartition97*f6dc9357SAndroid Build Coastguard Worker UInt64 GetPos(unsigned sectorSizeLog) const { return (UInt64)Lba << sectorSizeLog; }
GetSizeNArchive::NMbr::CPartition98*f6dc9357SAndroid Build Coastguard Worker UInt64 GetSize(unsigned sectorSizeLog) const { return (UInt64)NumBlocks << sectorSizeLog; }
99*f6dc9357SAndroid Build Coastguard Worker
CheckLbaLimitsNArchive::NMbr::CPartition100*f6dc9357SAndroid Build Coastguard Worker bool CheckLbaLimits() const { return (UInt32)0xFFFFFFFF - Lba >= NumBlocks; }
ParseNArchive::NMbr::CPartition101*f6dc9357SAndroid Build Coastguard Worker bool Parse(const Byte *p)
102*f6dc9357SAndroid Build Coastguard Worker {
103*f6dc9357SAndroid Build Coastguard Worker Status = p[0];
104*f6dc9357SAndroid Build Coastguard Worker BeginChs.Parse(p + 1);
105*f6dc9357SAndroid Build Coastguard Worker Type = p[4];
106*f6dc9357SAndroid Build Coastguard Worker EndChs.Parse(p + 5);
107*f6dc9357SAndroid Build Coastguard Worker Lba = GetUi32(p + 8);
108*f6dc9357SAndroid Build Coastguard Worker NumBlocks = GetUi32(p + 12);
109*f6dc9357SAndroid Build Coastguard Worker if (Type == 0)
110*f6dc9357SAndroid Build Coastguard Worker return true;
111*f6dc9357SAndroid Build Coastguard Worker if (Status != 0 && Status != 0x80)
112*f6dc9357SAndroid Build Coastguard Worker return false;
113*f6dc9357SAndroid Build Coastguard Worker return BeginChs.Check()
114*f6dc9357SAndroid Build Coastguard Worker && EndChs.Check()
115*f6dc9357SAndroid Build Coastguard Worker // && CompareChs(BeginChs, EndChs) <= 0
116*f6dc9357SAndroid Build Coastguard Worker && NumBlocks > 0
117*f6dc9357SAndroid Build Coastguard Worker && CheckLbaLimits();
118*f6dc9357SAndroid Build Coastguard Worker }
119*f6dc9357SAndroid Build Coastguard Worker
120*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
PrintNArchive::NMbr::CPartition121*f6dc9357SAndroid Build Coastguard Worker void Print() const
122*f6dc9357SAndroid Build Coastguard Worker {
123*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop, prop2;
124*f6dc9357SAndroid Build Coastguard Worker BeginChs.ToString(prop);
125*f6dc9357SAndroid Build Coastguard Worker EndChs.ToString(prop2);
126*f6dc9357SAndroid Build Coastguard Worker printf(" %2x %2x %8X %8X %12S %12S", (int)Status, (int)Type, Lba, NumBlocks, prop.bstrVal, prop2.bstrVal);
127*f6dc9357SAndroid Build Coastguard Worker }
128*f6dc9357SAndroid Build Coastguard Worker #endif
129*f6dc9357SAndroid Build Coastguard Worker };
130*f6dc9357SAndroid Build Coastguard Worker
131*f6dc9357SAndroid Build Coastguard Worker struct CPartType
132*f6dc9357SAndroid Build Coastguard Worker {
133*f6dc9357SAndroid Build Coastguard Worker UInt32 Id;
134*f6dc9357SAndroid Build Coastguard Worker const char *Ext;
135*f6dc9357SAndroid Build Coastguard Worker const char *Name;
136*f6dc9357SAndroid Build Coastguard Worker };
137*f6dc9357SAndroid Build Coastguard Worker
138*f6dc9357SAndroid Build Coastguard Worker #define kFat "fat"
139*f6dc9357SAndroid Build Coastguard Worker
140*f6dc9357SAndroid Build Coastguard Worker /*
141*f6dc9357SAndroid Build Coastguard Worker if we use "format" command in Windows 10 for existing partition:
142*f6dc9357SAndroid Build Coastguard Worker - if we format to ExFAT, it sets type=7
143*f6dc9357SAndroid Build Coastguard Worker - if we format to UDF, it doesn't change type from previous value.
144*f6dc9357SAndroid Build Coastguard Worker */
145*f6dc9357SAndroid Build Coastguard Worker
146*f6dc9357SAndroid Build Coastguard Worker static const unsigned kType_Windows_NTFS = 7;
147*f6dc9357SAndroid Build Coastguard Worker
148*f6dc9357SAndroid Build Coastguard Worker static const CPartType kPartTypes[] =
149*f6dc9357SAndroid Build Coastguard Worker {
150*f6dc9357SAndroid Build Coastguard Worker { 0x01, kFat, "FAT12" },
151*f6dc9357SAndroid Build Coastguard Worker { 0x04, kFat, "FAT16 DOS 3.0+" },
152*f6dc9357SAndroid Build Coastguard Worker { 0x05, NULL, "Extended" },
153*f6dc9357SAndroid Build Coastguard Worker { 0x06, kFat, "FAT16 DOS 3.31+" },
154*f6dc9357SAndroid Build Coastguard Worker { 0x07, "ntfs", "NTFS" },
155*f6dc9357SAndroid Build Coastguard Worker { 0x0B, kFat, "FAT32" },
156*f6dc9357SAndroid Build Coastguard Worker { 0x0C, kFat, "FAT32-LBA" },
157*f6dc9357SAndroid Build Coastguard Worker { 0x0E, kFat, "FAT16-LBA" },
158*f6dc9357SAndroid Build Coastguard Worker { 0x0F, NULL, "Extended-LBA" },
159*f6dc9357SAndroid Build Coastguard Worker { 0x11, kFat, "FAT12-Hidden" },
160*f6dc9357SAndroid Build Coastguard Worker { 0x14, kFat, "FAT16-Hidden < 32 MB" },
161*f6dc9357SAndroid Build Coastguard Worker { 0x16, kFat, "FAT16-Hidden >= 32 MB" },
162*f6dc9357SAndroid Build Coastguard Worker { 0x1B, kFat, "FAT32-Hidden" },
163*f6dc9357SAndroid Build Coastguard Worker { 0x1C, kFat, "FAT32-LBA-Hidden" },
164*f6dc9357SAndroid Build Coastguard Worker { 0x1E, kFat, "FAT16-LBA-WIN95-Hidden" },
165*f6dc9357SAndroid Build Coastguard Worker { 0x27, "ntfs", "NTFS-WinRE" },
166*f6dc9357SAndroid Build Coastguard Worker { 0x82, NULL, "Solaris x86 / Linux swap" },
167*f6dc9357SAndroid Build Coastguard Worker { 0x83, NULL, "Linux" },
168*f6dc9357SAndroid Build Coastguard Worker { 0x8E, "lvm", "Linux LVM" },
169*f6dc9357SAndroid Build Coastguard Worker { 0xA5, NULL, "BSD slice" },
170*f6dc9357SAndroid Build Coastguard Worker { 0xBE, NULL, "Solaris 8 boot" },
171*f6dc9357SAndroid Build Coastguard Worker { 0xBF, NULL, "New Solaris x86" },
172*f6dc9357SAndroid Build Coastguard Worker { 0xC2, NULL, "Linux-Hidden" },
173*f6dc9357SAndroid Build Coastguard Worker { 0xC3, NULL, "Linux swap-Hidden" },
174*f6dc9357SAndroid Build Coastguard Worker { 0xEE, NULL, "GPT" },
175*f6dc9357SAndroid Build Coastguard Worker { 0xEE, NULL, "EFI" }
176*f6dc9357SAndroid Build Coastguard Worker };
177*f6dc9357SAndroid Build Coastguard Worker
FindPartType(UInt32 type)178*f6dc9357SAndroid Build Coastguard Worker static int FindPartType(UInt32 type)
179*f6dc9357SAndroid Build Coastguard Worker {
180*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPartTypes); i++)
181*f6dc9357SAndroid Build Coastguard Worker if (kPartTypes[i].Id == type)
182*f6dc9357SAndroid Build Coastguard Worker return (int)i;
183*f6dc9357SAndroid Build Coastguard Worker return -1;
184*f6dc9357SAndroid Build Coastguard Worker }
185*f6dc9357SAndroid Build Coastguard Worker
186*f6dc9357SAndroid Build Coastguard Worker struct CItem
187*f6dc9357SAndroid Build Coastguard Worker {
188*f6dc9357SAndroid Build Coastguard Worker bool IsReal;
189*f6dc9357SAndroid Build Coastguard Worker bool IsPrim;
190*f6dc9357SAndroid Build Coastguard Worker bool WasParsed;
191*f6dc9357SAndroid Build Coastguard Worker const char *FileSystem;
192*f6dc9357SAndroid Build Coastguard Worker UInt64 Size;
193*f6dc9357SAndroid Build Coastguard Worker CPartition Part;
194*f6dc9357SAndroid Build Coastguard Worker
CItemNArchive::NMbr::CItem195*f6dc9357SAndroid Build Coastguard Worker CItem():
196*f6dc9357SAndroid Build Coastguard Worker WasParsed(false),
197*f6dc9357SAndroid Build Coastguard Worker FileSystem(NULL)
198*f6dc9357SAndroid Build Coastguard Worker {}
199*f6dc9357SAndroid Build Coastguard Worker };
200*f6dc9357SAndroid Build Coastguard Worker
201*f6dc9357SAndroid Build Coastguard Worker
202*f6dc9357SAndroid Build Coastguard Worker Z7_class_CHandler_final: public CHandlerCont
203*f6dc9357SAndroid Build Coastguard Worker {
204*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_COM7_IMP(IInArchive_Cont)
205*f6dc9357SAndroid Build Coastguard Worker
206*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CItem> _items;
207*f6dc9357SAndroid Build Coastguard Worker UInt64 _totalSize;
208*f6dc9357SAndroid Build Coastguard Worker CByteBuffer _buffer;
209*f6dc9357SAndroid Build Coastguard Worker
210*f6dc9357SAndroid Build Coastguard Worker UInt32 _signature;
211*f6dc9357SAndroid Build Coastguard Worker unsigned _sectorSizeLog;
212*f6dc9357SAndroid Build Coastguard Worker
213*f6dc9357SAndroid Build Coastguard Worker virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override Z7_final
214*f6dc9357SAndroid Build Coastguard Worker {
215*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _items[index];
216*f6dc9357SAndroid Build Coastguard Worker pos = item.Part.GetPos(_sectorSizeLog);
217*f6dc9357SAndroid Build Coastguard Worker size = item.Size;
218*f6dc9357SAndroid Build Coastguard Worker return NExtract::NOperationResult::kOK;
219*f6dc9357SAndroid Build Coastguard Worker }
220*f6dc9357SAndroid Build Coastguard Worker
221*f6dc9357SAndroid Build Coastguard Worker HRESULT ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level);
222*f6dc9357SAndroid Build Coastguard Worker };
223*f6dc9357SAndroid Build Coastguard Worker
224*f6dc9357SAndroid Build Coastguard Worker /*
225*f6dc9357SAndroid Build Coastguard Worker static bool IsEmptyBuffer(const Byte *data, size_t size)
226*f6dc9357SAndroid Build Coastguard Worker {
227*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++)
228*f6dc9357SAndroid Build Coastguard Worker if (data[i] != 0)
229*f6dc9357SAndroid Build Coastguard Worker return false;
230*f6dc9357SAndroid Build Coastguard Worker return true;
231*f6dc9357SAndroid Build Coastguard Worker }
232*f6dc9357SAndroid Build Coastguard Worker */
233*f6dc9357SAndroid Build Coastguard Worker
234*f6dc9357SAndroid Build Coastguard Worker const char *GetFileSystem(ISequentialInStream *stream, UInt64 partitionSize);
235*f6dc9357SAndroid Build Coastguard Worker
236*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level)
237*f6dc9357SAndroid Build Coastguard Worker {
238*f6dc9357SAndroid Build Coastguard Worker if (level >= 128 || _items.Size() >= 128)
239*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
240*f6dc9357SAndroid Build Coastguard Worker
241*f6dc9357SAndroid Build Coastguard Worker const unsigned kNumHeaderParts = 4;
242*f6dc9357SAndroid Build Coastguard Worker CPartition parts[kNumHeaderParts];
243*f6dc9357SAndroid Build Coastguard Worker
244*f6dc9357SAndroid Build Coastguard Worker if (level == 0)
245*f6dc9357SAndroid Build Coastguard Worker _sectorSizeLog = 9;
246*f6dc9357SAndroid Build Coastguard Worker const UInt32 kSectorSize = (UInt32)1 << _sectorSizeLog;
247*f6dc9357SAndroid Build Coastguard Worker UInt32 bufSize = kSectorSize;
248*f6dc9357SAndroid Build Coastguard Worker if (level == 0 && _totalSize >= (1 << 12))
249*f6dc9357SAndroid Build Coastguard Worker bufSize = (1 << 12);
250*f6dc9357SAndroid Build Coastguard Worker _buffer.Alloc(bufSize);
251*f6dc9357SAndroid Build Coastguard Worker {
252*f6dc9357SAndroid Build Coastguard Worker Byte *buf = _buffer;
253*f6dc9357SAndroid Build Coastguard Worker const UInt64 newPos = (UInt64)lba << _sectorSizeLog;
254*f6dc9357SAndroid Build Coastguard Worker if (newPos + bufSize > _totalSize)
255*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
256*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(stream, newPos))
257*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream_FALSE(stream, buf, bufSize))
258*f6dc9357SAndroid Build Coastguard Worker if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA)
259*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
260*f6dc9357SAndroid Build Coastguard Worker if (level == 0)
261*f6dc9357SAndroid Build Coastguard Worker _signature = GetUi32(buf + 0x1B8);
262*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < kNumHeaderParts; i++)
263*f6dc9357SAndroid Build Coastguard Worker if (!parts[i].Parse(buf + 0x1BE + 16 * i))
264*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
265*f6dc9357SAndroid Build Coastguard Worker }
266*f6dc9357SAndroid Build Coastguard Worker
267*f6dc9357SAndroid Build Coastguard Worker // 23.02: now we try to detect 4kn format (4 KB sectors case)
268*f6dc9357SAndroid Build Coastguard Worker if (level == 0)
269*f6dc9357SAndroid Build Coastguard Worker // if (_totalSize >= (1 << 28)) // we don't expect small images with 4 KB sectors
270*f6dc9357SAndroid Build Coastguard Worker if (bufSize >= (1 << 12))
271*f6dc9357SAndroid Build Coastguard Worker {
272*f6dc9357SAndroid Build Coastguard Worker UInt32 lastLim = 0;
273*f6dc9357SAndroid Build Coastguard Worker UInt32 firstLba = 0;
274*f6dc9357SAndroid Build Coastguard Worker UInt32 numBlocks = 0; // in first partition
275*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < kNumHeaderParts; i++)
276*f6dc9357SAndroid Build Coastguard Worker {
277*f6dc9357SAndroid Build Coastguard Worker const CPartition &part = parts[i];
278*f6dc9357SAndroid Build Coastguard Worker if (part.IsEmpty())
279*f6dc9357SAndroid Build Coastguard Worker continue;
280*f6dc9357SAndroid Build Coastguard Worker if (firstLba == 0 && part.NumBlocks != 0)
281*f6dc9357SAndroid Build Coastguard Worker {
282*f6dc9357SAndroid Build Coastguard Worker firstLba = part.Lba;
283*f6dc9357SAndroid Build Coastguard Worker numBlocks = part.NumBlocks;
284*f6dc9357SAndroid Build Coastguard Worker }
285*f6dc9357SAndroid Build Coastguard Worker const UInt32 newLim = part.GetLimit();
286*f6dc9357SAndroid Build Coastguard Worker if (newLim < lastLim)
287*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
288*f6dc9357SAndroid Build Coastguard Worker lastLim = newLim;
289*f6dc9357SAndroid Build Coastguard Worker }
290*f6dc9357SAndroid Build Coastguard Worker if (lastLim != 0)
291*f6dc9357SAndroid Build Coastguard Worker {
292*f6dc9357SAndroid Build Coastguard Worker const UInt64 lim12 = (UInt64)lastLim << 12;
293*f6dc9357SAndroid Build Coastguard Worker if (lim12 <= _totalSize
294*f6dc9357SAndroid Build Coastguard Worker // && _totalSize - lim12 < (1 << 28) // we can try to exclude false positive cases
295*f6dc9357SAndroid Build Coastguard Worker )
296*f6dc9357SAndroid Build Coastguard Worker // if (IsEmptyBuffer(&_buffer[(1 << 9)], (1 << 12) - (1 << 9)))
297*f6dc9357SAndroid Build Coastguard Worker if (InStream_SeekSet(stream, (UInt64)firstLba << 12) == S_OK)
298*f6dc9357SAndroid Build Coastguard Worker if (GetFileSystem(stream, (UInt64)numBlocks << 12))
299*f6dc9357SAndroid Build Coastguard Worker _sectorSizeLog = 12;
300*f6dc9357SAndroid Build Coastguard Worker }
301*f6dc9357SAndroid Build Coastguard Worker }
302*f6dc9357SAndroid Build Coastguard Worker
303*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\n# %8X", lba));
304*f6dc9357SAndroid Build Coastguard Worker
305*f6dc9357SAndroid Build Coastguard Worker UInt32 limLba = lba + 1;
306*f6dc9357SAndroid Build Coastguard Worker if (limLba == 0)
307*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
308*f6dc9357SAndroid Build Coastguard Worker
309*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < kNumHeaderParts; i++)
310*f6dc9357SAndroid Build Coastguard Worker {
311*f6dc9357SAndroid Build Coastguard Worker CPartition &part = parts[i];
312*f6dc9357SAndroid Build Coastguard Worker
313*f6dc9357SAndroid Build Coastguard Worker if (part.IsEmpty())
314*f6dc9357SAndroid Build Coastguard Worker continue;
315*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\n %2d ", (unsigned)level));
316*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_DEBUG_INFO
317*f6dc9357SAndroid Build Coastguard Worker part.Print();
318*f6dc9357SAndroid Build Coastguard Worker #endif
319*f6dc9357SAndroid Build Coastguard Worker
320*f6dc9357SAndroid Build Coastguard Worker unsigned numItems = _items.Size();
321*f6dc9357SAndroid Build Coastguard Worker UInt32 newLba = lba + part.Lba;
322*f6dc9357SAndroid Build Coastguard Worker
323*f6dc9357SAndroid Build Coastguard Worker if (part.IsExtended())
324*f6dc9357SAndroid Build Coastguard Worker {
325*f6dc9357SAndroid Build Coastguard Worker // if (part.Type == 5) // Check it!
326*f6dc9357SAndroid Build Coastguard Worker newLba = baseLba + part.Lba;
327*f6dc9357SAndroid Build Coastguard Worker if (newLba < limLba)
328*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
329*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = ReadTables(stream, level < 1 ? newLba : baseLba, newLba, level + 1);
330*f6dc9357SAndroid Build Coastguard Worker if (res != S_FALSE && res != S_OK)
331*f6dc9357SAndroid Build Coastguard Worker return res;
332*f6dc9357SAndroid Build Coastguard Worker }
333*f6dc9357SAndroid Build Coastguard Worker if (newLba < limLba)
334*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
335*f6dc9357SAndroid Build Coastguard Worker part.Lba = newLba;
336*f6dc9357SAndroid Build Coastguard Worker if (!part.CheckLbaLimits())
337*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
338*f6dc9357SAndroid Build Coastguard Worker
339*f6dc9357SAndroid Build Coastguard Worker CItem n;
340*f6dc9357SAndroid Build Coastguard Worker n.Part = part;
341*f6dc9357SAndroid Build Coastguard Worker bool addItem = false;
342*f6dc9357SAndroid Build Coastguard Worker if (numItems == _items.Size())
343*f6dc9357SAndroid Build Coastguard Worker {
344*f6dc9357SAndroid Build Coastguard Worker n.IsPrim = (level == 0);
345*f6dc9357SAndroid Build Coastguard Worker n.IsReal = true;
346*f6dc9357SAndroid Build Coastguard Worker addItem = true;
347*f6dc9357SAndroid Build Coastguard Worker }
348*f6dc9357SAndroid Build Coastguard Worker else
349*f6dc9357SAndroid Build Coastguard Worker {
350*f6dc9357SAndroid Build Coastguard Worker const CItem &back = _items.Back();
351*f6dc9357SAndroid Build Coastguard Worker const UInt32 backLimit = back.Part.GetLimit();
352*f6dc9357SAndroid Build Coastguard Worker const UInt32 partLimit = part.GetLimit();
353*f6dc9357SAndroid Build Coastguard Worker if (backLimit < partLimit)
354*f6dc9357SAndroid Build Coastguard Worker {
355*f6dc9357SAndroid Build Coastguard Worker n.IsReal = false;
356*f6dc9357SAndroid Build Coastguard Worker n.Part.Lba = backLimit;
357*f6dc9357SAndroid Build Coastguard Worker n.Part.NumBlocks = partLimit - backLimit;
358*f6dc9357SAndroid Build Coastguard Worker addItem = true;
359*f6dc9357SAndroid Build Coastguard Worker }
360*f6dc9357SAndroid Build Coastguard Worker }
361*f6dc9357SAndroid Build Coastguard Worker if (addItem)
362*f6dc9357SAndroid Build Coastguard Worker {
363*f6dc9357SAndroid Build Coastguard Worker if (n.Part.GetLimit() < limLba)
364*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
365*f6dc9357SAndroid Build Coastguard Worker limLba = n.Part.GetLimit();
366*f6dc9357SAndroid Build Coastguard Worker n.Size = n.Part.GetSize(_sectorSizeLog);
367*f6dc9357SAndroid Build Coastguard Worker _items.Add(n);
368*f6dc9357SAndroid Build Coastguard Worker }
369*f6dc9357SAndroid Build Coastguard Worker }
370*f6dc9357SAndroid Build Coastguard Worker return S_OK;
371*f6dc9357SAndroid Build Coastguard Worker }
372*f6dc9357SAndroid Build Coastguard Worker
373*f6dc9357SAndroid Build Coastguard Worker
374*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Ntfs_Signature[] = { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 };
375*f6dc9357SAndroid Build Coastguard Worker
376*f6dc9357SAndroid Build Coastguard Worker static bool Is_Ntfs(const Byte *p)
377*f6dc9357SAndroid Build Coastguard Worker {
378*f6dc9357SAndroid Build Coastguard Worker if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA)
379*f6dc9357SAndroid Build Coastguard Worker return false;
380*f6dc9357SAndroid Build Coastguard Worker switch (p[0])
381*f6dc9357SAndroid Build Coastguard Worker {
382*f6dc9357SAndroid Build Coastguard Worker case 0xE9: /* codeOffset = 3 + (Int16)Get16(p + 1); */ break;
383*f6dc9357SAndroid Build Coastguard Worker case 0xEB: if (p[2] != 0x90) return false; /* codeOffset = 2 + (int)(signed char)p[1]; */ break;
384*f6dc9357SAndroid Build Coastguard Worker default: return false;
385*f6dc9357SAndroid Build Coastguard Worker }
386*f6dc9357SAndroid Build Coastguard Worker return memcmp(p + 3, k_Ntfs_Signature, Z7_ARRAY_SIZE(k_Ntfs_Signature)) == 0;
387*f6dc9357SAndroid Build Coastguard Worker }
388*f6dc9357SAndroid Build Coastguard Worker
389*f6dc9357SAndroid Build Coastguard Worker static const Byte k_ExFat_Signature[] = { 'E', 'X', 'F', 'A', 'T', ' ', ' ', ' ' };
390*f6dc9357SAndroid Build Coastguard Worker
391*f6dc9357SAndroid Build Coastguard Worker static bool Is_ExFat(const Byte *p)
392*f6dc9357SAndroid Build Coastguard Worker {
393*f6dc9357SAndroid Build Coastguard Worker if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA)
394*f6dc9357SAndroid Build Coastguard Worker return false;
395*f6dc9357SAndroid Build Coastguard Worker if (p[0] != 0xEB || p[1] != 0x76 || p[2] != 0x90)
396*f6dc9357SAndroid Build Coastguard Worker return false;
397*f6dc9357SAndroid Build Coastguard Worker return memcmp(p + 3, k_ExFat_Signature, Z7_ARRAY_SIZE(k_ExFat_Signature)) == 0;
398*f6dc9357SAndroid Build Coastguard Worker }
399*f6dc9357SAndroid Build Coastguard Worker
400*f6dc9357SAndroid Build Coastguard Worker static bool AllAreZeros(const Byte *p, size_t size)
401*f6dc9357SAndroid Build Coastguard Worker {
402*f6dc9357SAndroid Build Coastguard Worker for (size_t i = 0; i < size; i++)
403*f6dc9357SAndroid Build Coastguard Worker if (p[i] != 0)
404*f6dc9357SAndroid Build Coastguard Worker return false;
405*f6dc9357SAndroid Build Coastguard Worker return true;
406*f6dc9357SAndroid Build Coastguard Worker }
407*f6dc9357SAndroid Build Coastguard Worker
408*f6dc9357SAndroid Build Coastguard Worker static const UInt32 k_Udf_StartPos = 0x8000;
409*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Udf_Signature[] = { 0, 'B', 'E', 'A', '0', '1', 1, 0 };
410*f6dc9357SAndroid Build Coastguard Worker
411*f6dc9357SAndroid Build Coastguard Worker static bool Is_Udf(const Byte *p)
412*f6dc9357SAndroid Build Coastguard Worker {
413*f6dc9357SAndroid Build Coastguard Worker return memcmp(p + k_Udf_StartPos, k_Udf_Signature, sizeof(k_Udf_Signature)) == 0;
414*f6dc9357SAndroid Build Coastguard Worker }
415*f6dc9357SAndroid Build Coastguard Worker
416*f6dc9357SAndroid Build Coastguard Worker
417*f6dc9357SAndroid Build Coastguard Worker const char *GetFileSystem(ISequentialInStream *stream, UInt64 partitionSize)
418*f6dc9357SAndroid Build Coastguard Worker {
419*f6dc9357SAndroid Build Coastguard Worker const size_t kHeaderSize = 1 << 9;
420*f6dc9357SAndroid Build Coastguard Worker if (partitionSize >= kHeaderSize)
421*f6dc9357SAndroid Build Coastguard Worker {
422*f6dc9357SAndroid Build Coastguard Worker Byte buf[kHeaderSize];
423*f6dc9357SAndroid Build Coastguard Worker if (ReadStream_FAIL(stream, buf, kHeaderSize) == S_OK)
424*f6dc9357SAndroid Build Coastguard Worker {
425*f6dc9357SAndroid Build Coastguard Worker // NTFS is expected default filesystem for (Type == 7)
426*f6dc9357SAndroid Build Coastguard Worker if (Is_Ntfs(buf))
427*f6dc9357SAndroid Build Coastguard Worker return "NTFS";
428*f6dc9357SAndroid Build Coastguard Worker if (Is_ExFat(buf))
429*f6dc9357SAndroid Build Coastguard Worker return "exFAT";
430*f6dc9357SAndroid Build Coastguard Worker if (NFat::IsArc_Fat(buf, kHeaderSize))
431*f6dc9357SAndroid Build Coastguard Worker return "FAT";
432*f6dc9357SAndroid Build Coastguard Worker const size_t kHeaderSize2 = k_Udf_StartPos + (1 << 9);
433*f6dc9357SAndroid Build Coastguard Worker if (partitionSize >= kHeaderSize2)
434*f6dc9357SAndroid Build Coastguard Worker {
435*f6dc9357SAndroid Build Coastguard Worker if (AllAreZeros(buf, kHeaderSize))
436*f6dc9357SAndroid Build Coastguard Worker {
437*f6dc9357SAndroid Build Coastguard Worker CByteBuffer buffer(kHeaderSize2);
438*f6dc9357SAndroid Build Coastguard Worker // memcpy(buffer, buf, kHeaderSize);
439*f6dc9357SAndroid Build Coastguard Worker if (ReadStream_FAIL(stream, buffer + kHeaderSize, kHeaderSize2 - kHeaderSize) == S_OK)
440*f6dc9357SAndroid Build Coastguard Worker if (Is_Udf(buffer))
441*f6dc9357SAndroid Build Coastguard Worker return "UDF";
442*f6dc9357SAndroid Build Coastguard Worker }
443*f6dc9357SAndroid Build Coastguard Worker }
444*f6dc9357SAndroid Build Coastguard Worker }
445*f6dc9357SAndroid Build Coastguard Worker }
446*f6dc9357SAndroid Build Coastguard Worker return NULL;
447*f6dc9357SAndroid Build Coastguard Worker }
448*f6dc9357SAndroid Build Coastguard Worker
449*f6dc9357SAndroid Build Coastguard Worker
450*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
451*f6dc9357SAndroid Build Coastguard Worker const UInt64 * /* maxCheckStartPosition */,
452*f6dc9357SAndroid Build Coastguard Worker IArchiveOpenCallback * /* openArchiveCallback */))
453*f6dc9357SAndroid Build Coastguard Worker {
454*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
455*f6dc9357SAndroid Build Coastguard Worker Close();
456*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_GetSize_SeekToEnd(stream, _totalSize))
457*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadTables(stream, 0, 0, 0))
458*f6dc9357SAndroid Build Coastguard Worker if (_items.IsEmpty())
459*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
460*f6dc9357SAndroid Build Coastguard Worker {
461*f6dc9357SAndroid Build Coastguard Worker const UInt32 lbaLimit = _items.Back().Part.GetLimit();
462*f6dc9357SAndroid Build Coastguard Worker const UInt64 lim = (UInt64)lbaLimit << _sectorSizeLog;
463*f6dc9357SAndroid Build Coastguard Worker if (lim < _totalSize)
464*f6dc9357SAndroid Build Coastguard Worker {
465*f6dc9357SAndroid Build Coastguard Worker CItem n;
466*f6dc9357SAndroid Build Coastguard Worker n.Part.Lba = lbaLimit;
467*f6dc9357SAndroid Build Coastguard Worker n.Size = _totalSize - lim;
468*f6dc9357SAndroid Build Coastguard Worker n.IsReal = false;
469*f6dc9357SAndroid Build Coastguard Worker _items.Add(n);
470*f6dc9357SAndroid Build Coastguard Worker }
471*f6dc9357SAndroid Build Coastguard Worker }
472*f6dc9357SAndroid Build Coastguard Worker
473*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, _items)
474*f6dc9357SAndroid Build Coastguard Worker {
475*f6dc9357SAndroid Build Coastguard Worker CItem &item = _items[i];
476*f6dc9357SAndroid Build Coastguard Worker if (item.Part.Type != kType_Windows_NTFS)
477*f6dc9357SAndroid Build Coastguard Worker continue;
478*f6dc9357SAndroid Build Coastguard Worker if (InStream_SeekSet(stream, item.Part.GetPos(_sectorSizeLog)) != S_OK)
479*f6dc9357SAndroid Build Coastguard Worker continue;
480*f6dc9357SAndroid Build Coastguard Worker item.FileSystem = GetFileSystem(stream, item.Size);
481*f6dc9357SAndroid Build Coastguard Worker item.WasParsed = true;
482*f6dc9357SAndroid Build Coastguard Worker }
483*f6dc9357SAndroid Build Coastguard Worker
484*f6dc9357SAndroid Build Coastguard Worker _stream = stream;
485*f6dc9357SAndroid Build Coastguard Worker return S_OK;
486*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
487*f6dc9357SAndroid Build Coastguard Worker }
488*f6dc9357SAndroid Build Coastguard Worker
489*f6dc9357SAndroid Build Coastguard Worker
490*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
491*f6dc9357SAndroid Build Coastguard Worker {
492*f6dc9357SAndroid Build Coastguard Worker _totalSize = 0;
493*f6dc9357SAndroid Build Coastguard Worker _items.Clear();
494*f6dc9357SAndroid Build Coastguard Worker _stream.Release();
495*f6dc9357SAndroid Build Coastguard Worker return S_OK;
496*f6dc9357SAndroid Build Coastguard Worker }
497*f6dc9357SAndroid Build Coastguard Worker
498*f6dc9357SAndroid Build Coastguard Worker
499*f6dc9357SAndroid Build Coastguard Worker enum
500*f6dc9357SAndroid Build Coastguard Worker {
501*f6dc9357SAndroid Build Coastguard Worker kpidPrimary = kpidUserDefined,
502*f6dc9357SAndroid Build Coastguard Worker kpidBegChs,
503*f6dc9357SAndroid Build Coastguard Worker kpidEndChs
504*f6dc9357SAndroid Build Coastguard Worker };
505*f6dc9357SAndroid Build Coastguard Worker
506*f6dc9357SAndroid Build Coastguard Worker static const CStatProp kProps[] =
507*f6dc9357SAndroid Build Coastguard Worker {
508*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidPath, VT_BSTR},
509*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidSize, VT_UI8},
510*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidFileSystem, VT_BSTR},
511*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidOffset, VT_UI8},
512*f6dc9357SAndroid Build Coastguard Worker { "Primary", kpidPrimary, VT_BOOL},
513*f6dc9357SAndroid Build Coastguard Worker { "Begin CHS", kpidBegChs, VT_BSTR},
514*f6dc9357SAndroid Build Coastguard Worker { "End CHS", kpidEndChs, VT_BSTR}
515*f6dc9357SAndroid Build Coastguard Worker };
516*f6dc9357SAndroid Build Coastguard Worker
517*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
518*f6dc9357SAndroid Build Coastguard Worker {
519*f6dc9357SAndroid Build Coastguard Worker kpidSectorSize,
520*f6dc9357SAndroid Build Coastguard Worker kpidId
521*f6dc9357SAndroid Build Coastguard Worker };
522*f6dc9357SAndroid Build Coastguard Worker
523*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props_WITH_NAME
524*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
525*f6dc9357SAndroid Build Coastguard Worker
526*f6dc9357SAndroid Build Coastguard Worker
527*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
528*f6dc9357SAndroid Build Coastguard Worker {
529*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
530*f6dc9357SAndroid Build Coastguard Worker switch (propID)
531*f6dc9357SAndroid Build Coastguard Worker {
532*f6dc9357SAndroid Build Coastguard Worker case kpidMainSubfile:
533*f6dc9357SAndroid Build Coastguard Worker {
534*f6dc9357SAndroid Build Coastguard Worker int mainIndex = -1;
535*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, _items)
536*f6dc9357SAndroid Build Coastguard Worker if (_items[i].IsReal)
537*f6dc9357SAndroid Build Coastguard Worker {
538*f6dc9357SAndroid Build Coastguard Worker if (mainIndex >= 0)
539*f6dc9357SAndroid Build Coastguard Worker {
540*f6dc9357SAndroid Build Coastguard Worker mainIndex = -1;
541*f6dc9357SAndroid Build Coastguard Worker break;
542*f6dc9357SAndroid Build Coastguard Worker }
543*f6dc9357SAndroid Build Coastguard Worker mainIndex = (int)i;
544*f6dc9357SAndroid Build Coastguard Worker }
545*f6dc9357SAndroid Build Coastguard Worker if (mainIndex >= 0)
546*f6dc9357SAndroid Build Coastguard Worker prop = (UInt32)(Int32)mainIndex;
547*f6dc9357SAndroid Build Coastguard Worker break;
548*f6dc9357SAndroid Build Coastguard Worker }
549*f6dc9357SAndroid Build Coastguard Worker case kpidPhySize: prop = _totalSize; break;
550*f6dc9357SAndroid Build Coastguard Worker case kpidSectorSize: prop = (UInt32)((UInt32)1 << _sectorSizeLog); break;
551*f6dc9357SAndroid Build Coastguard Worker case kpidId: prop = _signature; break;
552*f6dc9357SAndroid Build Coastguard Worker }
553*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
554*f6dc9357SAndroid Build Coastguard Worker return S_OK;
555*f6dc9357SAndroid Build Coastguard Worker }
556*f6dc9357SAndroid Build Coastguard Worker
557*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
558*f6dc9357SAndroid Build Coastguard Worker {
559*f6dc9357SAndroid Build Coastguard Worker *numItems = _items.Size();
560*f6dc9357SAndroid Build Coastguard Worker return S_OK;
561*f6dc9357SAndroid Build Coastguard Worker }
562*f6dc9357SAndroid Build Coastguard Worker
563*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
564*f6dc9357SAndroid Build Coastguard Worker {
565*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
566*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
567*f6dc9357SAndroid Build Coastguard Worker
568*f6dc9357SAndroid Build Coastguard Worker const CItem &item = _items[index];
569*f6dc9357SAndroid Build Coastguard Worker const CPartition &part = item.Part;
570*f6dc9357SAndroid Build Coastguard Worker switch (propID)
571*f6dc9357SAndroid Build Coastguard Worker {
572*f6dc9357SAndroid Build Coastguard Worker case kpidPath:
573*f6dc9357SAndroid Build Coastguard Worker {
574*f6dc9357SAndroid Build Coastguard Worker AString s;
575*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(index);
576*f6dc9357SAndroid Build Coastguard Worker if (item.IsReal)
577*f6dc9357SAndroid Build Coastguard Worker {
578*f6dc9357SAndroid Build Coastguard Worker s.Add_Dot();
579*f6dc9357SAndroid Build Coastguard Worker const char *ext = NULL;
580*f6dc9357SAndroid Build Coastguard Worker if (item.FileSystem)
581*f6dc9357SAndroid Build Coastguard Worker {
582*f6dc9357SAndroid Build Coastguard Worker ext = "";
583*f6dc9357SAndroid Build Coastguard Worker AString fs (item.FileSystem);
584*f6dc9357SAndroid Build Coastguard Worker fs.MakeLower_Ascii();
585*f6dc9357SAndroid Build Coastguard Worker s += fs;
586*f6dc9357SAndroid Build Coastguard Worker }
587*f6dc9357SAndroid Build Coastguard Worker else if (!item.WasParsed)
588*f6dc9357SAndroid Build Coastguard Worker {
589*f6dc9357SAndroid Build Coastguard Worker const int typeIndex = FindPartType(part.Type);
590*f6dc9357SAndroid Build Coastguard Worker if (typeIndex >= 0)
591*f6dc9357SAndroid Build Coastguard Worker ext = kPartTypes[(unsigned)typeIndex].Ext;
592*f6dc9357SAndroid Build Coastguard Worker }
593*f6dc9357SAndroid Build Coastguard Worker if (!ext)
594*f6dc9357SAndroid Build Coastguard Worker ext = "img";
595*f6dc9357SAndroid Build Coastguard Worker s += ext;
596*f6dc9357SAndroid Build Coastguard Worker }
597*f6dc9357SAndroid Build Coastguard Worker prop = s;
598*f6dc9357SAndroid Build Coastguard Worker break;
599*f6dc9357SAndroid Build Coastguard Worker }
600*f6dc9357SAndroid Build Coastguard Worker case kpidFileSystem:
601*f6dc9357SAndroid Build Coastguard Worker if (item.IsReal)
602*f6dc9357SAndroid Build Coastguard Worker {
603*f6dc9357SAndroid Build Coastguard Worker char s[32];
604*f6dc9357SAndroid Build Coastguard Worker ConvertUInt32ToString(part.Type, s);
605*f6dc9357SAndroid Build Coastguard Worker const char *res = s;
606*f6dc9357SAndroid Build Coastguard Worker if (item.FileSystem)
607*f6dc9357SAndroid Build Coastguard Worker {
608*f6dc9357SAndroid Build Coastguard Worker // strcat(s, "-");
609*f6dc9357SAndroid Build Coastguard Worker // strcpy(s, item.FileSystem);
610*f6dc9357SAndroid Build Coastguard Worker res = item.FileSystem;
611*f6dc9357SAndroid Build Coastguard Worker }
612*f6dc9357SAndroid Build Coastguard Worker else if (!item.WasParsed)
613*f6dc9357SAndroid Build Coastguard Worker {
614*f6dc9357SAndroid Build Coastguard Worker const int typeIndex = FindPartType(part.Type);
615*f6dc9357SAndroid Build Coastguard Worker if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Name)
616*f6dc9357SAndroid Build Coastguard Worker res = kPartTypes[(unsigned)typeIndex].Name;
617*f6dc9357SAndroid Build Coastguard Worker }
618*f6dc9357SAndroid Build Coastguard Worker prop = res;
619*f6dc9357SAndroid Build Coastguard Worker }
620*f6dc9357SAndroid Build Coastguard Worker break;
621*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
622*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize: prop = item.Size; break;
623*f6dc9357SAndroid Build Coastguard Worker case kpidOffset: prop = part.GetPos(_sectorSizeLog); break;
624*f6dc9357SAndroid Build Coastguard Worker case kpidPrimary: if (item.IsReal) prop = item.IsPrim; break;
625*f6dc9357SAndroid Build Coastguard Worker case kpidBegChs: if (item.IsReal) part.BeginChs.ToString(prop); break;
626*f6dc9357SAndroid Build Coastguard Worker case kpidEndChs: if (item.IsReal) part.EndChs.ToString(prop); break;
627*f6dc9357SAndroid Build Coastguard Worker }
628*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
629*f6dc9357SAndroid Build Coastguard Worker return S_OK;
630*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
631*f6dc9357SAndroid Build Coastguard Worker }
632*f6dc9357SAndroid Build Coastguard Worker
633*f6dc9357SAndroid Build Coastguard Worker
634*f6dc9357SAndroid Build Coastguard Worker // 3, { 1, 1, 0 },
635*f6dc9357SAndroid Build Coastguard Worker // 2, { 0x55, 0x1FF },
636*f6dc9357SAndroid Build Coastguard Worker
637*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I_NO_SIG(
638*f6dc9357SAndroid Build Coastguard Worker "MBR", "mbr", NULL, 0xDB,
639*f6dc9357SAndroid Build Coastguard Worker 0,
640*f6dc9357SAndroid Build Coastguard Worker NArcInfoFlags::kPureStartOpen,
641*f6dc9357SAndroid Build Coastguard Worker NULL)
642*f6dc9357SAndroid Build Coastguard Worker
643*f6dc9357SAndroid Build Coastguard Worker }}
644