xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Iso/IsoHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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