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