xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Zip/ZipIn.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Archive/ZipIn.h
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_ZIP_IN_H
4*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_ZIP_IN_H
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyBuffer2.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyCom.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../IStream.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "ZipHeader.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "ZipItem.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size);
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
18*f6dc9357SAndroid Build Coastguard Worker namespace NZip {
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker class CItemEx: public CItem
21*f6dc9357SAndroid Build Coastguard Worker {
22*f6dc9357SAndroid Build Coastguard Worker public:
23*f6dc9357SAndroid Build Coastguard Worker   UInt32 LocalFullHeaderSize; // including Name and Extra
24*f6dc9357SAndroid Build Coastguard Worker   // int ParentOfAltStream; // -1, if not AltStream
25*f6dc9357SAndroid Build Coastguard Worker 
26*f6dc9357SAndroid Build Coastguard Worker   bool DescriptorWasRead;
27*f6dc9357SAndroid Build Coastguard Worker 
CItemEx()28*f6dc9357SAndroid Build Coastguard Worker   CItemEx():
29*f6dc9357SAndroid Build Coastguard Worker     // ParentOfAltStream(-1),
30*f6dc9357SAndroid Build Coastguard Worker     DescriptorWasRead(false) {}
31*f6dc9357SAndroid Build Coastguard Worker 
GetLocalFullSize()32*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetLocalFullSize() const
33*f6dc9357SAndroid Build Coastguard Worker     { return LocalFullHeaderSize + GetPackSizeWithDescriptor(); }
GetDataPosition()34*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetDataPosition() const
35*f6dc9357SAndroid Build Coastguard Worker     { return LocalHeaderPos + LocalFullHeaderSize; }
36*f6dc9357SAndroid Build Coastguard Worker 
IsBadDescriptor()37*f6dc9357SAndroid Build Coastguard Worker   bool IsBadDescriptor() const
38*f6dc9357SAndroid Build Coastguard Worker   {
39*f6dc9357SAndroid Build Coastguard Worker     return !FromCentral && FromLocal && HasDescriptor() && !DescriptorWasRead;
40*f6dc9357SAndroid Build Coastguard Worker   }
41*f6dc9357SAndroid Build Coastguard Worker };
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker 
44*f6dc9357SAndroid Build Coastguard Worker struct CInArchiveInfo
45*f6dc9357SAndroid Build Coastguard Worker {
46*f6dc9357SAndroid Build Coastguard Worker   Int64 Base; /* Base offset of start of archive in stream.
47*f6dc9357SAndroid Build Coastguard Worker                  Offsets in headers must be calculated from that Base.
48*f6dc9357SAndroid Build Coastguard Worker                  Base is equal to MarkerPos for normal ZIPs.
49*f6dc9357SAndroid Build Coastguard Worker                  Base can point to PE stub for some ZIP SFXs.
50*f6dc9357SAndroid Build Coastguard Worker                  if CentralDir was read,
51*f6dc9357SAndroid Build Coastguard Worker                    Base can be negative, if start of data is not available,
52*f6dc9357SAndroid Build Coastguard Worker                  if CentralDirs was not read,
53*f6dc9357SAndroid Build Coastguard Worker                    Base = ArcInfo.MarkerPos; */
54*f6dc9357SAndroid Build Coastguard Worker 
55*f6dc9357SAndroid Build Coastguard Worker   /* The following *Pos variables contain absolute offsets in Stream */
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker   UInt64 MarkerPos;  /* Pos of first signature, it can point to kSpan/kNoSpan signature
58*f6dc9357SAndroid Build Coastguard Worker                         = MarkerPos2      in most archives
59*f6dc9357SAndroid Build Coastguard Worker                         = MarkerPos2 - 4  if there is kSpan/kNoSpan signature */
60*f6dc9357SAndroid Build Coastguard Worker   UInt64 MarkerPos2; // Pos of first local item signature in stream
61*f6dc9357SAndroid Build Coastguard Worker   UInt64 FinishPos;  // Finish pos of archive data in starting volume
62*f6dc9357SAndroid Build Coastguard Worker   UInt64 FileEndPos; // Finish pos of stream
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker   UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base).
65*f6dc9357SAndroid Build Coastguard Worker                                   = 0 in most archives
66*f6dc9357SAndroid Build Coastguard Worker                                   = size of stub for some SFXs */
67*f6dc9357SAndroid Build Coastguard Worker 
68*f6dc9357SAndroid Build Coastguard Worker 
69*f6dc9357SAndroid Build Coastguard Worker   int MarkerVolIndex;
70*f6dc9357SAndroid Build Coastguard Worker 
71*f6dc9357SAndroid Build Coastguard Worker   bool CdWasRead;
72*f6dc9357SAndroid Build Coastguard Worker   bool IsSpanMode;
73*f6dc9357SAndroid Build Coastguard Worker   bool ThereIsTail;
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker   // UInt32 BaseVolIndex;
76*f6dc9357SAndroid Build Coastguard Worker 
77*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer Comment;
78*f6dc9357SAndroid Build Coastguard Worker 
79*f6dc9357SAndroid Build Coastguard Worker 
CInArchiveInfoCInArchiveInfo80*f6dc9357SAndroid Build Coastguard Worker   CInArchiveInfo():
81*f6dc9357SAndroid Build Coastguard Worker       Base(0),
82*f6dc9357SAndroid Build Coastguard Worker       MarkerPos(0),
83*f6dc9357SAndroid Build Coastguard Worker       MarkerPos2(0),
84*f6dc9357SAndroid Build Coastguard Worker       FinishPos(0),
85*f6dc9357SAndroid Build Coastguard Worker       FileEndPos(0),
86*f6dc9357SAndroid Build Coastguard Worker       FirstItemRelatOffset(0),
87*f6dc9357SAndroid Build Coastguard Worker       MarkerVolIndex(-1),
88*f6dc9357SAndroid Build Coastguard Worker       CdWasRead(false),
89*f6dc9357SAndroid Build Coastguard Worker       IsSpanMode(false),
90*f6dc9357SAndroid Build Coastguard Worker       ThereIsTail(false)
91*f6dc9357SAndroid Build Coastguard Worker       // BaseVolIndex(0)
92*f6dc9357SAndroid Build Coastguard Worker       {}
93*f6dc9357SAndroid Build Coastguard Worker 
ClearCInArchiveInfo94*f6dc9357SAndroid Build Coastguard Worker   void Clear()
95*f6dc9357SAndroid Build Coastguard Worker   {
96*f6dc9357SAndroid Build Coastguard Worker     // BaseVolIndex = 0;
97*f6dc9357SAndroid Build Coastguard Worker     Base = 0;
98*f6dc9357SAndroid Build Coastguard Worker     MarkerPos = 0;
99*f6dc9357SAndroid Build Coastguard Worker     MarkerPos2 = 0;
100*f6dc9357SAndroid Build Coastguard Worker     FinishPos = 0;
101*f6dc9357SAndroid Build Coastguard Worker     FileEndPos = 0;
102*f6dc9357SAndroid Build Coastguard Worker     MarkerVolIndex = -1;
103*f6dc9357SAndroid Build Coastguard Worker     ThereIsTail = false;
104*f6dc9357SAndroid Build Coastguard Worker 
105*f6dc9357SAndroid Build Coastguard Worker     FirstItemRelatOffset = 0;
106*f6dc9357SAndroid Build Coastguard Worker 
107*f6dc9357SAndroid Build Coastguard Worker     CdWasRead = false;
108*f6dc9357SAndroid Build Coastguard Worker     IsSpanMode = false;
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker     Comment.Free();
111*f6dc9357SAndroid Build Coastguard Worker   }
112*f6dc9357SAndroid Build Coastguard Worker };
113*f6dc9357SAndroid Build Coastguard Worker 
114*f6dc9357SAndroid Build Coastguard Worker 
115*f6dc9357SAndroid Build Coastguard Worker struct CCdInfo
116*f6dc9357SAndroid Build Coastguard Worker {
117*f6dc9357SAndroid Build Coastguard Worker   bool IsFromEcd64;
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker   UInt16 CommentSize;
120*f6dc9357SAndroid Build Coastguard Worker 
121*f6dc9357SAndroid Build Coastguard Worker   // 64
122*f6dc9357SAndroid Build Coastguard Worker   UInt16 VersionMade;
123*f6dc9357SAndroid Build Coastguard Worker   UInt16 VersionNeedExtract;
124*f6dc9357SAndroid Build Coastguard Worker 
125*f6dc9357SAndroid Build Coastguard Worker   // old zip
126*f6dc9357SAndroid Build Coastguard Worker   UInt32 ThisDisk;
127*f6dc9357SAndroid Build Coastguard Worker   UInt32 CdDisk;
128*f6dc9357SAndroid Build Coastguard Worker   UInt64 NumEntries_in_ThisDisk;
129*f6dc9357SAndroid Build Coastguard Worker   UInt64 NumEntries;
130*f6dc9357SAndroid Build Coastguard Worker   UInt64 Size;
131*f6dc9357SAndroid Build Coastguard Worker   UInt64 Offset;
132*f6dc9357SAndroid Build Coastguard Worker 
CCdInfoCCdInfo133*f6dc9357SAndroid Build Coastguard Worker   CCdInfo() { memset(this, 0, sizeof(*this)); IsFromEcd64 = false; }
134*f6dc9357SAndroid Build Coastguard Worker 
135*f6dc9357SAndroid Build Coastguard Worker   void ParseEcd32(const Byte *p);   // (p) includes signature
136*f6dc9357SAndroid Build Coastguard Worker   void ParseEcd64e(const Byte *p);  // (p) exclude signature
137*f6dc9357SAndroid Build Coastguard Worker 
IsEmptyArcCCdInfo138*f6dc9357SAndroid Build Coastguard Worker   bool IsEmptyArc() const
139*f6dc9357SAndroid Build Coastguard Worker   {
140*f6dc9357SAndroid Build Coastguard Worker     return ThisDisk == 0
141*f6dc9357SAndroid Build Coastguard Worker         && CdDisk == 0
142*f6dc9357SAndroid Build Coastguard Worker         && NumEntries_in_ThisDisk == 0
143*f6dc9357SAndroid Build Coastguard Worker         && NumEntries == 0
144*f6dc9357SAndroid Build Coastguard Worker         && Size == 0
145*f6dc9357SAndroid Build Coastguard Worker         && Offset == 0 // test it
146*f6dc9357SAndroid Build Coastguard Worker     ;
147*f6dc9357SAndroid Build Coastguard Worker   }
148*f6dc9357SAndroid Build Coastguard Worker };
149*f6dc9357SAndroid Build Coastguard Worker 
150*f6dc9357SAndroid Build Coastguard Worker 
151*f6dc9357SAndroid Build Coastguard Worker struct CVols
152*f6dc9357SAndroid Build Coastguard Worker {
153*f6dc9357SAndroid Build Coastguard Worker   struct CSubStreamInfo
154*f6dc9357SAndroid Build Coastguard Worker   {
155*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IInStream> Stream;
156*f6dc9357SAndroid Build Coastguard Worker     UInt64 Size;
157*f6dc9357SAndroid Build Coastguard Worker 
SeekToStartCVols::CSubStreamInfo158*f6dc9357SAndroid Build Coastguard Worker     HRESULT SeekToStart() const { return InStream_SeekToBegin(Stream); }
159*f6dc9357SAndroid Build Coastguard Worker 
CSubStreamInfoCVols::CSubStreamInfo160*f6dc9357SAndroid Build Coastguard Worker     CSubStreamInfo(): Size(0) {}
161*f6dc9357SAndroid Build Coastguard Worker   };
162*f6dc9357SAndroid Build Coastguard Worker 
163*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CSubStreamInfo> Streams;
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker   int StreamIndex;   // -1 for StartStream
166*f6dc9357SAndroid Build Coastguard Worker                      // -2 for ZipStream at multivol detection code
167*f6dc9357SAndroid Build Coastguard Worker                      // >=0 volume index in multivol
168*f6dc9357SAndroid Build Coastguard Worker 
169*f6dc9357SAndroid Build Coastguard Worker   bool NeedSeek;
170*f6dc9357SAndroid Build Coastguard Worker 
171*f6dc9357SAndroid Build Coastguard Worker   bool DisableVolsSearch;
172*f6dc9357SAndroid Build Coastguard Worker   bool StartIsExe;  // is .exe
173*f6dc9357SAndroid Build Coastguard Worker   bool StartIsZ;    // is .zip or .zNN
174*f6dc9357SAndroid Build Coastguard Worker   bool StartIsZip;  // is .zip
175*f6dc9357SAndroid Build Coastguard Worker   bool IsUpperCase;
176*f6dc9357SAndroid Build Coastguard Worker   bool MissingZip;
177*f6dc9357SAndroid Build Coastguard Worker 
178*f6dc9357SAndroid Build Coastguard Worker   bool ecd_wasRead;
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker   Int32 StartVolIndex; // -1, if unknown vol index
181*f6dc9357SAndroid Build Coastguard Worker                        // = (NN - 1), if StartStream is .zNN
182*f6dc9357SAndroid Build Coastguard Worker                        // = 0, if start vol is exe
183*f6dc9357SAndroid Build Coastguard Worker 
184*f6dc9357SAndroid Build Coastguard Worker   Int32 StartParsingVol; // if we need local parsing, we must use that stream
185*f6dc9357SAndroid Build Coastguard Worker   unsigned NumVols;
186*f6dc9357SAndroid Build Coastguard Worker 
187*f6dc9357SAndroid Build Coastguard Worker   int EndVolIndex; // index of last volume (ecd volume),
188*f6dc9357SAndroid Build Coastguard Worker                    // -1, if is not multivol
189*f6dc9357SAndroid Build Coastguard Worker 
190*f6dc9357SAndroid Build Coastguard Worker   UString BaseName; // name of archive including '.'
191*f6dc9357SAndroid Build Coastguard Worker   UString MissingName;
192*f6dc9357SAndroid Build Coastguard Worker 
193*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IInStream> ZipStream;
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker   CCdInfo ecd;
196*f6dc9357SAndroid Build Coastguard Worker 
197*f6dc9357SAndroid Build Coastguard Worker   UInt64 TotalBytesSize; // for MultiVol only
198*f6dc9357SAndroid Build Coastguard Worker 
ClearRefsCVols199*f6dc9357SAndroid Build Coastguard Worker   void ClearRefs()
200*f6dc9357SAndroid Build Coastguard Worker   {
201*f6dc9357SAndroid Build Coastguard Worker     Streams.Clear();
202*f6dc9357SAndroid Build Coastguard Worker     ZipStream.Release();
203*f6dc9357SAndroid Build Coastguard Worker     TotalBytesSize = 0;
204*f6dc9357SAndroid Build Coastguard Worker   }
205*f6dc9357SAndroid Build Coastguard Worker 
ClearCVols206*f6dc9357SAndroid Build Coastguard Worker   void Clear()
207*f6dc9357SAndroid Build Coastguard Worker   {
208*f6dc9357SAndroid Build Coastguard Worker     StreamIndex = -1;
209*f6dc9357SAndroid Build Coastguard Worker     NeedSeek = false;
210*f6dc9357SAndroid Build Coastguard Worker 
211*f6dc9357SAndroid Build Coastguard Worker     DisableVolsSearch = false;
212*f6dc9357SAndroid Build Coastguard Worker     StartIsExe = false;
213*f6dc9357SAndroid Build Coastguard Worker     StartIsZ = false;
214*f6dc9357SAndroid Build Coastguard Worker     StartIsZip = false;
215*f6dc9357SAndroid Build Coastguard Worker     IsUpperCase = false;
216*f6dc9357SAndroid Build Coastguard Worker 
217*f6dc9357SAndroid Build Coastguard Worker     StartVolIndex = -1;
218*f6dc9357SAndroid Build Coastguard Worker     StartParsingVol = 0;
219*f6dc9357SAndroid Build Coastguard Worker     NumVols = 0;
220*f6dc9357SAndroid Build Coastguard Worker     EndVolIndex = -1;
221*f6dc9357SAndroid Build Coastguard Worker 
222*f6dc9357SAndroid Build Coastguard Worker     BaseName.Empty();
223*f6dc9357SAndroid Build Coastguard Worker     MissingName.Empty();
224*f6dc9357SAndroid Build Coastguard Worker 
225*f6dc9357SAndroid Build Coastguard Worker     MissingZip = false;
226*f6dc9357SAndroid Build Coastguard Worker     ecd_wasRead = false;
227*f6dc9357SAndroid Build Coastguard Worker 
228*f6dc9357SAndroid Build Coastguard Worker     ClearRefs();
229*f6dc9357SAndroid Build Coastguard Worker   }
230*f6dc9357SAndroid Build Coastguard Worker 
231*f6dc9357SAndroid Build Coastguard Worker   HRESULT ParseArcName(IArchiveOpenVolumeCallback *volCallback);
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker   HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
234*f6dc9357SAndroid Build Coastguard Worker };
235*f6dc9357SAndroid Build Coastguard Worker 
236*f6dc9357SAndroid Build Coastguard Worker 
237*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
238*f6dc9357SAndroid Build Coastguard Worker   CVolStream
239*f6dc9357SAndroid Build Coastguard Worker   , ISequentialInStream
240*f6dc9357SAndroid Build Coastguard Worker )
241*f6dc9357SAndroid Build Coastguard Worker public:
242*f6dc9357SAndroid Build Coastguard Worker   CVols *Vols;
243*f6dc9357SAndroid Build Coastguard Worker };
244*f6dc9357SAndroid Build Coastguard Worker 
245*f6dc9357SAndroid Build Coastguard Worker 
246*f6dc9357SAndroid Build Coastguard Worker class CInArchive
247*f6dc9357SAndroid Build Coastguard Worker {
248*f6dc9357SAndroid Build Coastguard Worker   CMidBuffer Buffer;
249*f6dc9357SAndroid Build Coastguard Worker   size_t _bufPos;
250*f6dc9357SAndroid Build Coastguard Worker   size_t _bufCached;
251*f6dc9357SAndroid Build Coastguard Worker 
252*f6dc9357SAndroid Build Coastguard Worker   UInt64 _streamPos;
253*f6dc9357SAndroid Build Coastguard Worker   UInt64 _cnt;
254*f6dc9357SAndroid Build Coastguard Worker 
255*f6dc9357SAndroid Build Coastguard Worker   // UInt32 _startLocalFromCd_Disk;
256*f6dc9357SAndroid Build Coastguard Worker   // UInt64 _startLocalFromCd_Offset;
257*f6dc9357SAndroid Build Coastguard Worker 
258*f6dc9357SAndroid Build Coastguard Worker   size_t GetAvail() const { return _bufCached - _bufPos; }
259*f6dc9357SAndroid Build Coastguard Worker 
260*f6dc9357SAndroid Build Coastguard Worker   void InitBuf() { _bufPos = 0; _bufCached = 0; }
261*f6dc9357SAndroid Build Coastguard Worker   void DisableBufMode() { InitBuf(); _inBufMode = false; }
262*f6dc9357SAndroid Build Coastguard Worker 
263*f6dc9357SAndroid Build Coastguard Worker   void SkipLookahed(size_t skip)
264*f6dc9357SAndroid Build Coastguard Worker   {
265*f6dc9357SAndroid Build Coastguard Worker     _bufPos += skip;
266*f6dc9357SAndroid Build Coastguard Worker     _cnt += skip;
267*f6dc9357SAndroid Build Coastguard Worker   }
268*f6dc9357SAndroid Build Coastguard Worker 
269*f6dc9357SAndroid Build Coastguard Worker   HRESULT AllocateBuffer(size_t size);
270*f6dc9357SAndroid Build Coastguard Worker 
271*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetVirtStreamPos() { return _streamPos - _bufCached + _bufPos; }
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker   bool _inBufMode;
274*f6dc9357SAndroid Build Coastguard Worker 
275*f6dc9357SAndroid Build Coastguard Worker   bool IsArcOpen;
276*f6dc9357SAndroid Build Coastguard Worker   bool CanStartNewVol;
277*f6dc9357SAndroid Build Coastguard Worker 
278*f6dc9357SAndroid Build Coastguard Worker   UInt32 _signature;
279*f6dc9357SAndroid Build Coastguard Worker 
280*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IInStream> StreamRef;
281*f6dc9357SAndroid Build Coastguard Worker   IInStream *Stream;
282*f6dc9357SAndroid Build Coastguard Worker   IInStream *StartStream;
283*f6dc9357SAndroid Build Coastguard Worker   IArchiveOpenCallback *Callback;
284*f6dc9357SAndroid Build Coastguard Worker 
285*f6dc9357SAndroid Build Coastguard Worker   HRESULT Seek_SavePos(UInt64 offset);
286*f6dc9357SAndroid Build Coastguard Worker   HRESULT SeekToVol(int volIndex, UInt64 offset);
287*f6dc9357SAndroid Build Coastguard Worker 
288*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadFromCache(Byte *data, unsigned size, unsigned &processed);
289*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadFromCache_FALSE(Byte *data, unsigned size);
290*f6dc9357SAndroid Build Coastguard Worker 
291*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadVols2(IArchiveOpenVolumeCallback *volCallback,
292*f6dc9357SAndroid Build Coastguard Worker       unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols);
293*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadVols();
294*f6dc9357SAndroid Build Coastguard Worker 
295*f6dc9357SAndroid Build Coastguard Worker   HRESULT FindMarker(const UInt64 *searchLimit);
296*f6dc9357SAndroid Build Coastguard Worker   HRESULT IncreaseRealPosition(UInt64 addValue, bool &isFinished);
297*f6dc9357SAndroid Build Coastguard Worker 
298*f6dc9357SAndroid Build Coastguard Worker   HRESULT LookAhead(size_t minRequiredInBuffer);
299*f6dc9357SAndroid Build Coastguard Worker   void SafeRead(Byte *data, unsigned size);
300*f6dc9357SAndroid Build Coastguard Worker   void ReadBuffer(CByteBuffer &buffer, unsigned size);
301*f6dc9357SAndroid Build Coastguard Worker   // Byte ReadByte();
302*f6dc9357SAndroid Build Coastguard Worker   // UInt16 ReadUInt16();
303*f6dc9357SAndroid Build Coastguard Worker   UInt32 ReadUInt32();
304*f6dc9357SAndroid Build Coastguard Worker   UInt64 ReadUInt64();
305*f6dc9357SAndroid Build Coastguard Worker 
306*f6dc9357SAndroid Build Coastguard Worker   void ReadSignature();
307*f6dc9357SAndroid Build Coastguard Worker 
308*f6dc9357SAndroid Build Coastguard Worker   void Skip(size_t num);
309*f6dc9357SAndroid Build Coastguard Worker   HRESULT Skip64(UInt64 num, unsigned numFiles);
310*f6dc9357SAndroid Build Coastguard Worker 
311*f6dc9357SAndroid Build Coastguard Worker   bool ReadFileName(unsigned nameSize, AString &dest);
312*f6dc9357SAndroid Build Coastguard Worker 
313*f6dc9357SAndroid Build Coastguard Worker   bool ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
314*f6dc9357SAndroid Build Coastguard Worker       UInt64 &unpackSize, UInt64 &packSize, CItem *cdItem);
315*f6dc9357SAndroid Build Coastguard Worker   bool ReadLocalItem(CItemEx &item);
316*f6dc9357SAndroid Build Coastguard Worker   HRESULT FindDescriptor(CItemEx &item, unsigned numFiles);
317*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadCdItem(CItemEx &item);
318*f6dc9357SAndroid Build Coastguard Worker   HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo);
319*f6dc9357SAndroid Build Coastguard Worker   HRESULT FindCd(bool checkOffsetMode);
320*f6dc9357SAndroid Build Coastguard Worker   HRESULT TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize);
321*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize);
322*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadLocals(CObjectVector<CItemEx> &localItems);
323*f6dc9357SAndroid Build Coastguard Worker 
324*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadHeaders(CObjectVector<CItemEx> &items);
325*f6dc9357SAndroid Build Coastguard Worker 
326*f6dc9357SAndroid Build Coastguard Worker   HRESULT GetVolStream(unsigned vol, UInt64 pos, CMyComPtr<ISequentialInStream> &stream);
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker public:
329*f6dc9357SAndroid Build Coastguard Worker   CInArchiveInfo ArcInfo;
330*f6dc9357SAndroid Build Coastguard Worker 
331*f6dc9357SAndroid Build Coastguard Worker   bool IsArc;
332*f6dc9357SAndroid Build Coastguard Worker   bool IsZip64;
333*f6dc9357SAndroid Build Coastguard Worker 
334*f6dc9357SAndroid Build Coastguard Worker   bool IsApk;
335*f6dc9357SAndroid Build Coastguard Worker   bool IsCdUnsorted;
336*f6dc9357SAndroid Build Coastguard Worker 
337*f6dc9357SAndroid Build Coastguard Worker   bool HeadersError;
338*f6dc9357SAndroid Build Coastguard Worker   bool HeadersWarning;
339*f6dc9357SAndroid Build Coastguard Worker   bool ExtraMinorError;
340*f6dc9357SAndroid Build Coastguard Worker   bool UnexpectedEnd;
341*f6dc9357SAndroid Build Coastguard Worker   bool LocalsWereRead;
342*f6dc9357SAndroid Build Coastguard Worker   bool LocalsCenterMerged;
343*f6dc9357SAndroid Build Coastguard Worker   bool NoCentralDir;
344*f6dc9357SAndroid Build Coastguard Worker   bool Overflow32bit; // = true, if zip without Zip64 extension support and it has some fields values truncated to 32-bits.
345*f6dc9357SAndroid Build Coastguard Worker   bool Cd_NumEntries_Overflow_16bit; // = true, if no Zip64 and 16-bit ecd:NumEntries was overflowed.
346*f6dc9357SAndroid Build Coastguard Worker 
347*f6dc9357SAndroid Build Coastguard Worker   bool MarkerIsFound;
348*f6dc9357SAndroid Build Coastguard Worker   bool MarkerIsSafe;
349*f6dc9357SAndroid Build Coastguard Worker 
350*f6dc9357SAndroid Build Coastguard Worker   bool IsMultiVol;
351*f6dc9357SAndroid Build Coastguard Worker   bool UseDisk_in_SingleVol;
352*f6dc9357SAndroid Build Coastguard Worker   UInt32 EcdVolIndex;
353*f6dc9357SAndroid Build Coastguard Worker 
354*f6dc9357SAndroid Build Coastguard Worker   CVols Vols;
355*f6dc9357SAndroid Build Coastguard Worker 
356*f6dc9357SAndroid Build Coastguard Worker   bool Force_ReadLocals_Mode;
357*f6dc9357SAndroid Build Coastguard Worker   bool Disable_VolsRead;
358*f6dc9357SAndroid Build Coastguard Worker   bool Disable_FindMarker;
359*f6dc9357SAndroid Build Coastguard Worker 
360*f6dc9357SAndroid Build Coastguard Worker   CInArchive():
361*f6dc9357SAndroid Build Coastguard Worker       IsArcOpen(false),
362*f6dc9357SAndroid Build Coastguard Worker       Stream(NULL),
363*f6dc9357SAndroid Build Coastguard Worker       StartStream(NULL),
364*f6dc9357SAndroid Build Coastguard Worker       Callback(NULL),
365*f6dc9357SAndroid Build Coastguard Worker       Force_ReadLocals_Mode(false),
366*f6dc9357SAndroid Build Coastguard Worker       Disable_VolsRead(false),
367*f6dc9357SAndroid Build Coastguard Worker       Disable_FindMarker(false)
368*f6dc9357SAndroid Build Coastguard Worker       {}
369*f6dc9357SAndroid Build Coastguard Worker 
370*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetPhySize() const
371*f6dc9357SAndroid Build Coastguard Worker   {
372*f6dc9357SAndroid Build Coastguard Worker     if (IsMultiVol)
373*f6dc9357SAndroid Build Coastguard Worker       return ArcInfo.FinishPos;
374*f6dc9357SAndroid Build Coastguard Worker     else
375*f6dc9357SAndroid Build Coastguard Worker       return (UInt64)((Int64)ArcInfo.FinishPos - ArcInfo.Base);
376*f6dc9357SAndroid Build Coastguard Worker   }
377*f6dc9357SAndroid Build Coastguard Worker 
378*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetOffset() const
379*f6dc9357SAndroid Build Coastguard Worker   {
380*f6dc9357SAndroid Build Coastguard Worker     if (IsMultiVol)
381*f6dc9357SAndroid Build Coastguard Worker       return 0;
382*f6dc9357SAndroid Build Coastguard Worker     else
383*f6dc9357SAndroid Build Coastguard Worker       return (UInt64)ArcInfo.Base;
384*f6dc9357SAndroid Build Coastguard Worker   }
385*f6dc9357SAndroid Build Coastguard Worker 
386*f6dc9357SAndroid Build Coastguard Worker 
387*f6dc9357SAndroid Build Coastguard Worker   void ClearRefs();
388*f6dc9357SAndroid Build Coastguard Worker   void Close();
389*f6dc9357SAndroid Build Coastguard Worker   HRESULT Open(IInStream *stream, const UInt64 *searchLimit, IArchiveOpenCallback *callback, CObjectVector<CItemEx> &items);
390*f6dc9357SAndroid Build Coastguard Worker 
391*f6dc9357SAndroid Build Coastguard Worker   bool IsOpen() const { return IsArcOpen; }
392*f6dc9357SAndroid Build Coastguard Worker 
393*f6dc9357SAndroid Build Coastguard Worker   bool AreThereErrors() const
394*f6dc9357SAndroid Build Coastguard Worker   {
395*f6dc9357SAndroid Build Coastguard Worker     return HeadersError
396*f6dc9357SAndroid Build Coastguard Worker         || UnexpectedEnd
397*f6dc9357SAndroid Build Coastguard Worker         || !Vols.MissingName.IsEmpty();
398*f6dc9357SAndroid Build Coastguard Worker   }
399*f6dc9357SAndroid Build Coastguard Worker 
400*f6dc9357SAndroid Build Coastguard Worker   bool IsLocalOffsetOK(const CItemEx &item) const
401*f6dc9357SAndroid Build Coastguard Worker   {
402*f6dc9357SAndroid Build Coastguard Worker     if (item.FromLocal)
403*f6dc9357SAndroid Build Coastguard Worker       return true;
404*f6dc9357SAndroid Build Coastguard Worker     return (Int64)GetOffset() + (Int64)item.LocalHeaderPos >= 0;
405*f6dc9357SAndroid Build Coastguard Worker   }
406*f6dc9357SAndroid Build Coastguard Worker 
407*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetEmbeddedStubSize() const
408*f6dc9357SAndroid Build Coastguard Worker   {
409*f6dc9357SAndroid Build Coastguard Worker     // it's possible that first item in CD doesn refers to first local item
410*f6dc9357SAndroid Build Coastguard Worker     // so FirstItemRelatOffset is not first local item
411*f6dc9357SAndroid Build Coastguard Worker 
412*f6dc9357SAndroid Build Coastguard Worker     if (ArcInfo.CdWasRead)
413*f6dc9357SAndroid Build Coastguard Worker       return ArcInfo.FirstItemRelatOffset;
414*f6dc9357SAndroid Build Coastguard Worker     if (IsMultiVol)
415*f6dc9357SAndroid Build Coastguard Worker       return 0;
416*f6dc9357SAndroid Build Coastguard Worker     return (UInt64)((Int64)ArcInfo.MarkerPos2 - ArcInfo.Base);
417*f6dc9357SAndroid Build Coastguard Worker   }
418*f6dc9357SAndroid Build Coastguard Worker 
419*f6dc9357SAndroid Build Coastguard Worker 
420*f6dc9357SAndroid Build Coastguard Worker   HRESULT CheckDescriptor(const CItemEx &item);
421*f6dc9357SAndroid Build Coastguard Worker   HRESULT Read_LocalItem_After_CdItem(CItemEx &item, bool &isAvail, bool &headersError);
422*f6dc9357SAndroid Build Coastguard Worker   HRESULT Read_LocalItem_After_CdItem_Full(CItemEx &item);
423*f6dc9357SAndroid Build Coastguard Worker 
424*f6dc9357SAndroid Build Coastguard Worker   HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr<ISequentialInStream> &stream);
425*f6dc9357SAndroid Build Coastguard Worker 
426*f6dc9357SAndroid Build Coastguard Worker   IInStream *GetBaseStream() { return StreamRef; }
427*f6dc9357SAndroid Build Coastguard Worker 
428*f6dc9357SAndroid Build Coastguard Worker   bool CanUpdate() const
429*f6dc9357SAndroid Build Coastguard Worker   {
430*f6dc9357SAndroid Build Coastguard Worker     if (AreThereErrors()
431*f6dc9357SAndroid Build Coastguard Worker        || IsMultiVol
432*f6dc9357SAndroid Build Coastguard Worker        || ArcInfo.Base < 0
433*f6dc9357SAndroid Build Coastguard Worker        || (Int64)ArcInfo.MarkerPos2 < ArcInfo.Base
434*f6dc9357SAndroid Build Coastguard Worker        || ArcInfo.ThereIsTail
435*f6dc9357SAndroid Build Coastguard Worker        || GetEmbeddedStubSize() != 0
436*f6dc9357SAndroid Build Coastguard Worker        || IsApk
437*f6dc9357SAndroid Build Coastguard Worker        || IsCdUnsorted)
438*f6dc9357SAndroid Build Coastguard Worker       return false;
439*f6dc9357SAndroid Build Coastguard Worker 
440*f6dc9357SAndroid Build Coastguard Worker     // 7-zip probably can update archives with embedded stubs.
441*f6dc9357SAndroid Build Coastguard Worker     // we just disable that feature for more safety.
442*f6dc9357SAndroid Build Coastguard Worker 
443*f6dc9357SAndroid Build Coastguard Worker     return true;
444*f6dc9357SAndroid Build Coastguard Worker   }
445*f6dc9357SAndroid Build Coastguard Worker };
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker }}
448*f6dc9357SAndroid Build Coastguard Worker 
449*f6dc9357SAndroid Build Coastguard Worker #endif
450