xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Wim/WimHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // WimHandler.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MethodProps.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ProgressUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #include "WimHandler.h"
15*f6dc9357SAndroid Build Coastguard Worker 
16*f6dc9357SAndroid Build Coastguard Worker #define Get16(p) GetUi16(p)
17*f6dc9357SAndroid Build Coastguard Worker #define Get32(p) GetUi32(p)
18*f6dc9357SAndroid Build Coastguard Worker #define Get64(p) GetUi64(p)
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
23*f6dc9357SAndroid Build Coastguard Worker namespace NWim {
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #define FILES_DIR_NAME "[DELETED]"
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker // #define WIM_DETAILS
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
30*f6dc9357SAndroid Build Coastguard Worker {
31*f6dc9357SAndroid Build Coastguard Worker   kpidPath,
32*f6dc9357SAndroid Build Coastguard Worker   kpidIsDir,
33*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
34*f6dc9357SAndroid Build Coastguard Worker   kpidPackSize,
35*f6dc9357SAndroid Build Coastguard Worker   kpidMTime,
36*f6dc9357SAndroid Build Coastguard Worker   kpidCTime,
37*f6dc9357SAndroid Build Coastguard Worker   kpidATime,
38*f6dc9357SAndroid Build Coastguard Worker   kpidAttrib,
39*f6dc9357SAndroid Build Coastguard Worker   kpidMethod,
40*f6dc9357SAndroid Build Coastguard Worker   kpidSolid,
41*f6dc9357SAndroid Build Coastguard Worker   kpidShortName,
42*f6dc9357SAndroid Build Coastguard Worker   kpidINode,
43*f6dc9357SAndroid Build Coastguard Worker   kpidLinks,
44*f6dc9357SAndroid Build Coastguard Worker   kpidIsAltStream,
45*f6dc9357SAndroid Build Coastguard Worker   kpidNumAltStreams,
46*f6dc9357SAndroid Build Coastguard Worker 
47*f6dc9357SAndroid Build Coastguard Worker   #ifdef WIM_DETAILS
48*f6dc9357SAndroid Build Coastguard Worker   , kpidVolume
49*f6dc9357SAndroid Build Coastguard Worker   , kpidOffset
50*f6dc9357SAndroid Build Coastguard Worker   #endif
51*f6dc9357SAndroid Build Coastguard Worker };
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker enum
54*f6dc9357SAndroid Build Coastguard Worker {
55*f6dc9357SAndroid Build Coastguard Worker   kpidNumImages = kpidUserDefined,
56*f6dc9357SAndroid Build Coastguard Worker   kpidBootImage
57*f6dc9357SAndroid Build Coastguard Worker };
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker static const CStatProp kArcProps[] =
60*f6dc9357SAndroid Build Coastguard Worker {
61*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidSize, VT_UI8},
62*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidPackSize, VT_UI8},
63*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidMethod, VT_BSTR},
64*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidClusterSize, VT_UI4},
65*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidCTime, VT_FILETIME},
66*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidMTime, VT_FILETIME},
67*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidComment, VT_BSTR},
68*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidUnpackVer, VT_BSTR},
69*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidIsVolume, VT_BOOL},
70*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidVolume, VT_UI4},
71*f6dc9357SAndroid Build Coastguard Worker   { NULL, kpidNumVolumes, VT_UI4},
72*f6dc9357SAndroid Build Coastguard Worker   { "Images", kpidNumImages, VT_UI4},
73*f6dc9357SAndroid Build Coastguard Worker   { "Boot Image", kpidBootImage, VT_UI4}
74*f6dc9357SAndroid Build Coastguard Worker };
75*f6dc9357SAndroid Build Coastguard Worker 
76*f6dc9357SAndroid Build Coastguard Worker 
77*f6dc9357SAndroid Build Coastguard Worker static const char * const k_Methods[] =
78*f6dc9357SAndroid Build Coastguard Worker {
79*f6dc9357SAndroid Build Coastguard Worker     "Copy"
80*f6dc9357SAndroid Build Coastguard Worker   , "XPress"
81*f6dc9357SAndroid Build Coastguard Worker   , "LZX"
82*f6dc9357SAndroid Build Coastguard Worker   , "LZMS"
83*f6dc9357SAndroid Build Coastguard Worker };
84*f6dc9357SAndroid Build Coastguard Worker 
85*f6dc9357SAndroid Build Coastguard Worker 
86*f6dc9357SAndroid Build Coastguard Worker 
87*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
88*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps_WITH_NAME
89*f6dc9357SAndroid Build Coastguard Worker 
AddErrorMessage(AString & s,const char * message)90*f6dc9357SAndroid Build Coastguard Worker static void AddErrorMessage(AString &s, const char *message)
91*f6dc9357SAndroid Build Coastguard Worker {
92*f6dc9357SAndroid Build Coastguard Worker   if (!s.IsEmpty())
93*f6dc9357SAndroid Build Coastguard Worker     s += ". ";
94*f6dc9357SAndroid Build Coastguard Worker   s += message;
95*f6dc9357SAndroid Build Coastguard Worker }
96*f6dc9357SAndroid Build Coastguard Worker 
97*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetArchiveProperty (PROPID propID,PROPVARIANT * value))98*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
101*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker   const CImageInfo *image = NULL;
104*f6dc9357SAndroid Build Coastguard Worker   if (_xmls.Size() == 1)
105*f6dc9357SAndroid Build Coastguard Worker   {
106*f6dc9357SAndroid Build Coastguard Worker     const CWimXml &xml = _xmls[0];
107*f6dc9357SAndroid Build Coastguard Worker     if (xml.Images.Size() == 1)
108*f6dc9357SAndroid Build Coastguard Worker       image = &xml.Images[0];
109*f6dc9357SAndroid Build Coastguard Worker   }
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
112*f6dc9357SAndroid Build Coastguard Worker   {
113*f6dc9357SAndroid Build Coastguard Worker     case kpidPhySize:  prop = _phySize; break;
114*f6dc9357SAndroid Build Coastguard Worker     case kpidSize: prop = _db.GetUnpackSize(); break;
115*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize: prop = _db.GetPackSize(); break;
116*f6dc9357SAndroid Build Coastguard Worker 
117*f6dc9357SAndroid Build Coastguard Worker     case kpidCTime:
118*f6dc9357SAndroid Build Coastguard Worker       if (_xmls.Size() == 1)
119*f6dc9357SAndroid Build Coastguard Worker       {
120*f6dc9357SAndroid Build Coastguard Worker         const CWimXml &xml = _xmls[0];
121*f6dc9357SAndroid Build Coastguard Worker         int index = -1;
122*f6dc9357SAndroid Build Coastguard Worker         FOR_VECTOR (i, xml.Images)
123*f6dc9357SAndroid Build Coastguard Worker         {
124*f6dc9357SAndroid Build Coastguard Worker           const CImageInfo &image2 = xml.Images[i];
125*f6dc9357SAndroid Build Coastguard Worker           if (image2.CTimeDefined)
126*f6dc9357SAndroid Build Coastguard Worker             if (index < 0 || ::CompareFileTime(&image2.CTime, &xml.Images[index].CTime) < 0)
127*f6dc9357SAndroid Build Coastguard Worker               index = (int)i;
128*f6dc9357SAndroid Build Coastguard Worker         }
129*f6dc9357SAndroid Build Coastguard Worker         if (index >= 0)
130*f6dc9357SAndroid Build Coastguard Worker           prop = xml.Images[index].CTime;
131*f6dc9357SAndroid Build Coastguard Worker       }
132*f6dc9357SAndroid Build Coastguard Worker       break;
133*f6dc9357SAndroid Build Coastguard Worker 
134*f6dc9357SAndroid Build Coastguard Worker     case kpidMTime:
135*f6dc9357SAndroid Build Coastguard Worker       if (_xmls.Size() == 1)
136*f6dc9357SAndroid Build Coastguard Worker       {
137*f6dc9357SAndroid Build Coastguard Worker         const CWimXml &xml = _xmls[0];
138*f6dc9357SAndroid Build Coastguard Worker         int index = -1;
139*f6dc9357SAndroid Build Coastguard Worker         FOR_VECTOR (i, xml.Images)
140*f6dc9357SAndroid Build Coastguard Worker         {
141*f6dc9357SAndroid Build Coastguard Worker           const CImageInfo &image2 = xml.Images[i];
142*f6dc9357SAndroid Build Coastguard Worker           if (image2.MTimeDefined)
143*f6dc9357SAndroid Build Coastguard Worker             if (index < 0 || ::CompareFileTime(&image2.MTime, &xml.Images[index].MTime) > 0)
144*f6dc9357SAndroid Build Coastguard Worker               index = (int)i;
145*f6dc9357SAndroid Build Coastguard Worker         }
146*f6dc9357SAndroid Build Coastguard Worker         if (index >= 0)
147*f6dc9357SAndroid Build Coastguard Worker           prop = xml.Images[index].MTime;
148*f6dc9357SAndroid Build Coastguard Worker       }
149*f6dc9357SAndroid Build Coastguard Worker       break;
150*f6dc9357SAndroid Build Coastguard Worker 
151*f6dc9357SAndroid Build Coastguard Worker     case kpidComment:
152*f6dc9357SAndroid Build Coastguard Worker       if (image)
153*f6dc9357SAndroid Build Coastguard Worker       {
154*f6dc9357SAndroid Build Coastguard Worker         if (_xmlInComments)
155*f6dc9357SAndroid Build Coastguard Worker         {
156*f6dc9357SAndroid Build Coastguard Worker           UString s;
157*f6dc9357SAndroid Build Coastguard Worker           _xmls[0].ToUnicode(s);
158*f6dc9357SAndroid Build Coastguard Worker           prop = s;
159*f6dc9357SAndroid Build Coastguard Worker         }
160*f6dc9357SAndroid Build Coastguard Worker         else if (image->NameDefined)
161*f6dc9357SAndroid Build Coastguard Worker           prop = image->Name;
162*f6dc9357SAndroid Build Coastguard Worker       }
163*f6dc9357SAndroid Build Coastguard Worker       break;
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker     case kpidUnpackVer:
166*f6dc9357SAndroid Build Coastguard Worker     {
167*f6dc9357SAndroid Build Coastguard Worker       UInt32 ver1 = _version >> 16;
168*f6dc9357SAndroid Build Coastguard Worker       UInt32 ver2 = (_version >> 8) & 0xFF;
169*f6dc9357SAndroid Build Coastguard Worker       UInt32 ver3 = (_version) & 0xFF;
170*f6dc9357SAndroid Build Coastguard Worker 
171*f6dc9357SAndroid Build Coastguard Worker       AString res;
172*f6dc9357SAndroid Build Coastguard Worker       res.Add_UInt32(ver1);
173*f6dc9357SAndroid Build Coastguard Worker       res.Add_Dot();
174*f6dc9357SAndroid Build Coastguard Worker       res.Add_UInt32(ver2);
175*f6dc9357SAndroid Build Coastguard Worker       if (ver3 != 0)
176*f6dc9357SAndroid Build Coastguard Worker       {
177*f6dc9357SAndroid Build Coastguard Worker         res.Add_Dot();
178*f6dc9357SAndroid Build Coastguard Worker         res.Add_UInt32(ver3);
179*f6dc9357SAndroid Build Coastguard Worker       }
180*f6dc9357SAndroid Build Coastguard Worker       prop = res;
181*f6dc9357SAndroid Build Coastguard Worker       break;
182*f6dc9357SAndroid Build Coastguard Worker     }
183*f6dc9357SAndroid Build Coastguard Worker 
184*f6dc9357SAndroid Build Coastguard Worker     case kpidIsVolume:
185*f6dc9357SAndroid Build Coastguard Worker       if (_xmls.Size() > 0)
186*f6dc9357SAndroid Build Coastguard Worker       {
187*f6dc9357SAndroid Build Coastguard Worker         UInt16 volIndex = _xmls[0].VolIndex;
188*f6dc9357SAndroid Build Coastguard Worker         if (volIndex < _volumes.Size())
189*f6dc9357SAndroid Build Coastguard Worker           prop = (_volumes[volIndex].Header.NumParts > 1);
190*f6dc9357SAndroid Build Coastguard Worker       }
191*f6dc9357SAndroid Build Coastguard Worker       break;
192*f6dc9357SAndroid Build Coastguard Worker     case kpidVolume:
193*f6dc9357SAndroid Build Coastguard Worker       if (_xmls.Size() > 0)
194*f6dc9357SAndroid Build Coastguard Worker       {
195*f6dc9357SAndroid Build Coastguard Worker         UInt16 volIndex = _xmls[0].VolIndex;
196*f6dc9357SAndroid Build Coastguard Worker         if (volIndex < _volumes.Size())
197*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt32)_volumes[volIndex].Header.PartNumber;
198*f6dc9357SAndroid Build Coastguard Worker       }
199*f6dc9357SAndroid Build Coastguard Worker       break;
200*f6dc9357SAndroid Build Coastguard Worker     case kpidNumVolumes: if (_volumes.Size() > 0) prop = (UInt32)(_volumes.Size() - 1); break;
201*f6dc9357SAndroid Build Coastguard Worker 
202*f6dc9357SAndroid Build Coastguard Worker     case kpidClusterSize:
203*f6dc9357SAndroid Build Coastguard Worker       if (_xmls.Size() > 0)
204*f6dc9357SAndroid Build Coastguard Worker       {
205*f6dc9357SAndroid Build Coastguard Worker         UInt16 volIndex = _xmls[0].VolIndex;
206*f6dc9357SAndroid Build Coastguard Worker         if (volIndex < _volumes.Size())
207*f6dc9357SAndroid Build Coastguard Worker         {
208*f6dc9357SAndroid Build Coastguard Worker           const CHeader &h = _volumes[volIndex].Header;
209*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt32)1 << h.ChunkSizeBits;
210*f6dc9357SAndroid Build Coastguard Worker         }
211*f6dc9357SAndroid Build Coastguard Worker       }
212*f6dc9357SAndroid Build Coastguard Worker       break;
213*f6dc9357SAndroid Build Coastguard Worker 
214*f6dc9357SAndroid Build Coastguard Worker     case kpidName:
215*f6dc9357SAndroid Build Coastguard Worker       if (_firstVolumeIndex >= 0)
216*f6dc9357SAndroid Build Coastguard Worker       {
217*f6dc9357SAndroid Build Coastguard Worker         const CHeader &h = _volumes[_firstVolumeIndex].Header;
218*f6dc9357SAndroid Build Coastguard Worker         if (GetUi32(h.Guid) != 0)
219*f6dc9357SAndroid Build Coastguard Worker         {
220*f6dc9357SAndroid Build Coastguard Worker           char temp[64];
221*f6dc9357SAndroid Build Coastguard Worker           RawLeGuidToString(h.Guid, temp);
222*f6dc9357SAndroid Build Coastguard Worker           temp[8] = 0; // for reduced GUID
223*f6dc9357SAndroid Build Coastguard Worker           AString s (temp);
224*f6dc9357SAndroid Build Coastguard Worker           const char *ext = ".wim";
225*f6dc9357SAndroid Build Coastguard Worker           if (h.NumParts != 1)
226*f6dc9357SAndroid Build Coastguard Worker           {
227*f6dc9357SAndroid Build Coastguard Worker             s += '_';
228*f6dc9357SAndroid Build Coastguard Worker             if (h.PartNumber != 1)
229*f6dc9357SAndroid Build Coastguard Worker               s.Add_UInt32(h.PartNumber);
230*f6dc9357SAndroid Build Coastguard Worker             ext = ".swm";
231*f6dc9357SAndroid Build Coastguard Worker           }
232*f6dc9357SAndroid Build Coastguard Worker           s += ext;
233*f6dc9357SAndroid Build Coastguard Worker           prop = s;
234*f6dc9357SAndroid Build Coastguard Worker         }
235*f6dc9357SAndroid Build Coastguard Worker       }
236*f6dc9357SAndroid Build Coastguard Worker       break;
237*f6dc9357SAndroid Build Coastguard Worker 
238*f6dc9357SAndroid Build Coastguard Worker     case kpidExtension:
239*f6dc9357SAndroid Build Coastguard Worker       if (_firstVolumeIndex >= 0)
240*f6dc9357SAndroid Build Coastguard Worker       {
241*f6dc9357SAndroid Build Coastguard Worker         const CHeader &h = _volumes[_firstVolumeIndex].Header;
242*f6dc9357SAndroid Build Coastguard Worker         if (h.NumParts > 1)
243*f6dc9357SAndroid Build Coastguard Worker         {
244*f6dc9357SAndroid Build Coastguard Worker           AString s;
245*f6dc9357SAndroid Build Coastguard Worker           if (h.PartNumber != 1)
246*f6dc9357SAndroid Build Coastguard Worker           {
247*f6dc9357SAndroid Build Coastguard Worker             s.Add_UInt32(h.PartNumber);
248*f6dc9357SAndroid Build Coastguard Worker             s.Add_Dot();
249*f6dc9357SAndroid Build Coastguard Worker           }
250*f6dc9357SAndroid Build Coastguard Worker           s += "swm";
251*f6dc9357SAndroid Build Coastguard Worker           prop = s;
252*f6dc9357SAndroid Build Coastguard Worker         }
253*f6dc9357SAndroid Build Coastguard Worker       }
254*f6dc9357SAndroid Build Coastguard Worker       break;
255*f6dc9357SAndroid Build Coastguard Worker 
256*f6dc9357SAndroid Build Coastguard Worker     case kpidNumImages: prop = (UInt32)_db.Images.Size(); break;
257*f6dc9357SAndroid Build Coastguard Worker     case kpidBootImage: if (_bootIndex != 0) prop = (UInt32)_bootIndex; break;
258*f6dc9357SAndroid Build Coastguard Worker 
259*f6dc9357SAndroid Build Coastguard Worker     case kpidMethod:
260*f6dc9357SAndroid Build Coastguard Worker     {
261*f6dc9357SAndroid Build Coastguard Worker       UInt32 methodUnknown = 0;
262*f6dc9357SAndroid Build Coastguard Worker       UInt32 methodMask = 0;
263*f6dc9357SAndroid Build Coastguard Worker       unsigned chunkSizeBits = 0;
264*f6dc9357SAndroid Build Coastguard Worker 
265*f6dc9357SAndroid Build Coastguard Worker       {
266*f6dc9357SAndroid Build Coastguard Worker         FOR_VECTOR (i, _xmls)
267*f6dc9357SAndroid Build Coastguard Worker         {
268*f6dc9357SAndroid Build Coastguard Worker           const CHeader &header = _volumes[_xmls[i].VolIndex].Header;
269*f6dc9357SAndroid Build Coastguard Worker           unsigned method = header.GetMethod();
270*f6dc9357SAndroid Build Coastguard Worker           if (method < Z7_ARRAY_SIZE(k_Methods))
271*f6dc9357SAndroid Build Coastguard Worker             methodMask |= ((UInt32)1 << method);
272*f6dc9357SAndroid Build Coastguard Worker           else
273*f6dc9357SAndroid Build Coastguard Worker             methodUnknown = method;
274*f6dc9357SAndroid Build Coastguard Worker           if (chunkSizeBits < header.ChunkSizeBits)
275*f6dc9357SAndroid Build Coastguard Worker             chunkSizeBits = header.ChunkSizeBits;
276*f6dc9357SAndroid Build Coastguard Worker         }
277*f6dc9357SAndroid Build Coastguard Worker       }
278*f6dc9357SAndroid Build Coastguard Worker 
279*f6dc9357SAndroid Build Coastguard Worker       AString res;
280*f6dc9357SAndroid Build Coastguard Worker 
281*f6dc9357SAndroid Build Coastguard Worker       unsigned numMethods = 0;
282*f6dc9357SAndroid Build Coastguard Worker 
283*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_Methods); i++)
284*f6dc9357SAndroid Build Coastguard Worker       {
285*f6dc9357SAndroid Build Coastguard Worker         if (methodMask & ((UInt32)1 << i))
286*f6dc9357SAndroid Build Coastguard Worker         {
287*f6dc9357SAndroid Build Coastguard Worker           res.Add_Space_if_NotEmpty();
288*f6dc9357SAndroid Build Coastguard Worker           res += k_Methods[i];
289*f6dc9357SAndroid Build Coastguard Worker           numMethods++;
290*f6dc9357SAndroid Build Coastguard Worker         }
291*f6dc9357SAndroid Build Coastguard Worker       }
292*f6dc9357SAndroid Build Coastguard Worker 
293*f6dc9357SAndroid Build Coastguard Worker       if (methodUnknown != 0)
294*f6dc9357SAndroid Build Coastguard Worker       {
295*f6dc9357SAndroid Build Coastguard Worker         res.Add_Space_if_NotEmpty();
296*f6dc9357SAndroid Build Coastguard Worker         res.Add_UInt32(methodUnknown);
297*f6dc9357SAndroid Build Coastguard Worker         numMethods++;
298*f6dc9357SAndroid Build Coastguard Worker       }
299*f6dc9357SAndroid Build Coastguard Worker 
300*f6dc9357SAndroid Build Coastguard Worker       if (numMethods == 1 && chunkSizeBits != 0)
301*f6dc9357SAndroid Build Coastguard Worker       {
302*f6dc9357SAndroid Build Coastguard Worker         res.Add_Colon();
303*f6dc9357SAndroid Build Coastguard Worker         res.Add_UInt32((UInt32)chunkSizeBits);
304*f6dc9357SAndroid Build Coastguard Worker       }
305*f6dc9357SAndroid Build Coastguard Worker 
306*f6dc9357SAndroid Build Coastguard Worker       prop = res;
307*f6dc9357SAndroid Build Coastguard Worker       break;
308*f6dc9357SAndroid Build Coastguard Worker     }
309*f6dc9357SAndroid Build Coastguard Worker 
310*f6dc9357SAndroid Build Coastguard Worker     case kpidIsTree: prop = true; break;
311*f6dc9357SAndroid Build Coastguard Worker     case kpidIsAltStream: prop = _db.ThereAreAltStreams; break;
312*f6dc9357SAndroid Build Coastguard Worker     case kpidIsAux: prop = true; break;
313*f6dc9357SAndroid Build Coastguard Worker     // WIM uses special prefix to represent deleted items
314*f6dc9357SAndroid Build Coastguard Worker     // case kpidIsDeleted: prop = _db.ThereAreDeletedStreams; break;
315*f6dc9357SAndroid Build Coastguard Worker     case kpidINode: prop = true; break;
316*f6dc9357SAndroid Build Coastguard Worker 
317*f6dc9357SAndroid Build Coastguard Worker     case kpidErrorFlags:
318*f6dc9357SAndroid Build Coastguard Worker     {
319*f6dc9357SAndroid Build Coastguard Worker       UInt32 flags = 0;
320*f6dc9357SAndroid Build Coastguard Worker       if (!_isArc) flags |= kpv_ErrorFlags_IsNotArc;
321*f6dc9357SAndroid Build Coastguard Worker       if (_db.HeadersError) flags |= kpv_ErrorFlags_HeadersError;
322*f6dc9357SAndroid Build Coastguard Worker       if (_unsupported) flags |= kpv_ErrorFlags_UnsupportedMethod;
323*f6dc9357SAndroid Build Coastguard Worker       prop = flags;
324*f6dc9357SAndroid Build Coastguard Worker       break;
325*f6dc9357SAndroid Build Coastguard Worker     }
326*f6dc9357SAndroid Build Coastguard Worker 
327*f6dc9357SAndroid Build Coastguard Worker     case kpidWarning:
328*f6dc9357SAndroid Build Coastguard Worker     {
329*f6dc9357SAndroid Build Coastguard Worker       AString s;
330*f6dc9357SAndroid Build Coastguard Worker       if (_xmlError)
331*f6dc9357SAndroid Build Coastguard Worker         AddErrorMessage(s, "XML error");
332*f6dc9357SAndroid Build Coastguard Worker       if (_db.RefCountError)
333*f6dc9357SAndroid Build Coastguard Worker         AddErrorMessage(s, "Some files have incorrect reference count");
334*f6dc9357SAndroid Build Coastguard Worker       if (!s.IsEmpty())
335*f6dc9357SAndroid Build Coastguard Worker         prop = s;
336*f6dc9357SAndroid Build Coastguard Worker       break;
337*f6dc9357SAndroid Build Coastguard Worker     }
338*f6dc9357SAndroid Build Coastguard Worker 
339*f6dc9357SAndroid Build Coastguard Worker     case kpidReadOnly:
340*f6dc9357SAndroid Build Coastguard Worker     {
341*f6dc9357SAndroid Build Coastguard Worker       bool readOnly = !IsUpdateSupported();
342*f6dc9357SAndroid Build Coastguard Worker       if (readOnly)
343*f6dc9357SAndroid Build Coastguard Worker         prop = readOnly;
344*f6dc9357SAndroid Build Coastguard Worker       break;
345*f6dc9357SAndroid Build Coastguard Worker     }
346*f6dc9357SAndroid Build Coastguard Worker   }
347*f6dc9357SAndroid Build Coastguard Worker 
348*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
349*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
350*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
351*f6dc9357SAndroid Build Coastguard Worker }
352*f6dc9357SAndroid Build Coastguard Worker 
GetFileTime(const Byte * p,NCOM::CPropVariant & prop)353*f6dc9357SAndroid Build Coastguard Worker static void GetFileTime(const Byte *p, NCOM::CPropVariant &prop)
354*f6dc9357SAndroid Build Coastguard Worker {
355*f6dc9357SAndroid Build Coastguard Worker   prop.vt = VT_FILETIME;
356*f6dc9357SAndroid Build Coastguard Worker   prop.filetime.dwLowDateTime = Get32(p);
357*f6dc9357SAndroid Build Coastguard Worker   prop.filetime.dwHighDateTime = Get32(p + 4);
358*f6dc9357SAndroid Build Coastguard Worker   prop.Set_FtPrec(k_PropVar_TimePrec_100ns);
359*f6dc9357SAndroid Build Coastguard Worker }
360*f6dc9357SAndroid Build Coastguard Worker 
361*f6dc9357SAndroid Build Coastguard Worker 
MethodToProp(int method,int chunksSizeBits,NCOM::CPropVariant & prop)362*f6dc9357SAndroid Build Coastguard Worker static void MethodToProp(int method, int chunksSizeBits, NCOM::CPropVariant &prop)
363*f6dc9357SAndroid Build Coastguard Worker {
364*f6dc9357SAndroid Build Coastguard Worker   if (method >= 0)
365*f6dc9357SAndroid Build Coastguard Worker   {
366*f6dc9357SAndroid Build Coastguard Worker     char temp[32];
367*f6dc9357SAndroid Build Coastguard Worker 
368*f6dc9357SAndroid Build Coastguard Worker     if ((unsigned)method < Z7_ARRAY_SIZE(k_Methods))
369*f6dc9357SAndroid Build Coastguard Worker       MyStringCopy(temp, k_Methods[(unsigned)method]);
370*f6dc9357SAndroid Build Coastguard Worker     else
371*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt32ToString((UInt32)(unsigned)method, temp);
372*f6dc9357SAndroid Build Coastguard Worker 
373*f6dc9357SAndroid Build Coastguard Worker     if (chunksSizeBits >= 0)
374*f6dc9357SAndroid Build Coastguard Worker     {
375*f6dc9357SAndroid Build Coastguard Worker       size_t pos = strlen(temp);
376*f6dc9357SAndroid Build Coastguard Worker       temp[pos++] = ':';
377*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt32ToString((unsigned)chunksSizeBits, temp + pos);
378*f6dc9357SAndroid Build Coastguard Worker     }
379*f6dc9357SAndroid Build Coastguard Worker 
380*f6dc9357SAndroid Build Coastguard Worker     prop = temp;
381*f6dc9357SAndroid Build Coastguard Worker   }
382*f6dc9357SAndroid Build Coastguard Worker }
383*f6dc9357SAndroid Build Coastguard Worker 
384*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetProperty (UInt32 index,PROPID propID,PROPVARIANT * value))385*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
386*f6dc9357SAndroid Build Coastguard Worker {
387*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
388*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
389*f6dc9357SAndroid Build Coastguard Worker 
390*f6dc9357SAndroid Build Coastguard Worker   if (index < _db.SortedItems.Size())
391*f6dc9357SAndroid Build Coastguard Worker   {
392*f6dc9357SAndroid Build Coastguard Worker     unsigned realIndex = _db.SortedItems[index];
393*f6dc9357SAndroid Build Coastguard Worker     const CItem &item = _db.Items[realIndex];
394*f6dc9357SAndroid Build Coastguard Worker     const CStreamInfo *si = NULL;
395*f6dc9357SAndroid Build Coastguard Worker     const CVolume *vol = NULL;
396*f6dc9357SAndroid Build Coastguard Worker     if (item.StreamIndex >= 0)
397*f6dc9357SAndroid Build Coastguard Worker     {
398*f6dc9357SAndroid Build Coastguard Worker       si = &_db.DataStreams[item.StreamIndex];
399*f6dc9357SAndroid Build Coastguard Worker       vol = &_volumes[si->PartNumber];
400*f6dc9357SAndroid Build Coastguard Worker     }
401*f6dc9357SAndroid Build Coastguard Worker 
402*f6dc9357SAndroid Build Coastguard Worker     const CItem *mainItem = &item;
403*f6dc9357SAndroid Build Coastguard Worker     if (item.IsAltStream)
404*f6dc9357SAndroid Build Coastguard Worker       mainItem = &_db.Items[item.Parent];
405*f6dc9357SAndroid Build Coastguard Worker     const Byte *metadata = NULL;
406*f6dc9357SAndroid Build Coastguard Worker     if (mainItem->ImageIndex >= 0)
407*f6dc9357SAndroid Build Coastguard Worker       metadata = _db.Images[mainItem->ImageIndex].Meta + mainItem->Offset;
408*f6dc9357SAndroid Build Coastguard Worker 
409*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
410*f6dc9357SAndroid Build Coastguard Worker     {
411*f6dc9357SAndroid Build Coastguard Worker       case kpidPath:
412*f6dc9357SAndroid Build Coastguard Worker         if (item.ImageIndex >= 0)
413*f6dc9357SAndroid Build Coastguard Worker           _db.GetItemPath(realIndex, _showImageNumber, prop);
414*f6dc9357SAndroid Build Coastguard Worker         else
415*f6dc9357SAndroid Build Coastguard Worker         {
416*f6dc9357SAndroid Build Coastguard Worker           /*
417*f6dc9357SAndroid Build Coastguard Worker           while (s.Len() < _nameLenForStreams)
418*f6dc9357SAndroid Build Coastguard Worker             s = '0' + s;
419*f6dc9357SAndroid Build Coastguard Worker           */
420*f6dc9357SAndroid Build Coastguard Worker           /*
421*f6dc9357SAndroid Build Coastguard Worker           if (si->Resource.IsFree())
422*f6dc9357SAndroid Build Coastguard Worker             s = (AString)("[Free]" STRING_PATH_SEPARATOR) + sz;
423*f6dc9357SAndroid Build Coastguard Worker           else
424*f6dc9357SAndroid Build Coastguard Worker           */
425*f6dc9357SAndroid Build Coastguard Worker           AString s (FILES_DIR_NAME STRING_PATH_SEPARATOR);
426*f6dc9357SAndroid Build Coastguard Worker           s.Add_UInt32((UInt32)(Int32)item.StreamIndex);
427*f6dc9357SAndroid Build Coastguard Worker           prop = s;
428*f6dc9357SAndroid Build Coastguard Worker         }
429*f6dc9357SAndroid Build Coastguard Worker         break;
430*f6dc9357SAndroid Build Coastguard Worker 
431*f6dc9357SAndroid Build Coastguard Worker       case kpidName:
432*f6dc9357SAndroid Build Coastguard Worker         if (item.ImageIndex >= 0)
433*f6dc9357SAndroid Build Coastguard Worker           _db.GetItemName(realIndex, prop);
434*f6dc9357SAndroid Build Coastguard Worker         else
435*f6dc9357SAndroid Build Coastguard Worker         {
436*f6dc9357SAndroid Build Coastguard Worker           char sz[16];
437*f6dc9357SAndroid Build Coastguard Worker           ConvertUInt32ToString((UInt32)(Int32)item.StreamIndex, sz);
438*f6dc9357SAndroid Build Coastguard Worker           /*
439*f6dc9357SAndroid Build Coastguard Worker           AString s = sz;
440*f6dc9357SAndroid Build Coastguard Worker           while (s.Len() < _nameLenForStreams)
441*f6dc9357SAndroid Build Coastguard Worker             s = '0' + s;
442*f6dc9357SAndroid Build Coastguard Worker           */
443*f6dc9357SAndroid Build Coastguard Worker           prop = sz;
444*f6dc9357SAndroid Build Coastguard Worker         }
445*f6dc9357SAndroid Build Coastguard Worker         break;
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker       case kpidShortName:
448*f6dc9357SAndroid Build Coastguard Worker         if (item.ImageIndex >= 0 && !item.IsAltStream)
449*f6dc9357SAndroid Build Coastguard Worker           _db.GetShortName(realIndex, prop);
450*f6dc9357SAndroid Build Coastguard Worker         break;
451*f6dc9357SAndroid Build Coastguard Worker 
452*f6dc9357SAndroid Build Coastguard Worker       case kpidPackSize:
453*f6dc9357SAndroid Build Coastguard Worker       {
454*f6dc9357SAndroid Build Coastguard Worker         if (si)
455*f6dc9357SAndroid Build Coastguard Worker         {
456*f6dc9357SAndroid Build Coastguard Worker           if (!si->Resource.IsSolidSmall())
457*f6dc9357SAndroid Build Coastguard Worker             prop = si->Resource.PackSize;
458*f6dc9357SAndroid Build Coastguard Worker           else
459*f6dc9357SAndroid Build Coastguard Worker           {
460*f6dc9357SAndroid Build Coastguard Worker             if (si->Resource.SolidIndex >= 0)
461*f6dc9357SAndroid Build Coastguard Worker             {
462*f6dc9357SAndroid Build Coastguard Worker               const CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex];
463*f6dc9357SAndroid Build Coastguard Worker               if (ss.FirstSmallStream == item.StreamIndex)
464*f6dc9357SAndroid Build Coastguard Worker                 prop = _db.DataStreams[ss.StreamIndex].Resource.PackSize;
465*f6dc9357SAndroid Build Coastguard Worker             }
466*f6dc9357SAndroid Build Coastguard Worker           }
467*f6dc9357SAndroid Build Coastguard Worker         }
468*f6dc9357SAndroid Build Coastguard Worker         else if (!item.IsDir)
469*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt64)0;
470*f6dc9357SAndroid Build Coastguard Worker 
471*f6dc9357SAndroid Build Coastguard Worker         break;
472*f6dc9357SAndroid Build Coastguard Worker       }
473*f6dc9357SAndroid Build Coastguard Worker 
474*f6dc9357SAndroid Build Coastguard Worker       case kpidSize:
475*f6dc9357SAndroid Build Coastguard Worker       {
476*f6dc9357SAndroid Build Coastguard Worker         if (si)
477*f6dc9357SAndroid Build Coastguard Worker         {
478*f6dc9357SAndroid Build Coastguard Worker           if (si->Resource.IsSolid())
479*f6dc9357SAndroid Build Coastguard Worker           {
480*f6dc9357SAndroid Build Coastguard Worker             if (si->Resource.IsSolidBig())
481*f6dc9357SAndroid Build Coastguard Worker             {
482*f6dc9357SAndroid Build Coastguard Worker               if (si->Resource.SolidIndex >= 0)
483*f6dc9357SAndroid Build Coastguard Worker               {
484*f6dc9357SAndroid Build Coastguard Worker                 const CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex];
485*f6dc9357SAndroid Build Coastguard Worker                 prop = ss.UnpackSize;
486*f6dc9357SAndroid Build Coastguard Worker               }
487*f6dc9357SAndroid Build Coastguard Worker             }
488*f6dc9357SAndroid Build Coastguard Worker             else
489*f6dc9357SAndroid Build Coastguard Worker               prop = si->Resource.PackSize;
490*f6dc9357SAndroid Build Coastguard Worker           }
491*f6dc9357SAndroid Build Coastguard Worker           else
492*f6dc9357SAndroid Build Coastguard Worker             prop = si->Resource.UnpackSize;
493*f6dc9357SAndroid Build Coastguard Worker         }
494*f6dc9357SAndroid Build Coastguard Worker         else if (!item.IsDir)
495*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt64)0;
496*f6dc9357SAndroid Build Coastguard Worker 
497*f6dc9357SAndroid Build Coastguard Worker         break;
498*f6dc9357SAndroid Build Coastguard Worker       }
499*f6dc9357SAndroid Build Coastguard Worker 
500*f6dc9357SAndroid Build Coastguard Worker       case kpidIsDir: prop = item.IsDir; break;
501*f6dc9357SAndroid Build Coastguard Worker       case kpidIsAltStream: prop = item.IsAltStream; break;
502*f6dc9357SAndroid Build Coastguard Worker       case kpidNumAltStreams:
503*f6dc9357SAndroid Build Coastguard Worker       {
504*f6dc9357SAndroid Build Coastguard Worker         if (!item.IsAltStream && mainItem->HasMetadata())
505*f6dc9357SAndroid Build Coastguard Worker         {
506*f6dc9357SAndroid Build Coastguard Worker           UInt32 dirRecordSize = _db.IsOldVersion ? kDirRecordSizeOld : kDirRecordSize;
507*f6dc9357SAndroid Build Coastguard Worker           UInt32 numAltStreams = Get16(metadata + dirRecordSize - 6);
508*f6dc9357SAndroid Build Coastguard Worker           if (numAltStreams != 0)
509*f6dc9357SAndroid Build Coastguard Worker           {
510*f6dc9357SAndroid Build Coastguard Worker             if (!item.IsDir)
511*f6dc9357SAndroid Build Coastguard Worker               numAltStreams--;
512*f6dc9357SAndroid Build Coastguard Worker             prop = numAltStreams;
513*f6dc9357SAndroid Build Coastguard Worker           }
514*f6dc9357SAndroid Build Coastguard Worker         }
515*f6dc9357SAndroid Build Coastguard Worker         break;
516*f6dc9357SAndroid Build Coastguard Worker       }
517*f6dc9357SAndroid Build Coastguard Worker 
518*f6dc9357SAndroid Build Coastguard Worker       case kpidAttrib:
519*f6dc9357SAndroid Build Coastguard Worker         if (!item.IsAltStream && mainItem->ImageIndex >= 0)
520*f6dc9357SAndroid Build Coastguard Worker         {
521*f6dc9357SAndroid Build Coastguard Worker           /*
522*f6dc9357SAndroid Build Coastguard Worker           if (fileNameLen == 0 && isDir && !item.HasStream())
523*f6dc9357SAndroid Build Coastguard Worker             item.Attrib = 0x10; // some swm archives have system/hidden attributes for root
524*f6dc9357SAndroid Build Coastguard Worker           */
525*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt32)Get32(metadata + 8);
526*f6dc9357SAndroid Build Coastguard Worker         }
527*f6dc9357SAndroid Build Coastguard Worker         break;
528*f6dc9357SAndroid Build Coastguard Worker       case kpidCTime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x18: 0x28), prop); break;
529*f6dc9357SAndroid Build Coastguard Worker       case kpidATime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x20: 0x30), prop); break;
530*f6dc9357SAndroid Build Coastguard Worker       case kpidMTime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x28: 0x38), prop); break;
531*f6dc9357SAndroid Build Coastguard Worker 
532*f6dc9357SAndroid Build Coastguard Worker       case kpidINode:
533*f6dc9357SAndroid Build Coastguard Worker         if (mainItem->HasMetadata() && !_isOldVersion)
534*f6dc9357SAndroid Build Coastguard Worker         {
535*f6dc9357SAndroid Build Coastguard Worker           UInt32 attrib = (UInt32)Get32(metadata + 8);
536*f6dc9357SAndroid Build Coastguard Worker           if ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
537*f6dc9357SAndroid Build Coastguard Worker           {
538*f6dc9357SAndroid Build Coastguard Worker             // we don't know about that field in OLD WIM format
539*f6dc9357SAndroid Build Coastguard Worker             unsigned offset = 0x58; // (_db.IsOldVersion ? 0x30: 0x58);
540*f6dc9357SAndroid Build Coastguard Worker             UInt64 val = Get64(metadata + offset);
541*f6dc9357SAndroid Build Coastguard Worker             if (val != 0)
542*f6dc9357SAndroid Build Coastguard Worker               prop = val;
543*f6dc9357SAndroid Build Coastguard Worker           }
544*f6dc9357SAndroid Build Coastguard Worker         }
545*f6dc9357SAndroid Build Coastguard Worker         break;
546*f6dc9357SAndroid Build Coastguard Worker 
547*f6dc9357SAndroid Build Coastguard Worker       case kpidStreamId:
548*f6dc9357SAndroid Build Coastguard Worker         if (item.StreamIndex >= 0)
549*f6dc9357SAndroid Build Coastguard Worker           prop = (UInt32)item.StreamIndex;
550*f6dc9357SAndroid Build Coastguard Worker         break;
551*f6dc9357SAndroid Build Coastguard Worker 
552*f6dc9357SAndroid Build Coastguard Worker       case kpidMethod:
553*f6dc9357SAndroid Build Coastguard Worker           if (si)
554*f6dc9357SAndroid Build Coastguard Worker           {
555*f6dc9357SAndroid Build Coastguard Worker             const CResource &r = si->Resource;
556*f6dc9357SAndroid Build Coastguard Worker             if (r.IsSolid())
557*f6dc9357SAndroid Build Coastguard Worker             {
558*f6dc9357SAndroid Build Coastguard Worker               if (r.SolidIndex >= 0)
559*f6dc9357SAndroid Build Coastguard Worker               {
560*f6dc9357SAndroid Build Coastguard Worker                 CSolid &ss = _db.Solids[r.SolidIndex];
561*f6dc9357SAndroid Build Coastguard Worker                 MethodToProp(ss.Method, (int)ss.ChunkSizeBits, prop);
562*f6dc9357SAndroid Build Coastguard Worker               }
563*f6dc9357SAndroid Build Coastguard Worker             }
564*f6dc9357SAndroid Build Coastguard Worker             else
565*f6dc9357SAndroid Build Coastguard Worker             {
566*f6dc9357SAndroid Build Coastguard Worker               int method = 0;
567*f6dc9357SAndroid Build Coastguard Worker               int chunkSizeBits = -1;
568*f6dc9357SAndroid Build Coastguard Worker               if (r.IsCompressed())
569*f6dc9357SAndroid Build Coastguard Worker               {
570*f6dc9357SAndroid Build Coastguard Worker                 method = (int)vol->Header.GetMethod();
571*f6dc9357SAndroid Build Coastguard Worker                 chunkSizeBits = (int)vol->Header.ChunkSizeBits;
572*f6dc9357SAndroid Build Coastguard Worker               }
573*f6dc9357SAndroid Build Coastguard Worker               MethodToProp(method, chunkSizeBits, prop);
574*f6dc9357SAndroid Build Coastguard Worker             }
575*f6dc9357SAndroid Build Coastguard Worker           }
576*f6dc9357SAndroid Build Coastguard Worker           break;
577*f6dc9357SAndroid Build Coastguard Worker 
578*f6dc9357SAndroid Build Coastguard Worker       case kpidSolid: if (si) prop = si->Resource.IsSolid(); break;
579*f6dc9357SAndroid Build Coastguard Worker       case kpidLinks: if (si) prop = (UInt32)si->RefCount; break;
580*f6dc9357SAndroid Build Coastguard Worker       #ifdef WIM_DETAILS
581*f6dc9357SAndroid Build Coastguard Worker       case kpidVolume: if (si) prop = (UInt32)si->PartNumber; break;
582*f6dc9357SAndroid Build Coastguard Worker       case kpidOffset: if (si)  prop = (UInt64)si->Resource.Offset; break;
583*f6dc9357SAndroid Build Coastguard Worker       #endif
584*f6dc9357SAndroid Build Coastguard Worker     }
585*f6dc9357SAndroid Build Coastguard Worker   }
586*f6dc9357SAndroid Build Coastguard Worker   else
587*f6dc9357SAndroid Build Coastguard Worker   {
588*f6dc9357SAndroid Build Coastguard Worker     index -= _db.SortedItems.Size();
589*f6dc9357SAndroid Build Coastguard Worker     if (index < _numXmlItems)
590*f6dc9357SAndroid Build Coastguard Worker     {
591*f6dc9357SAndroid Build Coastguard Worker       switch (propID)
592*f6dc9357SAndroid Build Coastguard Worker       {
593*f6dc9357SAndroid Build Coastguard Worker         case kpidPath:
594*f6dc9357SAndroid Build Coastguard Worker         case kpidName: prop = _xmls[index].FileName; break;
595*f6dc9357SAndroid Build Coastguard Worker         case kpidIsDir: prop = false; break;
596*f6dc9357SAndroid Build Coastguard Worker         case kpidPackSize:
597*f6dc9357SAndroid Build Coastguard Worker         case kpidSize: prop = (UInt64)_xmls[index].Data.Size(); break;
598*f6dc9357SAndroid Build Coastguard Worker         case kpidMethod: /* prop = k_Method_Copy; */ break;
599*f6dc9357SAndroid Build Coastguard Worker       }
600*f6dc9357SAndroid Build Coastguard Worker     }
601*f6dc9357SAndroid Build Coastguard Worker     else
602*f6dc9357SAndroid Build Coastguard Worker     {
603*f6dc9357SAndroid Build Coastguard Worker       index -= _numXmlItems;
604*f6dc9357SAndroid Build Coastguard Worker       switch (propID)
605*f6dc9357SAndroid Build Coastguard Worker       {
606*f6dc9357SAndroid Build Coastguard Worker         case kpidPath:
607*f6dc9357SAndroid Build Coastguard Worker         case kpidName:
608*f6dc9357SAndroid Build Coastguard Worker           if (index < (UInt32)_db.VirtualRoots.Size())
609*f6dc9357SAndroid Build Coastguard Worker             prop = _db.Images[_db.VirtualRoots[index]].RootName;
610*f6dc9357SAndroid Build Coastguard Worker           else
611*f6dc9357SAndroid Build Coastguard Worker             prop = FILES_DIR_NAME;
612*f6dc9357SAndroid Build Coastguard Worker           break;
613*f6dc9357SAndroid Build Coastguard Worker         case kpidIsDir: prop = true; break;
614*f6dc9357SAndroid Build Coastguard Worker         case kpidIsAux: prop = true; break;
615*f6dc9357SAndroid Build Coastguard Worker       }
616*f6dc9357SAndroid Build Coastguard Worker     }
617*f6dc9357SAndroid Build Coastguard Worker   }
618*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
619*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
620*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
621*f6dc9357SAndroid Build Coastguard Worker }
622*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetRootProp (PROPID propID,PROPVARIANT * value))623*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetRootProp(PROPID propID, PROPVARIANT *value))
624*f6dc9357SAndroid Build Coastguard Worker {
625*f6dc9357SAndroid Build Coastguard Worker   // COM_TRY_BEGIN
626*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
627*f6dc9357SAndroid Build Coastguard Worker   if (_db.Images.Size() != 0 && _db.NumExcludededItems != 0)
628*f6dc9357SAndroid Build Coastguard Worker   {
629*f6dc9357SAndroid Build Coastguard Worker     const CImage &image = _db.Images[_db.IndexOfUserImage];
630*f6dc9357SAndroid Build Coastguard Worker     const CItem &item = _db.Items[image.StartItem];
631*f6dc9357SAndroid Build Coastguard Worker     if (!item.IsDir || item.ImageIndex != _db.IndexOfUserImage)
632*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
633*f6dc9357SAndroid Build Coastguard Worker     const Byte *metadata = image.Meta + item.Offset;
634*f6dc9357SAndroid Build Coastguard Worker 
635*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
636*f6dc9357SAndroid Build Coastguard Worker     {
637*f6dc9357SAndroid Build Coastguard Worker       case kpidIsDir: prop = true; break;
638*f6dc9357SAndroid Build Coastguard Worker       case kpidAttrib: prop = (UInt32)Get32(metadata + 8); break;
639*f6dc9357SAndroid Build Coastguard Worker       case kpidCTime: GetFileTime(metadata + (_db.IsOldVersion ? 0x18: 0x28), prop); break;
640*f6dc9357SAndroid Build Coastguard Worker       case kpidATime: GetFileTime(metadata + (_db.IsOldVersion ? 0x20: 0x30), prop); break;
641*f6dc9357SAndroid Build Coastguard Worker       case kpidMTime: GetFileTime(metadata + (_db.IsOldVersion ? 0x28: 0x38), prop); break;
642*f6dc9357SAndroid Build Coastguard Worker     }
643*f6dc9357SAndroid Build Coastguard Worker   }
644*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
645*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
646*f6dc9357SAndroid Build Coastguard Worker   // COM_TRY_END
647*f6dc9357SAndroid Build Coastguard Worker }
648*f6dc9357SAndroid Build Coastguard Worker 
GetSecurity(UInt32 realIndex,const void ** data,UInt32 * dataSize,UInt32 * propType)649*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::GetSecurity(UInt32 realIndex, const void **data, UInt32 *dataSize, UInt32 *propType)
650*f6dc9357SAndroid Build Coastguard Worker {
651*f6dc9357SAndroid Build Coastguard Worker   const CItem &item = _db.Items[realIndex];
652*f6dc9357SAndroid Build Coastguard Worker   if (item.IsAltStream || item.ImageIndex < 0)
653*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
654*f6dc9357SAndroid Build Coastguard Worker   const CImage &image = _db.Images[item.ImageIndex];
655*f6dc9357SAndroid Build Coastguard Worker   const Byte *metadata = image.Meta + item.Offset;
656*f6dc9357SAndroid Build Coastguard Worker   UInt32 securityId = Get32(metadata + 0xC);
657*f6dc9357SAndroid Build Coastguard Worker   if (securityId == (UInt32)(Int32)-1)
658*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
659*f6dc9357SAndroid Build Coastguard Worker   if (securityId >= (UInt32)image.SecurOffsets.Size())
660*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
661*f6dc9357SAndroid Build Coastguard Worker   UInt32 offs = image.SecurOffsets[securityId];
662*f6dc9357SAndroid Build Coastguard Worker   UInt32 len = image.SecurOffsets[securityId + 1] - offs;
663*f6dc9357SAndroid Build Coastguard Worker   const CByteBuffer &buf = image.Meta;
664*f6dc9357SAndroid Build Coastguard Worker   if (offs <= buf.Size() && buf.Size() - offs >= len)
665*f6dc9357SAndroid Build Coastguard Worker   {
666*f6dc9357SAndroid Build Coastguard Worker     *data = buf + offs;
667*f6dc9357SAndroid Build Coastguard Worker     *dataSize = len;
668*f6dc9357SAndroid Build Coastguard Worker     *propType = NPropDataType::kRaw;
669*f6dc9357SAndroid Build Coastguard Worker   }
670*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
671*f6dc9357SAndroid Build Coastguard Worker }
672*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetRootRawProp (PROPID propID,const void ** data,UInt32 * dataSize,UInt32 * propType))673*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType))
674*f6dc9357SAndroid Build Coastguard Worker {
675*f6dc9357SAndroid Build Coastguard Worker   *data = NULL;
676*f6dc9357SAndroid Build Coastguard Worker   *dataSize = 0;
677*f6dc9357SAndroid Build Coastguard Worker   *propType = 0;
678*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidNtSecure && _db.Images.Size() != 0 && _db.NumExcludededItems != 0)
679*f6dc9357SAndroid Build Coastguard Worker   {
680*f6dc9357SAndroid Build Coastguard Worker     const CImage &image = _db.Images[_db.IndexOfUserImage];
681*f6dc9357SAndroid Build Coastguard Worker     const CItem &item = _db.Items[image.StartItem];
682*f6dc9357SAndroid Build Coastguard Worker     if (!item.IsDir || item.ImageIndex != _db.IndexOfUserImage)
683*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
684*f6dc9357SAndroid Build Coastguard Worker     return GetSecurity(image.StartItem, data, dataSize, propType);
685*f6dc9357SAndroid Build Coastguard Worker   }
686*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
687*f6dc9357SAndroid Build Coastguard Worker }
688*f6dc9357SAndroid Build Coastguard Worker 
689*f6dc9357SAndroid Build Coastguard Worker static const Byte kRawProps[] =
690*f6dc9357SAndroid Build Coastguard Worker {
691*f6dc9357SAndroid Build Coastguard Worker   kpidSha1,
692*f6dc9357SAndroid Build Coastguard Worker   kpidNtReparse,
693*f6dc9357SAndroid Build Coastguard Worker   kpidNtSecure
694*f6dc9357SAndroid Build Coastguard Worker };
695*f6dc9357SAndroid Build Coastguard Worker 
696*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetNumRawProps (UInt32 * numProps))697*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps))
698*f6dc9357SAndroid Build Coastguard Worker {
699*f6dc9357SAndroid Build Coastguard Worker   *numProps = Z7_ARRAY_SIZE(kRawProps);
700*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
701*f6dc9357SAndroid Build Coastguard Worker }
702*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetRawPropInfo (UInt32 index,BSTR * name,PROPID * propID))703*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID))
704*f6dc9357SAndroid Build Coastguard Worker {
705*f6dc9357SAndroid Build Coastguard Worker   *propID = kRawProps[index];
706*f6dc9357SAndroid Build Coastguard Worker   *name = NULL;
707*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
708*f6dc9357SAndroid Build Coastguard Worker }
709*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetParent (UInt32 index,UInt32 * parent,UInt32 * parentType))710*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType))
711*f6dc9357SAndroid Build Coastguard Worker {
712*f6dc9357SAndroid Build Coastguard Worker   *parentType = NParentType::kDir;
713*f6dc9357SAndroid Build Coastguard Worker   *parent = (UInt32)(Int32)-1;
714*f6dc9357SAndroid Build Coastguard Worker   if (index >= _db.SortedItems.Size())
715*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
716*f6dc9357SAndroid Build Coastguard Worker 
717*f6dc9357SAndroid Build Coastguard Worker   const CItem &item = _db.Items[_db.SortedItems[index]];
718*f6dc9357SAndroid Build Coastguard Worker 
719*f6dc9357SAndroid Build Coastguard Worker   if (item.ImageIndex >= 0)
720*f6dc9357SAndroid Build Coastguard Worker   {
721*f6dc9357SAndroid Build Coastguard Worker     *parentType = item.IsAltStream ? NParentType::kAltStream : NParentType::kDir;
722*f6dc9357SAndroid Build Coastguard Worker     if (item.Parent >= 0)
723*f6dc9357SAndroid Build Coastguard Worker     {
724*f6dc9357SAndroid Build Coastguard Worker       if (_db.ExludedItem != item.Parent)
725*f6dc9357SAndroid Build Coastguard Worker         *parent = (unsigned)_db.Items[item.Parent].IndexInSorted;
726*f6dc9357SAndroid Build Coastguard Worker     }
727*f6dc9357SAndroid Build Coastguard Worker     else
728*f6dc9357SAndroid Build Coastguard Worker     {
729*f6dc9357SAndroid Build Coastguard Worker       CImage &image = _db.Images[item.ImageIndex];
730*f6dc9357SAndroid Build Coastguard Worker       if (image.VirtualRootIndex >= 0)
731*f6dc9357SAndroid Build Coastguard Worker         *parent = _db.SortedItems.Size() + _numXmlItems + (unsigned)image.VirtualRootIndex;
732*f6dc9357SAndroid Build Coastguard Worker     }
733*f6dc9357SAndroid Build Coastguard Worker   }
734*f6dc9357SAndroid Build Coastguard Worker   else
735*f6dc9357SAndroid Build Coastguard Worker     *parent = _db.SortedItems.Size() + _numXmlItems + _db.VirtualRoots.Size();
736*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
737*f6dc9357SAndroid Build Coastguard Worker }
738*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetRawProp (UInt32 index,PROPID propID,const void ** data,UInt32 * dataSize,UInt32 * propType))739*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType))
740*f6dc9357SAndroid Build Coastguard Worker {
741*f6dc9357SAndroid Build Coastguard Worker   *data = NULL;
742*f6dc9357SAndroid Build Coastguard Worker   *dataSize = 0;
743*f6dc9357SAndroid Build Coastguard Worker   *propType = 0;
744*f6dc9357SAndroid Build Coastguard Worker 
745*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidName)
746*f6dc9357SAndroid Build Coastguard Worker   {
747*f6dc9357SAndroid Build Coastguard Worker     if (index < _db.SortedItems.Size())
748*f6dc9357SAndroid Build Coastguard Worker     {
749*f6dc9357SAndroid Build Coastguard Worker       const CItem &item = _db.Items[_db.SortedItems[index]];
750*f6dc9357SAndroid Build Coastguard Worker       if (item.ImageIndex < 0)
751*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
752*f6dc9357SAndroid Build Coastguard Worker       const CImage &image = _db.Images[item.ImageIndex];
753*f6dc9357SAndroid Build Coastguard Worker       *propType = NPropDataType::kUtf16z;
754*f6dc9357SAndroid Build Coastguard Worker       if (image.NumEmptyRootItems != 0 && item.Parent < 0)
755*f6dc9357SAndroid Build Coastguard Worker       {
756*f6dc9357SAndroid Build Coastguard Worker         const CByteBuffer &buf = _db.Images[item.ImageIndex].RootNameBuf;
757*f6dc9357SAndroid Build Coastguard Worker         *data = (void *)(const Byte *)buf;
758*f6dc9357SAndroid Build Coastguard Worker         *dataSize = (UInt32)buf.Size();
759*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
760*f6dc9357SAndroid Build Coastguard Worker       }
761*f6dc9357SAndroid Build Coastguard Worker       const Byte *meta = image.Meta + item.Offset +
762*f6dc9357SAndroid Build Coastguard Worker           (item.IsAltStream ?
763*f6dc9357SAndroid Build Coastguard Worker           (_isOldVersion ? 0x10 : 0x24) :
764*f6dc9357SAndroid Build Coastguard Worker           (_isOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2));
765*f6dc9357SAndroid Build Coastguard Worker       *data = (const void *)(meta + 2);
766*f6dc9357SAndroid Build Coastguard Worker       *dataSize = (UInt32)Get16(meta) + 2;
767*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
768*f6dc9357SAndroid Build Coastguard Worker     }
769*f6dc9357SAndroid Build Coastguard Worker     {
770*f6dc9357SAndroid Build Coastguard Worker       index -= _db.SortedItems.Size();
771*f6dc9357SAndroid Build Coastguard Worker       if (index < _numXmlItems)
772*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
773*f6dc9357SAndroid Build Coastguard Worker       index -= _numXmlItems;
774*f6dc9357SAndroid Build Coastguard Worker       if (index >= (UInt32)_db.VirtualRoots.Size())
775*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
776*f6dc9357SAndroid Build Coastguard Worker       const CByteBuffer &buf = _db.Images[_db.VirtualRoots[index]].RootNameBuf;
777*f6dc9357SAndroid Build Coastguard Worker       *data = (void *)(const Byte *)buf;
778*f6dc9357SAndroid Build Coastguard Worker       *dataSize = (UInt32)buf.Size();
779*f6dc9357SAndroid Build Coastguard Worker       *propType = NPropDataType::kUtf16z;
780*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
781*f6dc9357SAndroid Build Coastguard Worker     }
782*f6dc9357SAndroid Build Coastguard Worker   }
783*f6dc9357SAndroid Build Coastguard Worker 
784*f6dc9357SAndroid Build Coastguard Worker   if (index >= _db.SortedItems.Size())
785*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
786*f6dc9357SAndroid Build Coastguard Worker 
787*f6dc9357SAndroid Build Coastguard Worker   unsigned index2 = _db.SortedItems[index];
788*f6dc9357SAndroid Build Coastguard Worker 
789*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidNtSecure)
790*f6dc9357SAndroid Build Coastguard Worker   {
791*f6dc9357SAndroid Build Coastguard Worker     return GetSecurity(index2, data, dataSize, propType);
792*f6dc9357SAndroid Build Coastguard Worker   }
793*f6dc9357SAndroid Build Coastguard Worker 
794*f6dc9357SAndroid Build Coastguard Worker   const CItem &item = _db.Items[index2];
795*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidSha1)
796*f6dc9357SAndroid Build Coastguard Worker   {
797*f6dc9357SAndroid Build Coastguard Worker     if (item.StreamIndex >= 0)
798*f6dc9357SAndroid Build Coastguard Worker       *data = _db.DataStreams[item.StreamIndex].Hash;
799*f6dc9357SAndroid Build Coastguard Worker     else
800*f6dc9357SAndroid Build Coastguard Worker     {
801*f6dc9357SAndroid Build Coastguard Worker       if (_isOldVersion)
802*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
803*f6dc9357SAndroid Build Coastguard Worker       const Byte *sha1 = _db.Images[item.ImageIndex].Meta + item.Offset + (item.IsAltStream ? 0x10 : 0x40);
804*f6dc9357SAndroid Build Coastguard Worker       if (IsEmptySha(sha1))
805*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
806*f6dc9357SAndroid Build Coastguard Worker       *data = sha1;
807*f6dc9357SAndroid Build Coastguard Worker     }
808*f6dc9357SAndroid Build Coastguard Worker     *dataSize = kHashSize;
809*f6dc9357SAndroid Build Coastguard Worker     *propType = NPropDataType::kRaw;
810*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
811*f6dc9357SAndroid Build Coastguard Worker   }
812*f6dc9357SAndroid Build Coastguard Worker 
813*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidNtReparse && !_isOldVersion)
814*f6dc9357SAndroid Build Coastguard Worker   {
815*f6dc9357SAndroid Build Coastguard Worker     // we don't know about Reparse field in OLD WIM format
816*f6dc9357SAndroid Build Coastguard Worker 
817*f6dc9357SAndroid Build Coastguard Worker     if (item.StreamIndex < 0)
818*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
819*f6dc9357SAndroid Build Coastguard Worker     if (index2 >= _db.ItemToReparse.Size())
820*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
821*f6dc9357SAndroid Build Coastguard Worker     int reparseIndex = _db.ItemToReparse[index2];
822*f6dc9357SAndroid Build Coastguard Worker     if (reparseIndex < 0)
823*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
824*f6dc9357SAndroid Build Coastguard Worker     const CByteBuffer &buf = _db.ReparseItems[reparseIndex];
825*f6dc9357SAndroid Build Coastguard Worker     if (buf.Size() == 0)
826*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
827*f6dc9357SAndroid Build Coastguard Worker     *data = buf;
828*f6dc9357SAndroid Build Coastguard Worker     *dataSize = (UInt32)buf.Size();
829*f6dc9357SAndroid Build Coastguard Worker     *propType = NPropDataType::kRaw;
830*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
831*f6dc9357SAndroid Build Coastguard Worker   }
832*f6dc9357SAndroid Build Coastguard Worker 
833*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
834*f6dc9357SAndroid Build Coastguard Worker }
835*f6dc9357SAndroid Build Coastguard Worker 
836*f6dc9357SAndroid Build Coastguard Worker class CVolumeName
837*f6dc9357SAndroid Build Coastguard Worker {
838*f6dc9357SAndroid Build Coastguard Worker   UString _before;
839*f6dc9357SAndroid Build Coastguard Worker   UString _after;
840*f6dc9357SAndroid Build Coastguard Worker public:
InitName(const UString & name)841*f6dc9357SAndroid Build Coastguard Worker   void InitName(const UString &name)
842*f6dc9357SAndroid Build Coastguard Worker   {
843*f6dc9357SAndroid Build Coastguard Worker     int dotPos = name.ReverseFind_Dot();
844*f6dc9357SAndroid Build Coastguard Worker     if (dotPos < 0)
845*f6dc9357SAndroid Build Coastguard Worker       dotPos = (int)name.Len();
846*f6dc9357SAndroid Build Coastguard Worker     _before.SetFrom(name.Ptr(), (unsigned)dotPos);
847*f6dc9357SAndroid Build Coastguard Worker     _after = name.Ptr(dotPos);
848*f6dc9357SAndroid Build Coastguard Worker   }
849*f6dc9357SAndroid Build Coastguard Worker 
GetNextName(UInt32 index) const850*f6dc9357SAndroid Build Coastguard Worker   UString GetNextName(UInt32 index) const
851*f6dc9357SAndroid Build Coastguard Worker   {
852*f6dc9357SAndroid Build Coastguard Worker     UString s = _before;
853*f6dc9357SAndroid Build Coastguard Worker     s.Add_UInt32(index);
854*f6dc9357SAndroid Build Coastguard Worker     s += _after;
855*f6dc9357SAndroid Build Coastguard Worker     return s;
856*f6dc9357SAndroid Build Coastguard Worker   }
857*f6dc9357SAndroid Build Coastguard Worker };
858*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Open (IInStream * inStream,const UInt64 *,IArchiveOpenCallback * callback))859*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback))
860*f6dc9357SAndroid Build Coastguard Worker {
861*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
862*f6dc9357SAndroid Build Coastguard Worker 
863*f6dc9357SAndroid Build Coastguard Worker   Close();
864*f6dc9357SAndroid Build Coastguard Worker   {
865*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
866*f6dc9357SAndroid Build Coastguard Worker 
867*f6dc9357SAndroid Build Coastguard Worker     CVolumeName seqName;
868*f6dc9357SAndroid Build Coastguard Worker     if (callback)
869*f6dc9357SAndroid Build Coastguard Worker       callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
870*f6dc9357SAndroid Build Coastguard Worker 
871*f6dc9357SAndroid Build Coastguard Worker     UInt32 numVolumes = 1;
872*f6dc9357SAndroid Build Coastguard Worker 
873*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 i = 1; i <= numVolumes; i++)
874*f6dc9357SAndroid Build Coastguard Worker     {
875*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<IInStream> curStream;
876*f6dc9357SAndroid Build Coastguard Worker 
877*f6dc9357SAndroid Build Coastguard Worker       if (i == 1)
878*f6dc9357SAndroid Build Coastguard Worker         curStream = inStream;
879*f6dc9357SAndroid Build Coastguard Worker       else
880*f6dc9357SAndroid Build Coastguard Worker       {
881*f6dc9357SAndroid Build Coastguard Worker         if (!openVolumeCallback)
882*f6dc9357SAndroid Build Coastguard Worker           continue;
883*f6dc9357SAndroid Build Coastguard Worker         const UString fullName = seqName.GetNextName(i);
884*f6dc9357SAndroid Build Coastguard Worker         const HRESULT result = openVolumeCallback->GetStream(fullName, &curStream);
885*f6dc9357SAndroid Build Coastguard Worker         if (result == S_FALSE)
886*f6dc9357SAndroid Build Coastguard Worker           continue;
887*f6dc9357SAndroid Build Coastguard Worker         if (result != S_OK)
888*f6dc9357SAndroid Build Coastguard Worker           return result;
889*f6dc9357SAndroid Build Coastguard Worker         if (!curStream)
890*f6dc9357SAndroid Build Coastguard Worker           break;
891*f6dc9357SAndroid Build Coastguard Worker       }
892*f6dc9357SAndroid Build Coastguard Worker 
893*f6dc9357SAndroid Build Coastguard Worker       CHeader header;
894*f6dc9357SAndroid Build Coastguard Worker       HRESULT res = NWim::ReadHeader(curStream, header, _phySize);
895*f6dc9357SAndroid Build Coastguard Worker 
896*f6dc9357SAndroid Build Coastguard Worker       if (res != S_OK)
897*f6dc9357SAndroid Build Coastguard Worker       {
898*f6dc9357SAndroid Build Coastguard Worker         if (i != 1 && res == S_FALSE)
899*f6dc9357SAndroid Build Coastguard Worker           continue;
900*f6dc9357SAndroid Build Coastguard Worker         return res;
901*f6dc9357SAndroid Build Coastguard Worker       }
902*f6dc9357SAndroid Build Coastguard Worker 
903*f6dc9357SAndroid Build Coastguard Worker       _isArc = true;
904*f6dc9357SAndroid Build Coastguard Worker       _bootIndex = header.BootIndex;
905*f6dc9357SAndroid Build Coastguard Worker       _version = header.Version;
906*f6dc9357SAndroid Build Coastguard Worker       _isOldVersion = header.IsOldVersion();
907*f6dc9357SAndroid Build Coastguard Worker       if (_firstVolumeIndex >= 0)
908*f6dc9357SAndroid Build Coastguard Worker         if (!header.AreFromOnArchive(_volumes[_firstVolumeIndex].Header))
909*f6dc9357SAndroid Build Coastguard Worker           break;
910*f6dc9357SAndroid Build Coastguard Worker       if (_volumes.Size() > header.PartNumber && _volumes[header.PartNumber].Stream)
911*f6dc9357SAndroid Build Coastguard Worker         break;
912*f6dc9357SAndroid Build Coastguard Worker       CWimXml xml;
913*f6dc9357SAndroid Build Coastguard Worker       xml.VolIndex = header.PartNumber;
914*f6dc9357SAndroid Build Coastguard Worker       res = _db.OpenXml(curStream, header, xml.Data);
915*f6dc9357SAndroid Build Coastguard Worker 
916*f6dc9357SAndroid Build Coastguard Worker       if (res == S_OK)
917*f6dc9357SAndroid Build Coastguard Worker       {
918*f6dc9357SAndroid Build Coastguard Worker         if (!xml.Parse())
919*f6dc9357SAndroid Build Coastguard Worker           _xmlError = true;
920*f6dc9357SAndroid Build Coastguard Worker 
921*f6dc9357SAndroid Build Coastguard Worker         if (xml.IsEncrypted)
922*f6dc9357SAndroid Build Coastguard Worker         {
923*f6dc9357SAndroid Build Coastguard Worker           _unsupported = true;
924*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
925*f6dc9357SAndroid Build Coastguard Worker         }
926*f6dc9357SAndroid Build Coastguard Worker 
927*f6dc9357SAndroid Build Coastguard Worker         UInt64 totalFiles = xml.GetTotalFilesAndDirs() + xml.Images.Size();
928*f6dc9357SAndroid Build Coastguard Worker         totalFiles += 16 + xml.Images.Size() * 4; // we reserve some additional items
929*f6dc9357SAndroid Build Coastguard Worker         if (totalFiles >= ((UInt32)1 << 30))
930*f6dc9357SAndroid Build Coastguard Worker           totalFiles = 0;
931*f6dc9357SAndroid Build Coastguard Worker         res = _db.Open(curStream, header, (unsigned)totalFiles, callback);
932*f6dc9357SAndroid Build Coastguard Worker       }
933*f6dc9357SAndroid Build Coastguard Worker 
934*f6dc9357SAndroid Build Coastguard Worker       if (res != S_OK)
935*f6dc9357SAndroid Build Coastguard Worker       {
936*f6dc9357SAndroid Build Coastguard Worker         if (i != 1 && res == S_FALSE)
937*f6dc9357SAndroid Build Coastguard Worker           continue;
938*f6dc9357SAndroid Build Coastguard Worker         return res;
939*f6dc9357SAndroid Build Coastguard Worker       }
940*f6dc9357SAndroid Build Coastguard Worker 
941*f6dc9357SAndroid Build Coastguard Worker       while (_volumes.Size() <= header.PartNumber)
942*f6dc9357SAndroid Build Coastguard Worker         _volumes.AddNew();
943*f6dc9357SAndroid Build Coastguard Worker       CVolume &volume = _volumes[header.PartNumber];
944*f6dc9357SAndroid Build Coastguard Worker       volume.Header = header;
945*f6dc9357SAndroid Build Coastguard Worker       volume.Stream = curStream;
946*f6dc9357SAndroid Build Coastguard Worker 
947*f6dc9357SAndroid Build Coastguard Worker       _firstVolumeIndex = header.PartNumber;
948*f6dc9357SAndroid Build Coastguard Worker 
949*f6dc9357SAndroid Build Coastguard Worker       if (_xmls.IsEmpty() || xml.Data != _xmls[0].Data)
950*f6dc9357SAndroid Build Coastguard Worker       {
951*f6dc9357SAndroid Build Coastguard Worker         xml.FileName = '[';
952*f6dc9357SAndroid Build Coastguard Worker         xml.FileName.Add_UInt32(xml.VolIndex);
953*f6dc9357SAndroid Build Coastguard Worker         xml.FileName += "].xml";
954*f6dc9357SAndroid Build Coastguard Worker         _xmls.Add(xml);
955*f6dc9357SAndroid Build Coastguard Worker       }
956*f6dc9357SAndroid Build Coastguard Worker 
957*f6dc9357SAndroid Build Coastguard Worker       if (i == 1)
958*f6dc9357SAndroid Build Coastguard Worker       {
959*f6dc9357SAndroid Build Coastguard Worker         if (header.PartNumber != 1)
960*f6dc9357SAndroid Build Coastguard Worker           break;
961*f6dc9357SAndroid Build Coastguard Worker         if (!openVolumeCallback)
962*f6dc9357SAndroid Build Coastguard Worker           break;
963*f6dc9357SAndroid Build Coastguard Worker         numVolumes = header.NumParts;
964*f6dc9357SAndroid Build Coastguard Worker         {
965*f6dc9357SAndroid Build Coastguard Worker           NCOM::CPropVariant prop;
966*f6dc9357SAndroid Build Coastguard Worker           RINOK(openVolumeCallback->GetProperty(kpidName, &prop))
967*f6dc9357SAndroid Build Coastguard Worker           if (prop.vt != VT_BSTR)
968*f6dc9357SAndroid Build Coastguard Worker             break;
969*f6dc9357SAndroid Build Coastguard Worker           seqName.InitName(prop.bstrVal);
970*f6dc9357SAndroid Build Coastguard Worker         }
971*f6dc9357SAndroid Build Coastguard Worker       }
972*f6dc9357SAndroid Build Coastguard Worker     }
973*f6dc9357SAndroid Build Coastguard Worker 
974*f6dc9357SAndroid Build Coastguard Worker     RINOK(_db.FillAndCheck(_volumes))
975*f6dc9357SAndroid Build Coastguard Worker     int defaultImageIndex = (int)_defaultImageNumber - 1;
976*f6dc9357SAndroid Build Coastguard Worker 
977*f6dc9357SAndroid Build Coastguard Worker     bool showImageNumber = (_db.Images.Size() != 1 && defaultImageIndex < 0);
978*f6dc9357SAndroid Build Coastguard Worker     if (!showImageNumber && _set_use_ShowImageNumber)
979*f6dc9357SAndroid Build Coastguard Worker       showImageNumber = _set_showImageNumber;
980*f6dc9357SAndroid Build Coastguard Worker 
981*f6dc9357SAndroid Build Coastguard Worker     if (!showImageNumber && _keepMode_ShowImageNumber)
982*f6dc9357SAndroid Build Coastguard Worker       showImageNumber = true;
983*f6dc9357SAndroid Build Coastguard Worker 
984*f6dc9357SAndroid Build Coastguard Worker     _showImageNumber = showImageNumber;
985*f6dc9357SAndroid Build Coastguard Worker 
986*f6dc9357SAndroid Build Coastguard Worker     RINOK(_db.GenerateSortedItems(defaultImageIndex, showImageNumber))
987*f6dc9357SAndroid Build Coastguard Worker     RINOK(_db.ExtractReparseStreams(_volumes, callback))
988*f6dc9357SAndroid Build Coastguard Worker 
989*f6dc9357SAndroid Build Coastguard Worker     /*
990*f6dc9357SAndroid Build Coastguard Worker     wchar_t sz[16];
991*f6dc9357SAndroid Build Coastguard Worker     ConvertUInt32ToString(_db.DataStreams.Size(), sz);
992*f6dc9357SAndroid Build Coastguard Worker     _nameLenForStreams = MyStringLen(sz);
993*f6dc9357SAndroid Build Coastguard Worker     */
994*f6dc9357SAndroid Build Coastguard Worker 
995*f6dc9357SAndroid Build Coastguard Worker     _xmlInComments = !_showImageNumber;
996*f6dc9357SAndroid Build Coastguard Worker     _numXmlItems = (_xmlInComments ? 0 : _xmls.Size());
997*f6dc9357SAndroid Build Coastguard Worker     _numIgnoreItems = _db.ThereAreDeletedStreams ? 1 : 0;
998*f6dc9357SAndroid Build Coastguard Worker   }
999*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1000*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
1001*f6dc9357SAndroid Build Coastguard Worker }
1002*f6dc9357SAndroid Build Coastguard Worker 
1003*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Close ())1004*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
1005*f6dc9357SAndroid Build Coastguard Worker {
1006*f6dc9357SAndroid Build Coastguard Worker   _firstVolumeIndex = -1;
1007*f6dc9357SAndroid Build Coastguard Worker   _phySize = 0;
1008*f6dc9357SAndroid Build Coastguard Worker   _db.Clear();
1009*f6dc9357SAndroid Build Coastguard Worker   _volumes.Clear();
1010*f6dc9357SAndroid Build Coastguard Worker   _xmls.Clear();
1011*f6dc9357SAndroid Build Coastguard Worker   // _nameLenForStreams = 0;
1012*f6dc9357SAndroid Build Coastguard Worker   _xmlInComments = false;
1013*f6dc9357SAndroid Build Coastguard Worker   _numXmlItems = 0;
1014*f6dc9357SAndroid Build Coastguard Worker   _numIgnoreItems = 0;
1015*f6dc9357SAndroid Build Coastguard Worker   _xmlError = false;
1016*f6dc9357SAndroid Build Coastguard Worker   _isArc = false;
1017*f6dc9357SAndroid Build Coastguard Worker   _unsupported = false;
1018*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1019*f6dc9357SAndroid Build Coastguard Worker }
1020*f6dc9357SAndroid Build Coastguard Worker 
1021*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::Extract (const UInt32 * indices,UInt32 numItems,Int32 testMode,IArchiveExtractCallback * extractCallback))1022*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
1023*f6dc9357SAndroid Build Coastguard Worker     Int32 testMode, IArchiveExtractCallback *extractCallback))
1024*f6dc9357SAndroid Build Coastguard Worker {
1025*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
1026*f6dc9357SAndroid Build Coastguard Worker   const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
1027*f6dc9357SAndroid Build Coastguard Worker 
1028*f6dc9357SAndroid Build Coastguard Worker   if (allFilesMode)
1029*f6dc9357SAndroid Build Coastguard Worker     numItems = _db.SortedItems.Size() + _numXmlItems + _db.VirtualRoots.Size() + _numIgnoreItems;
1030*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
1031*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
1032*f6dc9357SAndroid Build Coastguard Worker 
1033*f6dc9357SAndroid Build Coastguard Worker   UInt32 i;
1034*f6dc9357SAndroid Build Coastguard Worker   UInt64 totalSize = 0;
1035*f6dc9357SAndroid Build Coastguard Worker 
1036*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numItems; i++)
1037*f6dc9357SAndroid Build Coastguard Worker   {
1038*f6dc9357SAndroid Build Coastguard Worker     UInt32 index = allFilesMode ? i : indices[i];
1039*f6dc9357SAndroid Build Coastguard Worker     if (index < _db.SortedItems.Size())
1040*f6dc9357SAndroid Build Coastguard Worker     {
1041*f6dc9357SAndroid Build Coastguard Worker       int streamIndex = _db.Items[_db.SortedItems[index]].StreamIndex;
1042*f6dc9357SAndroid Build Coastguard Worker       if (streamIndex >= 0)
1043*f6dc9357SAndroid Build Coastguard Worker       {
1044*f6dc9357SAndroid Build Coastguard Worker         const CStreamInfo &si = _db.DataStreams[streamIndex];
1045*f6dc9357SAndroid Build Coastguard Worker         totalSize += _db.Get_UnpackSize_of_Resource(si.Resource);
1046*f6dc9357SAndroid Build Coastguard Worker       }
1047*f6dc9357SAndroid Build Coastguard Worker     }
1048*f6dc9357SAndroid Build Coastguard Worker     else
1049*f6dc9357SAndroid Build Coastguard Worker     {
1050*f6dc9357SAndroid Build Coastguard Worker       index -= _db.SortedItems.Size();
1051*f6dc9357SAndroid Build Coastguard Worker       if (index < _numXmlItems)
1052*f6dc9357SAndroid Build Coastguard Worker         totalSize += _xmls[index].Data.Size();
1053*f6dc9357SAndroid Build Coastguard Worker     }
1054*f6dc9357SAndroid Build Coastguard Worker   }
1055*f6dc9357SAndroid Build Coastguard Worker 
1056*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->SetTotal(totalSize))
1057*f6dc9357SAndroid Build Coastguard Worker 
1058*f6dc9357SAndroid Build Coastguard Worker   totalSize = 0;
1059*f6dc9357SAndroid Build Coastguard Worker   UInt64 currentItemUnPacked;
1060*f6dc9357SAndroid Build Coastguard Worker 
1061*f6dc9357SAndroid Build Coastguard Worker   int prevSuccessStreamIndex = -1;
1062*f6dc9357SAndroid Build Coastguard Worker 
1063*f6dc9357SAndroid Build Coastguard Worker   CUnpacker unpacker;
1064*f6dc9357SAndroid Build Coastguard Worker 
1065*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
1066*f6dc9357SAndroid Build Coastguard Worker   lps->Init(extractCallback, false);
1067*f6dc9357SAndroid Build Coastguard Worker 
1068*f6dc9357SAndroid Build Coastguard Worker   for (i = 0;; i++,
1069*f6dc9357SAndroid Build Coastguard Worker       totalSize += currentItemUnPacked)
1070*f6dc9357SAndroid Build Coastguard Worker   {
1071*f6dc9357SAndroid Build Coastguard Worker     currentItemUnPacked = 0;
1072*f6dc9357SAndroid Build Coastguard Worker     lps->InSize = unpacker.TotalPacked;
1073*f6dc9357SAndroid Build Coastguard Worker     lps->OutSize = totalSize;
1074*f6dc9357SAndroid Build Coastguard Worker     RINOK(lps->SetCur())
1075*f6dc9357SAndroid Build Coastguard Worker     if (i >= numItems)
1076*f6dc9357SAndroid Build Coastguard Worker       break;
1077*f6dc9357SAndroid Build Coastguard Worker 
1078*f6dc9357SAndroid Build Coastguard Worker     UInt32 index = allFilesMode ? i : indices[i];
1079*f6dc9357SAndroid Build Coastguard Worker     const Int32 askMode = testMode ?
1080*f6dc9357SAndroid Build Coastguard Worker         NExtract::NAskMode::kTest :
1081*f6dc9357SAndroid Build Coastguard Worker         NExtract::NAskMode::kExtract;
1082*f6dc9357SAndroid Build Coastguard Worker 
1083*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ISequentialOutStream> realOutStream;
1084*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
1085*f6dc9357SAndroid Build Coastguard Worker 
1086*f6dc9357SAndroid Build Coastguard Worker     if (index >= _db.SortedItems.Size())
1087*f6dc9357SAndroid Build Coastguard Worker     {
1088*f6dc9357SAndroid Build Coastguard Worker       if (!testMode && !realOutStream)
1089*f6dc9357SAndroid Build Coastguard Worker         continue;
1090*f6dc9357SAndroid Build Coastguard Worker       RINOK(extractCallback->PrepareOperation(askMode))
1091*f6dc9357SAndroid Build Coastguard Worker       index -= _db.SortedItems.Size();
1092*f6dc9357SAndroid Build Coastguard Worker       if (index < _numXmlItems)
1093*f6dc9357SAndroid Build Coastguard Worker       {
1094*f6dc9357SAndroid Build Coastguard Worker         const CByteBuffer &data = _xmls[index].Data;
1095*f6dc9357SAndroid Build Coastguard Worker         currentItemUnPacked = data.Size();
1096*f6dc9357SAndroid Build Coastguard Worker         if (realOutStream)
1097*f6dc9357SAndroid Build Coastguard Worker         {
1098*f6dc9357SAndroid Build Coastguard Worker           RINOK(WriteStream(realOutStream, (const Byte *)data, data.Size()))
1099*f6dc9357SAndroid Build Coastguard Worker           realOutStream.Release();
1100*f6dc9357SAndroid Build Coastguard Worker         }
1101*f6dc9357SAndroid Build Coastguard Worker       }
1102*f6dc9357SAndroid Build Coastguard Worker       RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK))
1103*f6dc9357SAndroid Build Coastguard Worker       continue;
1104*f6dc9357SAndroid Build Coastguard Worker     }
1105*f6dc9357SAndroid Build Coastguard Worker 
1106*f6dc9357SAndroid Build Coastguard Worker     const CItem &item = _db.Items[_db.SortedItems[index]];
1107*f6dc9357SAndroid Build Coastguard Worker     const int streamIndex = item.StreamIndex;
1108*f6dc9357SAndroid Build Coastguard Worker     if (streamIndex < 0)
1109*f6dc9357SAndroid Build Coastguard Worker     {
1110*f6dc9357SAndroid Build Coastguard Worker       if (!item.IsDir)
1111*f6dc9357SAndroid Build Coastguard Worker         if (!testMode && !realOutStream)
1112*f6dc9357SAndroid Build Coastguard Worker           continue;
1113*f6dc9357SAndroid Build Coastguard Worker       RINOK(extractCallback->PrepareOperation(askMode))
1114*f6dc9357SAndroid Build Coastguard Worker       realOutStream.Release();
1115*f6dc9357SAndroid Build Coastguard Worker       RINOK(extractCallback->SetOperationResult(!item.IsDir && _db.ItemHasStream(item) ?
1116*f6dc9357SAndroid Build Coastguard Worker           NExtract::NOperationResult::kDataError :
1117*f6dc9357SAndroid Build Coastguard Worker           NExtract::NOperationResult::kOK))
1118*f6dc9357SAndroid Build Coastguard Worker       continue;
1119*f6dc9357SAndroid Build Coastguard Worker     }
1120*f6dc9357SAndroid Build Coastguard Worker 
1121*f6dc9357SAndroid Build Coastguard Worker     const CStreamInfo &si = _db.DataStreams[streamIndex];
1122*f6dc9357SAndroid Build Coastguard Worker     currentItemUnPacked = _db.Get_UnpackSize_of_Resource(si.Resource);
1123*f6dc9357SAndroid Build Coastguard Worker     // currentItemPacked = _db.Get_PackSize_of_Resource(streamIndex);
1124*f6dc9357SAndroid Build Coastguard Worker 
1125*f6dc9357SAndroid Build Coastguard Worker     if (!testMode && !realOutStream)
1126*f6dc9357SAndroid Build Coastguard Worker       continue;
1127*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->PrepareOperation(askMode))
1128*f6dc9357SAndroid Build Coastguard Worker     Int32 opRes = NExtract::NOperationResult::kOK;
1129*f6dc9357SAndroid Build Coastguard Worker 
1130*f6dc9357SAndroid Build Coastguard Worker     if (streamIndex != prevSuccessStreamIndex || realOutStream)
1131*f6dc9357SAndroid Build Coastguard Worker     {
1132*f6dc9357SAndroid Build Coastguard Worker       Byte digest[kHashSize];
1133*f6dc9357SAndroid Build Coastguard Worker       const CVolume &vol = _volumes[si.PartNumber];
1134*f6dc9357SAndroid Build Coastguard Worker       const bool needDigest = !si.IsEmptyHash() && !_disable_Sha1Check;
1135*f6dc9357SAndroid Build Coastguard Worker       const HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header, &_db,
1136*f6dc9357SAndroid Build Coastguard Worker           realOutStream, lps, needDigest ? digest : NULL);
1137*f6dc9357SAndroid Build Coastguard Worker 
1138*f6dc9357SAndroid Build Coastguard Worker       if (res == S_OK)
1139*f6dc9357SAndroid Build Coastguard Worker       {
1140*f6dc9357SAndroid Build Coastguard Worker         if (!needDigest || memcmp(digest, si.Hash, kHashSize) == 0)
1141*f6dc9357SAndroid Build Coastguard Worker           prevSuccessStreamIndex = streamIndex;
1142*f6dc9357SAndroid Build Coastguard Worker         else
1143*f6dc9357SAndroid Build Coastguard Worker           opRes = NExtract::NOperationResult::kCRCError;
1144*f6dc9357SAndroid Build Coastguard Worker       }
1145*f6dc9357SAndroid Build Coastguard Worker       else if (res == S_FALSE)
1146*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kDataError;
1147*f6dc9357SAndroid Build Coastguard Worker       else if (res == E_NOTIMPL)
1148*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kUnsupportedMethod;
1149*f6dc9357SAndroid Build Coastguard Worker       else
1150*f6dc9357SAndroid Build Coastguard Worker         return res;
1151*f6dc9357SAndroid Build Coastguard Worker     }
1152*f6dc9357SAndroid Build Coastguard Worker 
1153*f6dc9357SAndroid Build Coastguard Worker     realOutStream.Release();
1154*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->SetOperationResult(opRes))
1155*f6dc9357SAndroid Build Coastguard Worker   }
1156*f6dc9357SAndroid Build Coastguard Worker 
1157*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1158*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
1159*f6dc9357SAndroid Build Coastguard Worker }
1160*f6dc9357SAndroid Build Coastguard Worker 
1161*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetNumberOfItems (UInt32 * numItems))1162*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
1163*f6dc9357SAndroid Build Coastguard Worker {
1164*f6dc9357SAndroid Build Coastguard Worker   *numItems = _db.SortedItems.Size() +
1165*f6dc9357SAndroid Build Coastguard Worker       _numXmlItems +
1166*f6dc9357SAndroid Build Coastguard Worker       _db.VirtualRoots.Size() +
1167*f6dc9357SAndroid Build Coastguard Worker       _numIgnoreItems;
1168*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1169*f6dc9357SAndroid Build Coastguard Worker }
1170*f6dc9357SAndroid Build Coastguard Worker 
CHandler()1171*f6dc9357SAndroid Build Coastguard Worker CHandler::CHandler()
1172*f6dc9357SAndroid Build Coastguard Worker {
1173*f6dc9357SAndroid Build Coastguard Worker   _keepMode_ShowImageNumber = false;
1174*f6dc9357SAndroid Build Coastguard Worker   InitDefaults();
1175*f6dc9357SAndroid Build Coastguard Worker   _xmlError = false;
1176*f6dc9357SAndroid Build Coastguard Worker }
1177*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::SetProperties (const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps))1178*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
1179*f6dc9357SAndroid Build Coastguard Worker {
1180*f6dc9357SAndroid Build Coastguard Worker   InitDefaults();
1181*f6dc9357SAndroid Build Coastguard Worker 
1182*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numProps; i++)
1183*f6dc9357SAndroid Build Coastguard Worker   {
1184*f6dc9357SAndroid Build Coastguard Worker     UString name = names[i];
1185*f6dc9357SAndroid Build Coastguard Worker     name.MakeLower_Ascii();
1186*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEmpty())
1187*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
1188*f6dc9357SAndroid Build Coastguard Worker 
1189*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT &prop = values[i];
1190*f6dc9357SAndroid Build Coastguard Worker 
1191*f6dc9357SAndroid Build Coastguard Worker     if (name[0] == L'x')
1192*f6dc9357SAndroid Build Coastguard Worker     {
1193*f6dc9357SAndroid Build Coastguard Worker       // some clients write 'x' property. So we support it
1194*f6dc9357SAndroid Build Coastguard Worker       UInt32 level = 0;
1195*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(name.Ptr(1), prop, level))
1196*f6dc9357SAndroid Build Coastguard Worker     }
1197*f6dc9357SAndroid Build Coastguard Worker     else if (name.IsEqualTo("is"))
1198*f6dc9357SAndroid Build Coastguard Worker     {
1199*f6dc9357SAndroid Build Coastguard Worker       RINOK(PROPVARIANT_to_bool(prop, _set_showImageNumber))
1200*f6dc9357SAndroid Build Coastguard Worker       _set_use_ShowImageNumber = true;
1201*f6dc9357SAndroid Build Coastguard Worker     }
1202*f6dc9357SAndroid Build Coastguard Worker     else if (name.IsEqualTo("im"))
1203*f6dc9357SAndroid Build Coastguard Worker     {
1204*f6dc9357SAndroid Build Coastguard Worker       UInt32 image = 9;
1205*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(L"", prop, image))
1206*f6dc9357SAndroid Build Coastguard Worker       _defaultImageNumber = (int)image;
1207*f6dc9357SAndroid Build Coastguard Worker     }
1208*f6dc9357SAndroid Build Coastguard Worker     else if (name.IsPrefixedBy_Ascii_NoCase("mt"))
1209*f6dc9357SAndroid Build Coastguard Worker     {
1210*f6dc9357SAndroid Build Coastguard Worker     }
1211*f6dc9357SAndroid Build Coastguard Worker     else if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
1212*f6dc9357SAndroid Build Coastguard Worker     {
1213*f6dc9357SAndroid Build Coastguard Worker     }
1214*f6dc9357SAndroid Build Coastguard Worker     else if (name.IsPrefixedBy_Ascii_NoCase("crc"))
1215*f6dc9357SAndroid Build Coastguard Worker     {
1216*f6dc9357SAndroid Build Coastguard Worker       name.Delete(0, 3);
1217*f6dc9357SAndroid Build Coastguard Worker       UInt32 crcSize = 1;
1218*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(name, prop, crcSize))
1219*f6dc9357SAndroid Build Coastguard Worker       _disable_Sha1Check = (crcSize == 0);
1220*f6dc9357SAndroid Build Coastguard Worker     }
1221*f6dc9357SAndroid Build Coastguard Worker     else
1222*f6dc9357SAndroid Build Coastguard Worker     {
1223*f6dc9357SAndroid Build Coastguard Worker       bool processed = false;
1224*f6dc9357SAndroid Build Coastguard Worker       RINOK(_timeOptions.Parse(name, prop, processed))
1225*f6dc9357SAndroid Build Coastguard Worker       if (!processed)
1226*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
1227*f6dc9357SAndroid Build Coastguard Worker     }
1228*f6dc9357SAndroid Build Coastguard Worker   }
1229*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1230*f6dc9357SAndroid Build Coastguard Worker }
1231*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::KeepModeForNextOpen ())1232*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::KeepModeForNextOpen())
1233*f6dc9357SAndroid Build Coastguard Worker {
1234*f6dc9357SAndroid Build Coastguard Worker   _keepMode_ShowImageNumber = _showImageNumber;
1235*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1236*f6dc9357SAndroid Build Coastguard Worker }
1237*f6dc9357SAndroid Build Coastguard Worker 
1238*f6dc9357SAndroid Build Coastguard Worker }}
1239