diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2007-07-24 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:52 +0300 |
commit | 980e181dcc9d64312a4dddfa58f80770506f27f5 (patch) | |
tree | 4ab20c1b4c7ebfe0f5fbf39ec2ce2cd3022ebf66 /CPP/7zip/Archive | |
parent | 7038848692e7049234f223703522681a19db49a5 (diff) |
4.50 beta
Diffstat (limited to 'CPP/7zip/Archive')
29 files changed, 618 insertions, 1038 deletions
diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h index 95e53340..1006f204 100755 --- a/CPP/7zip/Archive/7z/7zHandler.h +++ b/CPP/7zip/Archive/7z/7zHandler.h @@ -25,17 +25,6 @@ struct CRef int ItemIndex; }; -/* -struct CRef2 -{ - CRecordVector<CRef> Refs; - UInt64 UnPackSize; - UInt64 PackSize; - UInt64 StartPos; - CRef2(): UnPackSize(0), PackSize(0), StartPos(0) {} -}; -*/ - struct CVolume { int StartRef2Index; @@ -44,10 +33,6 @@ struct CVolume }; #endif -// {23170F69-40C1-278A-1000-000110070000} -DEFINE_GUID(CLSID_CFormat7z, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); - #ifndef __7Z_SET_PROPERTIES #ifdef EXTRACT_ONLY @@ -93,26 +78,7 @@ public: MY_QUERYINTERFACE_END MY_ADDREF_RELEASE - - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) #ifdef _7Z_VOL STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); @@ -123,14 +89,7 @@ public: #endif #ifndef EXTRACT_ONLY - // IOutArchiveHandler - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback); - - STDMETHOD(GetFileTimeType)(UInt32 *type); - - // ISetProperties - + INTERFACE_IOutArchive(;) #endif DECL_ISetCompressCodecsInfo diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp index c9150898..4f867708 100755 --- a/CPP/7zip/Archive/7z/7zIn.cpp +++ b/CPP/7zip/Archive/7z/7zIn.cpp @@ -19,6 +19,35 @@ extern "C" namespace NArchive { namespace N7z { +class CInArchiveException {}; + +static void ThrowException() { throw CInArchiveException(); } +static inline void ThrowEndOfData() { ThrowException(); } +static inline void ThrowUnsupported() { ThrowException(); } +static inline void ThrowIncorrect() { ThrowException(); } +static inline void ThrowUnsupportedVersion() { ThrowException(); } + +/* +class CInArchiveException +{ +public: + enum CCauseType + { + kUnsupportedVersion = 0, + kUnsupported, + kIncorrect, + kEndOfData, + } Cause; + CInArchiveException(CCauseType cause): Cause(cause) {}; +}; + +static void ThrowException(CInArchiveException::CCauseType c) { throw CInArchiveException(c); } +static void ThrowEndOfData() { ThrowException(CInArchiveException::kEndOfData); } +static void ThrowUnsupported() { ThrowException(CInArchiveException::kUnsupported); } +static void ThrowIncorrect() { ThrowException(CInArchiveException::kIncorrect); } +static void ThrowUnsupportedVersion() { ThrowException(CInArchiveException::kUnsupportedVersion); } +*/ + class CStreamSwitch { CInArchive *_archive; @@ -29,7 +58,7 @@ public: void Remove(); void Set(CInArchive *archive, const Byte *data, size_t size); void Set(CInArchive *archive, const CByteBuffer &byteBuffer); - HRESULT Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector); + void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector); }; void CStreamSwitch::Remove() @@ -54,174 +83,156 @@ void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) Set(archive, byteBuffer, byteBuffer.GetCapacity()); } -HRESULT CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector) +void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector) { Remove(); - Byte external; - RINOK(archive->ReadByte(external)); + Byte external = archive->ReadByte(); if (external != 0) { - CNum dataIndex; - RINOK(archive->ReadNum(dataIndex)); + int dataIndex = (int)archive->ReadNum(); + if (dataIndex < 0 || dataIndex >= dataVector->Size()) + ThrowIncorrect(); Set(archive, (*dataVector)[dataIndex]); } - return S_OK; } - -CInArchiveException::CInArchiveException(CCauseType cause): - Cause(cause) -{} +#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) +#define SZ_LITTLE_ENDIAN_UNALIGN +#endif -HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size, - UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = ReadStream(stream, data, size, &realProcessedSize); - if(processedSize != NULL) - *processedSize = realProcessedSize; - _position += realProcessedSize; - return result; -} +#ifdef SZ_LITTLE_ENDIAN_UNALIGN +static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; } +static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; } +static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; } +#else +static inline UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); } +static inline UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); } +static inline UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); } +#endif -HRESULT CInArchive::ReadDirect(void *data, UInt32 size, UInt32 *processedSize) +Byte CInByte2::ReadByte() { - return ReadDirect(_stream, data, size, processedSize); + if (_pos >= _size) + ThrowEndOfData(); + return _buffer[_pos++]; } -HRESULT CInArchive::SafeReadDirect(void *data, UInt32 size) +void CInByte2::ReadBytes(Byte *data, size_t size) { - UInt32 realProcessedSize; - RINOK(ReadDirect(data, size, &realProcessedSize)); - if (realProcessedSize != size) - throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); - return S_OK; + if (size > _size - _pos) + ThrowEndOfData(); + for (size_t i = 0; i < size; i++) + data[i] = _buffer[_pos++]; } -HRESULT CInArchive::SafeReadDirectByte(Byte &b) +void CInByte2::SkeepData(UInt64 size) { - return SafeReadDirect(&b, 1); + if (size > _size - _pos) + ThrowEndOfData(); } -HRESULT CInArchive::SafeReadDirectUInt32(UInt32 &value, UInt32 &crc) +void CInByte2::SkeepData() { - value = 0; - for (int i = 0; i < 4; i++) - { - Byte b; - RINOK(SafeReadDirectByte(b)); - value |= (UInt32(b) << (8 * i)); - crc = CRC_UPDATE_BYTE(crc, b); - } - return S_OK; + SkeepData(ReadNumber()); } -HRESULT CInArchive::SafeReadDirectUInt64(UInt64 &value, UInt32 &crc) +UInt64 CInByte2::ReadNumber() { - value = 0; - for (int i = 0; i < 8; i++) - { - Byte b; - RINOK(SafeReadDirectByte(b)); - value |= (UInt64(b) << (8 * i)); - crc = CRC_UPDATE_BYTE(crc, b); - } - return S_OK; -} - -HRESULT CInArchive::ReadNumber(UInt64 &value) -{ - Byte firstByte; - RINOK(ReadByte(firstByte)); + if (_pos >= _size) + ThrowEndOfData(); + Byte firstByte = _buffer[_pos++]; Byte mask = 0x80; - value = 0; + UInt64 value = 0; for (int i = 0; i < 8; i++) { if ((firstByte & mask) == 0) { UInt64 highPart = firstByte & (mask - 1); value += (highPart << (i * 8)); - return S_OK; + return value; } - Byte b; - RINOK(ReadByte(b)); - value |= (UInt64(b) << (8 * i)); + if (_pos >= _size) + ThrowEndOfData(); + value |= ((UInt64)_buffer[_pos++] << (8 * i)); mask >>= 1; } - return S_OK; + return value; } -HRESULT CInArchive::ReadNum(CNum &value) +CNum CInByte2::ReadNum() { - UInt64 value64; - RINOK(ReadNumber(value64)); - if (value64 > kNumMax) - return E_FAIL; - value = (CNum)value64; - return S_OK; + UInt64 value = ReadNumber(); + if (value > kNumMax) + ThrowUnsupported(); + return (CNum)value; } -HRESULT CInArchive::ReadUInt32(UInt32 &value) +UInt32 CInByte2::ReadUInt32() { - value = 0; - for (int i = 0; i < 4; i++) - { - Byte b; - RINOK(ReadByte(b)); - value |= (UInt32(b) << (8 * i)); - } - return S_OK; + if (_pos + 4 > _size) + ThrowEndOfData(); + UInt32 res = GetUInt32FromMem(_buffer + _pos); + _pos += 4; + return res; } -HRESULT CInArchive::ReadUInt64(UInt64 &value) +UInt64 CInByte2::ReadUInt64() { - value = 0; - for (int i = 0; i < 8; i++) - { - Byte b; - RINOK(ReadByte(b)); - value |= (UInt64(b) << (8 * i)); - } - return S_OK; + if (_pos + 8 > _size) + ThrowEndOfData(); + UInt64 res = GetUInt64FromMem(_buffer + _pos); + _pos += 8; + return res; } -static inline bool TestSignatureCandidate(const void *testBytes) +void CInByte2::ReadString(UString &s) { - for (int i = 0; i < kSignatureSize; i++) - if (((const Byte *)testBytes)[i] != kSignature[i]) - return false; - return true; + const Byte *buf = _buffer + _pos; + size_t rem = (_size - _pos) / 2; + { + size_t i; + for (i = 0; i < rem; i += 2) + if (buf[i] == 0 && buf[i + 1] == 0) + break; + if (i == rem) + ThrowEndOfData(); + rem = i; + } + int len = (int)(rem / 2); + if (len < 0 || (size_t)len * 2 != rem) + ThrowUnsupported(); + wchar_t *p = s.GetBuffer(len); + int i; + for (i = 0; i < len; i++, buf += 2) + p[i] = (wchar_t)GetUInt16FromMem(buf); + p[i] = 0; + s.ReleaseBuffer(len); + _pos += rem + 2; } -#ifdef _7Z_VOL -static inline bool TestFinishSignatureCandidate(const void *testBytes) +static inline bool TestSignatureCandidate(const Byte *p) { for (int i = 0; i < kSignatureSize; i++) - if (((const Byte *)testBytes)[i] != kFinishSignature[i]) + if (p[i] != kSignature[i]) return false; - return true; + return (p[0x1A] == 0 && p[0x1B] == 0); } -#endif HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { - _position = _arhiveBeginStreamPosition; - RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL)); - - Byte signature[kSignatureSize]; UInt32 processedSize; - RINOK(ReadDirect(stream, signature, kSignatureSize, &processedSize)); - if(processedSize != kSignatureSize) + RINOK(ReadStream(stream, _header, kHeaderSize, &processedSize)); + if (processedSize != kHeaderSize) return S_FALSE; - if (TestSignatureCandidate(signature)) + if (TestSignatureCandidate(_header)) return S_OK; CByteBuffer byteBuffer; const UInt32 kBufferSize = (1 << 16); byteBuffer.SetCapacity(kBufferSize); Byte *buffer = byteBuffer; - UInt32 numPrevBytes = kSignatureSize - 1; - memmove(buffer, signature + 1, numPrevBytes); + UInt32 numPrevBytes = kHeaderSize - 1; + memcpy(buffer, _header + 1, numPrevBytes); UInt64 curTestPos = _arhiveBeginStreamPosition + 1; for (;;) { @@ -229,18 +240,18 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit) break; UInt32 numReadBytes = kBufferSize - numPrevBytes; - RINOK(ReadDirect(stream, buffer + numPrevBytes, numReadBytes, &processedSize)); + RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); UInt32 numBytesInBuffer = numPrevBytes + processedSize; - if (numBytesInBuffer < kSignatureSize) + if (numBytesInBuffer < kHeaderSize) break; - UInt32 numTests = numBytesInBuffer - kSignatureSize + 1; + UInt32 numTests = numBytesInBuffer - kHeaderSize + 1; for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) { if (TestSignatureCandidate(buffer + pos)) { + memcpy(_header, buffer + pos, kHeaderSize); _arhiveBeginStreamPosition = curTestPos; - _position = curTestPos + kSignatureSize; - return stream->Seek(_position, STREAM_SEEK_SET, NULL); + return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL); } } numPrevBytes = numBytesInBuffer - numTests; @@ -249,76 +260,12 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search return S_FALSE; } -// Out: _position must point to end of signature - -#ifdef _7Z_VOL -HRESULT CInArchive::FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) -{ - RINOK(stream->Seek(0, STREAM_SEEK_END, &_position)); - if (_position < kSignatureSize) - return S_FALSE; - - CByteBuffer byteBuffer; - const UInt32 kBufferSize = (1 << 18); - byteBuffer.SetCapacity(kBufferSize); - Byte *buffer = byteBuffer; - UInt32 numPrevBytes = 0; - UInt64 limitPos = 0; - if (searchHeaderSizeLimit != NULL) - if (*searchHeaderSizeLimit < _position) - limitPos = _position - *searchHeaderSizeLimit; - - while(_position >= limitPos) - { - UInt32 numReadBytes = kBufferSize - numPrevBytes; - if (numReadBytes > _position) - numReadBytes = (UInt32)_position; - UInt32 numBytesInBuffer = numPrevBytes + numReadBytes; - if (numBytesInBuffer < kSignatureSize) - return S_FALSE; - _position -= numReadBytes; - RINOK(stream->Seek(_position, STREAM_SEEK_SET, &_position)); - UInt32 startPos = kBufferSize - numBytesInBuffer; - UInt32 processedSize; - RINOK(ReadDirect(stream, buffer + startPos, numReadBytes, &processedSize)); - if (processedSize != numReadBytes) - return S_FALSE; - _position -= processedSize; - for(UInt32 pos = kBufferSize; pos >= startPos + kSignatureSize; pos--) - { - if (TestFinishSignatureCandidate(buffer + pos - kSignatureSize)) - { - _position += pos - startPos; - return stream->Seek(_position, STREAM_SEEK_SET, NULL); - } - } - numPrevBytes = kSignatureSize - 1; - memmove(buffer + kBufferSize - numPrevBytes, buffer + startPos + 1, numPrevBytes); - } - return S_FALSE; -} -#endif - // S_FALSE means that file is not archive HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { Close(); RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) - _position = _arhiveBeginStreamPosition; - #ifdef _7Z_VOL - HRESULT result = FindFinishSignature(stream, searchHeaderSizeLimit); - if (result == S_OK) - _finishSignature = true; - else - { - if (result != S_FALSE) - return result; - _finishSignature = false; - RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); - } - #else RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); - #endif _stream = stream; return S_OK; } @@ -328,40 +275,19 @@ void CInArchive::Close() _stream.Release(); } -HRESULT CInArchive::SkeepData(UInt64 size) -{ - for (UInt64 i = 0; i < size; i++) - { - Byte temp; - RINOK(ReadByte(temp)); - } - return S_OK; -} - -HRESULT CInArchive::SkeepData() -{ - UInt64 size; - RINOK(ReadNumber(size)); - return SkeepData(size); -} - -HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) +void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) { for (;;) { - UInt64 type; - RINOK(ReadID(type)); - if (type == NID::kEnd) + if (ReadID() == NID::kEnd) break; SkeepData(); } - return S_OK; } -HRESULT CInArchive::GetNextFolderItem(CFolder &folder) +void CInArchive::GetNextFolderItem(CFolder &folder) { - CNum numCoders; - RINOK(ReadNum(numCoders)); + CNum numCoders = ReadNum(); folder.Coders.Clear(); folder.Coders.Reserve((int)numCoders); @@ -374,13 +300,12 @@ HRESULT CInArchive::GetNextFolderItem(CFolder &folder) CCoderInfo &coder = folder.Coders.Back(); { - Byte mainByte = 0; - RINOK(ReadByte(mainByte)); + Byte mainByte = ReadByte(); int idSize = (mainByte & 0xF); - BYTE longID[15]; - RINOK(ReadBytes(longID, idSize)); + Byte longID[15]; + ReadBytes(longID, idSize); if (idSize > 8) - return S_FALSE; + ThrowUnsupported(); UInt64 id = 0; for (int j = 0; j < idSize; j++) id |= (UInt64)longID[idSize - 1 - j] << (8 * j); @@ -388,8 +313,8 @@ HRESULT CInArchive::GetNextFolderItem(CFolder &folder) if ((mainByte & 0x10) != 0) { - RINOK(ReadNum(coder.NumInStreams)); - RINOK(ReadNum(coder.NumOutStreams)); + coder.NumInStreams = ReadNum(); + coder.NumOutStreams = ReadNum(); } else { @@ -398,28 +323,26 @@ HRESULT CInArchive::GetNextFolderItem(CFolder &folder) } if ((mainByte & 0x20) != 0) { - CNum propertiesSize = 0; - RINOK(ReadNum(propertiesSize)); + CNum propertiesSize = ReadNum(); coder.Properties.SetCapacity((size_t)propertiesSize); - RINOK(ReadBytes((Byte *)coder.Properties, (size_t)propertiesSize)); + ReadBytes((Byte *)coder.Properties, (size_t)propertiesSize); } if ((mainByte & 0x80) != 0) - return S_FALSE; + ThrowUnsupported(); } numInStreams += coder.NumInStreams; numOutStreams += coder.NumOutStreams; } CNum numBindPairs; - // RINOK(ReadNumber(numBindPairs)); numBindPairs = numOutStreams - 1; folder.BindPairs.Clear(); folder.BindPairs.Reserve(numBindPairs); for (i = 0; i < numBindPairs; i++) { CBindPair bindPair; - RINOK(ReadNum(bindPair.InIndex)); - RINOK(ReadNum(bindPair.OutIndex)); + bindPair.InIndex = ReadNum(); + bindPair.OutIndex = ReadNum(); folder.BindPairs.Add(bindPair); } @@ -436,78 +359,65 @@ HRESULT CInArchive::GetNextFolderItem(CFolder &folder) } else for(i = 0; i < numPackedStreams; i++) - { - CNum packStreamInfo; - RINOK(ReadNum(packStreamInfo)); - folder.PackStreams.Add(packStreamInfo); - } - - return S_OK; + folder.PackStreams.Add(ReadNum()); } -HRESULT CInArchive::WaitAttribute(UInt64 attribute) +void CInArchive::WaitAttribute(UInt64 attribute) { for (;;) { - UInt64 type; - RINOK(ReadID(type)); + UInt64 type = ReadID(); if (type == attribute) - return S_OK; + return; if (type == NID::kEnd) - return S_FALSE; - RINOK(SkeepData()); + ThrowIncorrect(); + SkeepData(); } } -HRESULT CInArchive::ReadHashDigests(int numItems, +void CInArchive::ReadHashDigests(int numItems, CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests) { - RINOK(ReadBoolVector2(numItems, digestsDefined)); + ReadBoolVector2(numItems, digestsDefined); digests.Clear(); digests.Reserve(numItems); for(int i = 0; i < numItems; i++) { UInt32 crc = 0; if (digestsDefined[i]) - RINOK(ReadUInt32(crc)); + crc = ReadUInt32(); digests.Add(crc); } - return S_OK; } -HRESULT CInArchive::ReadPackInfo( +void CInArchive::ReadPackInfo( UInt64 &dataOffset, CRecordVector<UInt64> &packSizes, CRecordVector<bool> &packCRCsDefined, CRecordVector<UInt32> &packCRCs) { - RINOK(ReadNumber(dataOffset)); - CNum numPackStreams; - RINOK(ReadNum(numPackStreams)); + dataOffset = ReadNumber(); + CNum numPackStreams = ReadNum(); - RINOK(WaitAttribute(NID::kSize)); + WaitAttribute(NID::kSize); packSizes.Clear(); packSizes.Reserve(numPackStreams); - for(CNum i = 0; i < numPackStreams; i++) - { - UInt64 size; - RINOK(ReadNumber(size)); - packSizes.Add(size); - } + for (CNum i = 0; i < numPackStreams; i++) + packSizes.Add(ReadNumber()); UInt64 type; for (;;) { - RINOK(ReadID(type)); + type = ReadID(); if (type == NID::kEnd) break; if (type == NID::kCRC) { - RINOK(ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs)); + ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs); continue; } - RINOK(SkeepData()); + SkeepData(); } if (packCRCsDefined.IsEmpty()) { @@ -521,56 +431,49 @@ HRESULT CInArchive::ReadPackInfo( packCRCs.Add(0); } } - return S_OK; } -HRESULT CInArchive::ReadUnPackInfo( +void CInArchive::ReadUnPackInfo( const CObjectVector<CByteBuffer> *dataVector, CObjectVector<CFolder> &folders) { - RINOK(WaitAttribute(NID::kFolder)); - CNum numFolders; - RINOK(ReadNum(numFolders)); + WaitAttribute(NID::kFolder); + CNum numFolders = ReadNum(); { CStreamSwitch streamSwitch; - RINOK(streamSwitch.Set(this, dataVector)); + streamSwitch.Set(this, dataVector); folders.Clear(); - folders.Reserve((UInt32)numFolders); + folders.Reserve(numFolders); for(CNum i = 0; i < numFolders; i++) { folders.Add(CFolder()); - RINOK(GetNextFolderItem(folders.Back())); + GetNextFolderItem(folders.Back()); } } - RINOK(WaitAttribute(NID::kCodersUnPackSize)); + WaitAttribute(NID::kCodersUnPackSize); CNum i; - for(i = 0; i < numFolders; i++) + for (i = 0; i < numFolders; i++) { CFolder &folder = folders[i]; CNum numOutStreams = folder.GetNumOutStreams(); folder.UnPackSizes.Reserve(numOutStreams); - for(CNum j = 0; j < numOutStreams; j++) - { - UInt64 unPackSize; - RINOK(ReadNumber(unPackSize)); - folder.UnPackSizes.Add(unPackSize); - } + for (CNum j = 0; j < numOutStreams; j++) + folder.UnPackSizes.Add(ReadNumber()); } for (;;) { - UInt64 type; - RINOK(ReadID(type)); + UInt64 type = ReadID(); if (type == NID::kEnd) - return S_OK; + return; if (type == NID::kCRC) { CRecordVector<bool> crcsDefined; CRecordVector<UInt32> crcs; - RINOK(ReadHashDigests(numFolders, crcsDefined, crcs)); + ReadHashDigests(numFolders, crcsDefined, crcs); for(i = 0; i < numFolders; i++) { CFolder &folder = folders[i]; @@ -579,11 +482,11 @@ HRESULT CInArchive::ReadUnPackInfo( } continue; } - RINOK(SkeepData()); + SkeepData(); } } -HRESULT CInArchive::ReadSubStreamsInfo( +void CInArchive::ReadSubStreamsInfo( const CObjectVector<CFolder> &folders, CRecordVector<CNum> &numUnPackStreamsInFolders, CRecordVector<UInt64> &unPackSizes, @@ -595,22 +498,18 @@ HRESULT CInArchive::ReadSubStreamsInfo( UInt64 type; for (;;) { - RINOK(ReadID(type)); + type = ReadID(); if (type == NID::kNumUnPackStream) { for(int i = 0; i < folders.Size(); i++) - { - CNum value; - RINOK(ReadNum(value)); - numUnPackStreamsInFolders.Add(value); - } + numUnPackStreamsInFolders.Add(ReadNum()); continue; } if (type == NID::kCRC || type == NID::kSize) break; if (type == NID::kEnd) break; - RINOK(SkeepData()); + SkeepData(); } if (numUnPackStreamsInFolders.IsEmpty()) @@ -627,21 +526,16 @@ HRESULT CInArchive::ReadSubStreamsInfo( continue; UInt64 sum = 0; for (CNum j = 1; j < numSubstreams; j++) - { - UInt64 size; if (type == NID::kSize) { - RINOK(ReadNumber(size)); + UInt64 size = ReadNumber(); unPackSizes.Add(size); sum += size; } - } unPackSizes.Add(folders[i].GetUnPackSize() - sum); } if (type == NID::kSize) - { - RINOK(ReadID(type)); - } + type = ReadID(); int numDigests = 0; int numDigestsTotal = 0; @@ -659,7 +553,7 @@ HRESULT CInArchive::ReadSubStreamsInfo( { CRecordVector<bool> digestsDefined2; CRecordVector<UInt32> digests2; - RINOK(ReadHashDigests(numDigests, digestsDefined2, digests2)); + ReadHashDigests(numDigests, digestsDefined2, digests2); int digestIndex = 0; for (i = 0; i < folders.Size(); i++) { @@ -690,17 +584,15 @@ HRESULT CInArchive::ReadSubStreamsInfo( digests.Add(0); } } - return S_OK; + return; } else - { - RINOK(SkeepData()); - } - RINOK(ReadID(type)); + SkeepData(); + type = ReadID(); } } -HRESULT CInArchive::ReadStreamsInfo( +void CInArchive::ReadStreamsInfo( const CObjectVector<CByteBuffer> *dataVector, UInt64 &dataOffset, CRecordVector<UInt64> &packSizes, @@ -714,52 +606,32 @@ HRESULT CInArchive::ReadStreamsInfo( { for (;;) { - UInt64 type; - RINOK(ReadID(type)); + UInt64 type = ReadID(); switch(type) { case NID::kEnd: - return S_OK; + return; case NID::kPackInfo: { - RINOK(ReadPackInfo(dataOffset, packSizes, - packCRCsDefined, packCRCs)); + ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs); break; } case NID::kUnPackInfo: { - RINOK(ReadUnPackInfo(dataVector, folders)); + ReadUnPackInfo(dataVector, folders); break; } case NID::kSubStreamsInfo: { - RINOK(ReadSubStreamsInfo(folders, numUnPackStreamsInFolders, - unPackSizes, digestsDefined, digests)); + ReadSubStreamsInfo(folders, numUnPackStreamsInFolders, + unPackSizes, digestsDefined, digests); break; } } } } -HRESULT CInArchive::ReadFileNames(CObjectVector<CFileItem> &files) -{ - for(int i = 0; i < files.Size(); i++) - { - UString &name = files[i].Name; - name.Empty(); - for (;;) - { - wchar_t c; - RINOK(ReadWideCharLE(c)); - if (c == L'\0') - break; - name += c; - } - } - return S_OK; -} - -HRESULT CInArchive::ReadBoolVector(int numItems, CBoolVector &v) +void CInArchive::ReadBoolVector(int numItems, CBoolVector &v) { v.Clear(); v.Reserve(numItems); @@ -769,36 +641,36 @@ HRESULT CInArchive::ReadBoolVector(int numItems, CBoolVector &v) { if (mask == 0) { - RINOK(ReadByte(b)); + b = ReadByte(); mask = 0x80; } v.Add((b & mask) != 0); mask >>= 1; } - return S_OK; } -HRESULT CInArchive::ReadBoolVector2(int numItems, CBoolVector &v) +void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v) { - Byte allAreDefined; - RINOK(ReadByte(allAreDefined)); + Byte allAreDefined = ReadByte(); if (allAreDefined == 0) - return ReadBoolVector(numItems, v); + { + ReadBoolVector(numItems, v); + return; + } v.Clear(); v.Reserve(numItems); for (int i = 0; i < numItems; i++) v.Add(true); - return S_OK; } -HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, +void CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, CObjectVector<CFileItem> &files, UInt64 type) { CBoolVector boolVector; - RINOK(ReadBoolVector2(files.Size(), boolVector)) + ReadBoolVector2(files.Size(), boolVector); CStreamSwitch streamSwitch; - RINOK(streamSwitch.Set(this, &dataVector)); + streamSwitch.Set(this, &dataVector); for(int i = 0; i < files.Size(); i++) { @@ -809,11 +681,8 @@ HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, bool defined = boolVector[i]; if (defined) { - UInt32 low, high; - RINOK(ReadUInt32(low)); - RINOK(ReadUInt32(high)); - fileTime.dwLowDateTime = low; - fileTime.dwHighDateTime = high; + fileTime.dwLowDateTime = ReadUInt32(); + fileTime.dwHighDateTime = ReadUInt32(); } switch(type) { @@ -834,7 +703,6 @@ HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector, break; } } - return S_OK; } HRESULT CInArchive::ReadAndDecodePackedStreams( @@ -856,7 +724,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( CRecordVector<bool> digestsDefined; CRecordVector<UInt32> digests; - RINOK(ReadStreamsInfo(NULL, + ReadStreamsInfo(NULL, dataOffset, packSizes, packCRCsDefined, @@ -865,7 +733,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( numUnPackStreamsInFolders, unPackSizes, digestsDefined, - digests)); + digests); // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; @@ -883,16 +751,15 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( const CFolder &folder = folders[i]; dataVector.Add(CByteBuffer()); CByteBuffer &data = dataVector.Back(); - UInt64 unPackSize = folder.GetUnPackSize(); - if (unPackSize > kNumMax) - return E_FAIL; - if (unPackSize > 0xFFFFFFFF) - return E_FAIL; - data.SetCapacity((size_t)unPackSize); + UInt64 unPackSize64 = folder.GetUnPackSize(); + size_t unPackSize = (size_t)unPackSize64; + if (unPackSize != unPackSize64) + ThrowUnsupported(); + data.SetCapacity(unPackSize); CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; - outStreamSpec->Init(data, (size_t)unPackSize); + outStreamSpec->Init(data, unPackSize); HRESULT result = decoder.Decode( EXTERNAL_CODECS_LOC_VARS @@ -908,8 +775,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( RINOK(result); if (folder.UnPackCRCDefined) - if (CrcCalc(data, (UInt32)unPackSize) != folder.UnPackCRC) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); + if (CrcCalc(data, unPackSize) != folder.UnPackCRC) + ThrowIncorrect(); for (int j = 0; j < folder.PackStreams.Size(); j++) dataStartPos += packSizes[packIndex++]; } @@ -924,13 +791,12 @@ HRESULT CInArchive::ReadHeader( #endif ) { - UInt64 type; - RINOK(ReadID(type)); + UInt64 type = ReadID(); if (type == NID::kArchiveProperties) { - RINOK(ReadArchiveProperties(database.ArchiveInfo)); - RINOK(ReadID(type)); + ReadArchiveProperties(database.ArchiveInfo); + type = ReadID(); } CObjectVector<CByteBuffer> dataVector; @@ -948,7 +814,7 @@ HRESULT CInArchive::ReadHeader( ); RINOK(result); database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; - RINOK(ReadID(type)); + type = ReadID(); } CRecordVector<UInt64> unPackSizes; @@ -957,7 +823,7 @@ HRESULT CInArchive::ReadHeader( if (type == NID::kMainStreamsInfo) { - RINOK(ReadStreamsInfo(&dataVector, + ReadStreamsInfo(&dataVector, database.ArchiveInfo.DataStartPosition, database.PackSizes, database.PackCRCsDefined, @@ -966,9 +832,9 @@ HRESULT CInArchive::ReadHeader( database.NumUnPackStreamsVector, unPackSizes, digestsDefined, - digests)); + digests); database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader; - RINOK(ReadID(type)); + type = ReadID(); } else { @@ -987,10 +853,9 @@ HRESULT CInArchive::ReadHeader( if (type == NID::kEnd) return S_OK; if (type != NID::kFilesInfo) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); + ThrowIncorrect(); - CNum numFiles; - RINOK(ReadNum(numFiles)); + CNum numFiles = ReadNum(); database.Files.Reserve(numFiles); CNum i; for(i = 0; i < numFiles; i++) @@ -1010,73 +875,56 @@ HRESULT CInArchive::ReadHeader( CBoolVector antiFileVector; CNum numEmptyStreams = 0; - // int sizePrev = -1; - // int posPrev = 0; - for (;;) { - /* - if (sizePrev >= 0) - if (sizePrev != _inByteBack->GetProcessedSize() - posPrev) - throw 2; - */ - UInt64 type; - RINOK(ReadID(type)); + UInt64 type = ReadID(); if (type == NID::kEnd) break; - UInt64 size; - RINOK(ReadNumber(size)); - - // sizePrev = size; - // posPrev = _inByteBack->GetProcessedSize(); - + UInt64 size = ReadNumber(); database.ArchiveInfo.FileInfoPopIDs.Add(type); switch(type) { case NID::kName: { CStreamSwitch streamSwitch; - RINOK(streamSwitch.Set(this, &dataVector)); - RINOK(ReadFileNames(database.Files)) + streamSwitch.Set(this, &dataVector); + for(int i = 0; i < database.Files.Size(); i++) + _inByteBack->ReadString(database.Files[i].Name); break; } case NID::kWinAttributes: { CBoolVector boolVector; - RINOK(ReadBoolVector2(database.Files.Size(), boolVector)) + ReadBoolVector2(database.Files.Size(), boolVector); CStreamSwitch streamSwitch; - RINOK(streamSwitch.Set(this, &dataVector)); + streamSwitch.Set(this, &dataVector); for(i = 0; i < numFiles; i++) { CFileItem &file = database.Files[i]; file.AreAttributesDefined = boolVector[i]; if (file.AreAttributesDefined) - { - RINOK(ReadUInt32(file.Attributes)); - } + file.Attributes = ReadUInt32(); } break; } case NID::kStartPos: { CBoolVector boolVector; - RINOK(ReadBoolVector2(database.Files.Size(), boolVector)) + ReadBoolVector2(database.Files.Size(), boolVector); CStreamSwitch streamSwitch; - RINOK(streamSwitch.Set(this, &dataVector)); + streamSwitch.Set(this, &dataVector); for(i = 0; i < numFiles; i++) { CFileItem &file = database.Files[i]; file.IsStartPosDefined = boolVector[i]; if (file.IsStartPosDefined) - { - RINOK(ReadUInt64(file.StartPos)); - } + file.StartPos = ReadUInt64(); } break; } case NID::kEmptyStream: { - RINOK(ReadBoolVector(numFiles, emptyStreamVector)) + ReadBoolVector(numFiles, emptyStreamVector); for (i = 0; i < (CNum)emptyStreamVector.Size(); i++) if (emptyStreamVector[i]) numEmptyStreams++; @@ -1091,25 +939,25 @@ HRESULT CInArchive::ReadHeader( } case NID::kEmptyFile: { - RINOK(ReadBoolVector(numEmptyStreams, emptyFileVector)) + ReadBoolVector(numEmptyStreams, emptyFileVector); break; } case NID::kAnti: { - RINOK(ReadBoolVector(numEmptyStreams, antiFileVector)) + ReadBoolVector(numEmptyStreams, antiFileVector); break; } case NID::kCreationTime: case NID::kLastWriteTime: case NID::kLastAccessTime: { - RINOK(ReadTime(dataVector, database.Files, type)) + ReadTime(dataVector, database.Files, type); break; } default: { database.ArchiveInfo.FileInfoPopIDs.DeleteBack(); - RINOK(SkeepData(size)); + SkeepData(size); } } } @@ -1191,7 +1039,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex() for (;;) { if (folderIndex >= Folders.Size()) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); + ThrowIncorrect(); FolderStartFileIndex.Add(i); // check it if (NumUnPackStreamsVector[folderIndex] != 0) break; @@ -1210,7 +1058,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex() } } -HRESULT CInArchive::ReadDatabase( +HRESULT CInArchive::ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS CArchiveDatabaseEx &database #ifndef _NO_CRYPTO @@ -1221,30 +1069,17 @@ HRESULT CInArchive::ReadDatabase( database.Clear(); database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; + database.ArchiveInfo.Version.Major = _header[6]; + database.ArchiveInfo.Version.Minor = _header[7]; - RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Major, 1)); - RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Minor, 1)); if (database.ArchiveInfo.Version.Major != kMajorVersion) - throw CInArchiveException(CInArchiveException::kUnsupportedVersion); - - #ifdef _7Z_VOL - if (_finishSignature) - { - RINOK(_stream->Seek(_position - (4 + kFinishHeaderSize) - - (kSignatureSize + 2), STREAM_SEEK_SET, &_position)); - } - #endif + ThrowUnsupportedVersion(); - UInt32 crcFromArchive; - UInt64 nextHeaderOffset; - UInt64 nextHeaderSize; - UInt32 nextHeaderCRC; - UInt32 crc = CRC_INIT_VAL; - UInt32 temp = 0; - RINOK(SafeReadDirectUInt32(crcFromArchive, temp)); - RINOK(SafeReadDirectUInt64(nextHeaderOffset, crc)); - RINOK(SafeReadDirectUInt64(nextHeaderSize, crc)); - RINOK(SafeReadDirectUInt32(nextHeaderCRC, crc)); + UInt32 crcFromArchive = GetUInt32FromMem(_header + 8); + UInt64 nextHeaderOffset = GetUInt64FromMem(_header + 0xC); + UInt64 nextHeaderSize = GetUInt64FromMem(_header + 0x14); + UInt32 nextHeaderCRC = GetUInt32FromMem(_header + 0x1C); + UInt32 crc = CrcCalc(_header + 0xC, 20); #ifdef FORMAT_7Z_RECOVERY if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) @@ -1260,7 +1095,7 @@ HRESULT CInArchive::ReadDatabase( RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2)); UInt32 realProcessedSize; - RINOK(ReadDirect(buf, (UInt32)kCheckSize, &realProcessedSize)); + RINOK(_stream->Read(buf, (UInt32)kCheckSize, &realProcessedSize)); int i; for (i = (int)realProcessedSize - 2; i >= 0; i--) @@ -1271,46 +1106,36 @@ HRESULT CInArchive::ReadDatabase( nextHeaderSize = realProcessedSize - i; nextHeaderOffset = cur2 - cur + i; nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); - RINOK(_stream->Seek(cur, STREAM_SEEK_SET, &_position)); + RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); } #endif #ifdef FORMAT_7Z_RECOVERY - crcFromArchive = CRC_GET_DIGEST(crc); + crcFromArchive = crc; #endif - #ifdef _7Z_VOL - UInt64 archiveStartOffset; // data offset from end if that struct - UInt64 additionalStartBlockSize; // start signature & start header size - if (_finishSignature) - { - RINOK(SafeReadDirectUInt64(archiveStartOffset)); - crc.UpdateUInt64(archiveStartOffset); - RINOK(SafeReadDirectUInt64(additionalStartBlockSize)); - crc.UpdateUInt64(additionalStartBlockSize); - database.ArchiveInfo.StartPositionAfterHeader = _position + archiveStartOffset; - } - else - #endif - { - database.ArchiveInfo.StartPositionAfterHeader = _position; - } - if (CRC_GET_DIGEST(crc) != crcFromArchive) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); + database.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; + + if (crc != crcFromArchive) + ThrowIncorrect(); if (nextHeaderSize == 0) return S_OK; - if (nextHeaderSize >= 0xFFFFFFFF) - return E_FAIL; + if (nextHeaderSize > (UInt64)0xFFFFFFFF) + return S_FALSE; - RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, &_position)); + RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL)); CByteBuffer buffer2; buffer2.SetCapacity((size_t)nextHeaderSize); - RINOK(SafeReadDirect(buffer2, (UInt32)nextHeaderSize)); + + UInt32 realProcessedSize; + RINOK(_stream->Read(buffer2, (UInt32)nextHeaderSize, &realProcessedSize)); + if (realProcessedSize != (UInt32)nextHeaderSize) + return S_FALSE; if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); + ThrowIncorrect(); CStreamSwitch streamSwitch; streamSwitch.Set(this, buffer2); @@ -1319,12 +1144,11 @@ HRESULT CInArchive::ReadDatabase( for (;;) { - UInt64 type; - RINOK(ReadID(type)); + UInt64 type = ReadID(); if (type == NID::kHeader) break; if (type != NID::kEncodedHeader) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); + ThrowIncorrect(); HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS database.ArchiveInfo.StartPositionAfterHeader, @@ -1338,7 +1162,7 @@ HRESULT CInArchive::ReadDatabase( if (dataVector.Size() == 0) return S_OK; if (dataVector.Size() > 1) - throw CInArchiveException(CInArchiveException::kIncorrectHeader); + ThrowIncorrect(); streamSwitch.Remove(); streamSwitch.Set(this, dataVector.Front()); } @@ -1352,4 +1176,24 @@ HRESULT CInArchive::ReadDatabase( ); } +HRESULT CInArchive::ReadDatabase( + DECL_EXTERNAL_CODECS_LOC_VARS + CArchiveDatabaseEx &database + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword + #endif + ) +{ + try + { + return ReadDatabase2( + EXTERNAL_CODECS_LOC_VARS database + #ifndef _NO_CRYPTO + , getTextPassword + #endif + ); + } + catch(CInArchiveException &) { return S_FALSE; } +} + }} diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h index 927c23f9..47cd3b35 100755 --- a/CPP/7zip/Archive/7z/7zIn.h +++ b/CPP/7zip/Archive/7z/7zIn.h @@ -3,32 +3,17 @@ #ifndef __7Z_IN_H #define __7Z_IN_H +#include "../../../Common/MyCom.h" #include "../../IStream.h" #include "../../IPassword.h" - #include "../../Common/CreateCoder.h" - -#include "../../../Common/MyCom.h" #include "../../Common/InBuffer.h" -#include "7zHeader.h" #include "7zItem.h" namespace NArchive { namespace N7z { -class CInArchiveException -{ -public: - enum CCauseType - { - kUnsupportedVersion = 0, - kUnexpectedEndOfArchive = 0, - kIncorrectHeader, - } Cause; - CInArchiveException(CCauseType cause); -}; - struct CInArchiveInfo { CArchiveVersion Version; @@ -43,7 +28,6 @@ struct CInArchiveInfo } }; - struct CArchiveDatabaseEx: public CArchiveDatabase { CInArchiveInfo ArchiveInfo; @@ -76,8 +60,7 @@ struct CArchiveDatabaseEx: public CArchiveDatabase UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const { return ArchiveInfo.DataStartPosition + - PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + - indexInFolder]; + PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder]; } UInt64 GetFolderFullPackSize(int folderIndex) const @@ -117,44 +100,33 @@ public: _size = size; _pos = 0; } - bool ReadByte(Byte &b) - { - if(_pos >= _size) - return false; - b = _buffer[_pos++]; - return true; - } - void ReadBytes(void *data, size_t size, size_t &processedSize) - { - for(processedSize = 0; processedSize < size && _pos < _size; processedSize++) - ((Byte *)data)[processedSize] = _buffer[_pos++]; - } - - bool ReadBytes(void *data, size_t size) - { - size_t processedSize; - ReadBytes(data, size, processedSize); - return (processedSize == size); - } - - size_t GetProcessedSize() const { return _pos; } + Byte ReadByte(); + void ReadBytes(Byte *data, size_t size); + void SkeepData(UInt64 size); + void SkeepData(); + UInt64 ReadNumber(); + CNum ReadNum(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + void ReadString(UString &s); }; class CStreamSwitch; + +const UInt32 kHeaderSize = 32; + class CInArchive { friend class CStreamSwitch; CMyComPtr<IInStream> _stream; - #ifdef _7Z_VOL - bool _finishSignature; - #endif CObjectVector<CInByte2> _inByteVector; CInByte2 *_inByteBack; UInt64 _arhiveBeginStreamPosition; - UInt64 _position; + + Byte _header[kHeaderSize]; void AddByteStream(const Byte *buffer, size_t size) { @@ -171,80 +143,42 @@ class CInArchive } private: - HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive - #ifdef _7Z_VOL - HRESULT FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive - #endif - - HRESULT ReadFileNames(CObjectVector<CFileItem> &files); - - HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size, - UInt32 *processedSize); - HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize); - HRESULT SafeReadDirect(void *data, UInt32 size); - HRESULT SafeReadDirectByte(Byte &b); - HRESULT SafeReadDirectUInt32(UInt32 &value, UInt32 &crc); - HRESULT SafeReadDirectUInt64(UInt64 &value, UInt32 &crc); - - HRESULT ReadBytes(void *data, size_t size) - { - if (!_inByteBack->ReadBytes(data, size)) - return E_FAIL; - return S_OK; - } - - HRESULT ReadByte(Byte &b) - { - if (!_inByteBack->ReadByte(b)) - return E_FAIL; - return S_OK; - } - - HRESULT ReadWideCharLE(wchar_t &c) - { - Byte b1 = 0; - if (!_inByteBack->ReadByte(b1)) - return E_FAIL; - Byte b2 = 0; - if (!_inByteBack->ReadByte(b2)) - return E_FAIL; - c = (wchar_t)(((wchar_t)(b2) << 8) + b1); - return S_OK; - } - - HRESULT ReadNumber(UInt64 &value); - HRESULT ReadNum(CNum &value); - HRESULT ReadID(UInt64 &value) { return ReadNumber(value); } - HRESULT ReadUInt32(UInt32 &value); - HRESULT ReadUInt64(UInt64 &value); + HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); - HRESULT SkeepData(UInt64 size); - HRESULT SkeepData(); - HRESULT WaitAttribute(UInt64 attribute); - - HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo); - HRESULT GetNextFolderItem(CFolder &itemInfo); - HRESULT ReadHashDigests(int numItems, + void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } + Byte ReadByte() { return _inByteBack->ReadByte(); } + UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } + CNum ReadNum() { return _inByteBack->ReadNum(); } + UInt64 ReadID() { return _inByteBack->ReadNumber(); } + UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); } + UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } + void SkeepData(UInt64 size) { _inByteBack->SkeepData(size); } + void SkeepData() { _inByteBack->SkeepData(); } + void WaitAttribute(UInt64 attribute); + + void ReadArchiveProperties(CInArchiveInfo &archiveInfo); + void GetNextFolderItem(CFolder &itemInfo); + void ReadHashDigests(int numItems, CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests); - HRESULT ReadPackInfo( + void ReadPackInfo( UInt64 &dataOffset, CRecordVector<UInt64> &packSizes, CRecordVector<bool> &packCRCsDefined, CRecordVector<UInt32> &packCRCs); - HRESULT ReadUnPackInfo( + void ReadUnPackInfo( const CObjectVector<CByteBuffer> *dataVector, CObjectVector<CFolder> &folders); - HRESULT ReadSubStreamsInfo( + void ReadSubStreamsInfo( const CObjectVector<CFolder> &folders, CRecordVector<CNum> &numUnPackStreamsInFolders, CRecordVector<UInt64> &unPackSizes, CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests); - HRESULT ReadStreamsInfo( + void ReadStreamsInfo( const CObjectVector<CByteBuffer> *dataVector, UInt64 &dataOffset, CRecordVector<UInt64> &packSizes, @@ -257,10 +191,9 @@ private: CRecordVector<UInt32> &digests); - HRESULT GetNextFileItem(CFileItem &itemInfo); - HRESULT ReadBoolVector(int numItems, CBoolVector &v); - HRESULT ReadBoolVector2(int numItems, CBoolVector &v); - HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector, + void ReadBoolVector(int numItems, CBoolVector &v); + void ReadBoolVector2(int numItems, CBoolVector &v); + void ReadTime(const CObjectVector<CByteBuffer> &dataVector, CObjectVector<CFileItem> &files, UInt64 type); HRESULT ReadAndDecodePackedStreams( DECL_EXTERNAL_CODECS_LOC_VARS @@ -277,6 +210,13 @@ private: ,ICryptoGetTextPassword *getTextPassword #endif ); + HRESULT ReadDatabase2( + DECL_EXTERNAL_CODECS_LOC_VARS + CArchiveDatabaseEx &database + #ifndef _NO_CRYPTO + ,ICryptoGetTextPassword *getTextPassword + #endif + ); public: HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive void Close(); diff --git a/CPP/7zip/Archive/Arj/ArjHandler.h b/CPP/7zip/Archive/Arj/ArjHandler.h index 58e67401..1f43808a 100755 --- a/CPP/7zip/Archive/Arj/ArjHandler.h +++ b/CPP/7zip/Archive/Arj/ArjHandler.h @@ -17,24 +17,7 @@ class CHandler: public: MY_UNKNOWN_IMP1(IInArchive) - STDMETHOD(Open)(IInStream *inStream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *callback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *anExtractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) CHandler(); private: diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.h b/CPP/7zip/Archive/BZip2/BZip2Handler.h index 96854eca..4a45e52f 100755 --- a/CPP/7zip/Archive/BZip2/BZip2Handler.h +++ b/CPP/7zip/Archive/BZip2/BZip2Handler.h @@ -53,32 +53,9 @@ public: MY_QUERYINTERFACE_END MY_ADDREF_RELEASE - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + INTERFACE_IInArchive(;) + INTERFACE_IOutArchive(;) - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - // IOutArchiveHandler - - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UInt32 *type); - - // ISetProperties STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); DECL_ISetCompressCodecsInfo diff --git a/CPP/7zip/Archive/Cab/CabHandler.h b/CPP/7zip/Archive/Cab/CabHandler.h index f5b6e39c..e17c3a7d 100755 --- a/CPP/7zip/Archive/Cab/CabHandler.h +++ b/CPP/7zip/Archive/Cab/CabHandler.h @@ -17,24 +17,7 @@ class CHandler: public: MY_UNKNOWN_IMP1(IInArchive) - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) private: CMvDatabaseEx m_Database; diff --git a/CPP/7zip/Archive/Chm/ChmHandler.h b/CPP/7zip/Archive/Chm/ChmHandler.h index 82eeb290..09113b8f 100755 --- a/CPP/7zip/Archive/Chm/ChmHandler.h +++ b/CPP/7zip/Archive/Chm/ChmHandler.h @@ -17,24 +17,7 @@ class CHandler: public: MY_UNKNOWN_IMP1(IInArchive) - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) private: CFilesDatabase m_Database; diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp index bff689dd..a297eb7f 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -26,13 +26,13 @@ void CCoder2::Code(ICompressProgressInfo *progress) { if (InSizePointers[i] != NULL) InSizePointers[i] = &InSizes[i]; - InStreamPointers.Add(InStreams[i]); + InStreamPointers.Add((ISequentialInStream *)InStreams[i]); } for (i = 0; i < NumOutStreams; i++) { if (OutSizePointers[i] != NULL) OutSizePointers[i] = &OutSizes[i]; - OutStreamPointers.Add(OutStreams[i]); + OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]); } if (Coder) Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.h b/CPP/7zip/Archive/Cpio/CpioHandler.h index eed1a06a..e9320e61 100755 --- a/CPP/7zip/Archive/Cpio/CpioHandler.h +++ b/CPP/7zip/Archive/Cpio/CpioHandler.h @@ -18,24 +18,7 @@ class CHandler: public: MY_UNKNOWN_IMP1(IInArchive) - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) private: CObjectVector<CItemEx> m_Items; diff --git a/CPP/7zip/Archive/Deb/DebHandler.h b/CPP/7zip/Archive/Deb/DebHandler.h index 4419dcdd..297a91be 100755 --- a/CPP/7zip/Archive/Deb/DebHandler.h +++ b/CPP/7zip/Archive/Deb/DebHandler.h @@ -18,24 +18,7 @@ class CHandler: public: MY_UNKNOWN_IMP1(IInArchive) - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) private: CObjectVector<CItemEx> _items; diff --git a/CPP/7zip/Archive/GZip/GZipHandler.h b/CPP/7zip/Archive/GZip/GZipHandler.h index c1f8968b..3f5a1acd 100755 --- a/CPP/7zip/Archive/GZip/GZipHandler.h +++ b/CPP/7zip/Archive/GZip/GZipHandler.h @@ -30,34 +30,9 @@ public: MY_QUERYINTERFACE_END MY_ADDREF_RELEASE - STDMETHOD(Open)(IInStream *inStream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); + INTERFACE_IInArchive(;) + INTERFACE_IOutArchive(;) - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - // IOutArchive - - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback); - - STDMETHOD(GetFileTimeType)(UInt32 *timeType); - - // ISetProperties STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); DECL_ISetCompressCodecsInfo diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h index 3ef26a75..5fe20a72 100755 --- a/CPP/7zip/Archive/IArchive.h +++ b/CPP/7zip/Archive/IArchive.h @@ -111,28 +111,28 @@ ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50) }; +/* +IInArchive::Extract: + indices must be sorted + numItems = 0xFFFFFFFF means "all files" + testMode != 0 means "test files without writing to outStream" +*/ + +#define INTERFACE_IInArchive(x) \ + STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \ + STDMETHOD(Close)() x; \ + STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \ + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \ + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \ + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; + ARCHIVE_INTERFACE(IInArchive, 0x60) { - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback) PURE; - STDMETHOD(Close)() PURE; - STDMETHOD(GetNumberOfItems)(UInt32 *numItems) PURE; - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) PURE; - // indices must be sorted - // numItems = 0xFFFFFFFF means all files - // testMode != 0 means "test files operation" - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE; - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) PURE; - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType) PURE; - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) PURE; - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType) PURE; + INTERFACE_IInArchive(PURE) }; @@ -156,11 +156,13 @@ ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) }; +#define INTERFACE_IOutArchive(x) \ + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \ + STDMETHOD(GetFileTimeType)(UInt32 *type) x; + ARCHIVE_INTERFACE(IOutArchive, 0xA0) { - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) PURE; - STDMETHOD(GetFileTimeType)(UInt32 *type) PURE; + INTERFACE_IOutArchive(PURE) }; diff --git a/CPP/7zip/Archive/Iso/IsoHandler.h b/CPP/7zip/Archive/Iso/IsoHandler.h index 07d75844..5750cbc9 100755 --- a/CPP/7zip/Archive/Iso/IsoHandler.h +++ b/CPP/7zip/Archive/Iso/IsoHandler.h @@ -14,40 +14,14 @@ namespace NIso { class CHandler: public IInArchive, - // public IOutArchive, public CMyUnknownImp { public: MY_UNKNOWN_IMP1( IInArchive - // IOutArchive ) - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - /* - // IOutArchive - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UInt32 *type); - */ + INTERFACE_IInArchive(;) private: CMyComPtr<IInStream> _inStream; diff --git a/CPP/7zip/Archive/Lzh/LzhHandler.h b/CPP/7zip/Archive/Lzh/LzhHandler.h index 35929793..2caf21fd 100755 --- a/CPP/7zip/Archive/Lzh/LzhHandler.h +++ b/CPP/7zip/Archive/Lzh/LzhHandler.h @@ -17,24 +17,7 @@ class CHandler: public: MY_UNKNOWN_IMP1(IInArchive) - STDMETHOD(Open)(IInStream *inStream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *callback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *anExtractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) CHandler(); private: diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.h b/CPP/7zip/Archive/Nsis/NsisHandler.h index e180f70d..82e76139 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.h +++ b/CPP/7zip/Archive/Nsis/NsisHandler.h @@ -32,16 +32,7 @@ public: MY_QUERYINTERFACE_END MY_ADDREF_RELEASE - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback); - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) DECL_ISetCompressCodecsInfo }; diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp index 8797a8e7..aa1e456f 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.cpp +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -57,9 +57,11 @@ void CInArchive::ReadBlockHeader(CBlockHeader &bh) static int CompareItems(void *const *p1, void *const *p2, void * /* param */) { - RINOZ(MyCompare( - (**(const CItem **)p1).Pos, - (**(const CItem **)p2).Pos)); + const CItem &i1 = **(CItem **)p1; + const CItem &i2 = **(CItem **)p2; + RINOZ(MyCompare(i1.Pos, i2.Pos)); + RINOZ(i1.Prefix.Compare(i2.Prefix)); + RINOZ(i1.Name.Compare(i2.Name)); return 0; } @@ -903,6 +905,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) { Items.Sort(CompareItems, 0); int i; + if (IsSolid) for (i = 0; i + 1 < Items.Size();) { if (Items[i].Pos == Items[i + 1].Pos) diff --git a/CPP/7zip/Archive/RPM/RpmHandler.h b/CPP/7zip/Archive/RPM/RpmHandler.h index ed0717f3..c78e8ce3 100755 --- a/CPP/7zip/Archive/RPM/RpmHandler.h +++ b/CPP/7zip/Archive/RPM/RpmHandler.h @@ -16,24 +16,7 @@ class CHandler: public: MY_UNKNOWN_IMP1(IInArchive) - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) private: CMyComPtr<IInStream> m_InStream; diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h index 96d5d241..811802a9 100755 --- a/CPP/7zip/Archive/Rar/RarHandler.h +++ b/CPP/7zip/Archive/Rar/RarHandler.h @@ -23,24 +23,7 @@ public: MY_QUERYINTERFACE_END MY_ADDREF_RELEASE - STDMETHOD(Open)(IInStream *aStream, - const UInt64 *aMaxCheckStartPosition, - IArchiveOpenCallback *anOpenArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *anExtractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) DECL_ISetCompressCodecsInfo diff --git a/CPP/7zip/Archive/Split/SplitHandler.h b/CPP/7zip/Archive/Split/SplitHandler.h index 65071cfd..79e63353 100755 --- a/CPP/7zip/Archive/Split/SplitHandler.h +++ b/CPP/7zip/Archive/Split/SplitHandler.h @@ -19,35 +19,10 @@ class CHandler: public: MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - // IOutArchiveHandler - /* - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback); - - STDMETHOD(GetFileTimeType)(UInt32 *type); - */ - private: UString _subName; UString _name; diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h index 7b6e3a40..8332fbfe 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.h +++ b/CPP/7zip/Archive/Tar/TarHandler.h @@ -22,29 +22,8 @@ public: IOutArchive ) - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - // IOutArchive - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UInt32 *type); + INTERFACE_IInArchive(;) + INTERFACE_IOutArchive(;) private: CObjectVector<CItemEx> _items; diff --git a/CPP/7zip/Archive/Wim/WimHandler.h b/CPP/7zip/Archive/Wim/WimHandler.h index 5142d785..25567743 100755 --- a/CPP/7zip/Archive/Wim/WimHandler.h +++ b/CPP/7zip/Archive/Wim/WimHandler.h @@ -28,25 +28,7 @@ class CHandler: { public: MY_UNKNOWN_IMP1(IInArchive) - - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) private: CDatabase m_Database; diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp index e99cb37b..80ac1954 100755 --- a/CPP/7zip/Archive/Wim/WimIn.cpp +++ b/CPP/7zip/Archive/Wim/WimIn.cpp @@ -11,6 +11,8 @@ #include "../Common/OutStreamWithSha1.h" +#include "../../../../C/CpuArch.h" + #include "WimIn.h" namespace NArchive{ @@ -26,11 +28,7 @@ static HRESULT ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size) return (realProcessedSize == size) ? S_OK : S_FALSE; } -#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) -#define WIM_LITTLE_ENDIAN_UNALIGN -#endif - -#ifdef WIM_LITTLE_ENDIAN_UNALIGN +#ifdef LITTLE_ENDIAN_UNALIGN static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; } static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; } static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; } diff --git a/CPP/7zip/Archive/Z/ZHandler.h b/CPP/7zip/Archive/Z/ZHandler.h index 21165390..e8b3b8c5 100755 --- a/CPP/7zip/Archive/Z/ZHandler.h +++ b/CPP/7zip/Archive/Z/ZHandler.h @@ -15,25 +15,7 @@ class CHandler: { public: MY_UNKNOWN_IMP1(IInArchive) - - STDMETHOD(Open)(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); + INTERFACE_IInArchive(;) private: CMyComPtr<IInStream> _stream; diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index c1185363..84269599 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -31,6 +31,10 @@ #include "../../Crypto/Zip/ZipCipher.h" #include "../../Crypto/WzAES/WzAES.h" +#ifdef ZIP_STRONG_SUPORT +#include "../../Crypto/ZipStrong/ZipStrong.h" +#endif + using namespace NWindows; using namespace NTime; @@ -47,22 +51,22 @@ const wchar_t *kHostOS[] = L"AMIGA", L"VMS", L"Unix", - L"VM_CMS", - L"Atari", // what if it's a minix filesystem? [cjh] - L"HPFS", // filesystem used by OS/2 (and NT 3.x) - L"Mac", - L"Z_System", - L"CPM", - L"TOPS20", // pkzip 2.50 NTFS - L"NTFS", // filesystem used by Windows NT - L"QDOS ", // SMS/QDOS - L"Acorn", // Archimedes Acorn RISC OS - L"VFAT", // filesystem used by Windows 95, NT + L"VM/CMS", + L"Atari", + L"HPFS", + L"Macintosh", + L"Z-System", + L"CP/M", + L"TOPS-20", + L"NTFS", + L"SMS/QDOS", + L"Acorn", + L"VFAT", L"MVS", - L"BeOS", // hybrid POSIX/database filesystem - // BeBOX or PowerMac + L"BeOS", L"Tandem", - L"THEOS" + L"OS/400", + L"OS/X" }; @@ -120,6 +124,33 @@ const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); const wchar_t *kPPMdMethod = L"PPMd"; const wchar_t *kAESMethod = L"AES"; const wchar_t *kZipCryptoMethod = L"ZipCrypto"; +const wchar_t *kStrongCryptoMethod = L"StrongCrypto"; + +struct CStrongCryptoPair +{ + UInt16 Id; + const wchar_t *Name; +}; + +CStrongCryptoPair g_StrongCryptoPairs[] = +{ + { NStrongCryptoFlags::kDES, L"DES" }, + { NStrongCryptoFlags::kRC2old, L"RC2a" }, + { NStrongCryptoFlags::k3DES168, L"3DES-168" }, + { NStrongCryptoFlags::k3DES112, L"3DES-112" }, + { NStrongCryptoFlags::kAES128, L"pkAES-128" }, + { NStrongCryptoFlags::kAES192, L"pkAES-192" }, + { NStrongCryptoFlags::kAES256, L"pkAES-256" }, + { NStrongCryptoFlags::kRC2, L"RC2" }, + { NStrongCryptoFlags::kBlowfish, L"Blowfish" }, + { NStrongCryptoFlags::kTwofish, L"Twofish" }, + { NStrongCryptoFlags::kRC4, L"RC4" } +}; + +STATPROPSTG kArcProperties[] = +{ + { NULL, kpidComment, VT_BSTR} +}; CHandler::CHandler(): m_ArchiveIsOpen(false) @@ -127,9 +158,33 @@ CHandler::CHandler(): InitMethodProperties(); } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM::CPropVariant &propVariant) { - value->vt = VT_EMPTY; + int size = (int)data.GetCapacity(); + if (size <= 0) + return; + AString s; + char *p = s.GetBuffer(size + 1); + memcpy(p, (const Byte *)data, size); + p[size] = '\0'; + s.ReleaseBuffer(); + propVariant = MultiByteToUnicodeString(s, codePage); +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidComment: + { + StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, propVariant); + break; + } + } + propVariant.Detach(value); + COM_TRY_END return S_OK; } @@ -142,7 +197,7 @@ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { - if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) return E_INVALIDARG; const STATPROPSTG &srcItem = kProperties[index]; *propID = srcItem.propid; @@ -153,14 +208,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) { - *numProperties = 0; + *numProperties = sizeof(kArcProperties) / sizeof(kArcProperties[0]); return S_OK; } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, + BSTR * name, PROPID * propID, VARTYPE *varType) { - return E_NOTIMPL; + if (index >= sizeof(kArcProperties) / sizeof(kArcProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kArcProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; } STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) @@ -169,23 +230,12 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -static void MyStrNCpy(char *dest, const char *src, int size) -{ - for (int i = 0; i < size; i++) - { - char c = src[i]; - dest[i] = c; - if (c == 0) - break; - } -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *aValue) +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; const CItemEx &item = m_Items[index]; - switch(aPropID) + switch(propID) { case kpidPath: propVariant = NItemName::GetOSName2( @@ -202,15 +252,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *a break; case kpidLastWriteTime: { - FILETIME aLocalFileTime, anUTCFileTime; - if (DosTimeToFileTime(item.Time, aLocalFileTime)) + FILETIME localFileTime, utcFileTime; + if (DosTimeToFileTime(item.Time, localFileTime)) { - if (!LocalFileTimeToFileTime(&aLocalFileTime, &anUTCFileTime)) - anUTCFileTime.dwHighDateTime = anUTCFileTime.dwLowDateTime = 0; + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; } else - anUTCFileTime.dwHighDateTime = anUTCFileTime.dwLowDateTime = 0; - propVariant = anUTCFileTime; + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + propVariant = utcFileTime; break; } case kpidAttributes: @@ -221,16 +271,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *a break; case kpidComment: { - int size = (int)item.Comment.GetCapacity(); - if (size > 0) - { - AString s; - char *p = s.GetBuffer(size + 1); - MyStrNCpy(p, (const char *)(const Byte *)item.Comment, size); - p[size] = '\0'; - s.ReleaseBuffer(); - propVariant = MultiByteToUnicodeString(s, item.GetCodePage()); - } + StringToProp(item.Comment, item.GetCodePage(), propVariant); break; } case kpidCRC: @@ -259,7 +300,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *a } else { - method += kZipCryptoMethod; + if (item.IsStrongEncrypted()) + { + CStrongCryptoField f; + bool finded = false; + if (item.CentralExtra.GetStrongCryptoField(f)) + { + for (int i = 0; i < sizeof(g_StrongCryptoPairs) / sizeof(g_StrongCryptoPairs[0]); i++) + { + const CStrongCryptoPair &pair = g_StrongCryptoPairs[i]; + if (f.AlgId == pair.Id) + { + method += pair.Name; + finded = true; + break; + } + } + } + if (!finded) + method += kStrongCryptoMethod; + } + else + method += kZipCryptoMethod; method += L" "; } } @@ -281,7 +343,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *a (kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS; break; } - propVariant.Detach(aValue); + propVariant.Detach(value); return S_OK; COM_TRY_END } @@ -353,6 +415,10 @@ class CZipDecoder NCrypto::NWzAES::CDecoder *_aesDecoderSpec; CMyComPtr<ICompressFilter> _zipCryptoDecoder; CMyComPtr<ICompressFilter> _aesDecoder; + #ifdef ZIP_STRONG_SUPORT + NCrypto::NZipStrong::CDecoder *_zsDecoderSpec; + CMyComPtr<ICompressFilter> _zsDecoder; + #endif CFilterCoder *filterStreamSpec; CMyComPtr<ISequentialInStream> filterStream; CMyComPtr<ICryptoGetTextPassword> getTextPassword; @@ -383,8 +449,27 @@ HRESULT CZipDecoder::Decode( bool needCRC = true; bool aesMode = false; + #ifdef ZIP_STRONG_SUPORT + bool pkAesMode = false; + #endif UInt16 methodId = item.CompressionMethod; if (item.IsEncrypted()) + { + if (item.IsStrongEncrypted()) + { + #ifdef ZIP_STRONG_SUPORT + CStrongCryptoField f; + if (item.CentralExtra.GetStrongCryptoField(f)) + { + pkAesMode = true; + } + if (!pkAesMode) + #endif + { + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + } if (methodId == NFileHeader::NCompressionMethod::kWzAES) { CWzAesExtraField aesField; @@ -394,8 +479,9 @@ HRESULT CZipDecoder::Decode( needCRC = aesField.NeedCrc(); } } + } - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;; + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; outStreamSpec->SetStream(realOutStream); outStreamSpec->Init(needCRC); @@ -434,6 +520,17 @@ HRESULT CZipDecoder::Decode( Byte properties = aesField.Strength; RINOK(_aesDecoderSpec->SetDecoderProperties2(&properties, 1)); } + #ifdef ZIP_STRONG_SUPORT + else if (pkAesMode) + { + if (!_zsDecoder) + { + _zsDecoderSpec = new NCrypto::NZipStrong::CDecoder; + _zsDecoder = _zsDecoderSpec; + } + cryptoFilter = _zsDecoder; + } + #endif else { if (!_zipCryptoDecoder) @@ -454,7 +551,11 @@ HRESULT CZipDecoder::Decode( CMyComBSTR password; RINOK(getTextPassword->CryptoGetTextPassword(&password)); AString charPassword; - if (aesMode) + if (aesMode + #ifdef ZIP_STRONG_SUPORT + || pkAesMode + #endif + ) { charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP); /* @@ -566,6 +667,12 @@ HRESULT CZipDecoder::Decode( { RINOK(_aesDecoderSpec->ReadHeader(inStream)); } + #ifdef ZIP_STRONG_SUPORT + else if (pkAesMode) + { + RINOK(_zsDecoderSpec->ReadHeader(inStream)); + } + #endif else { RINOK(_zipCryptoDecoderSpec->ReadHeader(inStream)); diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h index f7bf4cf1..28f44196 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.h +++ b/CPP/7zip/Archive/Zip/ZipHandler.h @@ -34,31 +34,9 @@ public: MY_QUERYINTERFACE_END MY_ADDREF_RELEASE - STDMETHOD(Open)(IInStream *aStream, - const UInt64 *aMaxCheckStartPosition, - IArchiveOpenCallback *anOpenArchiveCallback); - STDMETHOD(Close)(); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *anExtractCallback); - - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); - - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); - STDMETHOD(GetPropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType); - - // IOutArchive - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback); - STDMETHOD(GetFileTimeType)(UInt32 *timeType); - - // ISetProperties + INTERFACE_IInArchive(;) + INTERFACE_IOutArchive(;) + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); DECL_ISetCompressCodecsInfo diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h index ac98ea76..8ce2718a 100755 --- a/CPP/7zip/Archive/Zip/ZipHeader.h +++ b/CPP/7zip/Archive/Zip/ZipHeader.h @@ -86,6 +86,7 @@ namespace NFileHeader enum { kZip64 = 0x01, + kStrongEncrypt = 0x17, kWzAES = 0x9901 }; } @@ -157,8 +158,9 @@ namespace NFileHeader const int kNumUsedBits = 4; const int kUsedBitsMask = (1 << kNumUsedBits) - 1; - const int kEncryptedMask = 1 << 0; - const int kDescriptorUsedMask = 1 << 3; + const int kEncrypted = 1 << 0; + const int kDescriptorUsedMask = 1 << 3; + const int kStrongEncrypted = 1 << 6; const int kImplodeDictionarySizeMask = 1 << 1; const int kImplodeLiteralsOnMask = 1 << 2; @@ -173,8 +175,7 @@ namespace NFileHeader { enum EEnum { - kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32 - // pkzip 2.50 (FAT / VFAT / FAT32 file systems) + kFAT = 0, kAMIGA = 1, kVMS = 2, // VAX/VMS kUnix = 3, @@ -191,11 +192,10 @@ namespace NFileHeader kVFAT = 14, // filesystem used by Windows 95, NT kMVS = 15, kBeOS = 16, // hybrid POSIX/database filesystem - // BeBOX or PowerMac kTandem = 17, - kTHEOS = 18 + kOS400 = 18, + kOSX = 19 }; - // const int kNumHostSystems = 19; } namespace NUnixAttribute { diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h index 80de2272..62be592b 100755 --- a/CPP/7zip/Archive/Zip/ZipIn.h +++ b/CPP/7zip/Archive/Zip/ZipIn.h @@ -64,7 +64,6 @@ class CInArchive UInt32 m_Signature; UInt64 m_StreamStartPosition; UInt64 m_Position; - CInArchiveInfo m_ArchiveInfo; AString m_NameBuffer; HRESULT Seek(UInt64 offset); @@ -95,6 +94,8 @@ class CInArchive HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize); HRESULT ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset); public: + CInArchiveInfo m_ArchiveInfo; + HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress); HRESULT ReadLocalItemAfterCdItem(CItemEx &item); HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp index 86c2764b..480a1abb 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.cpp +++ b/CPP/7zip/Archive/Zip/ZipItem.cpp @@ -19,14 +19,9 @@ bool operator!=(const CVersion &v1, const CVersion &v2) return !(v1 == v2); } -bool CLocalItem::IsEncrypted() const -{ return (Flags & NFileHeader::NFlags::kEncryptedMask) != 0; } -bool CLocalItem::HasDescriptor() const - { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; } - bool CLocalItem::IsImplodeBigDictionary() const { -if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) + if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) throw 12312212; return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0; } @@ -130,6 +125,6 @@ void CLocalItem::SetBitMask(int bitMask, bool enable) } void CLocalItem::SetEncrypted(bool encrypted) - { SetBitMask(NFileHeader::NFlags::kEncryptedMask, encrypted); } + { SetBitMask(NFileHeader::NFlags::kEncrypted, encrypted); } }} diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h index 4a7a47f1..2395a37a 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.h +++ b/CPP/7zip/Archive/Zip/ZipItem.h @@ -67,6 +67,43 @@ struct CWzAesExtraField } }; +namespace NStrongCryptoFlags +{ + const UInt16 kDES = 0x6601; + const UInt16 kRC2old = 0x6602; + const UInt16 k3DES168 = 0x6603; + const UInt16 k3DES112 = 0x6609; + const UInt16 kAES128 = 0x660E; + const UInt16 kAES192 = 0x660F; + const UInt16 kAES256 = 0x6610; + const UInt16 kRC2 = 0x6702; + const UInt16 kBlowfish = 0x6720; + const UInt16 kTwofish = 0x6721; + const UInt16 kRC4 = 0x6801; +} + +struct CStrongCryptoField +{ + UInt16 Format; + UInt16 AlgId; + UInt16 BitLen; + UInt16 Flags; + + bool ParseFromSubBlock(const CExtraSubBlock &sb) + { + if (sb.ID != NFileHeader::NExtraID::kStrongEncrypt) + return false; + const Byte *p = (const Byte *)sb.Data; + if (sb.Data.GetCapacity() < 8) + return false; + Format = (((UInt16)p[1]) << 8) | p[0]; + AlgId = (((UInt16)p[3]) << 8) | p[2]; + BitLen = (((UInt16)p[5]) << 8) | p[4]; + Flags = (((UInt16)p[7]) << 8) | p[6]; + return (Format == 2); + } +}; + struct CExtraBlock { CObjectVector<CExtraSubBlock> SubBlocks; @@ -80,19 +117,34 @@ struct CExtraBlock } bool GetWzAesField(CWzAesExtraField &aesField) const { - // size_t res = 0; for (int i = 0; i < SubBlocks.Size(); i++) if (aesField.ParseFromSubBlock(SubBlocks[i])) return true; return false; } + bool GetStrongCryptoField(CStrongCryptoField &f) const + { + for (int i = 0; i < SubBlocks.Size(); i++) + if (f.ParseFromSubBlock(SubBlocks[i])) + return true; + return false; + } + bool HasWzAesField() const { CWzAesExtraField aesField; return GetWzAesField(aesField); } + /* + bool HasStrongCryptoField() const + { + CStrongCryptoField f; + return GetStrongCryptoField(f); + } + */ + void RemoveUnknownSubBlocks() { for (int i = SubBlocks.Size() - 1; i >= 0;) @@ -122,7 +174,8 @@ public: CExtraBlock LocalExtra; - bool IsEncrypted() const; + bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; } + bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; }; bool IsImplodeBigDictionary() const; bool IsImplodeLiteralsOn() const; @@ -131,7 +184,8 @@ public: bool IgnoreItem() const { return false; } UInt32 GetWinAttributes() const; - bool HasDescriptor() const; + bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; } + private: void SetFlagBits(int startBitNumber, int numBits, int value); |