xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Wim/WimIn.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Archive/WimIn.h
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_ARCHIVE_WIM_IN_H
4*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_ARCHIVE_WIM_IN_H
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/Alloc.h"
7*f6dc9357SAndroid Build Coastguard Worker 
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/AutoPtr.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyBuffer.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyXml.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/CopyCoder.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/LzmsDecoder.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/LzxDecoder.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #include "../IArchive.h"
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
21*f6dc9357SAndroid Build Coastguard Worker namespace NWim {
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker /*
24*f6dc9357SAndroid Build Coastguard Worker WIM versions:
25*f6dc9357SAndroid Build Coastguard Worker hexVer : headerSize : ver
26*f6dc9357SAndroid Build Coastguard Worker  : 1.07.01 - 1.08.01 : Longhorn.4001-4015 - another header, no signature, CAB compression
27*f6dc9357SAndroid Build Coastguard Worker 10900 : 60 : 1.09 : Longhorn.4029-4039 (2003)
28*f6dc9357SAndroid Build Coastguard Worker 10A00 : 60 : 1.10 : Longhorn.4083 (2004) image starting from 1
29*f6dc9357SAndroid Build Coastguard Worker 10B00 : ?? : 1.11 : ??
30*f6dc9357SAndroid Build Coastguard Worker 10C00 : 74 : 1.12 : Longhorn.4093 - VistaBeta1.5112 (2005) - (Multi-Part, SHA1)
31*f6dc9357SAndroid Build Coastguard Worker 10D00 : D0 : 1.13 : VistaBeta2 - Win10, (NumImages, BootIndex, IntegrityResource)
32*f6dc9357SAndroid Build Coastguard Worker 00E00 : D0 : 0.14 : LZMS, solid, esd, dism
33*f6dc9357SAndroid Build Coastguard Worker */
34*f6dc9357SAndroid Build Coastguard Worker 
35*f6dc9357SAndroid Build Coastguard Worker const unsigned kDirRecordSizeOld = 62;
36*f6dc9357SAndroid Build Coastguard Worker const unsigned kDirRecordSize = 102;
37*f6dc9357SAndroid Build Coastguard Worker 
38*f6dc9357SAndroid Build Coastguard Worker /*
39*f6dc9357SAndroid Build Coastguard Worker   There is error in WIM specification about dwReparseTag, dwReparseReserved and liHardLink fields.
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker   Correct DIRENTRY structure:
42*f6dc9357SAndroid Build Coastguard Worker   {
43*f6dc9357SAndroid Build Coastguard Worker     hex offset
44*f6dc9357SAndroid Build Coastguard Worker      0    UInt64  Len;
45*f6dc9357SAndroid Build Coastguard Worker      8    UInt32  Attrib;
46*f6dc9357SAndroid Build Coastguard Worker      C    UInt32  SecurityId;
47*f6dc9357SAndroid Build Coastguard Worker 
48*f6dc9357SAndroid Build Coastguard Worker     10    UInt64  SubdirOffset; // = 0 for files
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker     18    UInt64  unused1; // = 0?
51*f6dc9357SAndroid Build Coastguard Worker     20    UInt64  unused2; // = 0?
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker     28    UInt64  CTime;
54*f6dc9357SAndroid Build Coastguard Worker     30    UInt64  ATime;
55*f6dc9357SAndroid Build Coastguard Worker     38    UInt64  MTime;
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker     40    Byte    Sha1[20];
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker     54    UInt32  Unknown1; // is it 0 always?
60*f6dc9357SAndroid Build Coastguard Worker 
61*f6dc9357SAndroid Build Coastguard Worker 
62*f6dc9357SAndroid Build Coastguard Worker     union
63*f6dc9357SAndroid Build Coastguard Worker     {
64*f6dc9357SAndroid Build Coastguard Worker     58    UInt64  NtNodeId;
65*f6dc9357SAndroid Build Coastguard Worker         {
66*f6dc9357SAndroid Build Coastguard Worker     58    UInt32  ReparseTag;
67*f6dc9357SAndroid Build Coastguard Worker     5C    UInt32  ReparseFlags; // is it 0 always? Check with new imagex.
68*f6dc9357SAndroid Build Coastguard Worker         }
69*f6dc9357SAndroid Build Coastguard Worker     }
70*f6dc9357SAndroid Build Coastguard Worker 
71*f6dc9357SAndroid Build Coastguard Worker     60    UInt16  Streams;
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker     62    UInt16  ShortNameLen;
74*f6dc9357SAndroid Build Coastguard Worker     64    UInt16  FileNameLen;
75*f6dc9357SAndroid Build Coastguard Worker 
76*f6dc9357SAndroid Build Coastguard Worker     66    UInt16  Name[];
77*f6dc9357SAndroid Build Coastguard Worker           UInt16  ShortName[];
78*f6dc9357SAndroid Build Coastguard Worker   }
79*f6dc9357SAndroid Build Coastguard Worker 
80*f6dc9357SAndroid Build Coastguard Worker   // DIRENTRY for WIM_VERSION <= 1.10
81*f6dc9357SAndroid Build Coastguard Worker   DIRENTRY_OLD structure:
82*f6dc9357SAndroid Build Coastguard Worker   {
83*f6dc9357SAndroid Build Coastguard Worker     hex offset
84*f6dc9357SAndroid Build Coastguard Worker      0    UInt64  Len;
85*f6dc9357SAndroid Build Coastguard Worker      8    UInt32  Attrib;
86*f6dc9357SAndroid Build Coastguard Worker      C    UInt32  SecurityId;
87*f6dc9357SAndroid Build Coastguard Worker 
88*f6dc9357SAndroid Build Coastguard Worker     union
89*f6dc9357SAndroid Build Coastguard Worker     {
90*f6dc9357SAndroid Build Coastguard Worker     10    UInt64  SubdirOffset; //
91*f6dc9357SAndroid Build Coastguard Worker 
92*f6dc9357SAndroid Build Coastguard Worker     10    UInt32  OldWimFileId; // used for files in old WIMs
93*f6dc9357SAndroid Build Coastguard Worker     14    UInt32  OldWimFileId_Reserved; // = 0
94*f6dc9357SAndroid Build Coastguard Worker     }
95*f6dc9357SAndroid Build Coastguard Worker 
96*f6dc9357SAndroid Build Coastguard Worker     18    UInt64  CTime;
97*f6dc9357SAndroid Build Coastguard Worker     20    UInt64  ATime;
98*f6dc9357SAndroid Build Coastguard Worker     28    UInt64  MTime;
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker     30    UInt64  Unknown; // NtNodeId ?
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker     38    UInt16  Streams;
103*f6dc9357SAndroid Build Coastguard Worker     3A    UInt16  ShortNameLen;
104*f6dc9357SAndroid Build Coastguard Worker     3C    UInt16  FileNameLen;
105*f6dc9357SAndroid Build Coastguard Worker     3E    UInt16  FileName[];
106*f6dc9357SAndroid Build Coastguard Worker           UInt16  ShortName[];
107*f6dc9357SAndroid Build Coastguard Worker   }
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker   ALT_STREAM structure:
110*f6dc9357SAndroid Build Coastguard Worker   {
111*f6dc9357SAndroid Build Coastguard Worker     hex offset
112*f6dc9357SAndroid Build Coastguard Worker      0    UInt64  Len;
113*f6dc9357SAndroid Build Coastguard Worker      8    UInt64  Unused;
114*f6dc9357SAndroid Build Coastguard Worker     10    Byte    Sha1[20];
115*f6dc9357SAndroid Build Coastguard Worker     24    UInt16  FileNameLen;
116*f6dc9357SAndroid Build Coastguard Worker     26    UInt16  FileName[];
117*f6dc9357SAndroid Build Coastguard Worker   }
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker   ALT_STREAM_OLD structure:
120*f6dc9357SAndroid Build Coastguard Worker   {
121*f6dc9357SAndroid Build Coastguard Worker     hex offset
122*f6dc9357SAndroid Build Coastguard Worker      0    UInt64  Len;
123*f6dc9357SAndroid Build Coastguard Worker      8    UInt64  StreamId; // 32-bit value
124*f6dc9357SAndroid Build Coastguard Worker     10    UInt16  FileNameLen;
125*f6dc9357SAndroid Build Coastguard Worker     12    UInt16  FileName[];
126*f6dc9357SAndroid Build Coastguard Worker   }
127*f6dc9357SAndroid Build Coastguard Worker 
128*f6dc9357SAndroid Build Coastguard Worker   If item is file (not Directory) and there are alternative streams,
129*f6dc9357SAndroid Build Coastguard Worker   there is additional ALT_STREAM item of main "unnamed" stream in Streams array.
130*f6dc9357SAndroid Build Coastguard Worker 
131*f6dc9357SAndroid Build Coastguard Worker */
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker 
134*f6dc9357SAndroid Build Coastguard Worker namespace NResourceFlags
135*f6dc9357SAndroid Build Coastguard Worker {
136*f6dc9357SAndroid Build Coastguard Worker   // const Byte kFree = 1 << 0;
137*f6dc9357SAndroid Build Coastguard Worker   const Byte kMetadata = 1 << 1;
138*f6dc9357SAndroid Build Coastguard Worker   const Byte kCompressed = 1 << 2;
139*f6dc9357SAndroid Build Coastguard Worker   // const Byte kSpanned = 1 << 3;
140*f6dc9357SAndroid Build Coastguard Worker   const Byte kSolid = 1 << 4;
141*f6dc9357SAndroid Build Coastguard Worker }
142*f6dc9357SAndroid Build Coastguard Worker 
143*f6dc9357SAndroid Build Coastguard Worker const UInt64 k_SolidBig_Resource_Marker = (UInt64)1 << 32;
144*f6dc9357SAndroid Build Coastguard Worker 
145*f6dc9357SAndroid Build Coastguard Worker struct CResource
146*f6dc9357SAndroid Build Coastguard Worker {
147*f6dc9357SAndroid Build Coastguard Worker   UInt64 PackSize;
148*f6dc9357SAndroid Build Coastguard Worker   UInt64 Offset;
149*f6dc9357SAndroid Build Coastguard Worker   UInt64 UnpackSize;
150*f6dc9357SAndroid Build Coastguard Worker   Byte Flags;
151*f6dc9357SAndroid Build Coastguard Worker   bool KeepSolid;
152*f6dc9357SAndroid Build Coastguard Worker   int SolidIndex;
153*f6dc9357SAndroid Build Coastguard Worker 
ClearCResource154*f6dc9357SAndroid Build Coastguard Worker   void Clear()
155*f6dc9357SAndroid Build Coastguard Worker   {
156*f6dc9357SAndroid Build Coastguard Worker     PackSize = 0;
157*f6dc9357SAndroid Build Coastguard Worker     Offset = 0;
158*f6dc9357SAndroid Build Coastguard Worker     UnpackSize = 0;
159*f6dc9357SAndroid Build Coastguard Worker     Flags = 0;
160*f6dc9357SAndroid Build Coastguard Worker     KeepSolid = false;
161*f6dc9357SAndroid Build Coastguard Worker     SolidIndex = -1;
162*f6dc9357SAndroid Build Coastguard Worker   }
163*f6dc9357SAndroid Build Coastguard Worker 
GetEndLimitCResource164*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetEndLimit() const { return Offset + PackSize; }
165*f6dc9357SAndroid Build Coastguard Worker   void Parse(const Byte *p);
ParseAndUpdatePhySizeCResource166*f6dc9357SAndroid Build Coastguard Worker   void ParseAndUpdatePhySize(const Byte *p, UInt64 &phySize)
167*f6dc9357SAndroid Build Coastguard Worker   {
168*f6dc9357SAndroid Build Coastguard Worker     Parse(p);
169*f6dc9357SAndroid Build Coastguard Worker     UInt64 v = GetEndLimit();
170*f6dc9357SAndroid Build Coastguard Worker     if (phySize < v)
171*f6dc9357SAndroid Build Coastguard Worker       phySize = v;
172*f6dc9357SAndroid Build Coastguard Worker   }
173*f6dc9357SAndroid Build Coastguard Worker 
174*f6dc9357SAndroid Build Coastguard Worker   void WriteTo(Byte *p) const;
175*f6dc9357SAndroid Build Coastguard Worker 
IsMetadataCResource176*f6dc9357SAndroid Build Coastguard Worker   bool IsMetadata() const { return (Flags & NResourceFlags::kMetadata) != 0; }
IsCompressedCResource177*f6dc9357SAndroid Build Coastguard Worker   bool IsCompressed() const { return (Flags & NResourceFlags::kCompressed) != 0; }
IsSolidCResource178*f6dc9357SAndroid Build Coastguard Worker   bool IsSolid() const { return (Flags & NResourceFlags::kSolid) != 0; }
IsSolidBigCResource179*f6dc9357SAndroid Build Coastguard Worker   bool IsSolidBig() const { return IsSolid() && UnpackSize == k_SolidBig_Resource_Marker; }
IsSolidSmallCResource180*f6dc9357SAndroid Build Coastguard Worker   bool IsSolidSmall() const { return IsSolid() && UnpackSize == 0; }
181*f6dc9357SAndroid Build Coastguard Worker 
IsEmptyCResource182*f6dc9357SAndroid Build Coastguard Worker   bool IsEmpty() const { return (UnpackSize == 0); }
183*f6dc9357SAndroid Build Coastguard Worker };
184*f6dc9357SAndroid Build Coastguard Worker 
185*f6dc9357SAndroid Build Coastguard Worker 
186*f6dc9357SAndroid Build Coastguard Worker struct CSolid
187*f6dc9357SAndroid Build Coastguard Worker {
188*f6dc9357SAndroid Build Coastguard Worker   unsigned StreamIndex;
189*f6dc9357SAndroid Build Coastguard Worker   // unsigned NumRefs;
190*f6dc9357SAndroid Build Coastguard Worker   int FirstSmallStream;
191*f6dc9357SAndroid Build Coastguard Worker 
192*f6dc9357SAndroid Build Coastguard Worker   UInt64 SolidOffset;
193*f6dc9357SAndroid Build Coastguard Worker 
194*f6dc9357SAndroid Build Coastguard Worker   UInt64 UnpackSize;
195*f6dc9357SAndroid Build Coastguard Worker   int Method;
196*f6dc9357SAndroid Build Coastguard Worker   unsigned ChunkSizeBits;
197*f6dc9357SAndroid Build Coastguard Worker 
198*f6dc9357SAndroid Build Coastguard Worker   UInt64 HeadersSize;
199*f6dc9357SAndroid Build Coastguard Worker   // size_t NumChunks;
200*f6dc9357SAndroid Build Coastguard Worker   CObjArray<UInt64> Chunks; // [NumChunks + 1] (start offset)
201*f6dc9357SAndroid Build Coastguard Worker 
GetChunkPackSizeCSolid202*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetChunkPackSize(size_t chunkIndex) const { return Chunks[chunkIndex + 1] - Chunks[chunkIndex]; }
203*f6dc9357SAndroid Build Coastguard Worker 
CSolidCSolid204*f6dc9357SAndroid Build Coastguard Worker   CSolid():
205*f6dc9357SAndroid Build Coastguard Worker       FirstSmallStream(-1),
206*f6dc9357SAndroid Build Coastguard Worker       // NumRefs(0),
207*f6dc9357SAndroid Build Coastguard Worker       Method(-1)
208*f6dc9357SAndroid Build Coastguard Worker       {}
209*f6dc9357SAndroid Build Coastguard Worker };
210*f6dc9357SAndroid Build Coastguard Worker 
211*f6dc9357SAndroid Build Coastguard Worker 
212*f6dc9357SAndroid Build Coastguard Worker namespace NHeaderFlags
213*f6dc9357SAndroid Build Coastguard Worker {
214*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kCompression  = 1 << 1;
215*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kReadOnly     = 1 << 2;
216*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kSpanned      = 1 << 3;
217*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kResourceOnly = 1 << 4;
218*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kMetadataOnly = 1 << 5;
219*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kWriteInProgress = 1 << 6;
220*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kReparsePointFixup = 1 << 7;
221*f6dc9357SAndroid Build Coastguard Worker 
222*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kXPRESS       = (UInt32)1 << 17;
223*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kLZX          = (UInt32)1 << 18;
224*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kLZMS         = (UInt32)1 << 19;
225*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kXPRESS2      = (UInt32)1 << 21; // XPRESS with nonstandard chunk size ?
226*f6dc9357SAndroid Build Coastguard Worker 
227*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kMethodMask   = 0xFFFE0000;
228*f6dc9357SAndroid Build Coastguard Worker }
229*f6dc9357SAndroid Build Coastguard Worker 
230*f6dc9357SAndroid Build Coastguard Worker 
231*f6dc9357SAndroid Build Coastguard Worker namespace NMethod
232*f6dc9357SAndroid Build Coastguard Worker {
233*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kXPRESS = 1;
234*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kLZX    = 2;
235*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kLZMS   = 3;
236*f6dc9357SAndroid Build Coastguard Worker }
237*f6dc9357SAndroid Build Coastguard Worker 
238*f6dc9357SAndroid Build Coastguard Worker 
239*f6dc9357SAndroid Build Coastguard Worker const UInt32 k_Version_NonSolid = 0x10D00;
240*f6dc9357SAndroid Build Coastguard Worker const UInt32 k_Version_Solid = 0xE00;
241*f6dc9357SAndroid Build Coastguard Worker 
242*f6dc9357SAndroid Build Coastguard Worker const unsigned kHeaderSizeMax = 0xD0;
243*f6dc9357SAndroid Build Coastguard Worker const unsigned kSignatureSize = 8;
244*f6dc9357SAndroid Build Coastguard Worker extern const Byte kSignature[kSignatureSize];
245*f6dc9357SAndroid Build Coastguard Worker 
246*f6dc9357SAndroid Build Coastguard Worker const unsigned kChunkSizeBits = 15;
247*f6dc9357SAndroid Build Coastguard Worker const UInt32 kChunkSize = (UInt32)1 << kChunkSizeBits;
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker 
250*f6dc9357SAndroid Build Coastguard Worker struct CHeader
251*f6dc9357SAndroid Build Coastguard Worker {
252*f6dc9357SAndroid Build Coastguard Worker   UInt32 Version;
253*f6dc9357SAndroid Build Coastguard Worker   UInt32 Flags;
254*f6dc9357SAndroid Build Coastguard Worker   UInt32 ChunkSize;
255*f6dc9357SAndroid Build Coastguard Worker   unsigned ChunkSizeBits;
256*f6dc9357SAndroid Build Coastguard Worker   Byte Guid[16];
257*f6dc9357SAndroid Build Coastguard Worker   UInt16 PartNumber;
258*f6dc9357SAndroid Build Coastguard Worker   UInt16 NumParts;
259*f6dc9357SAndroid Build Coastguard Worker   UInt32 NumImages;
260*f6dc9357SAndroid Build Coastguard Worker   UInt32 BootIndex;
261*f6dc9357SAndroid Build Coastguard Worker 
262*f6dc9357SAndroid Build Coastguard Worker   bool _isOldVersion; // 1.10-
263*f6dc9357SAndroid Build Coastguard Worker   bool _isNewVersion; // 1.13+ or 0.14
264*f6dc9357SAndroid Build Coastguard Worker 
265*f6dc9357SAndroid Build Coastguard Worker   CResource OffsetResource;
266*f6dc9357SAndroid Build Coastguard Worker   CResource XmlResource;
267*f6dc9357SAndroid Build Coastguard Worker   CResource MetadataResource;
268*f6dc9357SAndroid Build Coastguard Worker   CResource IntegrityResource;
269*f6dc9357SAndroid Build Coastguard Worker 
270*f6dc9357SAndroid Build Coastguard Worker   void SetDefaultFields(bool useLZX);
271*f6dc9357SAndroid Build Coastguard Worker 
272*f6dc9357SAndroid Build Coastguard Worker   void WriteTo(Byte *p) const;
273*f6dc9357SAndroid Build Coastguard Worker   HRESULT Parse(const Byte *p, UInt64 &phySize);
274*f6dc9357SAndroid Build Coastguard Worker 
IsCompressedCHeader275*f6dc9357SAndroid Build Coastguard Worker   bool IsCompressed() const { return (Flags & NHeaderFlags::kCompression) != 0; }
276*f6dc9357SAndroid Build Coastguard Worker 
IsSupportedCHeader277*f6dc9357SAndroid Build Coastguard Worker   bool IsSupported() const
278*f6dc9357SAndroid Build Coastguard Worker   {
279*f6dc9357SAndroid Build Coastguard Worker     return (!IsCompressed()
280*f6dc9357SAndroid Build Coastguard Worker         || (Flags & NHeaderFlags::kLZX) != 0
281*f6dc9357SAndroid Build Coastguard Worker         || (Flags & NHeaderFlags::kXPRESS) != 0
282*f6dc9357SAndroid Build Coastguard Worker         || (Flags & NHeaderFlags::kLZMS) != 0
283*f6dc9357SAndroid Build Coastguard Worker         || (Flags & NHeaderFlags::kXPRESS2) != 0);
284*f6dc9357SAndroid Build Coastguard Worker   }
285*f6dc9357SAndroid Build Coastguard Worker 
GetMethodCHeader286*f6dc9357SAndroid Build Coastguard Worker   unsigned GetMethod() const
287*f6dc9357SAndroid Build Coastguard Worker   {
288*f6dc9357SAndroid Build Coastguard Worker     if (!IsCompressed())
289*f6dc9357SAndroid Build Coastguard Worker       return 0;
290*f6dc9357SAndroid Build Coastguard Worker     UInt32 mask = (Flags & NHeaderFlags::kMethodMask);
291*f6dc9357SAndroid Build Coastguard Worker     if (mask == 0) return 0;
292*f6dc9357SAndroid Build Coastguard Worker     if (mask == NHeaderFlags::kXPRESS) return NMethod::kXPRESS;
293*f6dc9357SAndroid Build Coastguard Worker     if (mask == NHeaderFlags::kLZX) return NMethod::kLZX;
294*f6dc9357SAndroid Build Coastguard Worker     if (mask == NHeaderFlags::kLZMS) return NMethod::kLZMS;
295*f6dc9357SAndroid Build Coastguard Worker     if (mask == NHeaderFlags::kXPRESS2) return NMethod::kXPRESS;
296*f6dc9357SAndroid Build Coastguard Worker     return mask;
297*f6dc9357SAndroid Build Coastguard Worker   }
298*f6dc9357SAndroid Build Coastguard Worker 
IsOldVersionCHeader299*f6dc9357SAndroid Build Coastguard Worker   bool IsOldVersion() const { return _isOldVersion; }
IsNewVersionCHeader300*f6dc9357SAndroid Build Coastguard Worker   bool IsNewVersion() const { return _isNewVersion; }
IsSolidVersionCHeader301*f6dc9357SAndroid Build Coastguard Worker   bool IsSolidVersion() const { return (Version == k_Version_Solid); }
302*f6dc9357SAndroid Build Coastguard Worker 
AreFromOnArchiveCHeader303*f6dc9357SAndroid Build Coastguard Worker   bool AreFromOnArchive(const CHeader &h)
304*f6dc9357SAndroid Build Coastguard Worker   {
305*f6dc9357SAndroid Build Coastguard Worker     return (memcmp(Guid, h.Guid, sizeof(Guid)) == 0) && (h.NumParts == NumParts);
306*f6dc9357SAndroid Build Coastguard Worker   }
307*f6dc9357SAndroid Build Coastguard Worker };
308*f6dc9357SAndroid Build Coastguard Worker 
309*f6dc9357SAndroid Build Coastguard Worker 
310*f6dc9357SAndroid Build Coastguard Worker const unsigned kHashSize = 20;
311*f6dc9357SAndroid Build Coastguard Worker 
IsEmptySha(const Byte * data)312*f6dc9357SAndroid Build Coastguard Worker inline bool IsEmptySha(const Byte *data)
313*f6dc9357SAndroid Build Coastguard Worker {
314*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < kHashSize; i++)
315*f6dc9357SAndroid Build Coastguard Worker     if (data[i] != 0)
316*f6dc9357SAndroid Build Coastguard Worker       return false;
317*f6dc9357SAndroid Build Coastguard Worker   return true;
318*f6dc9357SAndroid Build Coastguard Worker }
319*f6dc9357SAndroid Build Coastguard Worker 
320*f6dc9357SAndroid Build Coastguard Worker const unsigned kStreamInfoSize = 24 + 2 + 4 + kHashSize;
321*f6dc9357SAndroid Build Coastguard Worker 
322*f6dc9357SAndroid Build Coastguard Worker struct CStreamInfo
323*f6dc9357SAndroid Build Coastguard Worker {
324*f6dc9357SAndroid Build Coastguard Worker   CResource Resource;
325*f6dc9357SAndroid Build Coastguard Worker   UInt16 PartNumber;      // for NEW WIM format, we set it to 1 for OLD WIM format
326*f6dc9357SAndroid Build Coastguard Worker   UInt32 RefCount;
327*f6dc9357SAndroid Build Coastguard Worker   UInt32 Id;              // for OLD WIM format
328*f6dc9357SAndroid Build Coastguard Worker   Byte Hash[kHashSize];
329*f6dc9357SAndroid Build Coastguard Worker 
IsEmptyHashCStreamInfo330*f6dc9357SAndroid Build Coastguard Worker   bool IsEmptyHash() const { return IsEmptySha(Hash); }
331*f6dc9357SAndroid Build Coastguard Worker 
332*f6dc9357SAndroid Build Coastguard Worker   void WriteTo(Byte *p) const;
333*f6dc9357SAndroid Build Coastguard Worker };
334*f6dc9357SAndroid Build Coastguard Worker 
335*f6dc9357SAndroid Build Coastguard Worker 
336*f6dc9357SAndroid Build Coastguard Worker struct CItem
337*f6dc9357SAndroid Build Coastguard Worker {
338*f6dc9357SAndroid Build Coastguard Worker   size_t Offset;
339*f6dc9357SAndroid Build Coastguard Worker   int IndexInSorted;
340*f6dc9357SAndroid Build Coastguard Worker   int StreamIndex;
341*f6dc9357SAndroid Build Coastguard Worker   int Parent;
342*f6dc9357SAndroid Build Coastguard Worker   int ImageIndex; // -1 means that file is unreferenced in Images (deleted item?)
343*f6dc9357SAndroid Build Coastguard Worker   bool IsDir;
344*f6dc9357SAndroid Build Coastguard Worker   bool IsAltStream;
345*f6dc9357SAndroid Build Coastguard Worker 
HasMetadataCItem346*f6dc9357SAndroid Build Coastguard Worker   bool HasMetadata() const { return ImageIndex >= 0; }
347*f6dc9357SAndroid Build Coastguard Worker 
CItemCItem348*f6dc9357SAndroid Build Coastguard Worker   CItem():
349*f6dc9357SAndroid Build Coastguard Worker     IndexInSorted(-1),
350*f6dc9357SAndroid Build Coastguard Worker     StreamIndex(-1),
351*f6dc9357SAndroid Build Coastguard Worker     Parent(-1),
352*f6dc9357SAndroid Build Coastguard Worker     IsDir(false),
353*f6dc9357SAndroid Build Coastguard Worker     IsAltStream(false)
354*f6dc9357SAndroid Build Coastguard Worker     {}
355*f6dc9357SAndroid Build Coastguard Worker };
356*f6dc9357SAndroid Build Coastguard Worker 
357*f6dc9357SAndroid Build Coastguard Worker struct CImage
358*f6dc9357SAndroid Build Coastguard Worker {
359*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer Meta;
360*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<UInt32> SecurOffsets;
361*f6dc9357SAndroid Build Coastguard Worker   unsigned StartItem;
362*f6dc9357SAndroid Build Coastguard Worker   unsigned NumItems;
363*f6dc9357SAndroid Build Coastguard Worker   unsigned NumEmptyRootItems;
364*f6dc9357SAndroid Build Coastguard Worker   int VirtualRootIndex; // index in CDatabase::VirtualRoots[]
365*f6dc9357SAndroid Build Coastguard Worker   UString RootName;
366*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer RootNameBuf;
367*f6dc9357SAndroid Build Coastguard Worker 
CImageCImage368*f6dc9357SAndroid Build Coastguard Worker   CImage(): VirtualRootIndex(-1) {}
369*f6dc9357SAndroid Build Coastguard Worker };
370*f6dc9357SAndroid Build Coastguard Worker 
371*f6dc9357SAndroid Build Coastguard Worker 
372*f6dc9357SAndroid Build Coastguard Worker struct CImageInfo
373*f6dc9357SAndroid Build Coastguard Worker {
374*f6dc9357SAndroid Build Coastguard Worker   bool CTimeDefined;
375*f6dc9357SAndroid Build Coastguard Worker   bool MTimeDefined;
376*f6dc9357SAndroid Build Coastguard Worker   bool NameDefined;
377*f6dc9357SAndroid Build Coastguard Worker   bool IndexDefined;
378*f6dc9357SAndroid Build Coastguard Worker 
379*f6dc9357SAndroid Build Coastguard Worker   FILETIME CTime;
380*f6dc9357SAndroid Build Coastguard Worker   FILETIME MTime;
381*f6dc9357SAndroid Build Coastguard Worker   UString Name;
382*f6dc9357SAndroid Build Coastguard Worker 
383*f6dc9357SAndroid Build Coastguard Worker   UInt64 DirCount;
384*f6dc9357SAndroid Build Coastguard Worker   UInt64 FileCount;
385*f6dc9357SAndroid Build Coastguard Worker   UInt32 Index;
386*f6dc9357SAndroid Build Coastguard Worker 
387*f6dc9357SAndroid Build Coastguard Worker   int ItemIndexInXml;
388*f6dc9357SAndroid Build Coastguard Worker 
GetTotalFilesAndDirsCImageInfo389*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetTotalFilesAndDirs() const { return DirCount + FileCount; }
390*f6dc9357SAndroid Build Coastguard Worker 
CImageInfoCImageInfo391*f6dc9357SAndroid Build Coastguard Worker   CImageInfo(): CTimeDefined(false), MTimeDefined(false), NameDefined(false),
392*f6dc9357SAndroid Build Coastguard Worker       IndexDefined(false), ItemIndexInXml(-1) {}
393*f6dc9357SAndroid Build Coastguard Worker   void Parse(const CXmlItem &item);
394*f6dc9357SAndroid Build Coastguard Worker };
395*f6dc9357SAndroid Build Coastguard Worker 
396*f6dc9357SAndroid Build Coastguard Worker 
397*f6dc9357SAndroid Build Coastguard Worker struct CWimXml
398*f6dc9357SAndroid Build Coastguard Worker {
399*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer Data;
400*f6dc9357SAndroid Build Coastguard Worker   CXml Xml;
401*f6dc9357SAndroid Build Coastguard Worker 
402*f6dc9357SAndroid Build Coastguard Worker   UInt16 VolIndex;
403*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CImageInfo> Images;
404*f6dc9357SAndroid Build Coastguard Worker 
405*f6dc9357SAndroid Build Coastguard Worker   UString FileName;
406*f6dc9357SAndroid Build Coastguard Worker   bool IsEncrypted;
407*f6dc9357SAndroid Build Coastguard Worker 
GetTotalFilesAndDirsCWimXml408*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetTotalFilesAndDirs() const
409*f6dc9357SAndroid Build Coastguard Worker   {
410*f6dc9357SAndroid Build Coastguard Worker     UInt64 sum = 0;
411*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, Images)
412*f6dc9357SAndroid Build Coastguard Worker       sum += Images[i].GetTotalFilesAndDirs();
413*f6dc9357SAndroid Build Coastguard Worker     return sum;
414*f6dc9357SAndroid Build Coastguard Worker   }
415*f6dc9357SAndroid Build Coastguard Worker 
416*f6dc9357SAndroid Build Coastguard Worker   void ToUnicode(UString &s);
417*f6dc9357SAndroid Build Coastguard Worker   bool Parse();
418*f6dc9357SAndroid Build Coastguard Worker 
CWimXmlCWimXml419*f6dc9357SAndroid Build Coastguard Worker   CWimXml(): IsEncrypted(false) {}
420*f6dc9357SAndroid Build Coastguard Worker };
421*f6dc9357SAndroid Build Coastguard Worker 
422*f6dc9357SAndroid Build Coastguard Worker 
423*f6dc9357SAndroid Build Coastguard Worker struct CVolume
424*f6dc9357SAndroid Build Coastguard Worker {
425*f6dc9357SAndroid Build Coastguard Worker   CHeader Header;
426*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IInStream> Stream;
427*f6dc9357SAndroid Build Coastguard Worker };
428*f6dc9357SAndroid Build Coastguard Worker 
429*f6dc9357SAndroid Build Coastguard Worker 
430*f6dc9357SAndroid Build Coastguard Worker class CDatabase
431*f6dc9357SAndroid Build Coastguard Worker {
432*f6dc9357SAndroid Build Coastguard Worker   Byte *DirData;
433*f6dc9357SAndroid Build Coastguard Worker   size_t DirSize;
434*f6dc9357SAndroid Build Coastguard Worker   size_t DirProcessed;
435*f6dc9357SAndroid Build Coastguard Worker   size_t DirStartOffset;
436*f6dc9357SAndroid Build Coastguard Worker   IArchiveOpenCallback *OpenCallback;
437*f6dc9357SAndroid Build Coastguard Worker 
438*f6dc9357SAndroid Build Coastguard Worker   HRESULT ParseDirItem(size_t pos, int parent);
439*f6dc9357SAndroid Build Coastguard Worker   HRESULT ParseImageDirs(CByteBuffer &buf, int parent);
440*f6dc9357SAndroid Build Coastguard Worker 
441*f6dc9357SAndroid Build Coastguard Worker public:
442*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CStreamInfo> DataStreams;
443*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CStreamInfo> MetaStreams;
444*f6dc9357SAndroid Build Coastguard Worker 
445*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CSolid> Solids;
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CItem> Items;
448*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CByteBuffer> ReparseItems;
449*f6dc9357SAndroid Build Coastguard Worker   CIntVector ItemToReparse; // from index_in_Items to index_in_ReparseItems
450*f6dc9357SAndroid Build Coastguard Worker                             // -1 means no reparse;
451*f6dc9357SAndroid Build Coastguard Worker 
452*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CImage> Images;
453*f6dc9357SAndroid Build Coastguard Worker 
454*f6dc9357SAndroid Build Coastguard Worker   bool IsOldVersion9;
455*f6dc9357SAndroid Build Coastguard Worker   bool IsOldVersion;
456*f6dc9357SAndroid Build Coastguard Worker   bool ThereAreDeletedStreams;
457*f6dc9357SAndroid Build Coastguard Worker   bool ThereAreAltStreams;
458*f6dc9357SAndroid Build Coastguard Worker   bool RefCountError;
459*f6dc9357SAndroid Build Coastguard Worker   bool HeadersError;
460*f6dc9357SAndroid Build Coastguard Worker 
GetStartImageIndex()461*f6dc9357SAndroid Build Coastguard Worker   unsigned GetStartImageIndex() const { return IsOldVersion9 ? 0 : 1; }
GetDirAlignMask()462*f6dc9357SAndroid Build Coastguard Worker   unsigned GetDirAlignMask() const { return IsOldVersion9 ? 3 : 7; }
463*f6dc9357SAndroid Build Coastguard Worker 
464*f6dc9357SAndroid Build Coastguard Worker   // User Items can contain all images or just one image from all.
465*f6dc9357SAndroid Build Coastguard Worker   CUIntVector SortedItems;
466*f6dc9357SAndroid Build Coastguard Worker   int IndexOfUserImage;    // -1 : if more than one images was filled to Sorted Items
467*f6dc9357SAndroid Build Coastguard Worker 
468*f6dc9357SAndroid Build Coastguard Worker   unsigned NumExcludededItems;
469*f6dc9357SAndroid Build Coastguard Worker   int ExludedItem;          // -1 : if there are no exclude items
470*f6dc9357SAndroid Build Coastguard Worker   CUIntVector VirtualRoots; // we use them for old 1.10 WIM archives
471*f6dc9357SAndroid Build Coastguard Worker 
ThereIsError()472*f6dc9357SAndroid Build Coastguard Worker   bool ThereIsError() const { return RefCountError || HeadersError; }
473*f6dc9357SAndroid Build Coastguard Worker 
GetNumUserItemsInImage(unsigned imageIndex)474*f6dc9357SAndroid Build Coastguard Worker   unsigned GetNumUserItemsInImage(unsigned imageIndex) const
475*f6dc9357SAndroid Build Coastguard Worker   {
476*f6dc9357SAndroid Build Coastguard Worker     if (IndexOfUserImage >= 0 && imageIndex != (unsigned)IndexOfUserImage)
477*f6dc9357SAndroid Build Coastguard Worker       return 0;
478*f6dc9357SAndroid Build Coastguard Worker     if (imageIndex >= Images.Size())
479*f6dc9357SAndroid Build Coastguard Worker       return 0;
480*f6dc9357SAndroid Build Coastguard Worker     return Images[imageIndex].NumItems - NumExcludededItems;
481*f6dc9357SAndroid Build Coastguard Worker   }
482*f6dc9357SAndroid Build Coastguard Worker 
483*f6dc9357SAndroid Build Coastguard Worker   bool ItemHasStream(const CItem &item) const;
484*f6dc9357SAndroid Build Coastguard Worker 
Get_UnpackSize_of_Resource(const CResource & r)485*f6dc9357SAndroid Build Coastguard Worker   UInt64 Get_UnpackSize_of_Resource(const CResource &r) const
486*f6dc9357SAndroid Build Coastguard Worker   {
487*f6dc9357SAndroid Build Coastguard Worker     if (!r.IsSolid())
488*f6dc9357SAndroid Build Coastguard Worker       return r.UnpackSize;
489*f6dc9357SAndroid Build Coastguard Worker     if (r.IsSolidSmall())
490*f6dc9357SAndroid Build Coastguard Worker       return r.PackSize;
491*f6dc9357SAndroid Build Coastguard Worker     if (r.IsSolidBig() && r.SolidIndex >= 0)
492*f6dc9357SAndroid Build Coastguard Worker       return Solids[(unsigned)r.SolidIndex].UnpackSize;
493*f6dc9357SAndroid Build Coastguard Worker     return 0;
494*f6dc9357SAndroid Build Coastguard Worker   }
495*f6dc9357SAndroid Build Coastguard Worker 
Get_PackSize_of_Resource(unsigned streamIndex)496*f6dc9357SAndroid Build Coastguard Worker   UInt64 Get_PackSize_of_Resource(unsigned streamIndex) const
497*f6dc9357SAndroid Build Coastguard Worker   {
498*f6dc9357SAndroid Build Coastguard Worker     const CResource &r = DataStreams[streamIndex].Resource;
499*f6dc9357SAndroid Build Coastguard Worker     if (!r.IsSolidSmall())
500*f6dc9357SAndroid Build Coastguard Worker       return r.PackSize;
501*f6dc9357SAndroid Build Coastguard Worker     if (r.SolidIndex >= 0)
502*f6dc9357SAndroid Build Coastguard Worker     {
503*f6dc9357SAndroid Build Coastguard Worker       const CSolid &ss = Solids[(unsigned)r.SolidIndex];
504*f6dc9357SAndroid Build Coastguard Worker       if (ss.FirstSmallStream == (int)streamIndex)
505*f6dc9357SAndroid Build Coastguard Worker         return DataStreams[ss.StreamIndex].Resource.PackSize;
506*f6dc9357SAndroid Build Coastguard Worker     }
507*f6dc9357SAndroid Build Coastguard Worker     return 0;
508*f6dc9357SAndroid Build Coastguard Worker   }
509*f6dc9357SAndroid Build Coastguard Worker 
GetUnpackSize()510*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetUnpackSize() const
511*f6dc9357SAndroid Build Coastguard Worker   {
512*f6dc9357SAndroid Build Coastguard Worker     UInt64 res = 0;
513*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, DataStreams)
514*f6dc9357SAndroid Build Coastguard Worker       res += DataStreams[i].Resource.UnpackSize;
515*f6dc9357SAndroid Build Coastguard Worker     return res;
516*f6dc9357SAndroid Build Coastguard Worker   }
517*f6dc9357SAndroid Build Coastguard Worker 
GetPackSize()518*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetPackSize() const
519*f6dc9357SAndroid Build Coastguard Worker   {
520*f6dc9357SAndroid Build Coastguard Worker     UInt64 res = 0;
521*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, DataStreams)
522*f6dc9357SAndroid Build Coastguard Worker       res += DataStreams[i].Resource.PackSize;
523*f6dc9357SAndroid Build Coastguard Worker     return res;
524*f6dc9357SAndroid Build Coastguard Worker   }
525*f6dc9357SAndroid Build Coastguard Worker 
Clear()526*f6dc9357SAndroid Build Coastguard Worker   void Clear()
527*f6dc9357SAndroid Build Coastguard Worker   {
528*f6dc9357SAndroid Build Coastguard Worker     DataStreams.Clear();
529*f6dc9357SAndroid Build Coastguard Worker     MetaStreams.Clear();
530*f6dc9357SAndroid Build Coastguard Worker     Solids.Clear();
531*f6dc9357SAndroid Build Coastguard Worker 
532*f6dc9357SAndroid Build Coastguard Worker     Items.Clear();
533*f6dc9357SAndroid Build Coastguard Worker     ReparseItems.Clear();
534*f6dc9357SAndroid Build Coastguard Worker     ItemToReparse.Clear();
535*f6dc9357SAndroid Build Coastguard Worker 
536*f6dc9357SAndroid Build Coastguard Worker     SortedItems.Clear();
537*f6dc9357SAndroid Build Coastguard Worker 
538*f6dc9357SAndroid Build Coastguard Worker     Images.Clear();
539*f6dc9357SAndroid Build Coastguard Worker     VirtualRoots.Clear();
540*f6dc9357SAndroid Build Coastguard Worker 
541*f6dc9357SAndroid Build Coastguard Worker     IsOldVersion = false;
542*f6dc9357SAndroid Build Coastguard Worker     ThereAreDeletedStreams = false;
543*f6dc9357SAndroid Build Coastguard Worker     ThereAreAltStreams = false;
544*f6dc9357SAndroid Build Coastguard Worker     RefCountError = false;
545*f6dc9357SAndroid Build Coastguard Worker     HeadersError = false;
546*f6dc9357SAndroid Build Coastguard Worker   }
547*f6dc9357SAndroid Build Coastguard Worker 
CDatabase()548*f6dc9357SAndroid Build Coastguard Worker   CDatabase():
549*f6dc9357SAndroid Build Coastguard Worker     RefCountError(false),
550*f6dc9357SAndroid Build Coastguard Worker     HeadersError(false)
551*f6dc9357SAndroid Build Coastguard Worker     {}
552*f6dc9357SAndroid Build Coastguard Worker 
553*f6dc9357SAndroid Build Coastguard Worker   void GetShortName(unsigned index, NWindows::NCOM::CPropVariant &res) const;
554*f6dc9357SAndroid Build Coastguard Worker   void GetItemName(unsigned index1, NWindows::NCOM::CPropVariant &res) const;
555*f6dc9357SAndroid Build Coastguard Worker   void GetItemPath(unsigned index, bool showImageNumber, NWindows::NCOM::CPropVariant &res) const;
556*f6dc9357SAndroid Build Coastguard Worker 
557*f6dc9357SAndroid Build Coastguard Worker   HRESULT OpenXml(IInStream *inStream, const CHeader &h, CByteBuffer &xml);
558*f6dc9357SAndroid Build Coastguard Worker   HRESULT Open(IInStream *inStream, const CHeader &h, unsigned numItemsReserve, IArchiveOpenCallback *openCallback);
559*f6dc9357SAndroid Build Coastguard Worker   HRESULT FillAndCheck(const CObjectVector<CVolume> &volumes);
560*f6dc9357SAndroid Build Coastguard Worker 
561*f6dc9357SAndroid Build Coastguard Worker   /*
562*f6dc9357SAndroid Build Coastguard Worker     imageIndex showImageNumber NumImages
563*f6dc9357SAndroid Build Coastguard Worker          *        true           *       Show Image_Number
564*f6dc9357SAndroid Build Coastguard Worker         -1           *          >1       Show Image_Number
565*f6dc9357SAndroid Build Coastguard Worker         -1        false          1       Don't show Image_Number
566*f6dc9357SAndroid Build Coastguard Worker          N        false          *       Don't show Image_Number
567*f6dc9357SAndroid Build Coastguard Worker   */
568*f6dc9357SAndroid Build Coastguard Worker   HRESULT GenerateSortedItems(int imageIndex, bool showImageNumber);
569*f6dc9357SAndroid Build Coastguard Worker 
570*f6dc9357SAndroid Build Coastguard Worker   HRESULT ExtractReparseStreams(const CObjectVector<CVolume> &volumes, IArchiveOpenCallback *openCallback);
571*f6dc9357SAndroid Build Coastguard Worker };
572*f6dc9357SAndroid Build Coastguard Worker 
573*f6dc9357SAndroid Build Coastguard Worker HRESULT ReadHeader(IInStream *inStream, CHeader &header, UInt64 &phySize);
574*f6dc9357SAndroid Build Coastguard Worker 
575*f6dc9357SAndroid Build Coastguard Worker 
576*f6dc9357SAndroid Build Coastguard Worker struct CMidBuf
577*f6dc9357SAndroid Build Coastguard Worker {
578*f6dc9357SAndroid Build Coastguard Worker   Byte *Data;
579*f6dc9357SAndroid Build Coastguard Worker   size_t _size;
580*f6dc9357SAndroid Build Coastguard Worker 
CMidBufCMidBuf581*f6dc9357SAndroid Build Coastguard Worker   CMidBuf(): Data(NULL), _size(0) {}
582*f6dc9357SAndroid Build Coastguard Worker 
EnsureCapacityCMidBuf583*f6dc9357SAndroid Build Coastguard Worker   void EnsureCapacity(size_t size)
584*f6dc9357SAndroid Build Coastguard Worker   {
585*f6dc9357SAndroid Build Coastguard Worker     if (size > _size)
586*f6dc9357SAndroid Build Coastguard Worker     {
587*f6dc9357SAndroid Build Coastguard Worker       ::z7_AlignedFree(Data);
588*f6dc9357SAndroid Build Coastguard Worker       _size = 0;
589*f6dc9357SAndroid Build Coastguard Worker       Data = (Byte *)::z7_AlignedAlloc(size);
590*f6dc9357SAndroid Build Coastguard Worker       if (Data)
591*f6dc9357SAndroid Build Coastguard Worker         _size = size;
592*f6dc9357SAndroid Build Coastguard Worker     }
593*f6dc9357SAndroid Build Coastguard Worker   }
594*f6dc9357SAndroid Build Coastguard Worker 
~CMidBufCMidBuf595*f6dc9357SAndroid Build Coastguard Worker   ~CMidBuf() { ::z7_AlignedFree(Data); }
596*f6dc9357SAndroid Build Coastguard Worker };
597*f6dc9357SAndroid Build Coastguard Worker 
598*f6dc9357SAndroid Build Coastguard Worker 
599*f6dc9357SAndroid Build Coastguard Worker class CUnpacker
600*f6dc9357SAndroid Build Coastguard Worker {
601*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2<ICompressCoder, NCompress::CCopyCoder> copyCoder;
602*f6dc9357SAndroid Build Coastguard Worker   CMyUniquePtr<NCompress::NLzx::CDecoder> lzxDecoder;
603*f6dc9357SAndroid Build Coastguard Worker   CMyUniquePtr<NCompress::NLzms::CDecoder> lzmsDecoder;
604*f6dc9357SAndroid Build Coastguard Worker 
605*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer sizesBuf;
606*f6dc9357SAndroid Build Coastguard Worker 
607*f6dc9357SAndroid Build Coastguard Worker   CMidBuf packBuf;
608*f6dc9357SAndroid Build Coastguard Worker   CMidBuf unpackBuf;
609*f6dc9357SAndroid Build Coastguard Worker 
610*f6dc9357SAndroid Build Coastguard Worker   // solid resource
611*f6dc9357SAndroid Build Coastguard Worker   int _solidIndex;
612*f6dc9357SAndroid Build Coastguard Worker   size_t _unpackedChunkIndex;
613*f6dc9357SAndroid Build Coastguard Worker 
614*f6dc9357SAndroid Build Coastguard Worker   HRESULT UnpackChunk(
615*f6dc9357SAndroid Build Coastguard Worker       ISequentialInStream *inStream,
616*f6dc9357SAndroid Build Coastguard Worker       unsigned method, unsigned chunkSizeBits,
617*f6dc9357SAndroid Build Coastguard Worker       size_t inSize, size_t outSize,
618*f6dc9357SAndroid Build Coastguard Worker       ISequentialOutStream *outStream);
619*f6dc9357SAndroid Build Coastguard Worker 
620*f6dc9357SAndroid Build Coastguard Worker   HRESULT Unpack2(
621*f6dc9357SAndroid Build Coastguard Worker       IInStream *inStream,
622*f6dc9357SAndroid Build Coastguard Worker       const CResource &res,
623*f6dc9357SAndroid Build Coastguard Worker       const CHeader &header,
624*f6dc9357SAndroid Build Coastguard Worker       const CDatabase *db,
625*f6dc9357SAndroid Build Coastguard Worker       ISequentialOutStream *outStream,
626*f6dc9357SAndroid Build Coastguard Worker       ICompressProgressInfo *progress);
627*f6dc9357SAndroid Build Coastguard Worker 
628*f6dc9357SAndroid Build Coastguard Worker public:
629*f6dc9357SAndroid Build Coastguard Worker   UInt64 TotalPacked;
630*f6dc9357SAndroid Build Coastguard Worker 
CUnpacker()631*f6dc9357SAndroid Build Coastguard Worker   CUnpacker():
632*f6dc9357SAndroid Build Coastguard Worker       lzmsDecoder(NULL),
633*f6dc9357SAndroid Build Coastguard Worker       _solidIndex(-1),
634*f6dc9357SAndroid Build Coastguard Worker       _unpackedChunkIndex(0),
635*f6dc9357SAndroid Build Coastguard Worker       TotalPacked(0)
636*f6dc9357SAndroid Build Coastguard Worker       {}
637*f6dc9357SAndroid Build Coastguard Worker 
638*f6dc9357SAndroid Build Coastguard Worker   HRESULT Unpack(
639*f6dc9357SAndroid Build Coastguard Worker       IInStream *inStream,
640*f6dc9357SAndroid Build Coastguard Worker       const CResource &res,
641*f6dc9357SAndroid Build Coastguard Worker       const CHeader &header,
642*f6dc9357SAndroid Build Coastguard Worker       const CDatabase *db,
643*f6dc9357SAndroid Build Coastguard Worker       ISequentialOutStream *outStream,
644*f6dc9357SAndroid Build Coastguard Worker       ICompressProgressInfo *progress,
645*f6dc9357SAndroid Build Coastguard Worker       Byte *digest);
646*f6dc9357SAndroid Build Coastguard Worker 
647*f6dc9357SAndroid Build Coastguard Worker   HRESULT UnpackData(IInStream *inStream,
648*f6dc9357SAndroid Build Coastguard Worker       const CResource &resource, const CHeader &header,
649*f6dc9357SAndroid Build Coastguard Worker       const CDatabase *db,
650*f6dc9357SAndroid Build Coastguard Worker       CByteBuffer &buf, Byte *digest);
651*f6dc9357SAndroid Build Coastguard Worker };
652*f6dc9357SAndroid Build Coastguard Worker 
653*f6dc9357SAndroid Build Coastguard Worker }}
654*f6dc9357SAndroid Build Coastguard Worker 
655*f6dc9357SAndroid Build Coastguard Worker #endif
656