diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2010-11-11 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:04 +0300 |
commit | b75af1bba61529be6787dc470f9db60906a182e5 (patch) | |
tree | 9e0ffa6bd9ed8ac72856630225cfe07cbc63cede /CPP | |
parent | c65230d8585317f7cd58ae2982067385269fdee9 (diff) |
9.199.19
Diffstat (limited to 'CPP')
-rwxr-xr-x | CPP/7zip/Archive/Rar/RarHandler.cpp | 50 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Rar/RarHandler.h | 35 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Rar/RarHeader.h | 27 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Rar/RarIn.cpp | 199 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Rar/RarIn.h | 30 | ||||
-rwxr-xr-x | CPP/7zip/MyVersion.h | 8 | ||||
-rwxr-xr-x | CPP/7zip/UI/Common/ArchiveCommandLine.cpp | 5 | ||||
-rwxr-xr-x | CPP/7zip/UI/Common/Update.cpp | 81 | ||||
-rwxr-xr-x | CPP/7zip/UI/Common/Update.h | 20 | ||||
-rwxr-xr-x | CPP/7zip/UI/Console/UserInputUtils.cpp | 26 | ||||
-rwxr-xr-x | CPP/7zip/UI/FileManager/ListViewDialog.cpp | 3 | ||||
-rwxr-xr-x | CPP/7zip/UI/FileManager/PanelItemOpen.cpp | 2 | ||||
-rwxr-xr-x | CPP/7zip/UI/FileManager/PanelItems.cpp | 3 | ||||
-rwxr-xr-x | CPP/7zip/UI/FileManager/PanelSelect.cpp | 8 | ||||
-rwxr-xr-x | CPP/Common/CommandLineParser.cpp | 19 | ||||
-rwxr-xr-x | CPP/Common/CommandLineParser.h | 6 | ||||
-rwxr-xr-x | CPP/Common/Wildcard.cpp | 2 | ||||
-rwxr-xr-x | CPP/Windows/FileDir.cpp | 42 |
18 files changed, 302 insertions, 264 deletions
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index 54709f6c..5d072d34 100755 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -7,6 +7,7 @@ #include "Common/StringConvert.h" #include "Windows/PropVariant.h" +#include "Windows/PropVariantUtils.h" #include "Windows/Time.h" #include "../../IPassword.h" @@ -46,6 +47,20 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); static const wchar_t *kUnknownOS = L"Unknown"; +static const CUInt32PCharPair k_Flags[] = +{ + { 0, "Volume" }, + { 1, "Comment" }, + { 2, "Lock" }, + { 3, "Solid" }, + { 4, "NewVolName" }, // pack_comment in old versuons + { 5, "Authenticity" }, + { 6, "Recovery" }, + { 7, "BlockEncryption" }, + { 8, "FirstVolume" }, + { 9, "EncryptVer" } +}; + static const STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, @@ -70,6 +85,7 @@ static const STATPROPSTG kProps[] = static const STATPROPSTG kArcProps[] = { + { NULL, kpidCharacts, VT_BSTR}, { NULL, kpidSolid, VT_BOOL}, { NULL, kpidNumBlocks, VT_UI4}, // { NULL, kpidEncrypted, VT_BOOL}, @@ -98,6 +114,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) switch(propID) { case kpidSolid: prop = _archiveInfo.IsSolid(); break; + case kpidCharacts: FLAGS_TO_PROP(k_Flags, _archiveInfo.Flags, prop); break; // case kpidEncrypted: prop = _archiveInfo.IsEncrypted(); break; // it's for encrypted names. case kpidIsVolume: prop = _archiveInfo.IsVolume(); break; case kpidNumVolumes: prop = (UInt32)_archives.Size(); break; @@ -325,19 +342,19 @@ public: HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback) + IArchiveOpenCallback *openCallback) { { CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CMyComPtr<ICryptoGetTextPassword> getTextPassword; - CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; + CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openCallback; CVolumeName seqName; UInt64 totalBytes = 0; UInt64 curBytes = 0; - if (openArchiveCallback != NULL) + if (openCallback) { openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); @@ -379,12 +396,12 @@ HRESULT CHandler::Open2(IInStream *stream, inStream = stream; UInt64 endPos = 0; - if (openArchiveCallback != NULL) + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + if (openCallback) { - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); totalBytes += endPos; - RINOK(openArchiveCallback->SetTotal(NULL, &totalBytes)); + RINOK(openCallback->SetTotal(NULL, &totalBytes)); } NArchive::NRar::CInArchive archive; @@ -396,15 +413,16 @@ HRESULT CHandler::Open2(IInStream *stream, CItemEx item; for (;;) { + if (archive.m_Position > endPos) + { + AddErrorMessage("Unexpected end of archive"); + break; + } bool decryptionError; AString errorMessageLoc; HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError, errorMessageLoc); if (errorMessageLoc) - { - if (!_errorMessage.IsEmpty()) - _errorMessage += '\n'; - _errorMessage += errorMessageLoc; - } + AddErrorMessage(errorMessageLoc); if (result == S_FALSE) { if (decryptionError && _items.IsEmpty()) @@ -434,11 +452,11 @@ HRESULT CHandler::Open2(IInStream *stream, _refItems.Add(refItem); } _items.Add(item); - if (openArchiveCallback != NULL && _items.Size() % 100 == 0) + if (openCallback && _items.Size() % 100 == 0) { UInt64 numFiles = _items.Size(); UInt64 numBytes = curBytes + item.Position; - RINOK(openArchiveCallback->SetCompleted(&numFiles, &numBytes)); + RINOK(openCallback->SetCompleted(&numFiles, &numBytes)); } } curBytes += endPos; @@ -450,13 +468,13 @@ HRESULT CHandler::Open2(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback) + IArchiveOpenCallback *openCallback) { COM_TRY_BEGIN Close(); try { - HRESULT res = Open2(stream, maxCheckStartPosition, openArchiveCallback); + HRESULT res = Open2(stream, maxCheckStartPosition, openCallback); if (res != S_OK) Close(); return res; diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h index c8015b2a..79266827 100755 --- a/CPP/7zip/Archive/Rar/RarHandler.h +++ b/CPP/7zip/Archive/Rar/RarHandler.h @@ -4,11 +4,12 @@ #define __RAR_HANDLER_H #include "../IArchive.h" -#include "RarIn.h" -#include "RarVolumeInStream.h" #include "../../Common/CreateCoder.h" +#include "RarIn.h" +#include "RarVolumeInStream.h" + namespace NArchive { namespace NRar { @@ -17,17 +18,6 @@ class CHandler: PUBLIC_ISetCompressCodecsInfo public CMyUnknownImp { -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - - DECL_ISetCompressCodecsInfo - -private: CRecordVector<CRefItem> _refItems; CObjectVector<CItemEx> _items; CObjectVector<CInArchive> _archives; @@ -37,7 +27,6 @@ private: DECL_EXTERNAL_CODECS_VARS UInt64 GetPackSize(int refIndex) const; - // NArchive::NRar::CInArchive _archive; bool IsSolid(int refIndex) { @@ -50,10 +39,26 @@ private: } return item.IsSolid(); } + void AddErrorMessage(const AString &s) + { + if (!_errorMessage.IsEmpty()) + _errorMessage += '\n'; + _errorMessage += s; + } HRESULT Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback); + IArchiveOpenCallback *openCallback); + +public: + MY_QUERYINTERFACE_BEGIN2(IInArchive) + QUERY_ENTRY_ISetCompressCodecsInfo + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + INTERFACE_IInArchive(;) + + DECL_ISetCompressCodecsInfo }; }} diff --git a/CPP/7zip/Archive/Rar/RarHeader.h b/CPP/7zip/Archive/Rar/RarHeader.h index 8bb1da21..5c21a2ac 100755 --- a/CPP/7zip/Archive/Rar/RarHeader.h +++ b/CPP/7zip/Archive/Rar/RarHeader.h @@ -5,9 +5,9 @@ #include "Common/Types.h" -namespace NArchive{ -namespace NRar{ -namespace NHeader{ +namespace NArchive { +namespace NRar { +namespace NHeader { const int kMarkerSize = 7; extern Byte kMarker[kMarkerSize]; @@ -43,32 +43,13 @@ namespace NArchive const UInt16 kBlockEncryption = 0x80; const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later) const UInt16 kEncryptVer = 0x200; // RAR 3.6 there is EncryptVer Byte in End of MainHeader - - const int kHeaderSizeMin = 7; - struct CBlock - { - UInt16 CRC; - Byte Type; - UInt16 Flags; - UInt16 Size; - UInt16 Reserved1; - UInt32 Reserved2; - // UInt16 GetRealCRC() const; - }; + const int kHeaderSizeMin = 7; const int kArchiveHeaderSize = 13; const int kBlockHeadersAreEncrypted = 0x80; - struct CHeader360: public CBlock - { - Byte EncryptVersion; - bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } - bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; } - bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } - UInt32 GetBaseSize() const { return kArchiveHeaderSize + (IsEncryptOld() ? 0 : 1); } - }; } namespace NFile diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp index 7d64c6fd..e4c23752 100755 --- a/CPP/7zip/Archive/Rar/RarIn.cpp +++ b/CPP/7zip/Archive/Rar/RarIn.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include "../../../../C/7zCrc.h" +#include "../../../../C/CpuArch.h" #include "Common/StringConvert.h" #include "Common/UTFConvert.h" @@ -14,9 +15,16 @@ #include "RarIn.h" +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + namespace NArchive { namespace NRar { - + +static const char *k_UnexpectedEnd = "Unexpected end of archive"; +static const char *k_DecryptionError = "Decryption Error"; + void CInArchive::ThrowExceptionWithCode( CInArchiveException::CCauseType cause) { @@ -42,140 +50,80 @@ void CInArchive::Close() m_Stream.Release(); } - -static inline bool TestMarkerCandidate(const void *aTestBytes) -{ - for (UInt32 i = 0; i < NHeader::kMarkerSize; i++) - if (((const Byte *)aTestBytes)[i] != NHeader::kMarker[i]) - return false; - return true; -} - -HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit) -{ - RINOK(FindSignatureInStream(stream, - NHeader::kMarker, NHeader::kMarkerSize, - searchHeaderSizeLimit, m_ArchiveStartPosition)); - m_Stream = stream; - m_Position = m_ArchiveStartPosition + NHeader::kMarkerSize; - return m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL); -} - -void CInArchive::ThrowUnexpectedEndOfArchiveException() -{ - ThrowExceptionWithCode(CInArchiveException::kUnexpectedEndOfArchive); -} - -bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) +HRESULT CInArchive::ReadBytesSpec(void *data, size_t *resSize) { if (m_CryptoMode) { + size_t size = *resSize; + *resSize = 0; const Byte *bufData = m_DecryptedDataAligned; UInt32 bufSize = m_DecryptedDataSize; - UInt32 i; + size_t i; for (i = 0; i < size && m_CryptoPos < bufSize; i++) ((Byte *)data)[i] = bufData[m_CryptoPos++]; - return (i == size); + *resSize = i; + return S_OK; } - return (ReadStream_FALSE(m_Stream, data, size) == S_OK); -} - -void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size) -{ - if(!ReadBytesAndTestSize(data,size)) - ThrowUnexpectedEndOfArchiveException(); -} - -HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) -{ - size_t realProcessedSize = size; - HRESULT result = ReadStream(m_Stream, data, &realProcessedSize); - if (processedSize != NULL) - *processedSize = (UInt32)realProcessedSize; - AddToSeekValue(realProcessedSize); - return result; -} - -static UInt32 CrcUpdateUInt16(UInt32 crc, UInt16 v) -{ - crc = CRC_UPDATE_BYTE(crc, (Byte)(v & 0xFF)); - crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 8) & 0xFF)); - return crc; + return ReadStream(m_Stream, data, resSize); } -static UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 v) +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) { - crc = CRC_UPDATE_BYTE(crc, (Byte)(v & 0xFF)); - crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 8) & 0xFF)); - crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 16) & 0xFF)); - crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 24) & 0xFF)); - return crc; + size_t processed = size; + if (ReadBytesSpec(data, &processed) != S_OK) + return false; + return processed == size; } - HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { m_CryptoMode = false; RINOK(stream->Seek(0, STREAM_SEEK_SET, &m_StreamStartPosition)); m_Position = m_StreamStartPosition; - RINOK(FindAndReadMarker(stream, searchHeaderSizeLimit)); + UInt64 arcStartPos; + RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize, + searchHeaderSizeLimit, arcStartPos)); + m_Position = arcStartPos + NHeader::kMarkerSize; + RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); + Byte buf[NHeader::NArchive::kArchiveHeaderSize + 1]; - Byte buf[NHeader::NArchive::kArchiveHeaderSize]; - UInt32 processedSize; - ReadBytes(buf, sizeof(buf), &processedSize); - if (processedSize != sizeof(buf)) - return S_FALSE; - m_CurData = buf; - m_CurPos = 0; - m_PosLimit = sizeof(buf); - - m_ArchiveHeader.CRC = ReadUInt16(); - m_ArchiveHeader.Type = ReadByte(); - m_ArchiveHeader.Flags = ReadUInt16(); - m_ArchiveHeader.Size = ReadUInt16(); - m_ArchiveHeader.Reserved1 = ReadUInt16(); - m_ArchiveHeader.Reserved2 = ReadUInt32(); - m_ArchiveHeader.EncryptVersion = 0; - - UInt32 crc = CRC_INIT_VAL; - crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.Type); - crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Flags); - crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Size); - crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Reserved1); - crc = CrcUpdateUInt32(crc, m_ArchiveHeader.Reserved2); - - if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize) + RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize)); + AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize); + + + UInt32 blockSize = Get16(buf + 5); + + _header.EncryptVersion = 0; + _header.Flags = Get16(buf + 3); + + UInt32 headerSize = NHeader::NArchive::kArchiveHeaderSize; + if (_header.IsThereEncryptVer()) { - ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize); - if (processedSize != 1) + if (blockSize <= headerSize) return S_FALSE; - crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.EncryptVersion); + RINOK(ReadStream_FALSE(stream, buf + NHeader::NArchive::kArchiveHeaderSize, 1)); + AddToSeekValue(1); + _header.EncryptVersion = buf[NHeader::NArchive::kArchiveHeaderSize]; + headerSize += 1; } - - if(m_ArchiveHeader.CRC != (CRC_GET_DIGEST(crc) & 0xFFFF)) - ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); - if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader) + if (blockSize < headerSize || + buf[2] != NHeader::NBlockType::kArchiveHeader || + (UInt32)Get16(buf) != (CrcCalc(buf + 2, headerSize - 2) & 0xFFFF)) return S_FALSE; - m_ArchiveCommentPosition = m_Position; - m_SeekOnArchiveComment = true; - return S_OK; -} -void CInArchive::SkipArchiveComment() -{ - if (!m_SeekOnArchiveComment) - return; - AddToSeekValue(m_ArchiveHeader.Size - m_ArchiveHeader.GetBaseSize()); - m_SeekOnArchiveComment = false; + size_t commentSize = blockSize - headerSize; + _comment.SetCapacity(commentSize); + RINOK(ReadStream_FALSE(stream, _comment, commentSize)); + AddToSeekValue(commentSize); + m_Stream = stream; + _header.StartPosition = arcStartPos; + return S_OK; } void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const { - archiveInfo.StartPosition = m_ArchiveStartPosition; - archiveInfo.Flags = m_ArchiveHeader.Flags; - archiveInfo.CommentPosition = m_ArchiveCommentPosition; - archiveInfo.CommentSize = (UInt16)(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize); + archiveInfo = _header; } static void DecodeUnicodeFileName(const char *name, const Byte *encName, @@ -375,26 +323,21 @@ void CInArchive::AddToSeekValue(UInt64 addValue) HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage) { decryptionError = false; - if (m_SeekOnArchiveComment) - SkipArchiveComment(); for (;;) { - if (!SeekInArchive(m_Position)) - return S_FALSE; - if (!m_CryptoMode && (m_ArchiveHeader.Flags & + SeekInArchive(m_Position); + if (!m_CryptoMode && (_header.Flags & NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) { m_CryptoMode = false; if (getTextPassword == 0) return S_FALSE; - if(!SeekInArchive(m_Position)) - return S_FALSE; if (!m_RarAES) { m_RarAESSpec = new NCrypto::NRar29::CDecoder; m_RarAES = m_RarAESSpec; } - m_RarAESSpec->SetRar350Mode(m_ArchiveHeader.IsEncryptOld()); + m_RarAESSpec->SetRar350Mode(_header.IsEncryptOld()); // Salt const UInt32 kSaltSize = 8; @@ -438,9 +381,12 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa } m_FileHeaderData.EnsureCapacity(7); - if (!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7)) + size_t processed = 7; + RINOK(ReadBytesSpec((Byte *)m_FileHeaderData, &processed)); + if (processed != 7) { - errorMessage = "Unexpected end of archive"; + if (processed != 0) + errorMessage = k_UnexpectedEnd; return S_FALSE; } @@ -463,7 +409,12 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize); m_CurData = (Byte *)m_FileHeaderData; m_PosLimit = m_BlockHeader.HeadSize; - ReadBytesAndTestResult(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7); + if (!ReadBytesAndTestSize(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7)) + { + errorMessage = k_UnexpectedEnd; + return S_FALSE; + } + ReadHeaderReal(item); if ((CrcCalc(m_CurData + 2, m_BlockHeader.HeadSize - item.CommentSize - 2) & 0xFFFF) != m_BlockHeader.CRC) @@ -478,19 +429,25 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10)) { decryptionError = true; + errorMessage = k_DecryptionError; return S_FALSE; } if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) { m_FileHeaderData.EnsureCapacity(7 + 4); m_CurData = (Byte *)m_FileHeaderData; - ReadBytesAndTestResult(m_CurData + m_CurPos, 4); // test it + if (!ReadBytesAndTestSize(m_CurData + m_CurPos, 4)) + { + errorMessage = k_UnexpectedEnd; + return S_FALSE; + } m_PosLimit = 7 + 4; UInt32 dataSize = ReadUInt32(); AddToSeekValue(dataSize); if (m_CryptoMode && dataSize > (1 << 27)) { decryptionError = true; + errorMessage = k_DecryptionError; return S_FALSE; } m_CryptoPos = m_BlockHeader.HeadSize; @@ -503,11 +460,9 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa } } -bool CInArchive::SeekInArchive(UInt64 position) +void CInArchive::SeekInArchive(UInt64 position) { - UInt64 newPosition; - m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition); - return newPosition == position; + m_Stream->Seek(position, STREAM_SEEK_SET, NULL); } ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h index 75c98cc4..a6998db2 100755 --- a/CPP/7zip/Archive/Rar/RarIn.h +++ b/CPP/7zip/Archive/Rar/RarIn.h @@ -33,18 +33,20 @@ public: CInArchiveException(CCauseType cause) : Cause(cause) {} }; -class CInArchiveInfo + +struct CInArchiveInfo { -public: + UInt32 Flags; + Byte EncryptVersion; UInt64 StartPosition; - UInt16 Flags; - UInt64 CommentPosition; - UInt16 CommentSize; + bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; } bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } + bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; } + bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } }; class CInArchive @@ -52,23 +54,19 @@ class CInArchive CMyComPtr<IInStream> m_Stream; UInt64 m_StreamStartPosition; - UInt64 m_Position; - UInt64 m_ArchiveStartPosition; - NHeader::NArchive::CHeader360 m_ArchiveHeader; + CInArchiveInfo _header; CDynamicBuffer<char> m_NameBuffer; CDynamicBuffer<wchar_t> _unicodeNameBuffer; - bool m_SeekOnArchiveComment; - UInt64 m_ArchiveCommentPosition; + + CByteBuffer _comment; void ReadName(CItemEx &item, int nameSize); void ReadHeaderReal(CItemEx &item); - HRESULT ReadBytes(void *data, UInt32 size, UInt32 *aProcessedSize); + HRESULT ReadBytesSpec(void *data, size_t *size); bool ReadBytesAndTestSize(void *data, UInt32 size); - void ReadBytesAndTestResult(void *data, UInt32 size); - HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit); HRESULT Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit); void ThrowExceptionWithCode(CInArchiveException::CCauseType cause); @@ -108,15 +106,15 @@ class CInArchive } public: + UInt64 m_Position; + HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); void Close(); HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError, AString &errorMessage); - void SkipArchiveComment(); - void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; - bool SeekInArchive(UInt64 position); + void SeekInArchive(UInt64 position); ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); }; diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h index 2ca5dbc2..f3c49653 100755 --- a/CPP/7zip/MyVersion.h +++ b/CPP/7zip/MyVersion.h @@ -1,8 +1,8 @@ #define MY_VER_MAJOR 9 -#define MY_VER_MINOR 18 +#define MY_VER_MINOR 19 #define MY_VER_BUILD 0 -#define MY_VERSION "9.18 beta" -#define MY_7ZIP_VERSION "7-Zip 9.18 beta" -#define MY_DATE "2010-11-02" +#define MY_VERSION "9.19 beta" +#define MY_7ZIP_VERSION "7-Zip 9.19 beta" +#define MY_DATE "2010-11-11" #define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index f38cf874..8ae2e15e 100755 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -187,6 +187,7 @@ static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfil static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line"; static const char *kTerminalOutError = "I won't write compressed data to a terminal"; static const char *kSameTerminalError = "I won't write data and program's messages to same terminal"; +static const char *kEmptyFilePath = "Empty file path"; static void ThrowException(const char *errorMessage) { @@ -301,6 +302,8 @@ static void AddToCensorFromNonSwitchesStrings( for (int i = startIndex; i < nonSwitchStrings.Size(); i++) { const UString &s = nonSwitchStrings[i]; + if (s.IsEmpty()) + throw kEmptyFilePath; if (s[0] == kFileListID) AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage); else @@ -861,6 +864,8 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options) if (curCommandIndex >= numNonSwitchStrings) ThrowUserErrorException(); options.ArchiveName = nonSwitchStrings[curCommandIndex++]; + if (options.ArchiveName.IsEmpty()) + ThrowUserErrorException(); } AddToCensorFromNonSwitchesStrings( diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp index 15da3a2f..a57ec2a6 100755 --- a/CPP/7zip/UI/Common/Update.cpp +++ b/CPP/7zip/UI/Common/Update.cpp @@ -387,12 +387,11 @@ static HRESULT Compress( CMyComPtr<ISequentialOutStream> outStream; - const UString &archiveName = archivePath.GetFinalPath(); if (!stdOutMode) { UString resultPath; int pos; - if (!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) + if (!NFile::NDirectory::MyGetFullPathName(archivePath.GetFinalPath(), resultPath, pos)) throw 1417161; NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); } @@ -676,35 +675,38 @@ HRESULT UpdateArchive( } } - const UString archiveName = options.ArchivePath.GetFinalPath(); - - CArchiveLink archiveLink; - NFind::CFileInfoW archiveFileInfo; - - if (archiveFileInfo.Find(archiveName)) - { - if (archiveFileInfo.IsDir()) - throw "there is no such archive"; - if (options.VolumesSizes.Size() > 0) - return E_NOTIMPL; - CIntVector formatIndices; - if (options.MethodMode.FormatIndex >= 0) - formatIndices.Add(options.MethodMode.FormatIndex); - HRESULT result = archiveLink.Open2(codecs, formatIndices, false, NULL, archiveName, openCallback); - if (result == E_ABORT) - return result; - RINOK(callback->OpenResult(archiveName, result)); - RINOK(result); - if (archiveLink.VolumePaths.Size() > 1) + + CArchiveLink arcLink; + const UString arcPath = options.ArchivePath.GetFinalPath(); + + if (!options.ArchivePath.OriginalPath.IsEmpty()) + { + NFind::CFileInfoW fi; + if (fi.Find(arcPath)) { - errorInfo.SystemError = (DWORD)E_NOTIMPL; - errorInfo.Message = L"Updating for multivolume archives is not implemented"; - return E_NOTIMPL; + if (fi.IsDir()) + throw "there is no such archive"; + if (options.VolumesSizes.Size() > 0) + return E_NOTIMPL; + CIntVector formatIndices; + if (options.MethodMode.FormatIndex >= 0) + formatIndices.Add(options.MethodMode.FormatIndex); + HRESULT result = arcLink.Open2(codecs, formatIndices, false, NULL, arcPath, openCallback); + if (result == E_ABORT) + return result; + RINOK(callback->OpenResult(arcPath, result)); + RINOK(result); + if (arcLink.VolumePaths.Size() > 1) + { + errorInfo.SystemError = (DWORD)E_NOTIMPL; + errorInfo.Message = L"Updating for multivolume archives is not implemented"; + return E_NOTIMPL; + } + + CArc &arc = arcLink.Arcs.Back(); + arc.MTimeDefined = !fi.IsDevice; + arc.MTime = fi.MTime; } - - CArc &arc = archiveLink.Arcs.Back(); - arc.MTimeDefined = !archiveFileInfo.IsDevice; - arc.MTime = archiveFileInfo.MTime; } else { @@ -771,7 +773,7 @@ HRESULT UpdateArchive( bool createTempFile = false; - bool thereIsInArchive = archiveLink.IsOpen; + bool thereIsInArchive = arcLink.IsOpen; if (!options.StdOutMode && options.UpdateArchiveItself) { @@ -800,7 +802,8 @@ HRESULT UpdateArchive( // ap.Temp = true; // ap.TempPrefix = tempDirPrefix; } - if (i > 0 || !createTempFile) + if (!options.StdOutMode && + (i > 0 || !createTempFile)) { const UString &path = ap.GetFinalPath(); if (NFind::DoesFileOrDirExist(path)) @@ -816,18 +819,18 @@ HRESULT UpdateArchive( CObjectVector<CArcItem> arcItems; if (thereIsInArchive) { - RINOK(EnumerateInArchiveItems(censor, archiveLink.Arcs.Back(), arcItems)); + RINOK(EnumerateInArchiveItems(censor, arcLink.Arcs.Back(), arcItems)); } RINOK(UpdateWithItemLists(codecs, options, - thereIsInArchive ? archiveLink.GetArchive() : 0, + thereIsInArchive ? arcLink.GetArchive() : 0, arcItems, dirItems, tempFiles, errorInfo, callback)); if (thereIsInArchive) { - RINOK(archiveLink.Close()); - archiveLink.Release(); + RINOK(arcLink.Close()); + arcLink.Release(); } tempFiles.Paths.Clear(); @@ -838,19 +841,19 @@ HRESULT UpdateArchive( CArchivePath &ap = options.Commands[0].ArchivePath; const UString &tempPath = ap.GetTempPath(); if (thereIsInArchive) - if (!NDirectory::DeleteFileAlways(archiveName)) + if (!NDirectory::DeleteFileAlways(arcPath)) { errorInfo.SystemError = ::GetLastError(); errorInfo.Message = L"7-Zip cannot delete the file"; - errorInfo.FileName = archiveName; + errorInfo.FileName = arcPath; return E_FAIL; } - if (!NDirectory::MyMoveFile(tempPath, archiveName)) + if (!NDirectory::MyMoveFile(tempPath, arcPath)) { errorInfo.SystemError = ::GetLastError(); errorInfo.Message = L"7-Zip cannot move the file"; errorInfo.FileName = tempPath; - errorInfo.FileName2 = archiveName; + errorInfo.FileName2 = arcPath; return E_FAIL; } } diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h index b5dc21cf..49af0092 100755 --- a/CPP/7zip/UI/Common/Update.h +++ b/CPP/7zip/UI/Common/Update.h @@ -1,20 +1,20 @@ // Update.h -#ifndef __UPDATE_H -#define __UPDATE_H +#ifndef __COMMON_UPDATE_H +#define __COMMON_UPDATE_H #include "Common/Wildcard.h" -#include "Windows/FileFind.h" -#include "../../Archive/IArchive.h" -#include "UpdateAction.h" #include "ArchiveOpenCallback.h" -#include "UpdateCallback.h" -#include "Property.h" #include "LoadCodecs.h" +#include "Property.h" +#include "UpdateAction.h" +#include "UpdateCallback.h" struct CArchivePath { + UString OriginalPath; + UString Prefix; // path(folder) prefix including slash UString Name; // base name UString BaseExtension; // archive type extension or "exe" extension @@ -28,11 +28,11 @@ struct CArchivePath void ParseFromPath(const UString &path) { + OriginalPath = path; + SplitPathToParts(path, Prefix, Name); - if (Name.IsEmpty()) - return; int dotPos = Name.ReverseFind(L'.'); - if (dotPos <= 0) + if (dotPos < 0) return; if (dotPos == Name.Length() - 1) { diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp index bae33478..30ed5f99 100755 --- a/CPP/7zip/UI/Console/UserInputUtils.cpp +++ b/CPP/7zip/UI/Console/UserInputUtils.cpp @@ -53,9 +53,33 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) } } +#ifdef _WIN32 +#ifndef UNDER_CE +#define MY_DISABLE_ECHO +#endif +#endif + UString GetPassword(CStdOutStream *outStream) { - (*outStream) << "\nEnter password:"; + (*outStream) << "\nEnter password" + #ifdef MY_DISABLE_ECHO + " (will not be echoed)" + #endif + ":"; outStream->Flush(); + + #ifdef MY_DISABLE_ECHO + HANDLE console = GetStdHandle(STD_INPUT_HANDLE); + bool wasChanged = false; + DWORD mode = 0; + if (console != INVALID_HANDLE_VALUE && console != 0) + if (GetConsoleMode(console, &mode)) + wasChanged = (SetConsoleMode(console, mode & ~ENABLE_ECHO_INPUT) != 0); + UString res = g_StdIn.ScanUStringUntilNewLine(); + if (wasChanged) + SetConsoleMode(console, mode); + return res; + #else return g_StdIn.ScanUStringUntilNewLine(); + #endif } diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp index bec08e0d..f70572b9 100755 --- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp +++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp @@ -125,6 +125,8 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) } case 'A': { + // probably that code is unused ? + /* bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; if (ctrl) { @@ -133,6 +135,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) _listView.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); return true; } + */ } } } diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp index 6b8fdba2..10a8b73c 100755 --- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp +++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp @@ -210,7 +210,7 @@ static const char *kStartExtensions = #endif " exe bat com" " chm" - " msi doc xls ppt pps wps wpt wks xlr wdb vsd" + " msi doc xls ppt pps wps wpt wks xlr wdb vsd pub" " docx docm dotx dotm xlsx xlsm xltx xltm xlsb" " xlam pptx pptm potx potm ppam ppsx ppsm xsn" diff --git a/CPP/7zip/UI/FileManager/PanelItems.cpp b/CPP/7zip/UI/FileManager/PanelItems.cpp index 90d61b86..17cc3fcb 100755 --- a/CPP/7zip/UI/FileManager/PanelItems.cpp +++ b/CPP/7zip/UI/FileManager/PanelItems.cpp @@ -439,6 +439,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool { if (focusedPos >= _listView.GetItemCount()) focusedPos = _listView.GetItemCount() - 1; + // we select item only in showDots mode. SetFocusedSelectedItem(focusedPos, showDots); } // m_RedrawEnabled = true; @@ -484,7 +485,7 @@ void CPanel::GetOperatedItemIndices(CRecordVector<UInt32> &indices) const { int realIndex = GetRealItemIndex(focusedItem); if (realIndex != kParentIndex) - indices.Add(realIndex); + indices.Add(realIndex); } } } diff --git a/CPP/7zip/UI/FileManager/PanelSelect.cpp b/CPP/7zip/UI/FileManager/PanelSelect.cpp index 64cef433..29cf576b 100755 --- a/CPP/7zip/UI/FileManager/PanelSelect.cpp +++ b/CPP/7zip/UI/FileManager/PanelSelect.cpp @@ -245,7 +245,14 @@ void CPanel::KillSelection() { int focused = _listView.GetFocusedItem(); if (focused >= 0) + { + // CPanel::OnItemChanged notify for LVIS_SELECTED change doesn't work here. Why? + // so we change _selectedStatusVector[realIndex] here. + int realIndex = GetRealItemIndex(focused); + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = true; _listView.SetItemState(focused, LVIS_SELECTED, LVIS_SELECTED); + } } } @@ -297,4 +304,3 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate) } return; } - diff --git a/CPP/Common/CommandLineParser.cpp b/CPP/Common/CommandLineParser.cpp index 6de5e63b..80b467fc 100755 --- a/CPP/Common/CommandLineParser.cpp +++ b/CPP/Common/CommandLineParser.cpp @@ -6,7 +6,7 @@ namespace NCommandLineParser { -void SplitCommandLine(const UString &src, UString &dest1, UString &dest2) +bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) { dest1.Empty(); dest2.Empty(); @@ -15,17 +15,17 @@ void SplitCommandLine(const UString &src, UString &dest1, UString &dest2) for (i = 0; i < src.Length(); i++) { wchar_t c = src[i]; - if (c == L'\"') - quoteMode = !quoteMode; - else if (c == L' ' && !quoteMode) + if (c == L' ' && !quoteMode) { - i++; - break; + dest2 = src.Mid(i + 1); + return i != 0; } + if (c == L'\"') + quoteMode = !quoteMode; else dest1 += c; } - dest2 = src.Mid(i); + return i != 0; } void SplitCommandLine(const UString &s, UStringVector &parts) @@ -36,10 +36,7 @@ void SplitCommandLine(const UString &s, UStringVector &parts) for (;;) { UString s1, s2; - SplitCommandLine(sTemp, s1, s2); - // s1.Trim(); - // s2.Trim(); - if (!s1.IsEmpty()) + if (SplitCommandLine(sTemp, s1, s2)) parts.Add(s1); if (s2.IsEmpty()) break; diff --git a/CPP/Common/CommandLineParser.h b/CPP/Common/CommandLineParser.h index c57da9c4..3d0b41dd 100755 --- a/CPP/Common/CommandLineParser.h +++ b/CPP/Common/CommandLineParser.h @@ -1,13 +1,13 @@ // Common/CommandLineParser.h -#ifndef __COMMON_COMMANDLINEPARSER_H -#define __COMMON_COMMANDLINEPARSER_H +#ifndef __COMMON_COMMAND_LINE_PARSER_H +#define __COMMON_COMMAND_LINE_PARSER_H #include "MyString.h" namespace NCommandLineParser { -void SplitCommandLine(const UString &src, UString &dest1, UString &dest2); +bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2); void SplitCommandLine(const UString &s, UStringVector &parts); namespace NSwitchType { diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp index ac77e39b..476ddebd 100755 --- a/CPP/Common/Wildcard.cpp +++ b/CPP/Common/Wildcard.cpp @@ -374,6 +374,8 @@ int CCensor::FindPrefix(const UString &prefix) const void CCensor::AddItem(bool include, const UString &path, bool recursive) { UStringVector pathParts; + if (path.IsEmpty()) + throw "Empty file path"; SplitPathToParts(path, pathParts); bool forFile = true; if (pathParts.Back().IsEmpty()) diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp index 81fcd6ef..85794603 100755 --- a/CPP/Windows/FileDir.cpp +++ b/CPP/Windows/FileDir.cpp @@ -474,7 +474,7 @@ bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartS { resultPath = fileName; // change it - fileNamePartStartIndex = resultPath.ReverseFind('\\'); + fileNamePartStartIndex = resultPath.ReverseFind(WCHAR_PATH_SEPARATOR); fileNamePartStartIndex++; return true; } @@ -488,6 +488,38 @@ bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath) return (needLength > 0 && needLength < MAX_PATH); } +#ifdef WIN_LONG_PATH + +static UString GetLastPart(LPCWSTR path) +{ + int i = (int)wcslen(path); + for (; i > 0; i--) + { + WCHAR c = path[i - 1]; + if (c == WCHAR_PATH_SEPARATOR || c == '/') + break; + } + return path + i; +} + +static void AddTrailingDots(LPCWSTR oldPath, UString &newPath) +{ + int len = (int)wcslen(oldPath); + int i; + for (i = len; i > 0 && oldPath[i - 1] == '.'; i--); + if (i == 0 || i == len) + return; + UString oldName = GetLastPart(oldPath); + UString newName = GetLastPart(newPath); + int nonDotsLen = oldName.Length() - (len - i); + if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0) + return; + for (; i != len; i++) + newPath += '.'; +} + +#endif + bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex) { resultPath.Empty(); @@ -512,6 +544,11 @@ bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePa fileNamePartStartIndex = lstrlen(fileName); else fileNamePartStartIndex = (int)(fileNamePointer - buffer); + #ifdef _UNICODE + #ifdef WIN_LONG_PATH + AddTrailingDots(fileName, resultPath); + #endif + #endif return true; } @@ -542,6 +579,9 @@ bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartS fileNamePartStartIndex = MyStringLen(fileName); else fileNamePartStartIndex = (int)(fileNamePointer - buffer); + #ifdef WIN_LONG_PATH + AddTrailingDots(fileName, resultPath); + #endif } else { |