ZipIn.h (p7zip_15.14.1_src_all) | : | ZipIn.h (p7zip_16.02_src_all) | ||
---|---|---|---|---|
skipping to change at line 43 | skipping to change at line 43 | |||
Int64 Base; /* Base offset of start of archive in stream. | Int64 Base; /* Base offset of start of archive in stream. | |||
Offsets in headers must be calculated from that Base. | Offsets in headers must be calculated from that Base. | |||
Base is equal to MarkerPos for normal ZIPs. | Base is equal to MarkerPos for normal ZIPs. | |||
Base can point to PE stub for some ZIP SFXs. | Base can point to PE stub for some ZIP SFXs. | |||
if CentralDir was read, | if CentralDir was read, | |||
Base can be negative, if start of data is not available, | Base can be negative, if start of data is not available, | |||
if CentralDirs was not read, | if CentralDirs was not read, | |||
Base = ArcInfo.MarkerPos; */ | Base = ArcInfo.MarkerPos; */ | |||
/* The following *Pos variables contain absolute offsets in Stream */ | /* The following *Pos variables contain absolute offsets in Stream */ | |||
UInt64 MarkerPos; /* Pos of first signature, it can point to PK00 signature | ||||
UInt64 MarkerPos; /* Pos of first signature, it can point to kSpan/kNoSpan si | ||||
gnature | ||||
= MarkerPos2 in most archives | = MarkerPos2 in most archives | |||
= MarkerPos2 - 4 if there is PK00 signature */ | = MarkerPos2 - 4 if there is kSpan/kNoSpan signature */ | |||
UInt64 MarkerPos2; // Pos of first local item signature in stream | UInt64 MarkerPos2; // Pos of first local item signature in stream | |||
UInt64 FinishPos; // Finish pos of archive data | UInt64 FinishPos; // Finish pos of archive data in starting volume | |||
UInt64 FileEndPos; // Finish pos of stream | UInt64 FileEndPos; // Finish pos of stream | |||
UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base). | UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base). | |||
= 0 in most archives | = 0 in most archives | |||
= size of stub for some SFXs */ | = size of stub for some SFXs */ | |||
bool CdWasRead; | bool CdWasRead; | |||
bool IsSpanMode; | ||||
bool ThereIsTail; | ||||
CByteBuffer Comment; | // UInt32 BaseVolIndex; | |||
CInArchiveInfo(): Base(0), MarkerPos(0), MarkerPos2(0), FinishPos(0), FileEndP | CByteBuffer Comment; | |||
os(0), | ||||
FirstItemRelatOffset(0), CdWasRead(false) {} | ||||
UInt64 GetPhySize() const { return FinishPos - Base; } | CInArchiveInfo(): | |||
UInt64 GetEmbeddedStubSize() const | Base(0), | |||
{ | MarkerPos(0), | |||
if (CdWasRead) | MarkerPos2(0), | |||
return FirstItemRelatOffset; | FinishPos(0), | |||
return MarkerPos2 - Base; | FileEndPos(0), | |||
} | FirstItemRelatOffset(0), | |||
bool ThereIsTail() const { return FileEndPos > FinishPos; } | CdWasRead(false), | |||
IsSpanMode(false), | ||||
ThereIsTail(false) | ||||
// BaseVolIndex(0) | ||||
{} | ||||
void Clear() | void Clear() | |||
{ | { | |||
// BaseVolIndex = 0; | ||||
Base = 0; | Base = 0; | |||
MarkerPos = 0; | MarkerPos = 0; | |||
MarkerPos2 = 0; | MarkerPos2 = 0; | |||
FinishPos = 0; | FinishPos = 0; | |||
FileEndPos = 0; | FileEndPos = 0; | |||
ThereIsTail = false; | ||||
FirstItemRelatOffset = 0; | FirstItemRelatOffset = 0; | |||
CdWasRead = false; | CdWasRead = false; | |||
IsSpanMode = false; | ||||
Comment.Free(); | Comment.Free(); | |||
} | } | |||
}; | }; | |||
struct CProgressVirt | ||||
{ | ||||
virtual HRESULT SetCompletedLocal(UInt64 numFiles, UInt64 numBytes) = 0; | ||||
virtual HRESULT SetTotalCD(UInt64 numFiles) = 0; | ||||
virtual HRESULT SetCompletedCD(UInt64 numFiles) = 0; | ||||
}; | ||||
struct CCdInfo | struct CCdInfo | |||
{ | { | |||
// 64 | ||||
UInt16 VersionMade; | ||||
UInt16 VersionNeedExtract; | ||||
// old zip | ||||
UInt32 ThisDisk; | ||||
UInt32 CdDisk; | ||||
UInt64 NumEntries_in_ThisDisk; | ||||
UInt64 NumEntries; | UInt64 NumEntries; | |||
UInt64 Size; | UInt64 Size; | |||
UInt64 Offset; | UInt64 Offset; | |||
void ParseEcd(const Byte *p); | UInt16 CommentSize; | |||
void ParseEcd64(const Byte *p); | ||||
CCdInfo() { memset(this, 0, sizeof(*this)); } | ||||
void ParseEcd32(const Byte *p); // (p) includes signature | ||||
void ParseEcd64e(const Byte *p); // (p) exclude signature | ||||
}; | ||||
class CVols | ||||
{ | ||||
public: | ||||
struct CSubStreamInfo | ||||
{ | ||||
CMyComPtr<IInStream> Stream; | ||||
UInt64 Size; | ||||
CSubStreamInfo(): Size(0) {} | ||||
}; | ||||
CObjectVector<CSubStreamInfo> Streams; | ||||
int StreamIndex; | ||||
bool NeedSeek; | ||||
CMyComPtr<IInStream> ZipStream; | ||||
bool StartIsExe; // is .exe | ||||
bool StartIsZ; // is .zip or .zNN | ||||
bool StartIsZip; // is .zip | ||||
bool IsUpperCase; | ||||
Int32 StartVolIndex; // = (NN - 1), if StartStream is .zNN | ||||
Int32 StartParsingVol; // if we need local parsing, we must use that stream | ||||
unsigned NumVols; | ||||
int EndVolIndex; // index of last volume (ecd volume), | ||||
// -1, if is not multivol | ||||
UString BaseName; // including '.' | ||||
UString MissingName; | ||||
CCdInfo ecd; | ||||
bool ecd_wasRead; | ||||
void Clear() | ||||
{ | ||||
StreamIndex = -1; | ||||
NeedSeek = false; | ||||
StartIsExe = false; | ||||
StartIsZ = false; | ||||
StartIsZip = false; | ||||
IsUpperCase = false; | ||||
StartVolIndex = -1; | ||||
StartParsingVol = 0; | ||||
NumVols = 0; | ||||
EndVolIndex = -1; | ||||
BaseName.Empty(); | ||||
MissingName.Empty(); | ||||
ecd_wasRead = false; | ||||
Streams.Clear(); | ||||
ZipStream.Release(); | ||||
} | ||||
HRESULT ParseArcName(IArchiveOpenVolumeCallback *volCallback); | ||||
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); | ||||
UInt64 GetTotalSize() const | ||||
{ | ||||
UInt64 total = 0; | ||||
FOR_VECTOR (i, Streams) | ||||
total += Streams[i].Size; | ||||
return total; | ||||
} | ||||
}; | ||||
class CVolStream: | ||||
public ISequentialInStream, | ||||
public CMyUnknownImp | ||||
{ | ||||
public: | ||||
CVols *Vols; | ||||
MY_UNKNOWN_IMP1(ISequentialInStream) | ||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); | ||||
}; | }; | |||
class CInArchive | class CInArchive | |||
{ | { | |||
CInBuffer _inBuffer; | CInBuffer _inBuffer; | |||
bool _inBufMode; | bool _inBufMode; | |||
UInt32 m_Signature; | UInt32 m_Signature; | |||
UInt64 m_Position; | UInt64 m_Position; | |||
UInt64 _processedCnt; | ||||
bool CanStartNewVol; | ||||
CMyComPtr<IInStream> StreamRef; | ||||
IInStream *Stream; | ||||
IInStream *StartStream; | ||||
bool IsArcOpen; | ||||
HRESULT ReadVols2(IArchiveOpenVolumeCallback *volCallback, | ||||
unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, uns | ||||
igned &numMissingVols); | ||||
HRESULT ReadVols(); | ||||
HRESULT Seek(UInt64 offset); | HRESULT Seek(UInt64 offset); | |||
HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLim | HRESULT FindMarker(IInStream *stream, const UInt64 *searchLimit); | |||
it); | HRESULT IncreaseRealPosition(Int64 addValue, bool &isFinished); | |||
HRESULT IncreaseRealPosition(Int64 addValue); | ||||
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); | HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); | |||
void SafeReadBytes(void *data, unsigned size); | void SafeReadBytes(void *data, unsigned size); | |||
void ReadBuffer(CByteBuffer &buffer, unsigned size); | void ReadBuffer(CByteBuffer &buffer, unsigned size); | |||
Byte ReadByte(); | Byte ReadByte(); | |||
UInt16 ReadUInt16(); | UInt16 ReadUInt16(); | |||
UInt32 ReadUInt32(); | UInt32 ReadUInt32(); | |||
UInt64 ReadUInt64(); | UInt64 ReadUInt64(); | |||
void Skip(unsigned num); | void Skip(unsigned num); | |||
void Skip64(UInt64 num); | void Skip64(UInt64 num); | |||
void ReadFileName(unsigned nameSize, AString &dest); | void ReadFileName(unsigned nameSize, AString &dest); | |||
bool ReadExtra(unsigned extraSize, CExtraBlock &extraBlock, | bool ReadExtra(unsigned extraSize, CExtraBlock &extraBlock, | |||
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &d iskStartNumber); | UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &d iskStartNumber); | |||
bool ReadLocalItem(CItemEx &item); | bool ReadLocalItem(CItemEx &item); | |||
HRESULT ReadLocalItemDescriptor(CItemEx &item); | HRESULT ReadLocalItemDescriptor(CItemEx &item); | |||
HRESULT ReadCdItem(CItemEx &item); | HRESULT ReadCdItem(CItemEx &item); | |||
HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); | HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); | |||
HRESULT FindCd(CCdInfo &cdInfo); | HRESULT FindCd(bool checkOffsetMode); | |||
HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSiz | HRESULT TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 | |||
e, CProgressVirt *progress); | cdOffset, UInt64 cdSize); | |||
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize | HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64 &cdOffset | |||
, CProgressVirt *progress); | , UInt64 &cdSize); | |||
HRESULT ReadLocals(CObjectVector<CItemEx> &localItems, CProgressVirt *progress | HRESULT ReadLocals(CObjectVector<CItemEx> &localItems); | |||
); | ||||
HRESULT ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *progress); | HRESULT ReadHeaders2(CObjectVector<CItemEx> &items); | |||
HRESULT GetVolStream(unsigned vol, UInt64 pos, CMyComPtr<ISequentialInStream> | ||||
&stream); | ||||
public: | public: | |||
CInArchiveInfo ArcInfo; | CInArchiveInfo ArcInfo; | |||
bool IsArc; | bool IsArc; | |||
bool IsZip64; | bool IsZip64; | |||
bool HeadersError; | bool HeadersError; | |||
bool HeadersWarning; | bool HeadersWarning; | |||
bool ExtraMinorError; | bool ExtraMinorError; | |||
bool UnexpectedEnd; | bool UnexpectedEnd; | |||
bool NoCentralDir; | bool NoCentralDir; | |||
CMyComPtr<IInStream> Stream; | bool MarkerIsFound; | |||
bool IsMultiVol; | ||||
bool UseDisk_in_SingleVol; | ||||
UInt32 EcdVolIndex; | ||||
CVols Vols; | ||||
IArchiveOpenCallback *Callback; | ||||
CInArchive(): Stream(NULL), Callback(NULL), IsArcOpen(false) {} | ||||
UInt64 GetPhySize() const | ||||
{ | ||||
if (IsMultiVol) | ||||
return ArcInfo.FinishPos; | ||||
else | ||||
return ArcInfo.FinishPos - ArcInfo.Base; | ||||
} | ||||
UInt64 GetOffset() const | ||||
{ | ||||
if (IsMultiVol) | ||||
return 0; | ||||
else | ||||
return ArcInfo.Base; | ||||
} | ||||
void ClearRefs(); | ||||
void Close(); | void Close(); | |||
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); | HRESULT Open(IInStream *stream, const UInt64 *searchLimit, IArchiveOpenCallbac | |||
HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress); | k *callback, CObjectVector<CItemEx> &items); | |||
HRESULT ReadHeaders(CObjectVector<CItemEx> &items); | ||||
bool IsOpen() const { return Stream != NULL; } | bool IsOpen() const { return IsArcOpen; } | |||
bool AreThereErrors() const { return HeadersError || UnexpectedEnd; } | ||||
bool AreThereErrors() const | ||||
{ | ||||
return HeadersError | ||||
|| UnexpectedEnd | ||||
|| !Vols.MissingName.IsEmpty(); | ||||
} | ||||
bool IsLocalOffsetOK(const CItemEx &item) const | bool IsLocalOffsetOK(const CItemEx &item) const | |||
{ | { | |||
if (item.FromLocal) | if (item.FromLocal) | |||
return true; | return true; | |||
return /* ArcInfo.Base >= 0 || */ ArcInfo.Base + (Int64)item.LocalHeaderPos | return (Int64)GetOffset() + (Int64)item.LocalHeaderPos >= 0; | |||
>= 0; | } | |||
UInt64 GetEmbeddedStubSize() const | ||||
{ | ||||
if (ArcInfo.CdWasRead) | ||||
return ArcInfo.FirstItemRelatOffset; | ||||
if (IsMultiVol) | ||||
return 0; | ||||
return ArcInfo.MarkerPos2 - ArcInfo.Base; | ||||
} | } | |||
HRESULT ReadLocalItemAfterCdItem(CItemEx &item); | HRESULT ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail); | |||
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); | HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); | |||
ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); | HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr<ISeque ntialInStream> &stream); | |||
UInt64 GetOffsetInStream(UInt64 offsetFromArc) const { return ArcInfo.Base + o ffsetFromArc; } | IInStream *GetBaseStream() { return StreamRef; } | |||
bool CanUpdate() const | bool CanUpdate() const | |||
{ | { | |||
if (AreThereErrors()) | if (AreThereErrors() | |||
return false; | || IsMultiVol | |||
if (ArcInfo.Base < 0) | || ArcInfo.Base < 0 | |||
return false; | || (Int64)ArcInfo.MarkerPos2 < ArcInfo.Base | |||
if ((Int64)ArcInfo.MarkerPos2 < ArcInfo.Base) | || ArcInfo.ThereIsTail | |||
|| GetEmbeddedStubSize() != 0) | ||||
return false; | return false; | |||
// 7-zip probably can update archives with embedded stubs. | // 7-zip probably can update archives with embedded stubs. | |||
// we just disable that feature for more safety. | // we just disable that feature for more safety. | |||
if (ArcInfo.GetEmbeddedStubSize() != 0) | ||||
return false; | ||||
if (ArcInfo.ThereIsTail()) | ||||
return false; | ||||
return true; | return true; | |||
} | } | |||
}; | }; | |||
}} | }} | |||
#endif | #endif | |||
End of changes. 29 change blocks. | ||||
54 lines changed or deleted | 210 lines changed or added |