1*f6dc9357SAndroid Build Coastguard Worker // IsoHandler.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 "../../../Common/ComTry.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyLinux.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/LimitedStreams.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ProgressUtils.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/CopyCoder.h"
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ItemNameUtils.h"
16*f6dc9357SAndroid Build Coastguard Worker
17*f6dc9357SAndroid Build Coastguard Worker #include "IsoHandler.h"
18*f6dc9357SAndroid Build Coastguard Worker
19*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
20*f6dc9357SAndroid Build Coastguard Worker using namespace NTime;
21*f6dc9357SAndroid Build Coastguard Worker
22*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
23*f6dc9357SAndroid Build Coastguard Worker namespace NIso {
24*f6dc9357SAndroid Build Coastguard Worker
25*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
26*f6dc9357SAndroid Build Coastguard Worker {
27*f6dc9357SAndroid Build Coastguard Worker kpidPath,
28*f6dc9357SAndroid Build Coastguard Worker kpidIsDir,
29*f6dc9357SAndroid Build Coastguard Worker kpidSize,
30*f6dc9357SAndroid Build Coastguard Worker kpidPackSize,
31*f6dc9357SAndroid Build Coastguard Worker kpidMTime,
32*f6dc9357SAndroid Build Coastguard Worker // kpidCTime,
33*f6dc9357SAndroid Build Coastguard Worker // kpidATime,
34*f6dc9357SAndroid Build Coastguard Worker kpidPosixAttrib,
35*f6dc9357SAndroid Build Coastguard Worker // kpidUserId,
36*f6dc9357SAndroid Build Coastguard Worker // kpidGroupId,
37*f6dc9357SAndroid Build Coastguard Worker // kpidLinks,
38*f6dc9357SAndroid Build Coastguard Worker kpidSymLink
39*f6dc9357SAndroid Build Coastguard Worker };
40*f6dc9357SAndroid Build Coastguard Worker
41*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
42*f6dc9357SAndroid Build Coastguard Worker {
43*f6dc9357SAndroid Build Coastguard Worker kpidComment,
44*f6dc9357SAndroid Build Coastguard Worker kpidCTime,
45*f6dc9357SAndroid Build Coastguard Worker kpidMTime,
46*f6dc9357SAndroid Build Coastguard Worker // kpidHeadersSize
47*f6dc9357SAndroid Build Coastguard Worker };
48*f6dc9357SAndroid Build Coastguard Worker
49*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
50*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
51*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Open (IInStream * stream,const UInt64 *,IArchiveOpenCallback *))52*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
53*f6dc9357SAndroid Build Coastguard Worker const UInt64 * /* maxCheckStartPosition */,
54*f6dc9357SAndroid Build Coastguard Worker IArchiveOpenCallback * /* openArchiveCallback */))
55*f6dc9357SAndroid Build Coastguard Worker {
56*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
57*f6dc9357SAndroid Build Coastguard Worker Close();
58*f6dc9357SAndroid Build Coastguard Worker {
59*f6dc9357SAndroid Build Coastguard Worker RINOK(_archive.Open(stream))
60*f6dc9357SAndroid Build Coastguard Worker _stream = stream;
61*f6dc9357SAndroid Build Coastguard Worker }
62*f6dc9357SAndroid Build Coastguard Worker return S_OK;
63*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
64*f6dc9357SAndroid Build Coastguard Worker }
65*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Close ())66*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
67*f6dc9357SAndroid Build Coastguard Worker {
68*f6dc9357SAndroid Build Coastguard Worker _archive.Clear();
69*f6dc9357SAndroid Build Coastguard Worker _stream.Release();
70*f6dc9357SAndroid Build Coastguard Worker return S_OK;
71*f6dc9357SAndroid Build Coastguard Worker }
72*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetNumberOfItems (UInt32 * numItems))73*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
74*f6dc9357SAndroid Build Coastguard Worker {
75*f6dc9357SAndroid Build Coastguard Worker *numItems = _archive.Refs.Size() + _archive.BootEntries.Size();
76*f6dc9357SAndroid Build Coastguard Worker return S_OK;
77*f6dc9357SAndroid Build Coastguard Worker }
78*f6dc9357SAndroid Build Coastguard Worker
AddString(AString & s,const char * name,const Byte * p,unsigned size)79*f6dc9357SAndroid Build Coastguard Worker static void AddString(AString &s, const char *name, const Byte *p, unsigned size)
80*f6dc9357SAndroid Build Coastguard Worker {
81*f6dc9357SAndroid Build Coastguard Worker unsigned i;
82*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < size && p[i]; i++);
83*f6dc9357SAndroid Build Coastguard Worker for (; i > 0 && p[i - 1] == ' '; i--);
84*f6dc9357SAndroid Build Coastguard Worker if (i != 0)
85*f6dc9357SAndroid Build Coastguard Worker {
86*f6dc9357SAndroid Build Coastguard Worker AString d;
87*f6dc9357SAndroid Build Coastguard Worker d.SetFrom((const char *)p, i);
88*f6dc9357SAndroid Build Coastguard Worker s += name;
89*f6dc9357SAndroid Build Coastguard Worker s += ": ";
90*f6dc9357SAndroid Build Coastguard Worker s += d;
91*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
92*f6dc9357SAndroid Build Coastguard Worker }
93*f6dc9357SAndroid Build Coastguard Worker }
94*f6dc9357SAndroid Build Coastguard Worker
AddProp_Size64(AString & s,const char * name,UInt64 size)95*f6dc9357SAndroid Build Coastguard Worker static void AddProp_Size64(AString &s, const char *name, UInt64 size)
96*f6dc9357SAndroid Build Coastguard Worker {
97*f6dc9357SAndroid Build Coastguard Worker s += name;
98*f6dc9357SAndroid Build Coastguard Worker s += ": ";
99*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt64(size);
100*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
101*f6dc9357SAndroid Build Coastguard Worker }
102*f6dc9357SAndroid Build Coastguard Worker
103*f6dc9357SAndroid Build Coastguard Worker #define ADD_STRING(n, v) AddString(s, n, vol. v, sizeof(vol. v))
104*f6dc9357SAndroid Build Coastguard Worker
AddErrorMessage(AString & s,const char * message)105*f6dc9357SAndroid Build Coastguard Worker static void AddErrorMessage(AString &s, const char *message)
106*f6dc9357SAndroid Build Coastguard Worker {
107*f6dc9357SAndroid Build Coastguard Worker if (!s.IsEmpty())
108*f6dc9357SAndroid Build Coastguard Worker s += ". ";
109*f6dc9357SAndroid Build Coastguard Worker s += message;
110*f6dc9357SAndroid Build Coastguard Worker }
111*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetArchiveProperty (PROPID propID,PROPVARIANT * value))112*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
113*f6dc9357SAndroid Build Coastguard Worker {
114*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
115*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
116*f6dc9357SAndroid Build Coastguard Worker if (_stream)
117*f6dc9357SAndroid Build Coastguard Worker {
118*f6dc9357SAndroid Build Coastguard Worker const CVolumeDescriptor &vol = _archive.VolDescs[_archive.MainVolDescIndex];
119*f6dc9357SAndroid Build Coastguard Worker switch (propID)
120*f6dc9357SAndroid Build Coastguard Worker {
121*f6dc9357SAndroid Build Coastguard Worker case kpidComment:
122*f6dc9357SAndroid Build Coastguard Worker {
123*f6dc9357SAndroid Build Coastguard Worker AString s;
124*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("System", SystemId);
125*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("Volume", VolumeId);
126*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("VolumeSet", VolumeSetId);
127*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("Publisher", PublisherId);
128*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("Preparer", DataPreparerId);
129*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("Application", ApplicationId);
130*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("Copyright", CopyrightFileId);
131*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("Abstract", AbstractFileId);
132*f6dc9357SAndroid Build Coastguard Worker ADD_STRING("Bib", BibFileId);
133*f6dc9357SAndroid Build Coastguard Worker // ADD_STRING("EscapeSequence", EscapeSequence);
134*f6dc9357SAndroid Build Coastguard Worker AddProp_Size64(s, "VolumeSpaceSize", vol.Get_VolumeSpaceSize_inBytes());
135*f6dc9357SAndroid Build Coastguard Worker AddProp_Size64(s, "VolumeSetSize", vol.VolumeSetSize);
136*f6dc9357SAndroid Build Coastguard Worker AddProp_Size64(s, "VolumeSequenceNumber", vol.VolumeSequenceNumber);
137*f6dc9357SAndroid Build Coastguard Worker
138*f6dc9357SAndroid Build Coastguard Worker prop = s;
139*f6dc9357SAndroid Build Coastguard Worker break;
140*f6dc9357SAndroid Build Coastguard Worker }
141*f6dc9357SAndroid Build Coastguard Worker case kpidCTime: { vol.CTime.GetFileTime(prop); break; }
142*f6dc9357SAndroid Build Coastguard Worker case kpidMTime: { vol.MTime.GetFileTime(prop); break; }
143*f6dc9357SAndroid Build Coastguard Worker }
144*f6dc9357SAndroid Build Coastguard Worker }
145*f6dc9357SAndroid Build Coastguard Worker
146*f6dc9357SAndroid Build Coastguard Worker switch (propID)
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker case kpidPhySize: prop = _archive.PhySize; break;
149*f6dc9357SAndroid Build Coastguard Worker case kpidErrorFlags:
150*f6dc9357SAndroid Build Coastguard Worker {
151*f6dc9357SAndroid Build Coastguard Worker UInt32 v = 0;
152*f6dc9357SAndroid Build Coastguard Worker if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc;
153*f6dc9357SAndroid Build Coastguard Worker if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
154*f6dc9357SAndroid Build Coastguard Worker if (_archive.HeadersError) v |= kpv_ErrorFlags_HeadersError;
155*f6dc9357SAndroid Build Coastguard Worker prop = v;
156*f6dc9357SAndroid Build Coastguard Worker break;
157*f6dc9357SAndroid Build Coastguard Worker }
158*f6dc9357SAndroid Build Coastguard Worker
159*f6dc9357SAndroid Build Coastguard Worker case kpidError:
160*f6dc9357SAndroid Build Coastguard Worker {
161*f6dc9357SAndroid Build Coastguard Worker AString s;
162*f6dc9357SAndroid Build Coastguard Worker if (_archive.IncorrectBigEndian)
163*f6dc9357SAndroid Build Coastguard Worker AddErrorMessage(s, "Incorrect big-endian headers");
164*f6dc9357SAndroid Build Coastguard Worker if (_archive.SelfLinkedDirs)
165*f6dc9357SAndroid Build Coastguard Worker AddErrorMessage(s, "Self-linked directory");
166*f6dc9357SAndroid Build Coastguard Worker if (_archive.TooDeepDirs)
167*f6dc9357SAndroid Build Coastguard Worker AddErrorMessage(s, "Too deep directory levels");
168*f6dc9357SAndroid Build Coastguard Worker if (!s.IsEmpty())
169*f6dc9357SAndroid Build Coastguard Worker prop = s;
170*f6dc9357SAndroid Build Coastguard Worker break;
171*f6dc9357SAndroid Build Coastguard Worker }
172*f6dc9357SAndroid Build Coastguard Worker }
173*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
174*f6dc9357SAndroid Build Coastguard Worker return S_OK;
175*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
176*f6dc9357SAndroid Build Coastguard Worker }
177*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetProperty (UInt32 index,PROPID propID,PROPVARIANT * value))178*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
179*f6dc9357SAndroid Build Coastguard Worker {
180*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
181*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
182*f6dc9357SAndroid Build Coastguard Worker if (index >= (UInt32)_archive.Refs.Size())
183*f6dc9357SAndroid Build Coastguard Worker {
184*f6dc9357SAndroid Build Coastguard Worker index -= _archive.Refs.Size();
185*f6dc9357SAndroid Build Coastguard Worker const CBootInitialEntry &be = _archive.BootEntries[index];
186*f6dc9357SAndroid Build Coastguard Worker switch (propID)
187*f6dc9357SAndroid Build Coastguard Worker {
188*f6dc9357SAndroid Build Coastguard Worker case kpidPath:
189*f6dc9357SAndroid Build Coastguard Worker {
190*f6dc9357SAndroid Build Coastguard Worker AString s ("[BOOT]" STRING_PATH_SEPARATOR);
191*f6dc9357SAndroid Build Coastguard Worker if (_archive.BootEntries.Size() != 1)
192*f6dc9357SAndroid Build Coastguard Worker {
193*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(index + 1);
194*f6dc9357SAndroid Build Coastguard Worker s.Add_Minus();
195*f6dc9357SAndroid Build Coastguard Worker }
196*f6dc9357SAndroid Build Coastguard Worker s += be.GetName();
197*f6dc9357SAndroid Build Coastguard Worker prop = s;
198*f6dc9357SAndroid Build Coastguard Worker break;
199*f6dc9357SAndroid Build Coastguard Worker }
200*f6dc9357SAndroid Build Coastguard Worker case kpidIsDir: prop = false; break;
201*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
202*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize:
203*f6dc9357SAndroid Build Coastguard Worker prop = (UInt64)_archive.GetBootItemSize(index);
204*f6dc9357SAndroid Build Coastguard Worker break;
205*f6dc9357SAndroid Build Coastguard Worker }
206*f6dc9357SAndroid Build Coastguard Worker }
207*f6dc9357SAndroid Build Coastguard Worker else
208*f6dc9357SAndroid Build Coastguard Worker {
209*f6dc9357SAndroid Build Coastguard Worker const CRef &ref = _archive.Refs[index];
210*f6dc9357SAndroid Build Coastguard Worker const CDir &item = ref.Dir->_subItems[ref.Index];
211*f6dc9357SAndroid Build Coastguard Worker switch (propID)
212*f6dc9357SAndroid Build Coastguard Worker {
213*f6dc9357SAndroid Build Coastguard Worker case kpidPath:
214*f6dc9357SAndroid Build Coastguard Worker // if (item.FileId.GetCapacity() >= 0)
215*f6dc9357SAndroid Build Coastguard Worker {
216*f6dc9357SAndroid Build Coastguard Worker UString s;
217*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsJoliet())
218*f6dc9357SAndroid Build Coastguard Worker item.GetPathU(s);
219*f6dc9357SAndroid Build Coastguard Worker else
220*f6dc9357SAndroid Build Coastguard Worker s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP);
221*f6dc9357SAndroid Build Coastguard Worker
222*f6dc9357SAndroid Build Coastguard Worker if (s.Len() >= 2 && s[s.Len() - 2] == ';' && s.Back() == '1')
223*f6dc9357SAndroid Build Coastguard Worker s.DeleteFrom(s.Len() - 2);
224*f6dc9357SAndroid Build Coastguard Worker
225*f6dc9357SAndroid Build Coastguard Worker if (!s.IsEmpty() && s.Back() == L'.')
226*f6dc9357SAndroid Build Coastguard Worker s.DeleteBack();
227*f6dc9357SAndroid Build Coastguard Worker
228*f6dc9357SAndroid Build Coastguard Worker NItemName::ReplaceToOsSlashes_Remove_TailSlash(s);
229*f6dc9357SAndroid Build Coastguard Worker prop = s;
230*f6dc9357SAndroid Build Coastguard Worker }
231*f6dc9357SAndroid Build Coastguard Worker break;
232*f6dc9357SAndroid Build Coastguard Worker
233*f6dc9357SAndroid Build Coastguard Worker case kpidSymLink:
234*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSusp)
235*f6dc9357SAndroid Build Coastguard Worker {
236*f6dc9357SAndroid Build Coastguard Worker UInt32 mode;
237*f6dc9357SAndroid Build Coastguard Worker if (item.GetPx(_archive.SuspSkipSize, k_Px_Mode, mode))
238*f6dc9357SAndroid Build Coastguard Worker {
239*f6dc9357SAndroid Build Coastguard Worker if (MY_LIN_S_ISLNK(mode))
240*f6dc9357SAndroid Build Coastguard Worker {
241*f6dc9357SAndroid Build Coastguard Worker AString s8;
242*f6dc9357SAndroid Build Coastguard Worker if (item.GetSymLink(_archive.SuspSkipSize, s8))
243*f6dc9357SAndroid Build Coastguard Worker {
244*f6dc9357SAndroid Build Coastguard Worker UString s = MultiByteToUnicodeString(s8, CP_OEMCP);
245*f6dc9357SAndroid Build Coastguard Worker prop = s;
246*f6dc9357SAndroid Build Coastguard Worker }
247*f6dc9357SAndroid Build Coastguard Worker }
248*f6dc9357SAndroid Build Coastguard Worker }
249*f6dc9357SAndroid Build Coastguard Worker }
250*f6dc9357SAndroid Build Coastguard Worker break;
251*f6dc9357SAndroid Build Coastguard Worker
252*f6dc9357SAndroid Build Coastguard Worker
253*f6dc9357SAndroid Build Coastguard Worker case kpidPosixAttrib:
254*f6dc9357SAndroid Build Coastguard Worker /*
255*f6dc9357SAndroid Build Coastguard Worker case kpidLinks:
256*f6dc9357SAndroid Build Coastguard Worker case kpidUserId:
257*f6dc9357SAndroid Build Coastguard Worker case kpidGroupId:
258*f6dc9357SAndroid Build Coastguard Worker */
259*f6dc9357SAndroid Build Coastguard Worker {
260*f6dc9357SAndroid Build Coastguard Worker if (_archive.IsSusp)
261*f6dc9357SAndroid Build Coastguard Worker {
262*f6dc9357SAndroid Build Coastguard Worker UInt32 t = 0;
263*f6dc9357SAndroid Build Coastguard Worker switch (propID)
264*f6dc9357SAndroid Build Coastguard Worker {
265*f6dc9357SAndroid Build Coastguard Worker case kpidPosixAttrib: t = k_Px_Mode; break;
266*f6dc9357SAndroid Build Coastguard Worker /*
267*f6dc9357SAndroid Build Coastguard Worker case kpidLinks: t = k_Px_Links; break;
268*f6dc9357SAndroid Build Coastguard Worker case kpidUserId: t = k_Px_User; break;
269*f6dc9357SAndroid Build Coastguard Worker case kpidGroupId: t = k_Px_Group; break;
270*f6dc9357SAndroid Build Coastguard Worker */
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker UInt32 v;
273*f6dc9357SAndroid Build Coastguard Worker if (item.GetPx(_archive.SuspSkipSize, t, v))
274*f6dc9357SAndroid Build Coastguard Worker prop = v;
275*f6dc9357SAndroid Build Coastguard Worker }
276*f6dc9357SAndroid Build Coastguard Worker break;
277*f6dc9357SAndroid Build Coastguard Worker }
278*f6dc9357SAndroid Build Coastguard Worker
279*f6dc9357SAndroid Build Coastguard Worker case kpidIsDir: prop = item.IsDir(); break;
280*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
281*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize:
282*f6dc9357SAndroid Build Coastguard Worker if (!item.IsDir())
283*f6dc9357SAndroid Build Coastguard Worker prop = (UInt64)ref.TotalSize;
284*f6dc9357SAndroid Build Coastguard Worker break;
285*f6dc9357SAndroid Build Coastguard Worker
286*f6dc9357SAndroid Build Coastguard Worker case kpidMTime:
287*f6dc9357SAndroid Build Coastguard Worker // case kpidCTime:
288*f6dc9357SAndroid Build Coastguard Worker // case kpidATime:
289*f6dc9357SAndroid Build Coastguard Worker {
290*f6dc9357SAndroid Build Coastguard Worker // if
291*f6dc9357SAndroid Build Coastguard Worker item.DateTime.GetFileTime(prop);
292*f6dc9357SAndroid Build Coastguard Worker /*
293*f6dc9357SAndroid Build Coastguard Worker else
294*f6dc9357SAndroid Build Coastguard Worker {
295*f6dc9357SAndroid Build Coastguard Worker UInt32 t = 0;
296*f6dc9357SAndroid Build Coastguard Worker switch (propID)
297*f6dc9357SAndroid Build Coastguard Worker {
298*f6dc9357SAndroid Build Coastguard Worker case kpidMTime: t = k_Tf_MTime; break;
299*f6dc9357SAndroid Build Coastguard Worker case kpidCTime: t = k_Tf_CTime; break;
300*f6dc9357SAndroid Build Coastguard Worker case kpidATime: t = k_Tf_ATime; break;
301*f6dc9357SAndroid Build Coastguard Worker }
302*f6dc9357SAndroid Build Coastguard Worker CRecordingDateTime dt;
303*f6dc9357SAndroid Build Coastguard Worker if (item.GetTf(_archive.SuspSkipSize, t, dt))
304*f6dc9357SAndroid Build Coastguard Worker {
305*f6dc9357SAndroid Build Coastguard Worker FILETIME utc;
306*f6dc9357SAndroid Build Coastguard Worker if (dt.GetFileTime(utc))
307*f6dc9357SAndroid Build Coastguard Worker prop = utc;
308*f6dc9357SAndroid Build Coastguard Worker }
309*f6dc9357SAndroid Build Coastguard Worker }
310*f6dc9357SAndroid Build Coastguard Worker */
311*f6dc9357SAndroid Build Coastguard Worker break;
312*f6dc9357SAndroid Build Coastguard Worker }
313*f6dc9357SAndroid Build Coastguard Worker }
314*f6dc9357SAndroid Build Coastguard Worker }
315*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
316*f6dc9357SAndroid Build Coastguard Worker return S_OK;
317*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
318*f6dc9357SAndroid Build Coastguard Worker }
319*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::Extract (const UInt32 * indices,UInt32 numItems,Int32 testMode,IArchiveExtractCallback * extractCallback))320*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
321*f6dc9357SAndroid Build Coastguard Worker Int32 testMode, IArchiveExtractCallback *extractCallback))
322*f6dc9357SAndroid Build Coastguard Worker {
323*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
324*f6dc9357SAndroid Build Coastguard Worker const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
325*f6dc9357SAndroid Build Coastguard Worker if (allFilesMode)
326*f6dc9357SAndroid Build Coastguard Worker numItems = _archive.Refs.Size();
327*f6dc9357SAndroid Build Coastguard Worker if (numItems == 0)
328*f6dc9357SAndroid Build Coastguard Worker return S_OK;
329*f6dc9357SAndroid Build Coastguard Worker UInt64 totalSize = 0;
330*f6dc9357SAndroid Build Coastguard Worker UInt32 i;
331*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numItems; i++)
332*f6dc9357SAndroid Build Coastguard Worker {
333*f6dc9357SAndroid Build Coastguard Worker UInt32 index = (allFilesMode ? i : indices[i]);
334*f6dc9357SAndroid Build Coastguard Worker if (index < (UInt32)_archive.Refs.Size())
335*f6dc9357SAndroid Build Coastguard Worker {
336*f6dc9357SAndroid Build Coastguard Worker const CRef &ref = _archive.Refs[index];
337*f6dc9357SAndroid Build Coastguard Worker const CDir &item = ref.Dir->_subItems[ref.Index];
338*f6dc9357SAndroid Build Coastguard Worker if (!item.IsDir())
339*f6dc9357SAndroid Build Coastguard Worker totalSize += ref.TotalSize;
340*f6dc9357SAndroid Build Coastguard Worker }
341*f6dc9357SAndroid Build Coastguard Worker else
342*f6dc9357SAndroid Build Coastguard Worker totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
343*f6dc9357SAndroid Build Coastguard Worker }
344*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->SetTotal(totalSize))
345*f6dc9357SAndroid Build Coastguard Worker
346*f6dc9357SAndroid Build Coastguard Worker UInt64 currentTotalSize = 0;
347*f6dc9357SAndroid Build Coastguard Worker UInt64 currentItemSize;
348*f6dc9357SAndroid Build Coastguard Worker
349*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
350*f6dc9357SAndroid Build Coastguard Worker lps->Init(extractCallback, false);
351*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
352*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream;
353*f6dc9357SAndroid Build Coastguard Worker inStream->SetStream(_stream);
354*f6dc9357SAndroid Build Coastguard Worker
355*f6dc9357SAndroid Build Coastguard Worker for (i = 0;; i++, currentTotalSize += currentItemSize)
356*f6dc9357SAndroid Build Coastguard Worker {
357*f6dc9357SAndroid Build Coastguard Worker lps->InSize = lps->OutSize = currentTotalSize;
358*f6dc9357SAndroid Build Coastguard Worker RINOK(lps->SetCur())
359*f6dc9357SAndroid Build Coastguard Worker if (i >= numItems)
360*f6dc9357SAndroid Build Coastguard Worker break;
361*f6dc9357SAndroid Build Coastguard Worker currentItemSize = 0;
362*f6dc9357SAndroid Build Coastguard Worker Int32 opRes = NExtract::NOperationResult::kOK;
363*f6dc9357SAndroid Build Coastguard Worker {
364*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> realOutStream;
365*f6dc9357SAndroid Build Coastguard Worker const Int32 askMode = testMode ?
366*f6dc9357SAndroid Build Coastguard Worker NExtract::NAskMode::kTest :
367*f6dc9357SAndroid Build Coastguard Worker NExtract::NAskMode::kExtract;
368*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = allFilesMode ? i : indices[i];
369*f6dc9357SAndroid Build Coastguard Worker
370*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
371*f6dc9357SAndroid Build Coastguard Worker
372*f6dc9357SAndroid Build Coastguard Worker UInt64 blockIndex;
373*f6dc9357SAndroid Build Coastguard Worker if (index < (UInt32)_archive.Refs.Size())
374*f6dc9357SAndroid Build Coastguard Worker {
375*f6dc9357SAndroid Build Coastguard Worker const CRef &ref = _archive.Refs[index];
376*f6dc9357SAndroid Build Coastguard Worker const CDir &item = ref.Dir->_subItems[ref.Index];
377*f6dc9357SAndroid Build Coastguard Worker if (item.IsDir())
378*f6dc9357SAndroid Build Coastguard Worker {
379*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->PrepareOperation(askMode))
380*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK))
381*f6dc9357SAndroid Build Coastguard Worker continue;
382*f6dc9357SAndroid Build Coastguard Worker }
383*f6dc9357SAndroid Build Coastguard Worker currentItemSize = ref.TotalSize;
384*f6dc9357SAndroid Build Coastguard Worker blockIndex = item.ExtentLocation;
385*f6dc9357SAndroid Build Coastguard Worker }
386*f6dc9357SAndroid Build Coastguard Worker else
387*f6dc9357SAndroid Build Coastguard Worker {
388*f6dc9357SAndroid Build Coastguard Worker unsigned bootIndex = index - _archive.Refs.Size();
389*f6dc9357SAndroid Build Coastguard Worker const CBootInitialEntry &be = _archive.BootEntries[bootIndex];
390*f6dc9357SAndroid Build Coastguard Worker currentItemSize = _archive.GetBootItemSize(bootIndex);
391*f6dc9357SAndroid Build Coastguard Worker blockIndex = be.LoadRBA;
392*f6dc9357SAndroid Build Coastguard Worker }
393*f6dc9357SAndroid Build Coastguard Worker
394*f6dc9357SAndroid Build Coastguard Worker
395*f6dc9357SAndroid Build Coastguard Worker if (!testMode && !realOutStream)
396*f6dc9357SAndroid Build Coastguard Worker continue;
397*f6dc9357SAndroid Build Coastguard Worker
398*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->PrepareOperation(askMode))
399*f6dc9357SAndroid Build Coastguard Worker
400*f6dc9357SAndroid Build Coastguard Worker if (index < (UInt32)_archive.Refs.Size())
401*f6dc9357SAndroid Build Coastguard Worker {
402*f6dc9357SAndroid Build Coastguard Worker const CRef &ref = _archive.Refs[index];
403*f6dc9357SAndroid Build Coastguard Worker UInt64 offset = 0;
404*f6dc9357SAndroid Build Coastguard Worker for (UInt32 e = 0; e < ref.NumExtents; e++)
405*f6dc9357SAndroid Build Coastguard Worker {
406*f6dc9357SAndroid Build Coastguard Worker const CDir &item2 = ref.Dir->_subItems[ref.Index + e];
407*f6dc9357SAndroid Build Coastguard Worker if (item2.Size == 0)
408*f6dc9357SAndroid Build Coastguard Worker continue;
409*f6dc9357SAndroid Build Coastguard Worker lps->InSize = lps->OutSize = currentTotalSize + offset;
410*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_stream, (UInt64)item2.ExtentLocation * kBlockSize))
411*f6dc9357SAndroid Build Coastguard Worker inStream->Init(item2.Size);
412*f6dc9357SAndroid Build Coastguard Worker RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps))
413*f6dc9357SAndroid Build Coastguard Worker if (copyCoder->TotalSize != item2.Size)
414*f6dc9357SAndroid Build Coastguard Worker {
415*f6dc9357SAndroid Build Coastguard Worker opRes = NExtract::NOperationResult::kDataError;
416*f6dc9357SAndroid Build Coastguard Worker break;
417*f6dc9357SAndroid Build Coastguard Worker }
418*f6dc9357SAndroid Build Coastguard Worker offset += item2.Size;
419*f6dc9357SAndroid Build Coastguard Worker }
420*f6dc9357SAndroid Build Coastguard Worker }
421*f6dc9357SAndroid Build Coastguard Worker else
422*f6dc9357SAndroid Build Coastguard Worker {
423*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_stream, (UInt64)blockIndex * kBlockSize))
424*f6dc9357SAndroid Build Coastguard Worker inStream->Init(currentItemSize);
425*f6dc9357SAndroid Build Coastguard Worker RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps))
426*f6dc9357SAndroid Build Coastguard Worker if (copyCoder->TotalSize != currentItemSize)
427*f6dc9357SAndroid Build Coastguard Worker opRes = NExtract::NOperationResult::kDataError;
428*f6dc9357SAndroid Build Coastguard Worker }
429*f6dc9357SAndroid Build Coastguard Worker // realOutStream.Release();
430*f6dc9357SAndroid Build Coastguard Worker }
431*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->SetOperationResult(opRes))
432*f6dc9357SAndroid Build Coastguard Worker }
433*f6dc9357SAndroid Build Coastguard Worker return S_OK;
434*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
435*f6dc9357SAndroid Build Coastguard Worker }
436*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CHandler::GetStream (UInt32 index,ISequentialInStream ** stream))437*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream))
438*f6dc9357SAndroid Build Coastguard Worker {
439*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
440*f6dc9357SAndroid Build Coastguard Worker *stream = NULL;
441*f6dc9357SAndroid Build Coastguard Worker UInt64 blockIndex;
442*f6dc9357SAndroid Build Coastguard Worker UInt64 currentItemSize;
443*f6dc9357SAndroid Build Coastguard Worker
444*f6dc9357SAndroid Build Coastguard Worker if (index < _archive.Refs.Size())
445*f6dc9357SAndroid Build Coastguard Worker {
446*f6dc9357SAndroid Build Coastguard Worker const CRef &ref = _archive.Refs[index];
447*f6dc9357SAndroid Build Coastguard Worker const CDir &item = ref.Dir->_subItems[ref.Index];
448*f6dc9357SAndroid Build Coastguard Worker if (item.IsDir())
449*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
450*f6dc9357SAndroid Build Coastguard Worker
451*f6dc9357SAndroid Build Coastguard Worker if (ref.NumExtents > 1)
452*f6dc9357SAndroid Build Coastguard Worker {
453*f6dc9357SAndroid Build Coastguard Worker CExtentsStream *extentStreamSpec = new CExtentsStream();
454*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialInStream> extentStream = extentStreamSpec;
455*f6dc9357SAndroid Build Coastguard Worker
456*f6dc9357SAndroid Build Coastguard Worker extentStreamSpec->Stream = _stream;
457*f6dc9357SAndroid Build Coastguard Worker
458*f6dc9357SAndroid Build Coastguard Worker UInt64 virtOffset = 0;
459*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < ref.NumExtents; i++)
460*f6dc9357SAndroid Build Coastguard Worker {
461*f6dc9357SAndroid Build Coastguard Worker const CDir &item2 = ref.Dir->_subItems[ref.Index + i];
462*f6dc9357SAndroid Build Coastguard Worker if (item2.Size == 0)
463*f6dc9357SAndroid Build Coastguard Worker continue;
464*f6dc9357SAndroid Build Coastguard Worker CSeekExtent se;
465*f6dc9357SAndroid Build Coastguard Worker se.Phy = (UInt64)item2.ExtentLocation * kBlockSize;
466*f6dc9357SAndroid Build Coastguard Worker se.Virt = virtOffset;
467*f6dc9357SAndroid Build Coastguard Worker extentStreamSpec->Extents.Add(se);
468*f6dc9357SAndroid Build Coastguard Worker virtOffset += item2.Size;
469*f6dc9357SAndroid Build Coastguard Worker }
470*f6dc9357SAndroid Build Coastguard Worker if (virtOffset != ref.TotalSize)
471*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
472*f6dc9357SAndroid Build Coastguard Worker CSeekExtent se;
473*f6dc9357SAndroid Build Coastguard Worker se.Phy = 0;
474*f6dc9357SAndroid Build Coastguard Worker se.Virt = virtOffset;
475*f6dc9357SAndroid Build Coastguard Worker extentStreamSpec->Extents.Add(se);
476*f6dc9357SAndroid Build Coastguard Worker extentStreamSpec->Init();
477*f6dc9357SAndroid Build Coastguard Worker *stream = extentStream.Detach();
478*f6dc9357SAndroid Build Coastguard Worker return S_OK;
479*f6dc9357SAndroid Build Coastguard Worker }
480*f6dc9357SAndroid Build Coastguard Worker
481*f6dc9357SAndroid Build Coastguard Worker currentItemSize = item.Size;
482*f6dc9357SAndroid Build Coastguard Worker blockIndex = item.ExtentLocation;
483*f6dc9357SAndroid Build Coastguard Worker }
484*f6dc9357SAndroid Build Coastguard Worker else
485*f6dc9357SAndroid Build Coastguard Worker {
486*f6dc9357SAndroid Build Coastguard Worker unsigned bootIndex = index - _archive.Refs.Size();
487*f6dc9357SAndroid Build Coastguard Worker const CBootInitialEntry &be = _archive.BootEntries[bootIndex];
488*f6dc9357SAndroid Build Coastguard Worker currentItemSize = _archive.GetBootItemSize(bootIndex);
489*f6dc9357SAndroid Build Coastguard Worker blockIndex = be.LoadRBA;
490*f6dc9357SAndroid Build Coastguard Worker }
491*f6dc9357SAndroid Build Coastguard Worker
492*f6dc9357SAndroid Build Coastguard Worker return CreateLimitedInStream(_stream, (UInt64)blockIndex * kBlockSize, currentItemSize, stream);
493*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
494*f6dc9357SAndroid Build Coastguard Worker }
495*f6dc9357SAndroid Build Coastguard Worker
496*f6dc9357SAndroid Build Coastguard Worker }}
497