diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2009-08-17 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:00 +0300 |
commit | c99f3ebdd639c2adb03d8b44001b10af18516504 (patch) | |
tree | 92aaf34e5edbd7287c3f55037190da75ab0a8000 /CPP/7zip/Archive | |
parent | 829409452d85cd6dd9dfc9151f109d6e13a2bb1c (diff) |
9.06 beta
Diffstat (limited to 'CPP/7zip/Archive')
73 files changed, 3231 insertions, 988 deletions
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp index c97f893b..86753acd 100755 --- a/CPP/7zip/Archive/7z/7zEncode.cpp +++ b/CPP/7zip/Archive/7z/7zEncode.cpp @@ -164,8 +164,7 @@ HRESULT CEncoder::Encode( } for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { - CSequentialOutTempBufferImp *tempBufferSpec = - new CSequentialOutTempBufferImp; + CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp; CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec; tempBufferSpec->Init(&inOutTempBuffers[i - 1]); tempBuffers.Add(tempBuffer); @@ -260,9 +259,7 @@ HRESULT CEncoder::Encode( for (i = 1; i < _bindInfo.OutStreams.Size(); i++) { CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1]; - inOutTempBuffer.FlushWrite(); - inOutTempBuffer.InitReading(); - inOutTempBuffer.WriteToStream(outStream); + RINOK(inOutTempBuffer.WriteToStream(outStream)); packSizes.Add(inOutTempBuffer.GetDataSize()); } diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp index 06e9ef97..1b0f9ea1 100755 --- a/CPP/7zip/Archive/7z/7zExtract.cpp +++ b/CPP/7zip/Archive/7z/7zExtract.cpp @@ -44,7 +44,7 @@ struct CExtractFolderInfo }; }; -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) { COM_TRY_BEGIN @@ -52,7 +52,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; UInt64 importantTotalUnpacked = 0; - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = #ifdef _7Z_VOL @@ -244,25 +244,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (result == S_FALSE) { - RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); continue; } if (result == E_NOTIMPL) { - RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnSupportedMethod)); continue; } if (result != S_OK) return result; if (folderOutStream->WasWritingFinished() != S_OK) { - RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); continue; } } catch(...) { - RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); continue; } } diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp index 75505863..c5dbfa6d 100755 --- a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp +++ b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp @@ -37,9 +37,9 @@ HRESULT CFolderOutStream::Init( HRESULT CFolderOutStream::OpenFile() { Int32 askMode = ((*_extractStatuses)[_currentIndex]) ? (_testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract): - NArchive::NExtract::NAskMode::kSkip; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kSkip; CMyComPtr<ISequentialOutStream> realOutStream; UInt32 index = _startIndex + _currentIndex; RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode)); @@ -48,9 +48,9 @@ HRESULT CFolderOutStream::OpenFile() _fileIsOpen = true; const CFileItem &fi = _db->Files[index]; _rem = fi.Size; - if (askMode == NArchive::NExtract::NAskMode::kExtract && !realOutStream && + if (askMode == NExtract::NAskMode::kExtract && !realOutStream && !_db->IsItemAnti(index) && !fi.IsDir) - askMode = NArchive::NExtract::NAskMode::kSkip; + askMode = NExtract::NAskMode::kSkip; return _extractCallback->PrepareOperation(askMode); } @@ -67,8 +67,8 @@ HRESULT CFolderOutStream::CloseFileAndSetResult() const CFileItem &fi = _db->Files[_startIndex + _currentIndex]; return CloseFileAndSetResult( (fi.IsDir || !fi.CrcDefined || !_checkCrc || fi.Crc == _crcStreamSpec->GetCRC()) ? - NArchive::NExtract::NOperationResult::kOK : - NArchive::NExtract::NOperationResult::kCRCError); + NExtract::NOperationResult::kOK : + NExtract::NOperationResult::kCRCError); } HRESULT CFolderOutStream::ProcessEmptyFiles() diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp index 6f0cf6b2..136d0c5f 100755 --- a/CPP/7zip/Archive/7z/7zHandler.cpp +++ b/CPP/7zip/Archive/7z/7zHandler.cpp @@ -300,11 +300,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va else if (coder.MethodID == k_PPMD && coder.Props.GetCapacity() == 5) { Byte order = *(const Byte *)coder.Props; - methodsString += L'o'; - methodsString += ConvertUInt32ToString(order); - methodsString += L":mem"; + propsString = L'o'; + propsString += ConvertUInt32ToString(order); + propsString += L":mem"; UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1); - propsString = GetStringForSizeValue(dicSize); + propsString += GetStringForSizeValue(dicSize); } else if (coder.MethodID == k_AES && coder.Props.GetCapacity() >= 1) { diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp index e2c250ab..813510c8 100755 --- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp +++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -27,7 +27,13 @@ static const wchar_t *kDefaultMethodName = kLZMAMethodName; static const UInt32 kLzmaAlgorithmX5 = 1; static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; -static const UInt32 kDictionaryForHeaders = 1 << 20; +static const UInt32 kDictionaryForHeaders = + #ifdef UNDER_CE + 1 << 18 + #else + 1 << 20 + #endif +; static const UInt32 kNumFastBytesForHeaders = 273; static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5; diff --git a/CPP/7zip/Archive/7z/7zHeader.cpp b/CPP/7zip/Archive/7z/7zHeader.cpp index f232a23e..5b5f2fb3 100755 --- a/CPP/7zip/Archive/7z/7zHeader.cpp +++ b/CPP/7zip/Archive/7z/7zHeader.cpp @@ -1,4 +1,4 @@ -// 7z/Header.cpp +// 7zHeader.cpp #include "StdAfx.h" #include "7zHeader.h" @@ -6,22 +6,9 @@ namespace NArchive { namespace N7z { -Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}; +Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; #ifdef _7Z_VOL -Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; +Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; #endif -class SignatureInitializer -{ -public: - SignatureInitializer() - { - kSignature[0]--; - #ifdef _7Z_VOL - kFinishSignature[0]--; - #endif - }; -} g_SignatureInitializer; - }} - diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp index e897680e..8d241d74 100755 --- a/CPP/7zip/Archive/7z/7zOut.cpp +++ b/CPP/7zip/Archive/7z/7zOut.cpp @@ -541,16 +541,16 @@ void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) HRESULT COutArchive::EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const Byte *data, size_t dataSize, + CEncoder &encoder, const CByteBuffer &data, CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders) { - CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp; + CBufInStream *streamSpec = new CBufInStream; CMyComPtr<ISequentialInStream> stream = streamSpec; - streamSpec->Init(data, dataSize); + streamSpec->Init(data, data.GetCapacity()); CFolder folderItem; folderItem.UnpackCRCDefined = true; - folderItem.UnpackCRC = CrcCalc(data, dataSize); - UInt64 dataSize64 = dataSize; + folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity()); + UInt64 dataSize64 = data.GetCapacity(); RINOK(encoder.Encode( EXTERNAL_CODECS_LOC_VARS stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL)) @@ -558,16 +558,6 @@ HRESULT COutArchive::EncodeStream( return S_OK; } -HRESULT COutArchive::EncodeStream( - DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const CByteBuffer &data, - CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders) -{ - return EncodeStream( - EXTERNAL_CODECS_LOC_VARS - encoder, data, data.GetCapacity(), packSizes, folders); -} - void COutArchive::WriteHeader( const CArchiveDatabase &db, const CHeaderOptions &headerOptions, @@ -804,8 +794,8 @@ HRESULT COutArchive::WriteDatabase( CObjectVector<CFolder> folders; RINOK(EncodeStream( EXTERNAL_CODECS_LOC_VARS - encoder, (const Byte *)buf, - _countSize, packSizes, folders)); + encoder, buf, + packSizes, folders)); _writeToStream = true; diff --git a/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h index 9d8ef308..7b1b528e 100755 --- a/CPP/7zip/Archive/7z/7zOut.h +++ b/CPP/7zip/Archive/7z/7zOut.h @@ -100,10 +100,6 @@ class COutArchive HRESULT EncodeStream( DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const Byte *data, size_t dataSize, - CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); - HRESULT EncodeStream( - DECL_EXTERNAL_CODECS_LOC_VARS CEncoder &encoder, const CByteBuffer &data, CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); void WriteHeader( diff --git a/CPP/7zip/Archive/7z/7zRegister.cpp b/CPP/7zip/Archive/7z/7zRegister.cpp index e18c4d74..af59b644 100755 --- a/CPP/7zip/Archive/7z/7zRegister.cpp +++ b/CPP/7zip/Archive/7z/7zRegister.cpp @@ -5,14 +5,14 @@ #include "../../Common/RegisterArc.h" #include "7zHandler.h" -static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; } +static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; } #ifndef EXTRACT_ONLY -static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; } +static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; } #else #define CreateArcOut 0 #endif static CArcInfo g_ArcInfo = - { L"7z", L"7z", 0, 7, {'7' + 1 , 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut }; + { L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut }; REGISTER_ARC_DEC_SIG(7z) diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp index 9506e8f7..d1082808 100755 --- a/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../../C/CpuArch.h" + #include "../../Common/LimitedStreams.h" #include "../../Common/ProgressUtils.h" @@ -32,6 +34,10 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20; static const UInt32 kAlgorithmForBCJ2_LZMA = 1; static const UInt32 kNumFastBytesForBCJ2_LZMA = 64; +#ifdef MY_CPU_X86_OR_AMD64 +#define USE_86_FILTER +#endif + static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, UInt64 position, UInt64 size, ICompressProgressInfo *progress) { @@ -122,7 +128,7 @@ static int CompareFiles(const CFileItem &f1, const CFileItem &f2) } */ -const struct CFolderRepack +struct CFolderRepack { int FolderIndex; int Group; @@ -334,7 +340,9 @@ static bool IsExeExt(const UString &ext) return false; } -static void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult) +#ifdef USE_86_FILTER + +static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult) { methodResult.Id = methodID; methodResult.NumInStreams = numInStreams; @@ -409,6 +417,8 @@ static void MakeExeMethod(const CCompressionMethodMode &method, } } +#endif + static void FromUpdateItemToFileItem(const CUpdateItem &ui, CFileItem &file, CFileItem2 &file2) { @@ -665,7 +675,9 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password) static const int kNumGroupsMax = 4; +#ifdef USE_86_FILTER static bool Is86Group(int group) { return (group & 1) != 0; } +#endif static bool IsEncryptedGroup(int group) { return (group & 2) != 0; } static int GetGroupIndex(bool encrypted, int bcjFiltered) { return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); } @@ -865,9 +877,11 @@ HRESULT Update( const CSolidGroup &group = groups[groupIndex]; CCompressionMethodMode method; + #ifdef USE_86_FILTER if (Is86Group(groupIndex)) MakeExeMethod(*options.Method, options.MaxFilter, method); else + #endif method = *options.Method; if (IsEncryptedGroup(groupIndex)) diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile index 4489f290..baedf862 100755 --- a/CPP/7zip/Archive/7z/makefile +++ b/CPP/7zip/Archive/7z/makefile @@ -4,8 +4,6 @@ CFLAGS = $(CFLAGS) -I ../../../ \ -DCOMPRESS_MT \ -DEXTERNAL_CODECS \ -LIBS = $(LIBS) oleaut32.lib user32.lib - AR_OBJS = \ $O\ArchiveExports.obj \ $O\DllExports.obj \ diff --git a/CPP/7zip/Archive/ArchiveExports.cpp b/CPP/7zip/Archive/ArchiveExports.cpp index f7bc9c69..5dcf9806 100755 --- a/CPP/7zip/Archive/ArchiveExports.cpp +++ b/CPP/7zip/Archive/ArchiveExports.cpp @@ -10,11 +10,17 @@ static const unsigned int kNumArcsMax = 48; static unsigned int g_NumArcs = 0; +static unsigned int g_DefaultArcIndex = 0; static const CArcInfo *g_Arcs[kNumArcsMax]; void RegisterArc(const CArcInfo *arcInfo) { if (g_NumArcs < kNumArcsMax) + { + const wchar_t *p = arcInfo->Name; + if (p[0] == '7' && p[1] == 'z' && p[2] == 0) + g_DefaultArcIndex = g_NumArcs; g_Arcs[g_NumArcs++] = arcInfo; + } } DEFINE_GUID(CLSID_CArchiveHandler, @@ -117,7 +123,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) { - return GetHandlerProperty2(0, propID, value); + return GetHandlerProperty2(g_DefaultArcIndex, propID, value); } STDAPI GetNumberOfFormats(UINT32 *numFormats) diff --git a/CPP/7zip/Archive/ArjHandler.cpp b/CPP/7zip/Archive/ArjHandler.cpp index 66ad1677..0620ae84 100755 --- a/CPP/7zip/Archive/ArjHandler.cpp +++ b/CPP/7zip/Archive/ArjHandler.cpp @@ -652,13 +652,12 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (testModeSpec != 0); UInt64 totalUnpacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -714,7 +713,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; } - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -789,7 +788,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, COM_TRY_END } -static IInArchive *CreateArc() { return new CHandler; } +static IInArchive *CreateArc() { return new CHandler; } static CArcInfo g_ArcInfo = { L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/Bz2Handler.cpp b/CPP/7zip/Archive/Bz2Handler.cpp index 9b2c4048..5d2620ba 100755 --- a/CPP/7zip/Archive/Bz2Handler.cpp +++ b/CPP/7zip/Archive/Bz2Handler.cpp @@ -154,28 +154,23 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)-1); - if (!allFilesMode) - { - if (numItems == 0) - return S_OK; - if (numItems != 1 || indices[0] != 0) - return E_INVALIDARG; - } + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; - bool testMode = (_aTestMode != 0); if (_stream) extractCallback->SetTotal(_packSize); UInt64 currentTotalPacked = 0; RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); if (!testMode && !realOutStream) return S_OK; @@ -421,7 +416,7 @@ static IOutArchive *CreateArcOut() { return new CHandler; } #endif static CArcInfo g_ArcInfo = - { L"BZip2", L"bz2 bzip2 tbz2 tbz", L"* * .tar .tar", 2, { 'B', 'Z', 'h' }, 3, true, CreateArc, CreateArcOut }; + { L"bzip2", L"bz2 bzip2 tbz2 tbz", L"* * .tar .tar", 2, { 'B', 'Z', 'h' }, 3, true, CreateArc, CreateArcOut }; REGISTER_ARC(BZip2) diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp index ad015aaf..480a9a8a 100755 --- a/CPP/7zip/Archive/Cab/CabHandler.cpp +++ b/CPP/7zip/Archive/Cab/CabHandler.cpp @@ -2,6 +2,7 @@ #include "StdAfx.h" +#include "Common/Buffer.h" #include "Common/ComTry.h" #include "Common/Defs.h" #include "Common/IntToString.h" @@ -12,6 +13,7 @@ #include "Windows/Time.h" #include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" #include "../../Compress/CopyCoder.h" #include "../../Compress/DeflateDecoder.h" @@ -30,6 +32,8 @@ namespace NCab { // #define _CAB_DETAILS +static const UInt32 kMaxTempBufSize = 1 << 20; + #ifdef _CAB_DETAILS enum { @@ -279,7 +283,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, { const CInArchiveInfo &ai = m_Database.Volumes.Front().ArchiveInfo; if (ai.IsTherePrev()) - otherArchive = &ai.PreviousArchive; + otherArchive = &ai.PrevArc; else prevChecked = true; } @@ -287,7 +291,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, { const CInArchiveInfo &ai = m_Database.Volumes.Back().ArchiveInfo; if (ai.IsThereNext()) - otherArchive = &ai.NextArchive; + otherArchive = &ai.NextArc; } if (!otherArchive) break; @@ -328,7 +332,7 @@ STDMETHODIMP CHandler::Close() return S_OK; } -class CCabFolderOutStream: +class CFolderOutStream: public ISequentialOutStream, public CMyUnknownImp { @@ -339,6 +343,12 @@ public: private: const CMvDatabaseEx *m_Database; const CRecordVector<bool> *m_ExtractStatuses; + + CByteBuffer TempBuf; + bool TempBufMode; + bool IsSupported; + UInt32 m_BufStartFolderOffset; + int m_StartIndex; int m_CurrentIndex; CMyComPtr<IArchiveExtractCallback> m_ExtractCallback; @@ -348,11 +358,12 @@ private: bool m_IsOk; bool m_FileIsOpen; - UInt64 m_RemainFileSize; + UInt32 m_RemainFileSize; UInt64 m_FolderSize; UInt64 m_PosInFolder; HRESULT OpenFile(); + HRESULT CloseFile(); HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); public: HRESULT WriteEmptyFiles(); @@ -371,7 +382,7 @@ public: UInt64 GetPosInFolder() const { return m_PosInFolder; } }; -void CCabFolderOutStream::Init( +void CFolderOutStream::Init( const CMvDatabaseEx *database, const CRecordVector<bool> *extractStatuses, int startIndex, @@ -391,25 +402,66 @@ void CCabFolderOutStream::Init( m_PosInFolder = 0; m_FileIsOpen = false; m_IsOk = true; + TempBufMode = false; +} + +HRESULT CFolderOutStream::CloseFile() +{ + m_RealOutStream.Release(); + HRESULT res = m_ExtractCallback->SetOperationResult(m_IsOk ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError); + m_FileIsOpen = false; + return res; } -HRESULT CCabFolderOutStream::OpenFile() +HRESULT CFolderOutStream::OpenFile() { Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract) : NExtract::NAskMode::kSkip; + + if (!TempBufMode) + { + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + int curIndex = m_CurrentIndex + 1; + for (; curIndex < m_ExtractStatuses->Size(); curIndex++) + if ((*m_ExtractStatuses)[curIndex]) + { + const CMvItem &mvItem2 = m_Database->Items[m_StartIndex + curIndex]; + const CItem &item2 = m_Database->Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex]; + if (item.Offset != item2.Offset || + item.Size != item2.Size || + item.Size == 0) + break; + } + if (curIndex > m_CurrentIndex + 1) + { + size_t oldCapacity = TempBuf.GetCapacity(); + IsSupported = (item.Size <= kMaxTempBufSize); + if (item.Size > oldCapacity && IsSupported) + { + TempBuf.SetCapacity(0); + TempBuf.SetCapacity(item.Size); + } + TempBufMode = true; + m_BufStartFolderOffset = item.Offset; + } + } + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); if (!m_RealOutStream && !m_TestMode) - askMode = NArchive::NExtract::NAskMode::kSkip; + askMode = NExtract::NAskMode::kSkip; return m_ExtractCallback->PrepareOperation(askMode); } -HRESULT CCabFolderOutStream::WriteEmptyFiles() +HRESULT CFolderOutStream::WriteEmptyFiles() { if (m_FileIsOpen) return S_OK; - for(;m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++) + for (; m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++) { const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; @@ -419,22 +471,23 @@ HRESULT CCabFolderOutStream::WriteEmptyFiles() HRESULT result = OpenFile(); m_RealOutStream.Release(); RINOK(result); - RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); } return S_OK; } // This is Write function -HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) +HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) { + COM_TRY_BEGIN UInt32 realProcessed = 0; if (processedSize != NULL) *processedSize = 0; - while(size != 0) + while (size != 0) { if (m_FileIsOpen) { - UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size)); + UInt32 numBytesToWrite = MyMin(m_RemainFileSize, size); HRESULT res = S_OK; if (numBytesToWrite > 0) { @@ -446,6 +499,8 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); numBytesToWrite = processedSizeLocal; } + if (TempBufMode && IsSupported) + memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite); } realProcessed += numBytesToWrite; if (processedSize != NULL) @@ -459,11 +514,37 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce if (m_RemainFileSize == 0) { m_RealOutStream.Release(); - RINOK(m_ExtractCallback->SetOperationResult( - m_IsOk ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); - m_FileIsOpen = false; + RINOK(CloseFile()); + + if (TempBufMode) + { + while (m_CurrentIndex < m_ExtractStatuses->Size()) + { + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.Offset != m_BufStartFolderOffset) + break; + HRESULT result = OpenFile(); + m_FileIsOpen = true; + m_CurrentIndex++; + m_IsOk = true; + if (result == S_OK && m_RealOutStream && IsSupported) + result = WriteStream(m_RealOutStream, TempBuf, item.Size); + + if (IsSupported) + { + RINOK(CloseFile()); + RINOK(result); + } + else + { + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); + m_FileIsOpen = false; + } + } + TempBufMode = false; + } } if (realProcessed > 0) break; // with this break this function works as Write-Part @@ -483,7 +564,7 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce return E_FAIL; if (fileOffset > m_PosInFolder) { - UInt32 numBytesToWrite = (UInt32)MyMin((UInt64)fileOffset - m_PosInFolder, UInt64(size)); + UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size); realProcessed += numBytesToWrite; if (processedSize != NULL) *processedSize = realProcessed; @@ -501,14 +582,15 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce } } return WriteEmptyFiles(); + COM_TRY_END } -STDMETHODIMP CCabFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { return Write2(data, size, processedSize, true); } -HRESULT CCabFolderOutStream::FlushCorrupted() +HRESULT CFolderOutStream::FlushCorrupted() { const UInt32 kBufferSize = (1 << 10); Byte buffer[kBufferSize]; @@ -525,7 +607,7 @@ HRESULT CCabFolderOutStream::FlushCorrupted() } } -HRESULT CCabFolderOutStream::Unsupported() +HRESULT CFolderOutStream::Unsupported() { while(m_CurrentIndex < m_ExtractStatuses->Size()) { @@ -533,23 +615,23 @@ HRESULT CCabFolderOutStream::Unsupported() if (result != S_FALSE && result != S_OK) return result; m_RealOutStream.Release(); - RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); m_CurrentIndex++; } return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = m_Database.Items.Size(); if(numItems == 0) return S_OK; - bool testMode = (_aTestMode != 0); + bool testMode = (testModeSpec != 0); UInt64 totalUnPacked = 0; UInt32 i; @@ -610,14 +692,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, i++; if (item.IsDir()) { - Int32 askMode= testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } int folderIndex = m_Database.GetFolderIndex(&mvItem); @@ -625,13 +707,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { // If we need previous archive Int32 askMode= testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError)); continue; } int startIndex2 = m_Database.FolderStartFileIndex[folderIndex]; @@ -664,7 +746,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, lps->InSize = totalPacked; RINOK(lps->SetCur()); - CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream; + CFolderOutStream *cabFolderOutStream = new CFolderOutStream; CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream); const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())]; diff --git a/CPP/7zip/Archive/Cab/CabHeader.cpp b/CPP/7zip/Archive/Cab/CabHeader.cpp index d1f71df3..0cba1b0b 100755 --- a/CPP/7zip/Archive/Cab/CabHeader.cpp +++ b/CPP/7zip/Archive/Cab/CabHeader.cpp @@ -1,15 +1,15 @@ -// Archive/Cab/Header.h +// CabHeader.cpp #include "StdAfx.h" #include "CabHeader.h" -namespace NArchive{ -namespace NCab{ -namespace NHeader{ +namespace NArchive { +namespace NCab { +namespace NHeader { -Byte kMarker[kMarkerSize] = {'M' + 1, 'S', 'C', 'F', 0, 0, 0, 0 }; +Byte kMarker[kMarkerSize] = {'M', 'S', 'C', 'F', 0, 0, 0, 0 }; -struct SignatureInitializer { SignatureInitializer() { kMarker[0]--; }; } g_SignatureInitializer; +// struct CSignatureInitializer { CSignatureInitializer() { kMarker[0]--; }; } g_SignatureInitializer; }}} diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp index afc0faed..c0bffa2d 100755 --- a/CPP/7zip/Archive/Cab/CabIn.cpp +++ b/CPP/7zip/Archive/Cab/CabIn.cpp @@ -2,14 +2,14 @@ #include "StdAfx.h" -#include "CabIn.h" - #include "../Common/FindSignature.h" +#include "CabIn.h" + namespace NArchive { namespace NCab { -Byte CInArchive::ReadByte() +Byte CInArchive::Read8() { Byte b; if (!inBuffer.ReadByte(b)) @@ -17,23 +17,23 @@ Byte CInArchive::ReadByte() return b; } -UInt16 CInArchive::ReadUInt16() +UInt16 CInArchive::Read16() { UInt16 value = 0; for (int i = 0; i < 2; i++) { - Byte b = ReadByte(); + Byte b = Read8(); value |= (UInt16(b) << (8 * i)); } return value; } -UInt32 CInArchive::ReadUInt32() +UInt32 CInArchive::Read32() { UInt32 value = 0; for (int i = 0; i < 4; i++) { - Byte b = ReadByte(); + Byte b = Read8(); value |= (UInt32(b) << (8 * i)); } return value; @@ -44,7 +44,7 @@ AString CInArchive::SafeReadName() AString name; for (;;) { - Byte b = ReadByte(); + Byte b = Read8(); if (b == 0) return name; name += (char)b; @@ -57,61 +57,60 @@ void CInArchive::ReadOtherArchive(COtherArchive &oa) oa.DiskName = SafeReadName(); } -void CInArchive::Skip(size_t size) +void CInArchive::Skip(UInt32 size) { while (size-- != 0) - ReadByte(); + Read8(); } -HRESULT CInArchive::Open2(IInStream *stream, - const UInt64 *searchHeaderSizeLimit, - CDatabase &database) +HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db) { - database.Clear(); - RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition)); + IInStream *stream = db.Stream; + db.Clear(); + RINOK(stream->Seek(0, STREAM_SEEK_SET, &db.StartPosition)); RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize, - searchHeaderSizeLimit, database.StartPosition)); + searchHeaderSizeLimit, db.StartPosition)); - RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL)); + RINOK(stream->Seek(db.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL)); if (!inBuffer.Create(1 << 17)) return E_OUTOFMEMORY; inBuffer.SetStream(stream); inBuffer.Init(); - CInArchiveInfo &ai = database.ArchiveInfo; + CInArchiveInfo &ai = db.ArchiveInfo; - ai.Size = ReadUInt32(); - if (ReadUInt32() != 0) + ai.Size = Read32(); + if (Read32() != 0) return S_FALSE; - ai.FileHeadersOffset = ReadUInt32(); - if (ReadUInt32() != 0) + ai.FileHeadersOffset = Read32(); + if (Read32() != 0) return S_FALSE; - ai.VersionMinor = ReadByte(); - ai.VersionMajor = ReadByte(); - ai.NumFolders = ReadUInt16(); - ai.NumFiles = ReadUInt16(); - ai.Flags = ReadUInt16(); + ai.VersionMinor = Read8(); + ai.VersionMajor = Read8(); + ai.NumFolders = Read16(); + ai.NumFiles = Read16(); + ai.Flags = Read16(); if (ai.Flags > 7) return S_FALSE; - ai.SetID = ReadUInt16(); - ai.CabinetNumber = ReadUInt16(); + ai.SetID = Read16(); + ai.CabinetNumber = Read16(); if (ai.ReserveBlockPresent()) { - ai.PerCabinetAreaSize = ReadUInt16(); - ai.PerFolderAreaSize = ReadByte(); - ai.PerDataBlockAreaSize = ReadByte(); + ai.PerCabinetAreaSize = Read16(); + ai.PerFolderAreaSize = Read8(); + ai.PerDataBlockAreaSize = Read8(); Skip(ai.PerCabinetAreaSize); } { if (ai.IsTherePrev()) - ReadOtherArchive(ai.PreviousArchive); + ReadOtherArchive(ai.PrevArc); if (ai.IsThereNext()) - ReadOtherArchive(ai.NextArchive); + ReadOtherArchive(ai.NextArc); } int i; @@ -119,54 +118,40 @@ HRESULT CInArchive::Open2(IInStream *stream, { CFolder folder; - folder.DataStart = ReadUInt32(); - folder.NumDataBlocks = ReadUInt16(); - folder.CompressionTypeMajor = ReadByte(); - folder.CompressionTypeMinor = ReadByte(); + folder.DataStart = Read32(); + folder.NumDataBlocks = Read16(); + folder.CompressionTypeMajor = Read8(); + folder.CompressionTypeMinor = Read8(); Skip(ai.PerFolderAreaSize); - database.Folders.Add(folder); + db.Folders.Add(folder); } - RINOK(stream->Seek(database.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL)); + RINOK(stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL)); inBuffer.SetStream(stream); inBuffer.Init(); for (i = 0; i < ai.NumFiles; i++) { CItem item; - item.Size = ReadUInt32(); - item.Offset = ReadUInt32(); - item.FolderIndex = ReadUInt16(); - UInt16 pureDate = ReadUInt16(); - UInt16 pureTime = ReadUInt16(); + item.Size = Read32(); + item.Offset = Read32(); + item.FolderIndex = Read16(); + UInt16 pureDate = Read16(); + UInt16 pureTime = Read16(); item.Time = ((UInt32(pureDate) << 16)) | pureTime; - item.Attributes = ReadUInt16(); + item.Attributes = Read16(); item.Name = SafeReadName(); - int folderIndex = item.GetFolderIndex(database.Folders.Size()); - if (folderIndex >= database.Folders.Size()) + int folderIndex = item.GetFolderIndex(db.Folders.Size()); + if (folderIndex >= db.Folders.Size()) return S_FALSE; - database.Items.Add(item); + db.Items.Add(item); } return S_OK; } #define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } -HRESULT CInArchive::Open( - const UInt64 *searchHeaderSizeLimit, - CDatabaseEx &database) -{ - return Open2(database.Stream, searchHeaderSizeLimit, database); -} - - -static int CompareMvItems2(const CMvItem *p1, const CMvItem *p2) -{ - RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex)); - return MyCompare(p1->ItemIndex, p2->ItemIndex); -} - static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param) { const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param; @@ -185,7 +170,8 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param) RINOZ(MyCompare(f1, f2)); RINOZ(MyCompare(item1.Offset, item2.Offset)); RINOZ(MyCompare(item1.Size, item2.Size)); - return CompareMvItems2(p1, p2); + RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex)); + return MyCompare(p1->ItemIndex, p2->ItemIndex); } bool CMvDatabaseEx::AreItemsEqual(int i1, int i2) @@ -236,8 +222,7 @@ void CMvDatabaseEx::FillSortAndShrink() for (i = 0; i < Items.Size(); i++) { - const CMvItem &mvItem = Items[i]; - int folderIndex = GetFolderIndex(&mvItem); + int folderIndex = GetFolderIndex(&Items[i]); if (folderIndex >= FolderStartFileIndex.Size()) FolderStartFileIndex.Add(i); } @@ -260,7 +245,8 @@ bool CMvDatabaseEx::Check() return false; } } - UInt64 maxPos = 0; + UInt32 beginPos = 0; + UInt64 endPos = 0; int prevFolder = -2; for (int i = 0; i < Items.Size(); i++) { @@ -273,16 +259,12 @@ bool CMvDatabaseEx::Check() continue; int folderIndex = GetFolderIndex(&mvItem); if (folderIndex != prevFolder) - { prevFolder = folderIndex; - maxPos = 0; - continue; - } - if (item.Offset < maxPos) - return false; - maxPos = item.GetEndOffset(); - if (maxPos < item.Offset) + else if (item.Offset < endPos && + (item.Offset != beginPos || item.GetEndOffset() != endPos)) return false; + beginPos = item.Offset; + endPos = item.GetEndOffset(); } return true; } diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h index c9cfcbdd..1e9b188b 100755 --- a/CPP/7zip/Archive/Cab/CabIn.h +++ b/CPP/7zip/Archive/Cab/CabIn.h @@ -50,8 +50,8 @@ struct CArchiveInfo Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); } - COtherArchive PreviousArchive; - COtherArchive NextArchive; + COtherArchive PrevArc; + COtherArchive NextArc; CArchiveInfo() { @@ -63,7 +63,7 @@ struct CArchiveInfo PerCabinetAreaSize = 0; PerFolderAreaSize = 0; PerDataBlockAreaSize = 0; - } + } }; struct CInArchiveInfo: public CArchiveInfo @@ -73,13 +73,13 @@ struct CInArchiveInfo: public CArchiveInfo }; -class CDatabase +struct CDatabase { -public: UInt64 StartPosition; CInArchiveInfo ArchiveInfo; CObjectVector<CFolder> Folders; CObjectVector<CItem> Items; + void Clear() { ArchiveInfo.Clear(); @@ -104,9 +104,8 @@ public: UInt32 GetFileSize(int index) const { return Items[index].Size; } }; -class CDatabaseEx: public CDatabase +struct CDatabaseEx: public CDatabase { -public: CMyComPtr<IInStream> Stream; }; @@ -124,6 +123,7 @@ public: CRecordVector<CMvItem> Items; CRecordVector<int> StartFolderOfVol; CRecordVector<int> FolderStartFileIndex; + int GetFolderIndex(const CMvItem *mvi) const { const CDatabaseEx &db = Volumes[mvi->VolumeIndex]; @@ -145,20 +145,15 @@ class CInArchive { CInBuffer inBuffer; - Byte ReadByte(); - UInt16 ReadUInt16(); - UInt32 ReadUInt32(); + Byte Read8(); + UInt16 Read16(); + UInt32 Read32(); AString SafeReadName(); - void Skip(size_t size); + void Skip(UInt32 size); void ReadOtherArchive(COtherArchive &oa); - HRESULT Open2(IInStream *inStream, - const UInt64 *searchHeaderSizeLimit, - CDatabase &database); public: - HRESULT Open( - const UInt64 *searchHeaderSizeLimit, - CDatabaseEx &database); + HRESULT Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db); }; }} diff --git a/CPP/7zip/Archive/Cab/CabRegister.cpp b/CPP/7zip/Archive/Cab/CabRegister.cpp index 0ce8a87f..15fe4099 100755 --- a/CPP/7zip/Archive/Cab/CabRegister.cpp +++ b/CPP/7zip/Archive/Cab/CabRegister.cpp @@ -5,7 +5,7 @@ #include "../../Common/RegisterArc.h" #include "CabHandler.h" -static IInArchive *CreateArc() { return new NArchive::NCab::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NCab::CHandler; } static CArcInfo g_ArcInfo = { L"Cab", L"cab", 0, 8, { 0x4D, 0x53, 0x43, 0x46 }, 4, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp index 03bff821..a9e334b0 100755 --- a/CPP/7zip/Archive/Chm/ChmHandler.cpp +++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp @@ -275,7 +275,7 @@ HRESULT CChmFolderOutStream::OpenFile() m_RealOutStream.Release(); RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); if (!m_RealOutStream && !m_TestMode) - askMode = NArchive::NExtract::NAskMode::kSkip; + askMode = NExtract::NAskMode::kSkip; return m_ExtractCallback->PrepareOperation(askMode); } @@ -291,7 +291,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles() HRESULT result = OpenFile(); m_RealOutStream.Release(); RINOK(result); - RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); } return S_OK; } @@ -334,8 +334,8 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce m_RealOutStream.Release(); RINOK(m_ExtractCallback->SetOperationResult( m_IsOk ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); m_FileIsOpen = false; } if (realProcessed > 0) @@ -398,11 +398,11 @@ HRESULT CChmFolderOutStream::FlushCorrupted(UInt64 maxSize) } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = m_Database.NewFormat ? 1: @@ -411,7 +411,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, m_Database.Indices.Size()); if (numItems == 0) return S_OK; - bool testMode = (_aTestMode != 0); + bool testMode = (testModeSpec != 0); UInt64 currentTotalSize = 0; @@ -447,8 +447,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode= testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -456,32 +456,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { if (index != 0) return E_FAIL; - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; if (!testMode) { UInt32 size = m_Database.NewFormatString.Length(); RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size)); } - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } const CItem &item = m_Database.Items[index]; currentItemSize = item.Size; - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); if (item.Section != 0) { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); continue; } if (testMode) { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } @@ -491,8 +491,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; } @@ -543,15 +543,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const CItem &item = m_Database.Items[entryIndex]; UInt64 sectionIndex = item.Section; Int32 askMode= testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; if (item.IsDir()) { CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } @@ -562,17 +562,17 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); - Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + Int32 opRes = NExtract::NOperationResult::kOK; if (!testMode && item.Size != 0) { RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); streamSpec->Init(item.Size); RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); if (copyCoderSpec->TotalSize != item.Size) - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; } realOutStream.Release(); RINOK(extractCallback->SetOperationResult(opRes)); @@ -586,10 +586,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { CMyComPtr<ISequentialOutStream> realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if(!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); continue; } @@ -603,7 +603,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, chmFolderOutStream->Init(&m_Database, extractCallback, testMode); - if(lzxDecoderSpec == NULL) + if (lzxDecoderSpec == NULL) { lzxDecoderSpec = new NCompress::NLzx::CDecoder; lzxDecoder = lzxDecoderSpec; diff --git a/CPP/7zip/Archive/Chm/ChmRegister.cpp b/CPP/7zip/Archive/Chm/ChmRegister.cpp index abebe6c6..e5f38afa 100755 --- a/CPP/7zip/Archive/Chm/ChmRegister.cpp +++ b/CPP/7zip/Archive/Chm/ChmRegister.cpp @@ -5,7 +5,7 @@ #include "../../Common/RegisterArc.h" #include "ChmHandler.h" -static IInArchive *CreateArc() { return new NArchive::NChm::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NChm::CHandler; } static CArcInfo g_ArcInfo = { L"Chm", L"chm chi chq chw hxs hxi hxr hxq hxw lit", 0, 0xE9, { 'I', 'T', 'S', 'F' }, 4, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/Com/ComHandler.cpp b/CPP/7zip/Archive/Com/ComHandler.cpp index 287f6156..39fce0ae 100755 --- a/CPP/7zip/Archive/Com/ComHandler.cpp +++ b/CPP/7zip/Archive/Com/ComHandler.cpp @@ -95,12 +95,11 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _db.Refs.Size(); if (numItems == 0) @@ -135,30 +134,30 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ISequentialOutStream> outStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(index, &outStream, askMode)); if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } totalPackSize += _db.GetItemPackSize(item.Size); totalSize += item.Size; - if (!testMode && (!outStream)) + if (!testMode && !outStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); - Int32 res = NArchive::NExtract::NOperationResult::kDataError; + Int32 res = NExtract::NOperationResult::kDataError; CMyComPtr<ISequentialInStream> inStream; HRESULT hres = GetStream(index, &inStream); if (hres == S_FALSE) - res = NArchive::NExtract::NOperationResult::kDataError; + res = NExtract::NOperationResult::kDataError; else if (hres == E_NOTIMPL) - res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + res = NExtract::NOperationResult::kUnSupportedMethod; else { RINOK(hres); @@ -166,7 +165,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); if (copyCoderSpec->TotalSize == item.Size) - res = NArchive::NExtract::NOperationResult::kOK; + res = NExtract::NOperationResult::kOK; } } outStream.Release(); diff --git a/CPP/7zip/Archive/Com/ComRegister.cpp b/CPP/7zip/Archive/Com/ComRegister.cpp index c744b04f..6712b890 100755 --- a/CPP/7zip/Archive/Com/ComRegister.cpp +++ b/CPP/7zip/Archive/Com/ComRegister.cpp @@ -5,9 +5,9 @@ #include "../../Common/RegisterArc.h" #include "ComHandler.h" -static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; } static CArcInfo g_ArcInfo = - { L"Compound", L"msi doc xls ppt", 0, 0xE5, { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }, 8, false, CreateArc, 0 }; + { L"Compound", L"msi msp doc xls ppt", 0, 0xE5, { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }, 8, false, CreateArc, 0 }; REGISTER_ARC(Com) diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp index 6dfaf980..71996a63 100755 --- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp +++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp @@ -39,7 +39,7 @@ bool HasTailSlash(const AString &name, UINT codePage) if (name.IsEmpty()) return false; LPCSTR prev = - #ifdef _WIN32 + #if defined(_WIN32) && !defined(UNDER_CE) CharPrevExA((WORD)codePage, name, &name[name.Length()], 0); #else (LPCSTR)(name) + (name.Length() - 1); diff --git a/CPP/7zip/Archive/CpioHandler.cpp b/CPP/7zip/Archive/CpioHandler.cpp index e5a32936..2e64d1cd 100755 --- a/CPP/7zip/Archive/CpioHandler.cpp +++ b/CPP/7zip/Archive/CpioHandler.cpp @@ -71,7 +71,7 @@ namespace NFileHeader char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file bool CheckMagic() const { return memcmp(Magic, NMagic::kMagic1, 6) == 0 || - memcmp(Magic, NMagic::kMagic2, 6) == 0; }; + memcmp(Magic, NMagic::kMagic2, 6) == 0; }; }; */ @@ -540,12 +540,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -575,8 +574,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> outStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &outStream, askMode)); @@ -584,7 +583,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } if (!testMode && !outStream) @@ -592,7 +591,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->PrepareOperation(askMode)); if (testMode) { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } RINOK(_stream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); @@ -600,8 +599,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); outStream.Release(); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END @@ -615,7 +614,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) COM_TRY_END } -static IInArchive *CreateArc() { return new NArchive::NCpio::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NCpio::CHandler; } static CArcInfo g_ArcInfo = { L"Cpio", L"cpio", 0, 0xED, { 0 }, 0, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/DebHandler.cpp b/CPP/7zip/Archive/DebHandler.cpp index 0381e0fd..9f083269 100755 --- a/CPP/7zip/Archive/DebHandler.cpp +++ b/CPP/7zip/Archive/DebHandler.cpp @@ -236,7 +236,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, COM_TRY_BEGIN { CInArchive archive; - if(archive.Open(stream) != S_OK) + if (archive.Open(stream) != S_OK) return S_FALSE; _items.Clear(); @@ -314,12 +314,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -349,19 +348,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItem &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); currentTotalSize += item.Size; - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); if (testMode) { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } RINOK(_stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL)); @@ -369,8 +368,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END @@ -384,7 +383,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) COM_TRY_END } -static IInArchive *CreateArc() { return new NArchive::NDeb::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NDeb::CHandler; } static CArcInfo g_ArcInfo = { L"Deb", L"deb", 0, 0xEC, { '!', '<', 'a', 'r', 'c', 'h', '>', '\n' }, 8, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/DeflateProps.cpp b/CPP/7zip/Archive/DeflateProps.cpp new file mode 100755 index 00000000..8498e056 --- /dev/null +++ b/CPP/7zip/Archive/DeflateProps.cpp @@ -0,0 +1,118 @@ +// DeflateProps.cpp + +#include "StdAfx.h" + +#include "Windows/PropVariant.h" + +#include "Common/ParseProperties.h" + +#include "DeflateProps.h" + +namespace NArchive { + +static const UInt32 kAlgo1 = 0; +static const UInt32 kAlgo5 = 1; + +static const UInt32 kPasses1 = 1; +static const UInt32 kPasses7 = 3; +static const UInt32 kPasses9 = 10; + +static const UInt32 kFb1 = 32; +static const UInt32 kFb7 = 64; +static const UInt32 kFb9 = 128; + +void CDeflateProps::Normalize() +{ + UInt32 level = Level; + if (level == 0xFFFFFFFF) + level = 5; + + if (Algo == 0xFFFFFFFF) + Algo = (level >= 5 ? + kAlgo5 : + kAlgo1); + + if (NumPasses == 0xFFFFFFFF) + NumPasses = + (level >= 9 ? kPasses9 : + (level >= 7 ? kPasses7 : + kPasses1)); + if (Fb == 0xFFFFFFFF) + Fb = + (level >= 9 ? kFb9 : + (level >= 7 ? kFb7 : + kFb1)); +} + +HRESULT CDeflateProps::SetCoderProperties(ICompressSetCoderProperties *setCoderProperties) +{ + Normalize(); + + NWindows::NCOM::CPropVariant props[] = + { + Algo, + NumPasses, + Fb, + Mc + }; + PROPID propIDs[] = + { + NCoderPropID::kAlgorithm, + NCoderPropID::kNumPasses, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinderCycles + }; + int numProps = sizeof(propIDs) / sizeof(propIDs[0]); + if (!McDefined) + numProps--; + return setCoderProperties->SetCoderProperties(propIDs, props, numProps); +} + +HRESULT CDeflateProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps) +{ + Init(); + for (int i = 0; i < numProps; i++) + { + UString name = names[i]; + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + const PROPVARIANT &prop = values[i]; + if (name[0] == L'X') + { + UInt32 a = 9; + RINOK(ParsePropValue(name.Mid(1), prop, a)); + Level = a; + } + else if (name.Left(1) == L"A") + { + UInt32 a = kAlgo5; + RINOK(ParsePropValue(name.Mid(1), prop, a)); + Algo = a; + } + else if (name.Left(4) == L"PASS") + { + UInt32 a = kPasses9; + RINOK(ParsePropValue(name.Mid(4), prop, a)); + NumPasses = a; + } + else if (name.Left(2) == L"FB") + { + UInt32 a = kFb9; + RINOK(ParsePropValue(name.Mid(2), prop, a)); + Fb = a; + } + else if (name.Left(2) == L"MC") + { + UInt32 a = 0xFFFFFFFF; + RINOK(ParsePropValue(name.Mid(2), prop, a)); + Mc = a; + McDefined = true; + } + else + return E_INVALIDARG; + } + return S_OK; +} + +} diff --git a/CPP/7zip/Archive/DeflateProps.h b/CPP/7zip/Archive/DeflateProps.h new file mode 100755 index 00000000..e05a9d4a --- /dev/null +++ b/CPP/7zip/Archive/DeflateProps.h @@ -0,0 +1,35 @@ +// DeflateProps.h + +#ifndef __DEFLATE_PROPS_H +#define __DEFLATE_PROPS_H + +#include "../ICoder.h" + +namespace NArchive { + +class CDeflateProps +{ + UInt32 Level; + UInt32 NumPasses; + UInt32 Fb; + UInt32 Algo; + UInt32 Mc; + bool McDefined; + + void Init() + { + Level = NumPasses = Fb = Algo = Mc = 0xFFFFFFFF; + McDefined = false; + } + void Normalize(); +public: + CDeflateProps() { Init(); } + bool IsMaximum() const { return Algo > 0; } + + HRESULT SetCoderProperties(ICompressSetCoderProperties *setCoderProperties); + HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps); +}; + +} + +#endif diff --git a/CPP/7zip/Archive/DllExports.cpp b/CPP/7zip/Archive/DllExports.cpp index ccad2126..6c72dea7 100755 --- a/CPP/7zip/Archive/DllExports.cpp +++ b/CPP/7zip/Archive/DllExports.cpp @@ -5,6 +5,8 @@ #include "../../Common/MyInitGuid.h" #include "../../Common/ComTry.h" #include "../../Common/Types.h" + +#include "../../Windows/NtCheck.h" #include "../../Windows/PropVariant.h" #include "IArchive.h" @@ -12,17 +14,8 @@ #include "../IPassword.h" HINSTANCE g_hInstance; -#ifndef _UNICODE -bool g_IsNT = false; -static bool IsItWindowsNT() -{ - OSVERSIONINFO versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - if (!::GetVersionEx(&versionInfo)) - return false; - return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); -} -#endif + +#define NT_CHECK_FAIL_ACTION return FALSE; extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) @@ -30,9 +23,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) if (dwReason == DLL_PROCESS_ATTACH) { g_hInstance = hInstance; - #ifndef _UNICODE - g_IsNT = IsItWindowsNT(); - #endif + NT_CHECK; } return TRUE; } diff --git a/CPP/7zip/Archive/DllExports2.cpp b/CPP/7zip/Archive/DllExports2.cpp index fd8bff28..ad14ff06 100755 --- a/CPP/7zip/Archive/DllExports2.cpp +++ b/CPP/7zip/Archive/DllExports2.cpp @@ -3,43 +3,38 @@ #include "StdAfx.h" #include "../../Common/MyInitGuid.h" -#include "../../Common/ComTry.h" -#include "../../Common/Types.h" -#include "../../Windows/PropVariant.h" + #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES) #include "../../../C/Alloc.h" #endif -#include "IArchive.h" +#include "../../Common/ComTry.h" + +#include "../../Windows/NtCheck.h" +#include "../../Windows/PropVariant.h" + #include "../ICoder.h" #include "../IPassword.h" +#include "IArchive.h" + HINSTANCE g_hInstance; -#ifndef _UNICODE -#ifdef _WIN32 -bool g_IsNT = false; -static bool IsItWindowsNT() -{ - OSVERSIONINFO versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - if (!::GetVersionEx(&versionInfo)) - return false; - return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); -} -#endif -#endif + +#define NT_CHECK_FAIL_ACTION return FALSE; extern "C" -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { if (dwReason == DLL_PROCESS_ATTACH) { - g_hInstance = hInstance; - #ifndef _UNICODE - #ifdef _WIN32 - g_IsNT = IsItWindowsNT(); - #endif - #endif + g_hInstance = (HINSTANCE)hInstance; + NT_CHECK; } return TRUE; } diff --git a/CPP/7zip/Archive/DmgHandler.cpp b/CPP/7zip/Archive/DmgHandler.cpp index dd1e95ec..e63542be 100755 --- a/CPP/7zip/Archive/DmgHandler.cpp +++ b/CPP/7zip/Archive/DmgHandler.cpp @@ -573,12 +573,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _files.Size(); if (numItems == 0) @@ -635,14 +634,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; // const CItemEx &item = _files[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -652,7 +651,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, realOutStream.Release(); - Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + Int32 opRes = NExtract::NOperationResult::kOK; #ifdef DMG_SHOW_RAW if (index > _fileIndices.Size()) { @@ -688,7 +687,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, packPos += block.PackSize; if (block.UnpPos != unpPos) { - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; break; } @@ -705,13 +704,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, case METHOD_ZERO_2: realMethod = false; if (block.PackSize != 0) - opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + opRes = NExtract::NOperationResult::kUnSupportedMethod; break; case METHOD_COPY: if (block.UnpSize != block.PackSize) { - opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + opRes = NExtract::NOperationResult::kUnSupportedMethod; break; } res = copyCoder->Code(inStream, outStream, NULL, NULL, progress); @@ -730,26 +729,26 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, res = bzip2Coder->Code(inStream, outStream, NULL, NULL, progress); if (res == S_OK) if (streamSpec->GetSize() != block.PackSize) - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; break; } default: - opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + opRes = NExtract::NOperationResult::kUnSupportedMethod; break; } if (res != S_OK) { if (res != S_FALSE) return res; - if (opRes == NArchive::NExtract::NOperationResult::kOK) - opRes = NArchive::NExtract::NOperationResult::kDataError; + if (opRes == NExtract::NOperationResult::kOK) + opRes = NExtract::NOperationResult::kDataError; } unpPos += block.UnpSize; if (!outStreamSpec->IsFinishedOK()) { - if (realMethod && opRes == NArchive::NExtract::NOperationResult::kOK) - opRes = NArchive::NExtract::NOperationResult::kDataError; + if (realMethod && opRes == NExtract::NOperationResult::kOK) + opRes = NExtract::NOperationResult::kDataError; while (outStreamSpec->GetRem() != 0) { diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp index 66b18e7a..6f5a6776 100755 --- a/CPP/7zip/Archive/ElfHandler.cpp +++ b/CPP/7zip/Archive/ElfHandler.cpp @@ -466,12 +466,11 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _sections.Size(); if (numItems == 0) @@ -501,8 +500,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, lps->InSize = lps->OutSize = currentTotalSize; RINOK(lps->SetCur()); Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; UInt32 index = allFilesMode ? i : indices[i]; const CSegment &item = _sections[index]; currentItemSize = item.PSize; @@ -518,8 +517,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); outStream.Release(); RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/FatHandler.cpp b/CPP/7zip/Archive/FatHandler.cpp index f07d4ccb..6d7b249c 100755 --- a/CPP/7zip/Archive/FatHandler.cpp +++ b/CPP/7zip/Archive/FatHandler.cpp @@ -456,8 +456,11 @@ HRESULT CDatabase::ReadDir(Int32 parent, UInt32 cluster, int level) const Byte *p = ByteBuf + pos; if (p[0] == 0) { + /* + // FreeDOS formats FAT partition with cluster chain longer than required. if (clusterMode && !Header.IsEoc(cluster)) return S_FALSE; + */ break; } if (p[0] == 0xE5) @@ -883,12 +886,11 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = Items.Size(); if (numItems == 0) @@ -923,8 +925,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItem &item = Items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -932,14 +934,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } totalPackSize += Header.GetFilePackSize(item.Size); totalSize += item.Size; - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -947,7 +949,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, realOutStream.Release(); outStreamSpec->Init(); - int res = NArchive::NExtract::NOperationResult::kDataError; + int res = NExtract::NOperationResult::kDataError; CMyComPtr<ISequentialInStream> inStream; HRESULT hres = GetStream(index, &inStream); if (hres != S_FALSE) @@ -957,7 +959,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); if (copyCoderSpec->TotalSize == item.Size) - res = NArchive::NExtract::NOperationResult::kOK; + res = NExtract::NOperationResult::kOK; } } outStreamSpec->ReleaseStream(); @@ -973,7 +975,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -static IInArchive *CreateArc() { return new CHandler; } +static IInArchive *CreateArc() { return new CHandler; } static CArcInfo g_ArcInfo = { L"FAT", L"fat img", 0, 0xDA, { 0x55, 0xAA }, 2, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/FlvHandler.cpp b/CPP/7zip/Archive/FlvHandler.cpp new file mode 100755 index 00000000..a22c29e3 --- /dev/null +++ b/CPP/7zip/Archive/FlvHandler.cpp @@ -0,0 +1,544 @@ +// FlvHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/Buffer.h" +#include "Common/ComTry.h" +// #include "Common/Defs.h" +#include "Common/MyString.h" + +#include "Windows/PropVariant.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#define GetBe24(p) ( \ + ((UInt32)((const Byte *)(p))[0] << 16) | \ + ((UInt32)((const Byte *)(p))[1] << 8) | \ + ((const Byte *)(p))[2] ) + +#define Get16(p) GetBe16(p) +#define Get24(p) GetBe24(p) +#define Get32(p) GetBe32(p) + +namespace NArchive { +namespace NFlv { + +static const UInt32 kFileSizeMax = (UInt32)1 << 30; +static const int kNumChunksMax = (UInt32)1 << 23; + +const UInt32 kTagHeaderSize = 11; + +static const Byte kFlag_Video = 1; +static const Byte kFlag_Audio = 4; + +static const Byte kType_Audio = 8; +static const Byte kType_Video = 9; +static const Byte kType_Meta = 18; +static const int kNumTypes = 19; + +struct CItem +{ + UInt32 Offset; + UInt32 Size; + // UInt32 Time; + Byte Type; +}; + +struct CItem2 +{ + Byte Type; + Byte SubType; + Byte Props; + bool SameSubTypes; + int NumChunks; + size_t Size; + + CReferenceBuf *BufSpec; + CMyComPtr<IUnknown> RefBuf; + + bool IsAudio() const { return Type == kType_Audio; } +}; + +class CHandler: + public IInArchive, + public IInArchiveGetStream, + public CMyUnknownImp +{ + int _isRaw; + CMyComPtr<IInStream> _stream; + CObjectVector<CItem2> _items2; + // CByteBuffer _metadata; + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); + AString GetComment(); +public: + MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) + INTERFACE_IInArchive(;) + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidNumBlocks, VT_UI4}, + { NULL, kpidComment, VT_BSTR} +}; + +/* +STATPROPSTG kArcProps[] = +{ + { NULL, kpidComment, VT_BSTR} +}; +*/ + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +static const char *g_AudioTypes[16] = +{ + "pcm", + "adpcm", + "mp3", + "pcm_le", + "nellymoser16", + "nellymoser8", + "nellymoser", + "g711a", + "g711m", + "audio9", + "aac", + "speex", + "audio12", + "audio13", + "mp3", + "audio15" +}; + +static const char *g_VideoTypes[16] = +{ + "video0", + "jpeg", + "h263", + "screen", + "vp6", + "vp6alpha", + "screen2", + "avc", + "video8", + "video9", + "video10", + "video11", + "video12", + "video13", + "video14", + "video15" +}; + +static const char *g_Rates[4] = +{ + "5.5 kHz", + "11 kHz", + "22 kHz", + "44 kHz" +}; + +static void MyStrCat(char *d, const char *s) +{ + MyStringCopy(d + MyStringLen(d), s); +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + const CItem2 &item = _items2[index]; + switch(propID) + { + case kpidExtension: + prop = _isRaw ? + (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) : + (item.IsAudio() ? "audio.flv" : "video.flv"); + break; + case kpidSize: + case kpidPackSize: + prop = (UInt64)item.Size; + break; + case kpidNumBlocks: prop = (UInt32)item.NumChunks; break; + case kpidComment: + { + char sz[64]; + MyStringCopy(sz, (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) ); + if (item.IsAudio()) + { + MyStrCat(sz, " "); + MyStrCat(sz, g_Rates[(item.Props >> 2) & 3]); + MyStrCat(sz, (item.Props & 2) ? " 16-bit" : " 8-bit"); + MyStrCat(sz, (item.Props & 1) ? " stereo" : " mono"); + } + prop = sz; + break; + } + } + prop.Detach(value); + return S_OK; +} + +/* +AString CHandler::GetComment() +{ + const Byte *p = _metadata; + size_t size = _metadata.GetCapacity(); + AString res; + if (size > 0) + { + p++; + size--; + for (;;) + { + if (size < 2) + break; + int len = Get16(p); + p += 2; + size -= 2; + if (len == 0 || (size_t)len > size) + break; + { + AString temp; + char *sz = temp.GetBuffer(len); + memcpy(sz, p, len); + sz[len] = 0; + temp.ReleaseBuffer(); + if (!res.IsEmpty()) + res += '\n'; + res += temp; + } + p += len; + size -= len; + if (size < 1) + break; + Byte type = *p++; + size--; + bool ok = false; + switch(type) + { + case 0: + { + if (size < 8) + break; + ok = true; + Byte reverse[8]; + for (int i = 0; i < 8; i++) + { + bool little_endian = 1; + if (little_endian) + reverse[i] = p[7 - i]; + else + reverse[i] = p[i]; + } + double d = *(double *)reverse; + char temp[32]; + sprintf(temp, " = %.3f", d); + res += temp; + p += 8; + size -= 8; + break; + } + case 8: + { + if (size < 4) + break; + ok = true; + // UInt32 numItems = Get32(p); + p += 4; + size -= 4; + break; + } + } + if (!ok) + break; + } + } + return res; +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidComment: prop = GetComment(); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} +*/ + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) +{ + CRecordVector<CItem> items; + + const UInt32 kHeaderSize = 13; + Byte header[kHeaderSize]; + RINOK(ReadStream_FALSE(stream, header, kHeaderSize)); + if (header[0] != 'F' || + header[1] != 'L' || + header[2] != 'V' || + header[3] != 1 || + (header[4] & 0xFA) != 0) + return S_FALSE; + UInt32 offset = Get32(header + 5); + if (offset != 9 || Get32(header + 9) != 0) + return S_FALSE; + offset += 4; + + CByteBuffer inBuf; + size_t fileSize; + { + UInt64 fileSize64; + RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize64)); + if (fileSize64 > kFileSizeMax) + return S_FALSE; + + if (callback) + RINOK(callback->SetTotal(NULL, &fileSize64)) + + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + fileSize = (size_t)fileSize64; + inBuf.SetCapacity(fileSize); + for (size_t pos = 0; pos < fileSize;) + { + UInt64 offset64 = pos; + if (callback) + RINOK(callback->SetCompleted(NULL, &offset64)) + size_t rem = MyMin(fileSize - pos, (size_t)(1 << 20)); + RINOK(ReadStream_FALSE(stream, inBuf + pos, rem)); + pos += rem; + } + } + + int lasts[kNumTypes]; + int i; + for (i = 0; i < kNumTypes; i++) + lasts[i] = -1; + + while (offset < fileSize) + { + CItem item; + item.Offset = offset; + const Byte *buf = inBuf + offset; + offset += kTagHeaderSize; + if (offset > fileSize) + return S_FALSE; + + item.Type = buf[0]; + UInt32 size = Get24(buf + 1); + if (size < 1) + return S_FALSE; + // item.Time = Get24(buf + 4); + // item.Time |= (UInt32)buf[7] << 24; + if (Get24(buf + 8) != 0) // streamID + return S_FALSE; + + UInt32 curSize = kTagHeaderSize + size + 4; + item.Size = curSize; + + offset += curSize - kTagHeaderSize; + if (offset > fileSize) + return S_FALSE; + + if (Get32(buf + kTagHeaderSize + size) != kTagHeaderSize + size) + return S_FALSE; + + // printf("\noffset = %6X type = %2d time = %6d size = %6d", (UInt32)offset, item.Type, item.Time, item.Size); + + if (item.Type == kType_Meta) + { + // _metadata = item.Buf; + } + else + { + if (item.Type != kType_Audio && item.Type != kType_Video) + return S_FALSE; + if (items.Size() >= kNumChunksMax) + return S_FALSE; + Byte firstByte = buf[kTagHeaderSize]; + Byte subType, props; + if (item.Type == kType_Audio) + { + subType = firstByte >> 4; + props = firstByte & 0xF; + } + else + { + subType = firstByte & 0xF; + props = firstByte >> 4; + } + int last = lasts[item.Type]; + if (last < 0) + { + CItem2 item2; + item2.RefBuf = item2.BufSpec = new CReferenceBuf; + item2.Size = curSize; + item2.Type = item.Type; + item2.SubType = subType; + item2.Props = props; + item2.NumChunks = 1; + item2.SameSubTypes = true; + lasts[item.Type] = _items2.Add(item2); + } + else + { + CItem2 &item2 = _items2[last]; + if (subType != item2.SubType) + item2.SameSubTypes = false; + item2.Size += curSize; + item2.NumChunks++; + } + items.Add(item); + } + } + + _isRaw = (_items2.Size() == 1); + for (i = 0; i < _items2.Size(); i++) + { + CItem2 &item2 = _items2[i]; + CByteBuffer &itemBuf = item2.BufSpec->Buf; + if (_isRaw) + { + if (!item2.SameSubTypes) + return S_FALSE; + itemBuf.SetCapacity((size_t)item2.Size - (kTagHeaderSize + 4 + 1) * item2.NumChunks); + item2.Size = 0; + } + else + { + itemBuf.SetCapacity(kHeaderSize + (size_t)item2.Size); + memcpy(itemBuf, header, kHeaderSize); + itemBuf[4] = item2.IsAudio() ? kFlag_Audio : kFlag_Video; + item2.Size = kHeaderSize; + } + } + + for (i = 0; i < items.Size(); i++) + { + const CItem &item = items[i]; + CItem2 &item2 = _items2[lasts[item.Type]]; + size_t size = item.Size; + const Byte *src = inBuf + item.Offset; + if (_isRaw) + { + src += kTagHeaderSize + 1; + size -= (kTagHeaderSize + 4 + 1); + } + memcpy(item2.BufSpec->Buf + item2.Size, src, size); + item2.Size += size; + } + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + Close(); + HRESULT res; + try + { + res = Open2(inStream, callback); + if (res == S_OK) + _stream = inStream; + } + catch(...) { res = S_FALSE; } + if (res != S_OK) + { + Close(); + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _stream.Release(); + _items2.Clear(); + // _metadata.SetCapacity(0); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items2.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == (UInt32)-1); + if (allFilesMode) + numItems = _items2.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _items2[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + totalSize = 0; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + for (i = 0; i < numItems; i++) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()); + CMyComPtr<ISequentialOutStream> outStream; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + const CItem2 &item = _items2[index]; + RINOK(extractCallback->GetStream(index, &outStream, askMode)); + totalSize += item.Size; + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + if (outStream) + { + RINOK(WriteStream(outStream, item.BufSpec->Buf, item.BufSpec->Buf.GetCapacity())); + } + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +{ + COM_TRY_BEGIN + *stream = 0; + CBufInStream *streamSpec = new CBufInStream; + CMyComPtr<ISequentialInStream> streamTemp = streamSpec; + streamSpec->Init(_items2[index].BufSpec); + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"FLV", L"flv", 0, 0xD6, { 'F', 'L', 'V' }, 3, false, CreateArc, 0 }; + +REGISTER_ARC(Flv) + +}} diff --git a/CPP/7zip/Archive/GzHandler.cpp b/CPP/7zip/Archive/GzHandler.cpp index 8f91003f..7b73bddc 100755 --- a/CPP/7zip/Archive/GzHandler.cpp +++ b/CPP/7zip/Archive/GzHandler.cpp @@ -20,7 +20,8 @@ #include "Common/InStreamWithCRC.h" #include "Common/OutStreamWithCRC.h" -#include "Common/ParseProperties.h" + +#include "DeflateProps.h" #define Get32(p) GetUi32(p) @@ -288,54 +289,6 @@ HRESULT CItem::WriteFooter(ISequentialOutStream *stream) return WriteStream(stream, buf, 8); } -static const UInt32 kAlgoX1 = 0; -static const UInt32 kAlgoX5 = 1; - -static const UInt32 kNumPassesX1 = 1; -static const UInt32 kNumPassesX7 = 3; -static const UInt32 kNumPassesX9 = 10; - -static const UInt32 kNumFastBytesX1 = 32; -static const UInt32 kNumFastBytesX7 = 64; -static const UInt32 kNumFastBytesX9 = 128; - -struct CCompressMode -{ - UInt32 NumPasses; - UInt32 NumFastBytes; - UInt32 Algo; - UInt32 Mc; - bool McDefined; - - bool IsMaximum() const { return Algo > 0; } - - void Init() - { - NumPasses = NumFastBytes = Mc = Algo = 0xFFFFFFFF; - McDefined = false; - } - - void Normalize(UInt32 level) - { - if (level == 0xFFFFFFFF) - level = 5; - if (NumPasses == 0xFFFFFFFF) - NumPasses = - (level >= 9 ? kNumPassesX9 : - (level >= 7 ? kNumPassesX7 : - kNumPassesX1)); - if (NumFastBytes == 0xFFFFFFFF) - NumFastBytes = - (level >= 9 ? kNumFastBytesX9 : - (level >= 7 ? kNumFastBytesX7 : - kNumFastBytesX1)); - if (Algo == 0xFFFFFFFF) - Algo = (level >= 5 ? - kAlgoX5 : - kAlgoX1); - } -}; - class CHandler: public IInArchive, public IArchiveOpenSeq, @@ -352,14 +305,7 @@ class CHandler: CMyComPtr<ICompressCoder> _decoder; NCompress::NDeflate::NDecoder::CCOMCoder *_decoderSpec; - CCompressMode _method; - UInt32 _level; - - void InitMethodProperties() - { - _level = 0xFFFFFFFF; - _method.Init(); - } + CDeflateProps _method; public: MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties) @@ -370,7 +316,6 @@ public: CHandler() { - InitMethodProperties(); _decoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder; _decoder = _decoderSpec; } @@ -496,28 +441,23 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)-1); - if (!allFilesMode) - { - if (numItems == 0) - return S_OK; - if (numItems != 1 || indices[0] != 0) - return E_INVALIDARG; - } + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; - bool testMode = (_aTestMode != 0); if (_stream) extractCallback->SetTotal(_packSize); UInt64 currentTotalPacked = 0; RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); if (!testMode && !realOutStream) return S_OK; @@ -557,8 +497,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (result != S_FALSE) return result; opRes = firstItem ? - NArchive::NExtract::NOperationResult::kDataError : - NArchive::NExtract::NOperationResult::kOK; + NExtract::NOperationResult::kDataError : + NExtract::NOperationResult::kOK; break; } } @@ -572,20 +512,20 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { if (result != S_FALSE) return result; - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; break; } _decoderSpec->AlignToByte(); if (item.ReadFooter1(_decoderSpec) != S_OK) { - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; break; } if (item.Crc != outStreamSpec->GetCRC() || item.Size32 != (UInt32)(outStreamSpec->GetSize() - startOffset)) { - opRes = NArchive::NExtract::NOperationResult::kCRCError; + opRes = NExtract::NOperationResult::kCRCError; break; } } @@ -605,7 +545,7 @@ static HRESULT UpdateArchive( ISequentialOutStream *outStream, UInt64 unpackSize, const CItem &newItem, - const CCompressMode &compressionMode, + CDeflateProps &deflateProps, IArchiveUpdateCallback *updateCallback) { UInt64 complexity = 0; @@ -627,7 +567,7 @@ static HRESULT UpdateArchive( CItem item = newItem; item.Method = NHeader::NCompressionMethod::kDeflate; - item.ExtraFlags = compressionMode.IsMaximum() ? + item.ExtraFlags = deflateProps.IsMaximum() ? NHeader::NExtraFlags::kMaximum : NHeader::NExtraFlags::kFastest; @@ -637,26 +577,7 @@ static HRESULT UpdateArchive( NCompress::NDeflate::NEncoder::CCOMCoder *deflateEncoderSpec = new NCompress::NDeflate::NEncoder::CCOMCoder; CMyComPtr<ICompressCoder> deflateEncoder = deflateEncoderSpec; - { - NWindows::NCOM::CPropVariant props[] = - { - compressionMode.Algo, - compressionMode.NumPasses, - compressionMode.NumFastBytes, - compressionMode.Mc - }; - PROPID propIDs[] = - { - NCoderPropID::kAlgorithm, - NCoderPropID::kNumPasses, - NCoderPropID::kNumFastBytes, - NCoderPropID::kMatchFinderCycles - }; - int numProps = sizeof(propIDs) / sizeof(propIDs[0]); - if (!compressionMode.McDefined) - numProps--; - RINOK(deflateEncoderSpec->SetCoderProperties(propIDs, props, numProps)); - } + RINOK(deflateProps.SetCoderProperties(deflateEncoderSpec)); RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress)); item.Crc = inStreamSpec->GetCRC(); @@ -738,7 +659,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt size = prop.uhVal.QuadPart; } - _method.Normalize(_level); return UpdateArchive(outStream, size, newItem, _method, updateCallback); } @@ -760,49 +680,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps) { - InitMethodProperties(); - for (int i = 0; i < numProps; i++) - { - UString name = names[i]; - name.MakeUpper(); - if (name.IsEmpty()) - return E_INVALIDARG; - const PROPVARIANT &prop = values[i]; - if (name[0] == L'X') - { - UInt32 level = 9; - RINOK(ParsePropValue(name.Mid(1), prop, level)); - _level = level; - } - else if (name.Left(4) == L"PASS") - { - UInt32 num = kNumPassesX9; - RINOK(ParsePropValue(name.Mid(4), prop, num)); - _method.NumPasses = num; - } - else if (name.Left(2) == L"FB") - { - UInt32 num = kNumFastBytesX9; - RINOK(ParsePropValue(name.Mid(2), prop, num)); - _method.NumFastBytes = num; - } - else if (name.Left(2) == L"MC") - { - UInt32 num = 0xFFFFFFFF; - RINOK(ParsePropValue(name.Mid(2), prop, num)); - _method.Mc = num; - _method.McDefined = true; - } - else if (name.Left(1) == L"A") - { - UInt32 num = kAlgoX5; - RINOK(ParsePropValue(name.Mid(1), prop, num)); - _method.Algo = num; - } - else - return E_INVALIDARG; - } - return S_OK; + return _method.SetProperties(names, values, numProps); } static IInArchive *CreateArc() { return new CHandler; } @@ -813,7 +691,7 @@ static IOutArchive *CreateArcOut() { return new CHandler; } #endif static CArcInfo g_ArcInfo = - { L"GZip", L"gz gzip tgz tpz", L"* * .tar .tar", 0xEF, { 0x1F, 0x8B, 8 }, 3, true, CreateArc, CreateArcOut }; + { L"gzip", L"gz gzip tgz tpz", L"* * .tar .tar", 0xEF, { 0x1F, 0x8B, 8 }, 3, true, CreateArc, CreateArcOut }; REGISTER_ARC(GZip) diff --git a/CPP/7zip/Archive/Hfs/HfsHandler.cpp b/CPP/7zip/Archive/Hfs/HfsHandler.cpp index ade53877..f226458d 100755 --- a/CPP/7zip/Archive/Hfs/HfsHandler.cpp +++ b/CPP/7zip/Archive/Hfs/HfsHandler.cpp @@ -137,12 +137,11 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _db.Items.Size(); if (numItems == 0) @@ -174,27 +173,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); UInt64 pos = 0; - int res = NArchive::NExtract::NOperationResult::kOK; + int res = NExtract::NOperationResult::kOK; int i; for (i = 0; i < item.Extents.Size(); i++) { if (item.Size == pos) break; - if (res != NArchive::NExtract::NOperationResult::kOK) + if (res != NExtract::NOperationResult::kOK) break; const CExtent &e = item.Extents[i]; RINOK(_stream->Seek((UInt64)e.Pos << _db.Header.BlockSizeLog, STREAM_SEEK_SET, NULL)); @@ -207,7 +206,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (rem == 0) { if (extentSize >= (UInt64)((UInt32)1 << _db.Header.BlockSizeLog)) - res = NArchive::NExtract::NOperationResult::kDataError; + res = NExtract::NOperationResult::kDataError; break; } UInt32 curSize = kBufSize; @@ -227,7 +226,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } } if (i != item.Extents.Size() || item.Size != pos) - res = NArchive::NExtract::NOperationResult::kDataError; + res = NExtract::NOperationResult::kDataError; realOutStream.Release(); RINOK(extractCallback->SetOperationResult(res)); } diff --git a/CPP/7zip/Archive/Hfs/HfsRegister.cpp b/CPP/7zip/Archive/Hfs/HfsRegister.cpp index 2d706900..51c3c2b1 100755 --- a/CPP/7zip/Archive/Hfs/HfsRegister.cpp +++ b/CPP/7zip/Archive/Hfs/HfsRegister.cpp @@ -5,7 +5,7 @@ #include "../../Common/RegisterArc.h" #include "HfsHandler.h" -static IInArchive *CreateArc() { return new NArchive::NHfs::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NHfs::CHandler; } static CArcInfo g_ArcInfo = { L"HFS", L"hfs", 0, 0xE3, { 'H', '+', 0, 4 }, 4, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/Icons/split.ico b/CPP/7zip/Archive/Icons/split.ico Binary files differindex 5cb93e84..79cb089b 100755 --- a/CPP/7zip/Archive/Icons/split.ico +++ b/CPP/7zip/Archive/Icons/split.ico diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp index ed8da189..9c20fec3 100755 --- a/CPP/7zip/Archive/Iso/IsoHandler.cpp +++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp @@ -152,12 +152,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _archive.Refs.Size(); if (numItems == 0) @@ -203,8 +202,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); currentItemSize = 0; CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; UInt32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -217,7 +217,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } currentItemSize = item.DataLength; @@ -231,7 +231,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, blockIndex = be.LoadRBA; } - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); outStreamSpec->SetStream(realOutStream); @@ -242,8 +242,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); outStreamSpec->ReleaseStream(); RINOK(extractCallback->SetOperationResult(outStreamSpec->IsFinishedOK() ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/Iso/IsoRegister.cpp b/CPP/7zip/Archive/Iso/IsoRegister.cpp index b43caba3..39f91198 100755 --- a/CPP/7zip/Archive/Iso/IsoRegister.cpp +++ b/CPP/7zip/Archive/Iso/IsoRegister.cpp @@ -5,7 +5,7 @@ #include "../../Common/RegisterArc.h" #include "IsoHandler.h" -static IInArchive *CreateArc() { return new NArchive::NIso::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NIso::CHandler; } static CArcInfo g_ArcInfo = { L"Iso", L"iso", 0, 0xE7, { 'C', 'D', '0', '0', '1', 0x1 }, 7, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/LzhHandler.cpp b/CPP/7zip/Archive/LzhHandler.cpp index 19a9516a..b9d953b9 100755 --- a/CPP/7zip/Archive/LzhHandler.cpp +++ b/CPP/7zip/Archive/LzhHandler.cpp @@ -168,13 +168,11 @@ struct CItem AString GetName() const { AString dirName = GetDirName(); - dirName.Replace((char)(unsigned char)0xFF, '\\'); - if (!dirName.IsEmpty()) - { - char c = dirName[dirName.Length() - 1]; - if (c != '\\') - dirName += '\\'; - } + const char kDirSeparator = '\\'; + // check kDirSeparator in Linux + dirName.Replace((char)(unsigned char)0xFF, kDirSeparator); + if (!dirName.IsEmpty() && dirName.Back() != kDirSeparator) + dirName += kDirSeparator; return dirName + GetFileName(); } }; @@ -469,7 +467,7 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro { UInt32 realProcessedSize; HRESULT result; - if(!_stream) + if (!_stream) { realProcessedSize = size; result = S_OK; @@ -477,7 +475,7 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro else result = _stream->Write(data, size, &realProcessedSize); _crc.Update(data, realProcessedSize); - if(processedSize != NULL) + if (processedSize != NULL) *processedSize = realProcessedSize; return result; } @@ -630,24 +628,19 @@ STDMETHODIMP CHandler::Close() return S_OK; } - - -////////////////////////////////////// -// CHandler::DecompressItems - -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, Int32 testModeSpec, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN bool testMode = (testModeSpec != 0); UInt64 totalUnPacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _items.Size(); - if(numItems == 0) + if (numItems == 0) return S_OK; UInt32 i; - for(i = 0; i < numItems; i++) + for (i = 0; i < numItems; i++) { const CItemEx &item = _items[allFilesMode ? i : indices[i]]; totalUnPacked += item.Size; @@ -674,7 +667,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ISequentialInStream> inStream(streamSpec); streamSpec->SetStream(_stream); - for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, + for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, currentTotalPacked += currentItemPacked) { currentItemUnPacked = 0; @@ -702,7 +695,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; } - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -773,7 +766,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, COM_TRY_END } -static IInArchive *CreateArc() { return new CHandler; } +static IInArchive *CreateArc() { return new CHandler; } static CArcInfo g_ArcInfo = { L"Lzh", L"lzh lha", 0, 6, { '-', 'l' }, 2, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/LzmaHandler.cpp b/CPP/7zip/Archive/LzmaHandler.cpp index 5dd0aac7..d9851501 100755 --- a/CPP/7zip/Archive/LzmaHandler.cpp +++ b/CPP/7zip/Archive/LzmaHandler.cpp @@ -319,28 +319,23 @@ STDMETHODIMP CHandler::Close() } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)-1); - if (!allFilesMode) - { - if (numItems == 0) - return S_OK; - if (numItems != 1 || indices[0] != 0) - return E_INVALIDARG; - } + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; - bool testMode = (_aTestMode != 0); if (_stream) extractCallback->SetTotal(_packSize); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); if (!testMode && !realOutStream) return S_OK; @@ -368,7 +363,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, _lzma86, _seqStream); RINOK(result); - Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + Int32 opRes = NExtract::NOperationResult::kOK; bool firstItem = true; for (;;) @@ -395,12 +390,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, result = decoder.Code(st, outStream, progress); if (result == E_NOTIMPL) { - opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + opRes = NExtract::NOperationResult::kUnSupportedMethod; break; } if (result == S_FALSE) { - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; break; } RINOK(result); diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp index 342a8e76..8d313b54 100755 --- a/CPP/7zip/Archive/MachoHandler.cpp +++ b/CPP/7zip/Archive/MachoHandler.cpp @@ -399,12 +399,11 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _sections.Size(); if (numItems == 0) @@ -434,8 +433,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, lps->InSize = lps->OutSize = currentTotalSize; RINOK(lps->SetCur()); Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; UInt32 index = allFilesMode ? i : indices[i]; const CSection &item = _sections[index]; currentItemSize = item.GetPackSize(); @@ -451,8 +450,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); outStream.Release(); RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/MbrHandler.cpp b/CPP/7zip/Archive/MbrHandler.cpp index 47b18f15..e2aa067f 100755 --- a/CPP/7zip/Archive/MbrHandler.cpp +++ b/CPP/7zip/Archive/MbrHandler.cpp @@ -431,12 +431,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _items.Size(); if (numItems == 0) @@ -467,14 +466,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> outStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItem &item = _items[index]; const CPartition &part = item.Part; RINOK(extractCallback->GetStream(index, &outStream, askMode)); totalSize += item.Size; - if (!testMode && (!outStream)) + if (!testMode && !outStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -483,8 +482,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); outStream.Release(); RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == item.Size ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END @@ -498,7 +497,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) COM_TRY_END } -static IInArchive *CreateArc() { return new CHandler; } +static IInArchive *CreateArc() { return new CHandler; } static CArcInfo g_ArcInfo = { L"MBR", L"mbr", 0, 0xDB, { 1, 1, 0 }, 3, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/MslzHandler.cpp b/CPP/7zip/Archive/MslzHandler.cpp new file mode 100755 index 00000000..67495e76 --- /dev/null +++ b/CPP/7zip/Archive/MslzHandler.cpp @@ -0,0 +1,257 @@ +// MslzHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/ComTry.h" +#include "Common/MyString.h" + +#include "Windows/PropVariant.h" + +#include "../Common/InBuffer.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "Common/DummyOutStream.h" + +namespace NArchive { +namespace NMslz { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ + CMyComPtr<IInStream> _stream; + UInt32 _size; + UInt64 _packSize; + UString _name; +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidPath: if (!_name.IsEmpty()) prop = _name; break; + case kpidSize: prop = _size; break; + case kpidPackSize: prop = _packSize; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +static const unsigned kSignatureSize = 9; +static const unsigned kHeaderSize = kSignatureSize + 1 + 4; +#define MSLZ_SIGNATURE { 0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33, 0x41 } +// old signature: 53 5A 20 88 F0 27 33 +static const Byte signature[kSignatureSize] = MSLZ_SIGNATURE; + +static const wchar_t *g_Exts[] = +{ + L"dll", + L"exe", + L"kmd", + L"sys" +}; + +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + { + Close(); + Byte buffer[kHeaderSize]; + RINOK(ReadStream_FALSE(stream, buffer, kHeaderSize)); + if (memcmp(buffer, signature, kSignatureSize) != 0) + return S_FALSE; + _size = GetUi32(buffer + 10); + if (_size > 0xFFFFFFE0) + return S_FALSE; + RINOK(stream->Seek(0, STREAM_SEEK_END, &_packSize)); + + if (callback) + { + CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; + callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + if (openVolumeCallback) + { + NWindows::NCOM::CPropVariant prop; + if (openVolumeCallback->GetProperty(kpidName, &prop) == S_OK && prop.vt == VT_BSTR) + { + UString baseName = prop.bstrVal; + if (!baseName.IsEmpty() && baseName.Back() == L'_') + { + baseName.DeleteBack(); + Byte replaceByte = buffer[kSignatureSize]; + if (replaceByte == 0) + { + for (int i = 0; i < sizeof(g_Exts) / sizeof(g_Exts[0]); i++) + { + UString s = g_Exts[i]; + int len = s.Length(); + Byte b = (Byte)s.Back(); + s.DeleteBack(); + if (baseName.Length() >= len && + baseName[baseName.Length() - len] == '.' && + s.CompareNoCase(baseName.Right(len - 1)) == 0) + { + replaceByte = b; + break; + } + } + } + if (replaceByte >= 0x20 && replaceByte < 0x80) + _name = baseName + (wchar_t)replaceByte; + } + } + } + } + _stream = stream; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _stream.Release(); + _name.Empty(); + return S_OK; +} + +// MslzDec is modified LZSS algorithm of Haruhiko Okumura: +// maxLen = 18; Okumura +// maxLen = 16; MS + +#define PROGRESS_AND_WRITE \ + if ((dest & kMask) == 0) { RINOK(WriteStream(outStream, buf, kBufSize)); \ + if ((dest & ((1 << 20) - 1)) == 0) \ + { UInt64 inSize = inStream.GetProcessedSize(); UInt64 outSize = dest; \ + RINOK(progress->SetRatioInfo(&inSize, &outSize)); }} + +static HRESULT MslzDec(CInBuffer &inStream, ISequentialOutStream *outStream, UInt32 unpackSize, ICompressProgressInfo *progress) +{ + const unsigned kBufSize = (1 << 12); + const unsigned kMask = kBufSize - 1; + Byte buf[kBufSize]; + UInt32 dest = 0; + memset(buf, ' ', kBufSize); + while (dest < unpackSize) + { + Byte b; + if (!inStream.ReadByte(b)) + return S_FALSE; + for (unsigned mask = (unsigned)b | 0x100; mask > 1 && dest < unpackSize; mask >>= 1) + { + if (!inStream.ReadByte(b)) + return S_FALSE; + if (mask & 1) + { + buf[dest++ & kMask] = b; + PROGRESS_AND_WRITE + } + else + { + Byte b1; + if (!inStream.ReadByte(b1)) + return S_FALSE; + const unsigned kMaxLen = 16; // 18 in Okumura's code. + unsigned src = (((((unsigned)b1 & 0xF0) << 4) | b) + kMaxLen) & kMask; + unsigned len = (b1 & 0xF) + 3; + if (len > kMaxLen || dest + len > unpackSize) + return S_FALSE; + do + { + buf[dest++ & kMask] = buf[src++ & kMask]; + PROGRESS_AND_WRITE + } + while (--len != 0); + } + } + } + return WriteStream(outStream, buf, dest & kMask); +} + +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + extractCallback->SetTotal(_size); + + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + if (!testMode && !realOutStream) + return S_OK; + + extractCallback->PrepareOperation(askMode); + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + CInBuffer s; + if (!s.Create(1 << 20)) + return E_OUTOFMEMORY; + s.SetStream(_stream); + s.Init(); + Byte buffer[kHeaderSize]; + Int32 opRes = NExtract::NOperationResult::kDataError; + if (s.ReadBytes(buffer, kHeaderSize) == kHeaderSize) + { + HRESULT result = MslzDec(s, outStream, _size, progress); + if (result == S_OK) + opRes = NExtract::NOperationResult::kOK; + else if (result != S_FALSE) + return result; + } + outStream.Release(); + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"MsLZ", L"", 0, 0xD5, MSLZ_SIGNATURE, kSignatureSize, false, CreateArc, 0 }; + +REGISTER_ARC(Mslz) + +}} diff --git a/CPP/7zip/Archive/MubHandler.cpp b/CPP/7zip/Archive/MubHandler.cpp index f099aad2..da4df24c 100755 --- a/CPP/7zip/Archive/MubHandler.cpp +++ b/CPP/7zip/Archive/MubHandler.cpp @@ -187,12 +187,11 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _numItems; if (numItems == 0) @@ -222,19 +221,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; UInt32 index = allFilesMode ? i : indices[i]; const CItem &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); currentTotalSize += item.Size; - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); if (testMode) { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } RINOK(_stream->Seek(_startPos + item.Offset, STREAM_SEEK_SET, NULL)); @@ -242,8 +241,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp index f2e3aab6..9a5daadf 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp +++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp @@ -263,12 +263,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) GetNumberOfItems(&numItems); if(numItems == 0) @@ -326,8 +325,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentItemSize = 0; RINOK(extractCallback->SetCompleted(¤tTotalSize)); CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; UInt32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -336,7 +336,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (index >= (UInt32)_archive.Items.Size()) { currentItemSize = _archive.Script.Length(); - if(!testMode && (!realOutStream)) + if(!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); if (!testMode) @@ -352,7 +352,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, else GetCompressedSize(index, currentItemSize); - if(!testMode && (!realOutStream)) + if(!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -477,8 +477,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } realOutStream.Release(); RINOK(extractCallback->SetOperationResult(dataError ? - NArchive::NExtract::NOperationResult::kDataError : - NArchive::NExtract::NOperationResult::kOK)); + NExtract::NOperationResult::kDataError : + NExtract::NOperationResult::kOK)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp index 9e7e89bb..06cc38eb 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.cpp +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -1,30 +1,21 @@ -// Archive/NsisIn.cpp +// NsisIn.cpp #include "StdAfx.h" -// #include <stdio.h> - -#include "NsisIn.h" -#include "NsisDecode.h" +#include "../../../../C/CpuArch.h" -#include "Windows/Defs.h" +#include "Common/IntToString.h" #include "../../Common/StreamUtils.h" -#include "Common/StringConvert.h" -#include "Common/IntToString.h" - -#include "../../../../C/CpuArch.h" +#include "NsisIn.h" #define Get32(p) GetUi32(p) namespace NArchive { namespace NNsis { -Byte kSignature[kSignatureSize] = { 0xEF + 1, 0xBE, 0xAD, 0xDE, -0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}; - -struct CSignatureInit { CSignatureInit() { kSignature[0]--; } } g_SignatureInit; +Byte kSignature[kSignatureSize] = NSIS_SIGNATURE; #ifdef NSIS_SCRIPT static const char *kCrLf = "\x0D\x0A"; diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h index 1fa6b4a6..3fc08440 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.h +++ b/CPP/7zip/Archive/Nsis/NsisIn.h @@ -1,17 +1,12 @@ -// Archive/NsisIn.h +// NsisIn.h #ifndef __ARCHIVE_NSIS_IN_H #define __ARCHIVE_NSIS_IN_H #include "Common/Buffer.h" -#include "Common/IntToString.h" #include "Common/MyCom.h" #include "Common/StringConvert.h" -#include "../../Common/CreateCoder.h" - -#include "../../IStream.h" - #include "NsisDecode.h" // #define NSIS_SCRIPT @@ -20,6 +15,8 @@ namespace NArchive { namespace NNsis { const int kSignatureSize = 16; +#define NSIS_SIGNATURE { 0xEF, 0xBE, 0xAD, 0xDE, 0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74} + extern Byte kSignature[kSignatureSize]; const UInt32 kFlagsMask = 0xF; diff --git a/CPP/7zip/Archive/Nsis/NsisRegister.cpp b/CPP/7zip/Archive/Nsis/NsisRegister.cpp index 7e6f7acb..41dedb0d 100755 --- a/CPP/7zip/Archive/Nsis/NsisRegister.cpp +++ b/CPP/7zip/Archive/Nsis/NsisRegister.cpp @@ -5,10 +5,9 @@ #include "../../Common/RegisterArc.h" #include "NsisHandler.h" -static IInArchive *CreateArc() { return new NArchive::NNsis::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NNsis::CHandler; } static CArcInfo g_ArcInfo = - { L"Nsis", 0, 0, 0x9, { 0xEF, 0xBE, 0xAD, 0xDE, -0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}, 16, false, CreateArc, 0 }; + { L"Nsis", L"", 0, 0x9, NSIS_SIGNATURE, NArchive::NNsis::kSignatureSize, false, CreateArc, 0 }; REGISTER_ARC(Nsis) diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp index 37847a24..f88dd012 100755 --- a/CPP/7zip/Archive/NtfsHandler.cpp +++ b/CPP/7zip/Archive/NtfsHandler.cpp @@ -124,7 +124,11 @@ bool CHeader::Parse(const Byte *p) // DriveNumber = p[0x24]; if (p[0x25] != 0) // CurrentHead return false; - if (p[0x26] != 0x80) // ExtendedBootSig + /* + NTFS-HDD: p[0x26] = 0x80 + NTFS-FLASH: p[0x26] = 0 + */ + if (p[0x26] != 0x80 && p[0x26] != 0) // ExtendedBootSig return false; if (p[0x27] != 0) // reserved return false; @@ -916,6 +920,9 @@ struct CDataRef int Num; }; +static const UInt32 kMagic_FILE = 0x454c4946; +static const UInt32 kMagic_BAAD = 0x44414142; + struct CMftRec { UInt32 Magic; @@ -934,7 +941,6 @@ struct CMftRec CSiAttr SiAttr; - void MoveAttrsFrom(CMftRec &src) { DataAttrs += src.DataAttrs; @@ -954,6 +960,8 @@ struct CMftRec bool Parse(Byte *p, int sectorSizeLog, UInt32 numSectors, UInt32 recNumber, CObjectVector<CAttr> *attrs); bool IsEmpty() const { return (Magic <= 2); } + bool IsFILE() const { return (Magic == kMagic_FILE); } + bool IsBAAD() const { return (Magic == kMagic_BAAD); } bool InUse() const { return (Flags & 1) != 0; } bool IsDir() const { return (Flags & 2) != 0; } @@ -1032,10 +1040,8 @@ bool CMftRec::Parse(Byte *p, int sectorSizeLog, UInt32 numSectors, UInt32 recNum CObjectVector<CAttr> *attrs) { G32(p, Magic); - if (IsEmpty()) - return true; - if (Magic != 0x454c4946) - return false; + if (!IsFILE()) + return IsEmpty() || IsBAAD(); UInt32 usaOffset; UInt32 numUsaItems; @@ -1246,7 +1252,7 @@ HRESULT CDatabase::Open() numSectorsInRec = 1 << (recSizeLog - Header.SectorSizeLog); if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, NULL, 0)) return S_FALSE; - if (mftRec.IsEmpty()) + if (!mftRec.IsFILE()) return S_FALSE; mftRec.ParseDataNames(); if (mftRec.DataRefs.IsEmpty()) @@ -1331,7 +1337,7 @@ HRESULT CDatabase::Open() for (i = 0; i < Recs.Size(); i++) { CMftRec &rec = Recs[i]; - if (rec.IsEmpty() || !rec.BaseMftRef.IsBaseItself()) + if (!rec.IsFILE() || !rec.BaseMftRef.IsBaseItself()) continue; int numNames = 0; // printf("\n%4d: ", i); @@ -1610,12 +1616,11 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = Items.Size(); if (numItems == 0) @@ -1655,8 +1660,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -1664,11 +1669,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); @@ -1679,12 +1684,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const CMftRec &rec = Recs[item.RecIndex]; const CAttr &data = rec.DataAttrs[rec.DataRefs[item.DataIndex].Start]; - int res = NArchive::NExtract::NOperationResult::kDataError; + int res = NExtract::NOperationResult::kDataError; { CMyComPtr<IInStream> inStream; HRESULT hres = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeLog, Header.NumClusters, &inStream); if (hres == S_FALSE) - res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + res = NExtract::NOperationResult::kUnSupportedMethod; else { RINOK(hres); @@ -1696,7 +1701,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(hres); } if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK) - res = NArchive::NExtract::NOperationResult::kOK; + res = NExtract::NOperationResult::kOK; } } } @@ -1715,7 +1720,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -static IInArchive *CreateArc() { return new CHandler; } +static IInArchive *CreateArc() { return new CHandler; } static CArcInfo g_ArcInfo = { L"NTFS", L"ntfs img", 0, 0xD9, { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 }, 9, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp index a1304ae4..fd900a58 100755 --- a/CPP/7zip/Archive/PeHandler.cpp +++ b/CPP/7zip/Archive/PeHandler.cpp @@ -4,9 +4,10 @@ #include "../../../C/CpuArch.h" -#include "Common/Buffer.h" +#include "Common/DynamicBuffer.h" #include "Common/ComTry.h" #include "Common/IntToString.h" +#include "Common/StringConvert.h" #include "Windows/PropVariantUtils.h" #include "Windows/Time.h" @@ -14,6 +15,7 @@ #include "../Common/LimitedStreams.h" #include "../Common/ProgressUtils.h" #include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" #include "../Common/StreamUtils.h" #include "../Compress/CopyCoder.h" @@ -168,6 +170,14 @@ struct COptHeader bool Is64Bit() const { return Magic == PE_OptHeader_Magic_64; } bool Parse(const Byte *p, UInt32 size); + + int GetNumFileAlignBits() const + { + for (int i = 9; i <= 16; i++) + if (((UInt32)1 << i) == FileAlign) + return i; + return -1; + } }; bool COptHeader::Parse(const Byte *p, UInt32 size) @@ -262,8 +272,8 @@ struct CSection void Parse(const Byte *p); }; -static bool operator <(const CSection &a1, const CSection &a2) { return (a1.Pa < a2.Pa); } -static bool operator ==(const CSection &a1, const CSection &a2) { return (a1.Pa == a2.Pa); } +static bool operator <(const CSection &a1, const CSection &a2) { return (a1.Pa < a2.Pa) || ((a1.Pa == a2.Pa) && (a1.PSize < a2.PSize)) ; } +static bool operator ==(const CSection &a1, const CSection &a2) { return (a1.Pa == a2.Pa) && (a1.PSize == a2.PSize); } static AString GetName(const Byte *name) { @@ -378,23 +388,182 @@ static const CUInt32PCharPair g_SubSystems[] = { 14, "XBOX" } }; +static const wchar_t *g_ResTypes[] = +{ + NULL, + L"CURSOR", + L"BITMAP", + L"ICON", + L"MENU", + L"DIALOG", + L"STRING", + L"FONTDIR", + L"FONT", + L"ACCELERATOR", + L"RCDATA", + L"MESSAGETABLE", + L"GROUP_CURSOR", + NULL, + L"GROUP_ICON", + NULL, + L"VERSION", + L"DLGINCLUDE", + NULL, + L"PLUGPLAY", + L"VXD", + L"ANICURSOR", + L"ANIICON", + L"HTML", + L"MANIFEST" +}; + +const UInt32 kFlag = (UInt32)1 << 31; +const UInt32 kMask = ~kFlag; + +struct CTableItem +{ + UInt32 Offset; + UInt32 ID; +}; + + +const UInt32 kBmpHeaderSize = 14; +const UInt32 kIconHeaderSize = 22; + +struct CResItem +{ + UInt32 Type; + UInt32 ID; + UInt32 Lang; + + UInt32 Size; + UInt32 Offset; + + UInt32 HeaderSize; + Byte Header[kIconHeaderSize]; // it must be enough for max size header. + bool Enabled; + + bool IsNameEqual(const CResItem &item) const { return Lang == item.Lang; } + UInt32 GetSize() const { return Size + HeaderSize; } + bool IsBmp() const { return Type == 2; } + bool IsIcon() const { return Type == 3; } + bool IsString() const { return Type == 6; } +}; + +struct CStringItem +{ + UInt32 Lang; + UInt32 Size; + CByteDynamicBuffer Buf; + + void AddChar(Byte c); + void AddWChar(UInt16 c); +}; + +void CStringItem::AddChar(Byte c) +{ + Buf.EnsureCapacity(Size + 2); + Buf[Size++] = c; + Buf[Size++] = 0; +} + +void CStringItem::AddWChar(UInt16 c) +{ + if (c == '\n') + { + AddChar('\\'); + c = 'n'; + } + Buf.EnsureCapacity(Size + 2); + SetUi16(Buf + Size, c); + Size += 2; +} + +struct CMixItem +{ + int SectionIndex; + int ResourceIndex; + int StringIndex; + + bool IsSectionItem() const { return ResourceIndex < 0 && StringIndex < 0; }; +}; + +struct CUsedBitmap +{ + CByteBuffer Buf; +public: + void Alloc(size_t size) + { + size = (size + 7) / 8; + Buf.SetCapacity(size); + memset(Buf, 0, size); + } + void Free() + { + Buf.SetCapacity(0); + } + bool SetRange(size_t from, int size) + { + for (int i = 0; i < size; i++) + { + size_t pos = (from + i) >> 3; + Byte mask = (Byte)(1 << ((from + i) & 7)); + Byte b = Buf[pos]; + if ((b & mask) != 0) + return false; + Buf[pos] = b | mask; + } + return true; + } +}; + + class CHandler: public IInArchive, + public IInArchiveGetStream, public CMyUnknownImp { - CMyComPtr<IInStream> _inStream; + CMyComPtr<IInStream> _stream; CObjectVector<CSection> _sections; UInt32 _peOffset; CHeader _header; COptHeader _optHeader; UInt32 _totalSize; UInt32 _totalSizeLimited; + + CRecordVector<CResItem> _items; + CObjectVector<CStringItem> _strings; + + CByteBuffer _buf; + bool _oneLang; + UString _resourceFileName; + CUsedBitmap _usedRes; + bool _parseResources; + + CRecordVector<CMixItem> _mixItems; + HRESULT LoadDebugSections(IInStream *stream, bool &thereIsSection); - HRESULT Open2(IInStream *stream); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); bool Parse(const Byte *buf, UInt32 size); + + void AddResNameToString(UString &s, UInt32 id) const; + UString GetLangPrefix(UInt32 lang); + HRESULT ReadString(UInt32 offset, UString &dest) const; + HRESULT ReadTable(UInt32 offset, CRecordVector<CTableItem> &items); + bool ParseStringRes(UInt32 id, UInt32 lang, const Byte *src, UInt32 size); + HRESULT OpenResources(int sectIndex, IInStream *stream, IArchiveOpenCallback *callback); + void CloseResources(); + + + bool CheckItem(const CSection §, const CResItem &item, size_t offset) const + { + return item.Offset >= sect.Va && offset <= _buf.GetCapacity() && _buf.GetCapacity() - offset >= item.Size; + } + public: - MY_UNKNOWN_IMP1(IInArchive) + MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) INTERFACE_IInArchive(;) + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; bool CHandler::Parse(const Byte *buf, UInt32 size) @@ -524,25 +693,25 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) break; } - case kpidOsVer: VerToProp(_optHeader.OsVer, prop); break; - case kpidImageVer: VerToProp(_optHeader.ImageVer, prop); break; - case kpidSubsysVer: VerToProp(_optHeader.SubsysVer, prop); break; - case kpidCodeSize: prop = _optHeader.CodeSize; break; - case kpidInitDataSize: prop = _optHeader.InitDataSize; break; - case kpidUnInitDataSize: prop = _optHeader.UninitDataSize; break; - case kpidImageSize: prop = _optHeader.ImageSize; break; - case kpidPhySize: prop = _totalSize; break; - case kpidHeadersSize: prop = _optHeader.HeadersSize; break; - case kpidChecksum: prop = _optHeader.CheckSum; break; + case kpidOsVer: VerToProp(_optHeader.OsVer, prop); break; + case kpidImageVer: VerToProp(_optHeader.ImageVer, prop); break; + case kpidSubsysVer: VerToProp(_optHeader.SubsysVer, prop); break; + case kpidCodeSize: prop = _optHeader.CodeSize; break; + case kpidInitDataSize: prop = _optHeader.InitDataSize; break; + case kpidUnInitDataSize: prop = _optHeader.UninitDataSize; break; + case kpidImageSize: prop = _optHeader.ImageSize; break; + case kpidPhySize: prop = _totalSize; break; + case kpidHeadersSize: prop = _optHeader.HeadersSize; break; + case kpidChecksum: prop = _optHeader.CheckSum; break; - case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break; - case kpidBit64: if (_optHeader.Is64Bit()) prop = true; break; - case kpidSubSystem: PAIR_TO_PROP(g_SubSystems, _optHeader.SubSystem, prop); break; + case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break; + case kpidBit64: if (_optHeader.Is64Bit()) prop = true; break; + case kpidSubSystem: PAIR_TO_PROP(g_SubSystems, _optHeader.SubSystem, prop); break; case kpidMTime: - case kpidCTime: TimeToProp(_header.Time, prop); break; - case kpidCharacts: FLAGS_TO_PROP(g_HeaderCharacts, _header.Flags, prop); break; - case kpidDllCharacts: FLAGS_TO_PROP(g_DllCharacts, _optHeader.DllCharacts, prop); break; + case kpidCTime: TimeToProp(_header.Time, prop); break; + case kpidCharacts: FLAGS_TO_PROP(g_HeaderCharacts, _header.Flags, prop); break; + case kpidDllCharacts: FLAGS_TO_PROP(g_DllCharacts, _optHeader.DllCharacts, prop); break; case kpidStackReserve: prop = _optHeader.StackReserve; break; case kpidStackCommit: prop = _optHeader.StackCommit; break; case kpidHeapReserve: prop = _optHeader.HeapReserve; break; @@ -553,22 +722,105 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) COM_TRY_END } +void CHandler::AddResNameToString(UString &s, UInt32 id) const +{ + if ((id & kFlag) != 0) + { + UString name; + if (ReadString(id & kMask, name) == S_OK) + { + if (name.IsEmpty()) + s += L"[]"; + else + { + if (name.Length() > 1 && name[0] == '"' && name.Back() == '"') + name = name.Mid(1, name.Length() - 2); + s += name; + } + return; + } + } + wchar_t sz[32]; + ConvertUInt32ToString(id, sz); + s += sz; +} + +UString CHandler::GetLangPrefix(UInt32 lang) +{ + UString s = _resourceFileName; + s += WCHAR_PATH_SEPARATOR; + if (!_oneLang) + { + AddResNameToString(s, lang); + s += WCHAR_PATH_SEPARATOR; + } + return s; +} + STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NCOM::CPropVariant prop; - const CSection &item = _sections[index]; - switch(propID) + const CMixItem &mixItem = _mixItems[index]; + if (mixItem.StringIndex >= 0) { - case kpidPath: StringToProp(item.Name, prop); break; - case kpidSize: prop = (UInt64)item.VSize; break; - case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; - case kpidOffset: prop = item.Pa; break; - case kpidVa: if (item.IsRealSect) prop = item.Va; break; - case kpidMTime: - case kpidCTime: - TimeToProp(item.IsDebug ? item.Time : _header.Time, prop); break; - case kpidCharacts: if (item.IsRealSect) FLAGS_TO_PROP(g_SectFlags, item.Flags, prop); break; + const CStringItem &item = _strings[mixItem.StringIndex]; + switch(propID) + { + case kpidPath: prop = GetLangPrefix(item.Lang) + L"string.txt"; break; + case kpidSize: + case kpidPackSize: + prop = (UInt64)item.Size; break; + } + } + else if (mixItem.ResourceIndex < 0) + { + const CSection &item = _sections[mixItem.SectionIndex]; + switch(propID) + { + case kpidPath: StringToProp(item.Name, prop); break; + case kpidSize: prop = (UInt64)item.VSize; break; + case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; + case kpidOffset: prop = item.Pa; break; + case kpidVa: if (item.IsRealSect) prop = item.Va; break; + case kpidMTime: + case kpidCTime: + TimeToProp(item.IsDebug ? item.Time : _header.Time, prop); break; + case kpidCharacts: if (item.IsRealSect) FLAGS_TO_PROP(g_SectFlags, item.Flags, prop); break; + } + } + else + { + const CResItem &item = _items[mixItem.ResourceIndex]; + switch(propID) + { + case kpidPath: + { + UString s = GetLangPrefix(item.Lang); + { + const wchar_t *p = NULL; + if (item.Type < sizeof(g_ResTypes) / sizeof(g_ResTypes[0])) + p = g_ResTypes[item.Type]; + if (p != 0) + s += p; + else + AddResNameToString(s, item.Type); + } + s += WCHAR_PATH_SEPARATOR; + AddResNameToString(s, item.ID); + if (item.HeaderSize != 0) + { + if (item.IsBmp()) + s += L".bmp"; + else if (item.IsIcon()) + s += L".ico"; + } + prop = s; + break; + } + case kpidSize: prop = (UInt64)item.GetSize(); break; + case kpidPackSize: prop = (UInt64)item.Size; break; + } } prop.Detach(value); return S_OK; @@ -640,7 +892,372 @@ HRESULT CHandler::LoadDebugSections(IInStream *stream, bool &thereIsSection) return S_OK; } -HRESULT CHandler::Open2(IInStream *stream) +HRESULT CHandler::ReadString(UInt32 offset, UString &dest) const +{ + if ((offset & 1) != 0 || offset >= _buf.GetCapacity()) + return S_FALSE; + size_t rem = _buf.GetCapacity() - offset; + if (rem < 2) + return S_FALSE; + unsigned length = Get16(_buf + offset); + if ((rem - 2) / 2 < length) + return S_FALSE; + dest.Empty(); + offset += 2; + for (unsigned i = 0; i < length; i++) + dest += (wchar_t)Get16(_buf + offset + i * 2); + return S_OK; +} + +HRESULT CHandler::ReadTable(UInt32 offset, CRecordVector<CTableItem> &items) +{ + if ((offset & 3) != 0 || offset >= _buf.GetCapacity()) + return S_FALSE; + size_t rem = _buf.GetCapacity() - offset; + if (rem < 16) + return S_FALSE; + items.Clear(); + unsigned numNameItems = Get16(_buf + offset + 12); + unsigned numIdItems = Get16(_buf + offset + 14); + unsigned numItems = numNameItems + numIdItems; + if ((rem - 16) / 8 < numItems) + return S_FALSE; + if (!_usedRes.SetRange(offset, 16 + numItems * 8)) + return S_FALSE; + offset += 16; + _oneLang = true; + unsigned i; + for (i = 0; i < numItems; i++) + { + CTableItem item; + const Byte *buf = _buf + offset; + offset += 8; + item.ID = Get32(buf + 0); + if (((item.ID & kFlag) != 0) != (i < numNameItems)) + return S_FALSE; + item.Offset = Get32(buf + 4); + items.Add(item); + } + return S_OK; +} + +static const UInt32 kFileSizeMax = (UInt32)1 << 30; +static const int kNumResItemsMax = (UInt32)1 << 23; +static const int kNumStringLangsMax = 128; + +// BITMAPINFOHEADER +struct CBitmapInfoHeader +{ + // UInt32 HeaderSize; + UInt32 XSize; + Int32 YSize; + UInt16 Planes; + UInt16 BitCount; + UInt32 Compression; + UInt32 SizeImage; + + bool Parse(const Byte *p, size_t size); +}; + +static const UInt32 kBitmapInfoHeader_Size = 0x28; + +bool CBitmapInfoHeader::Parse(const Byte *p, size_t size) +{ + if (size < kBitmapInfoHeader_Size || Get32(p) != kBitmapInfoHeader_Size) + return false; + XSize = Get32(p + 4); + YSize = (Int32)Get32(p + 8); + Planes = Get16(p + 12); + BitCount = Get16(p + 14); + Compression = Get32(p + 16); + SizeImage = Get32(p + 20); + return true; +}; + +static UInt32 GetImageSize(UInt32 xSize, UInt32 ySize, UInt32 bitCount) +{ + return ((xSize * bitCount + 7) / 8 + 3) / 4 * 4 * ySize; +} + +static UInt32 SetBitmapHeader(Byte *dest, const Byte *src, UInt32 size) +{ + CBitmapInfoHeader h; + if (!h.Parse(src, size)) + return 0; + if (h.YSize < 0) + h.YSize = -h.YSize; + if (h.XSize > (1 << 26) || h.YSize > (1 << 26) || h.Planes != 1 || h.BitCount > 32 || + h.Compression != 0) // BI_RGB + return 0; + if (h.SizeImage == 0) + h.SizeImage = GetImageSize(h.XSize, h.YSize, h.BitCount); + UInt32 totalSize = kBmpHeaderSize + size; + UInt32 offBits = totalSize - h.SizeImage; + // BITMAPFILEHEADER + SetUi16(dest, 0x4D42); + SetUi32(dest + 2, totalSize); + SetUi32(dest + 6, 0); + SetUi32(dest + 10, offBits); + return kBmpHeaderSize; +} + +static UInt32 SetIconHeader(Byte *dest, const Byte *src, UInt32 size) +{ + CBitmapInfoHeader h; + if (!h.Parse(src, size)) + return 0; + if (h.YSize < 0) + h.YSize = -h.YSize; + if (h.XSize > (1 << 26) || h.YSize > (1 << 26) || h.Planes != 1 || + h.Compression != 0) // BI_RGB + return 0; + + UInt32 numBitCount = h.BitCount; + if (numBitCount != 1 && + numBitCount != 4 && + numBitCount != 8 && + numBitCount != 24 && + numBitCount != 32) + return 0; + + if ((h.YSize & 1) != 0) + return 0; + h.YSize /= 2; + if (h.XSize > 0x100 || h.YSize > 0x100) + return 0; + + UInt32 imageSize; + // imageSize is not correct if AND mask array contains zeros + // in this case it is equal image1Size + + // UInt32 imageSize = h.SizeImage; + // if (imageSize == 0) + // { + UInt32 image1Size = GetImageSize(h.XSize, h.YSize, h.BitCount); + UInt32 image2Size = GetImageSize(h.XSize, h.YSize, 1); + imageSize = image1Size + image2Size; + // } + UInt32 numColors = 0; + if (numBitCount < 16) + numColors = 1 << numBitCount; + + SetUi16(dest, 0); // Reserved + SetUi16(dest + 2, 1); // RES_ICON + SetUi16(dest + 4, 1); // ResCount + + dest[6] = (Byte)h.XSize; // Width + dest[7] = (Byte)h.YSize; // Height + dest[8] = (Byte)numColors; // ColorCount + dest[9] = 0; // Reserved + + SetUi32(dest + 10, 0); // Reserved1 / Reserved2 + + UInt32 numQuadsBytes = numColors * 4; + UInt32 BytesInRes = kBitmapInfoHeader_Size + numQuadsBytes + imageSize; + SetUi32(dest + 14, BytesInRes); + SetUi32(dest + 18, kIconHeaderSize); + + /* + Description = DWORDToString(xSize) + + kDelimiterChar + DWORDToString(ySize) + + kDelimiterChar + DWORDToString(numBitCount); + */ + return kIconHeaderSize; +} + +bool CHandler::ParseStringRes(UInt32 id, UInt32 lang, const Byte *src, UInt32 size) +{ + if ((size & 1) != 0) + return false; + + int i; + for (i = 0; i < _strings.Size(); i++) + if (_strings[i].Lang == lang) + break; + if (i == _strings.Size()) + { + if (_strings.Size() >= kNumStringLangsMax) + return false; + CStringItem item; + item.Size = 0; + item.Lang = lang; + i = _strings.Add(item); + } + + CStringItem &item = _strings[i]; + id = (id - 1) << 4; + UInt32 pos = 0; + for (i = 0; i < 16; i++) + { + if (size - pos < 2) + return false; + UInt32 len = Get16(src + pos); + pos += 2; + if (len != 0) + { + if (size - pos < len * 2) + return false; + char temp[32]; + ConvertUInt32ToString(id + i, temp); + size_t tempLen = strlen(temp); + size_t j; + for (j = 0; j < tempLen; j++) + item.AddChar(temp[j]); + item.AddChar('\t'); + for (j = 0; j < len; j++, pos += 2) + item.AddWChar(Get16(src + pos)); + item.AddChar(0x0D); + item.AddChar(0x0A); + } + } + return (size == pos); +} + +HRESULT CHandler::OpenResources(int sectionIndex, IInStream *stream, IArchiveOpenCallback *callback) +{ + const CSection § = _sections[sectionIndex]; + size_t fileSize = sect.PSize; // Maybe we need sect.VSize here !!! + if (fileSize > kFileSizeMax) + return S_FALSE; + { + UInt64 fileSize64 = fileSize; + if (callback) + RINOK(callback->SetTotal(NULL, &fileSize64)); + RINOK(stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL)); + _buf.SetCapacity(fileSize); + for (size_t pos = 0; pos < fileSize;) + { + UInt64 offset64 = pos; + if (callback) + RINOK(callback->SetCompleted(NULL, &offset64)) + size_t rem = MyMin(fileSize - pos, (size_t)(1 << 20)); + RINOK(ReadStream_FALSE(stream, _buf + pos, rem)); + pos += rem; + } + } + + _usedRes.Alloc(fileSize); + CRecordVector<CTableItem> specItems; + RINOK(ReadTable(0, specItems)); + + _oneLang = true; + bool stringsOk = true; + size_t maxOffset = 0; + for (int i = 0; i < specItems.Size(); i++) + { + const CTableItem &item1 = specItems[i]; + if ((item1.Offset & kFlag) == 0) + return S_FALSE; + + CRecordVector<CTableItem> specItems2; + RINOK(ReadTable(item1.Offset & kMask, specItems2)); + + for (int j = 0; j < specItems2.Size(); j++) + { + const CTableItem &item2 = specItems2[j]; + if ((item2.Offset & kFlag) == 0) + return S_FALSE; + + CRecordVector<CTableItem> specItems3; + RINOK(ReadTable(item2.Offset & kMask, specItems3)); + + CResItem item; + item.Type = item1.ID; + item.ID = item2.ID; + + for (int k = 0; k < specItems3.Size(); k++) + { + if (_items.Size() >= kNumResItemsMax) + return S_FALSE; + const CTableItem &item3 = specItems3[k]; + if ((item3.Offset & kFlag) != 0) + return S_FALSE; + if (item3.Offset >= _buf.GetCapacity() || _buf.GetCapacity() - item3.Offset < 16) + return S_FALSE; + const Byte *buf = _buf + item3.Offset; + item.Lang = item3.ID; + item.Offset = Get32(buf + 0); + item.Size = Get32(buf + 4); + // UInt32 codePage = Get32(buf + 8); + if (Get32(buf + 12) != 0) + return S_FALSE; + if (!_items.IsEmpty() && _oneLang && !item.IsNameEqual(_items.Back())) + _oneLang = false; + + item.HeaderSize = 0; + + size_t offset = item.Offset - sect.Va; + if (offset > maxOffset) + maxOffset = offset; + if (offset + item.Size > maxOffset) + maxOffset = offset + item.Size; + + if (CheckItem(sect, item, offset)) + { + const Byte *data = _buf + offset; + if (item.IsBmp()) + item.HeaderSize = SetBitmapHeader(item.Header, data, item.Size); + else if (item.IsIcon()) + item.HeaderSize = SetIconHeader(item.Header, data, item.Size); + else if (item.IsString()) + { + if (stringsOk) + stringsOk = ParseStringRes(item.ID, item.Lang, data, item.Size); + } + } + + item.Enabled = true; + _items.Add(item); + } + } + } + + if (stringsOk && !_strings.IsEmpty()) + { + int i; + for (i = 0; i < _items.Size(); i++) + { + CResItem &item = _items[i]; + if (item.IsString()) + item.Enabled = false; + } + for (i = 0; i < _strings.Size(); i++) + { + if (_strings[i].Size == 0) + continue; + CMixItem mixItem; + mixItem.ResourceIndex = -1; + mixItem.StringIndex = i; + mixItem.SectionIndex = sectionIndex; + _mixItems.Add(mixItem); + } + } + + _usedRes.Free(); + + int numBits = _optHeader.GetNumFileAlignBits(); + if (numBits >= 0) + { + UInt32 mask = (1 << numBits) - 1; + size_t end = ((maxOffset + mask) & ~mask); + if (end < sect.VSize) + { + CSection sect2; + sect2.Flags = 0; + sect2.Pa = sect.Pa + (UInt32)maxOffset; + sect2.Va = sect.Va + (UInt32)maxOffset; + sect2.PSize = sect.VSize - (UInt32)maxOffset; + sect2.VSize = sect2.PSize; + sect2.Name = ".rsrc_1"; + sect2.Time = 0; + _sections.Add(sect2); + } + } + + return S_OK; +} + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { const UInt32 kBufSize = 1 << 18; const UInt32 kSigSize = 2; @@ -732,7 +1349,8 @@ HRESULT CHandler::Open2(IInStream *stream) sections.Sort(); UInt32 limit = (1 << 12); int num = 0; - for (int i = 0; i < sections.Size(); i++) + int numSections = sections.Size(); + for (int i = 0; i < numSections; i++) { const CSection &s = sections[i]; if (s.Pa > limit) @@ -740,20 +1358,72 @@ HRESULT CHandler::Open2(IInStream *stream) CSection s2; s2.Pa = s2.Va = limit; s2.PSize = s2.VSize = s.Pa - limit; - char sz[32]; - ConvertUInt64ToString(++num, sz); - s2.Name = "[data-"; - s2.Name += sz; - s2.Name += "]"; + s2.Name = '['; + s2.Name += GetDecString(num++); + s2.Name += ']'; _sections.Add(s2); + limit = s.Pa; } UInt32 next = s.Pa + s.PSize; - if (next < limit) + if (next < s.Pa) break; - limit = next; + if (next >= limit) + limit = next; } } + _parseResources = true; + + for (int i = 0; i < _sections.Size(); i++) + { + const CSection § = _sections[i]; + CMixItem mixItem; + mixItem.SectionIndex = i; + if (_parseResources && sect.Name == ".rsrc" && _items.IsEmpty()) + { + HRESULT res = OpenResources(i, stream, callback); + if (res == S_OK) + { + _resourceFileName = GetUnicodeString(sect.Name); + for (int j = 0; j < _items.Size(); j++) + if (_items[j].Enabled) + { + mixItem.ResourceIndex = j; + mixItem.StringIndex = -1; + _mixItems.Add(mixItem); + } + if (sect.PSize > sect.VSize) + { + int numBits = _optHeader.GetNumFileAlignBits(); + if (numBits >= 0) + { + UInt32 mask = (1 << numBits) - 1; + UInt32 end = ((sect.VSize + mask) & ~mask); + + if (sect.PSize > end) + { + CSection sect2; + sect2.Flags = 0; + sect2.Pa = sect.Pa + end; + sect2.Va = sect.Va + end; + sect2.PSize = sect.PSize - end; + sect2.VSize = sect2.PSize; + sect2.Name = ".rsrc_2"; + sect2.Time = 0; + _sections.Add(sect2); + } + } + } + continue; + } + if (res != S_FALSE) + return res; + CloseResources(); + } + mixItem.StringIndex = -1; + mixItem.ResourceIndex = -1; + _mixItems.Add(mixItem); + } return S_OK; } @@ -766,8 +1436,8 @@ HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 excludePos Byte *buf = buffer; UInt32 sum = 0; - UInt32 pos; - for(pos = 0;;) + UInt32 pos = 0; + for (;;) { UInt32 rem = size - pos; if (rem > kBufSize) @@ -806,46 +1476,60 @@ HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 excludePos return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) +STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) { COM_TRY_BEGIN Close(); - RINOK(Open2(inStream)); - _inStream = inStream; + RINOK(Open2(inStream, callback)); + _stream = inStream; return S_OK; COM_TRY_END } +void CHandler::CloseResources() +{ + _usedRes.Free(); + _items.Clear(); + _strings.Clear(); + _buf.SetCapacity(0); +} + STDMETHODIMP CHandler::Close() { - _inStream.Release(); + _stream.Release(); _sections.Clear(); - + _mixItems.Clear(); + CloseResources(); return S_OK; } STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { - *numItems = _sections.Size(); + *numItems = _mixItems.Size(); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) - numItems = _sections.Size(); + numItems = _mixItems.Size(); if (numItems == 0) return S_OK; UInt64 totalSize = 0; UInt32 i; for (i = 0; i < numItems; i++) - totalSize += _sections[allFilesMode ? i : indices[i]].GetPackSize(); + { + const CMixItem &mixItem = _mixItems[allFilesMode ? i : indices[i]]; + if (mixItem.StringIndex >= 0) + totalSize += _strings[mixItem.StringIndex].Size; + else if (mixItem.ResourceIndex < 0) + totalSize += _sections[mixItem.SectionIndex].GetPackSize(); + else + totalSize += _items[mixItem.ResourceIndex].GetSize(); + } extractCallback->SetTotal(totalSize); UInt64 currentTotalSize = 0; @@ -859,53 +1543,127 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, lps->Init(extractCallback, false); bool checkSumOK = true; - if (_optHeader.CheckSum != 0 && (int)numItems == _sections.Size()) + if (_optHeader.CheckSum != 0 && (int)numItems == _mixItems.Size()) { UInt32 checkSum = 0; - RINOK(_inStream->Seek(0, STREAM_SEEK_SET, NULL)); - CalcCheckSum(_inStream, _totalSizeLimited, _peOffset + kHeaderSize + 64, checkSum); + RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + CalcCheckSum(_stream, _totalSizeLimited, _peOffset + kHeaderSize + 64, checkSum); checkSumOK = (checkSum == _optHeader.CheckSum); } CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream(streamSpec); - streamSpec->SetStream(_inStream); + streamSpec->SetStream(_stream); for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { lps->InSize = lps->OutSize = currentTotalSize; RINOK(lps->SetCur()); Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; UInt32 index = allFilesMode ? i : indices[i]; - const CSection &item = _sections[index]; - currentItemSize = item.GetPackSize(); CMyComPtr<ISequentialOutStream> outStream; RINOK(extractCallback->GetStream(index, &outStream, askMode)); - if (!testMode && !outStream) - continue; + const CMixItem &mixItem = _mixItems[index]; + + const CSection § = _sections[mixItem.SectionIndex]; + bool isOk = true; + if (mixItem.StringIndex >= 0) + { + const CStringItem &item = _strings[mixItem.StringIndex]; + currentItemSize = item.Size; + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + if (outStream) + RINOK(WriteStream(outStream, item.Buf, item.Size)); + } + else if (mixItem.ResourceIndex < 0) + { + currentItemSize = sect.GetPackSize(); + if (!testMode && !outStream) + continue; - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_inStream->Seek(item.Pa, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(_stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL)); + streamSpec->Init(currentItemSize); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + isOk = (copyCoderSpec->TotalSize == currentItemSize); + } + else + { + const CResItem &item = _items[mixItem.ResourceIndex]; + currentItemSize = item.GetSize(); + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + size_t offset = item.Offset - sect.Va; + if (!CheckItem(sect, item, offset)) + isOk = false; + else if (outStream) + { + if (item.HeaderSize != 0) + RINOK(WriteStream(outStream, item.Header, item.HeaderSize)); + RINOK(WriteStream(outStream, _buf + offset, item.Size)); + } + } + outStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ? + RINOK(extractCallback->SetOperationResult(isOk ? checkSumOK ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kCRCError: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kCRCError: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END } +STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +{ + COM_TRY_BEGIN + *stream = 0; + + const CMixItem &mixItem = _mixItems[index]; + const CSection § = _sections[mixItem.SectionIndex]; + if (mixItem.IsSectionItem()) + return CreateLimitedInStream(_stream, sect.Pa, sect.PSize, stream); + + CBufInStream *inStreamSpec = new CBufInStream; + CMyComPtr<ISequentialInStream> streamTemp = inStreamSpec; + CReferenceBuf *referenceBuf = new CReferenceBuf; + CMyComPtr<IUnknown> ref = referenceBuf; + if (mixItem.StringIndex >= 0) + { + const CStringItem &item = _strings[mixItem.StringIndex]; + referenceBuf->Buf.SetCapacity(item.Size); + memcpy(referenceBuf->Buf, item.Buf, item.Size); + } + else + { + const CResItem &item = _items[mixItem.ResourceIndex]; + size_t offset = item.Offset - sect.Va; + if (!CheckItem(sect, item, offset)) + return S_FALSE; + referenceBuf->Buf.SetCapacity(item.HeaderSize + item.Size); + memcpy(referenceBuf->Buf, item.Header, item.HeaderSize); + memcpy(referenceBuf->Buf + item.HeaderSize, _buf + offset, item.Size); + } + inStreamSpec->Init(referenceBuf); + + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + static IInArchive *CreateArc() { return new CHandler; } static CArcInfo g_ArcInfo = - { L"PE", L"", 0, 0xDD, { 0 }, 0, false, CreateArc, 0 }; + { L"PE", L"exe dll sys", 0, 0xDD, { 'P', 'E', 0, 0 }, 4, false, CreateArc, 0 }; REGISTER_ARC(Pe) diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index 93c19265..b5decec8 100755 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -350,7 +350,7 @@ HRESULT CHandler::Open2(IInStream *stream, if (!openVolumeCallback) break; - if(_archives.Size() == 1) + if (_archives.Size() == 1) { if (!_archiveInfo.IsVolume()) break; @@ -395,9 +395,14 @@ HRESULT CHandler::Open2(IInStream *stream, CItemEx item; for (;;) { - HRESULT result = archive.GetNextItem(item, getTextPassword); + bool decryptionError; + HRESULT result = archive.GetNextItem(item, getTextPassword, decryptionError); if (result == S_FALSE) + { + if (decryptionError && _items.IsEmpty()) + return S_FALSE; break; + } RINOK(result); if (item.IgnoreItem()) continue; @@ -470,27 +475,25 @@ struct CMethodItem }; -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN CMyComPtr<ICryptoGetTextPassword> getTextPassword; - bool testMode = (_aTestMode != 0); - CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback; UInt64 censoredTotalUnPacked = 0, // censoredTotalPacked = 0, importantTotalUnPacked = 0; // importantTotalPacked = 0; - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _refItems.Size(); - if(numItems == 0) + if (numItems == 0) return S_OK; int lastIndex = 0; CRecordVector<int> importantIndexes; CRecordVector<bool> extractStatuses; - for(UInt32 t = 0; t < numItems; t++) + for (UInt32 t = 0; t < numItems; t++) { int index = allFilesMode ? t : indices[t]; const CRefItem &refItem = _refItems[index]; @@ -498,11 +501,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, censoredTotalUnPacked += item.Size; // censoredTotalPacked += item.PackSize; int j; - for(j = lastIndex; j <= index; j++) - // if(!_items[_refItems[j].ItemIndex].IsSolid()) - if(!IsSolid(j)) + for (j = lastIndex; j <= index; j++) + // if (!_items[_refItems[j].ItemIndex].IsSolid()) + if (!IsSolid(j)) lastIndex = j; - for(j = lastIndex; j <= index; j++) + for (j = lastIndex; j <= index; j++) { const CRefItem &refItem = _refItems[j]; const CItemEx &item = _items[refItem.ItemIndex]; @@ -543,7 +546,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, lps->Init(extractCallback, false); bool solidStart = true; - for(int i = 0; i < importantIndexes.Size(); i++, + for (int i = 0; i < importantIndexes.Size(); i++, currentImportantTotalUnPacked += currentUnPackSize, currentImportantTotalPacked += currentPackSize) { @@ -553,12 +556,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode; - if(extractStatuses[i]) + if (extractStatuses[i]) askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; else - askMode = NArchive::NExtract::NAskMode::kSkip; + askMode = NExtract::NAskMode::kSkip; UInt32 index = importantIndexes[i]; @@ -569,22 +572,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentPackSize = GetPackSize(index); - if(item.IgnoreItem()) + if (item.IgnoreItem()) continue; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); if (!IsSolid(index)) solidStart = true; - if(item.IsDir()) + if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } bool mustBeProcessedAnywhere = false; - if(i < importantIndexes.Size() - 1) + if (i < importantIndexes.Size() - 1) { // const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]]; // const CItemEx &nextItemInfo = _items[nextRefItem.ItemIndex]; @@ -596,7 +599,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; if (!realOutStream && !testMode) - askMode = NArchive::NExtract::NAskMode::kSkip; + askMode = NExtract::NAskMode::kSkip; RINOK(extractCallback->PrepareOperation(askMode)); @@ -664,15 +667,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, else { outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); continue; } RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); if (!getTextPassword) - extractCallback.QueryInterface(IID_ICryptoGetTextPassword, - &getTextPassword); + extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); if (getTextPassword) { CMyComBSTR password; @@ -729,7 +731,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item.UnPackVersion >= 29) { outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); continue; } */ @@ -758,7 +760,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (mi.Coder == 0) { outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); continue; } @@ -785,7 +787,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } default: outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); continue; } HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Size, progress); @@ -794,7 +796,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (result == S_FALSE) { outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError)); continue; } if (result != S_OK) @@ -808,8 +810,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; bool crcOK = outStreamSpec->GetCRC() == lastItem.FileCRC; outStream.Release(); - RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kCRCError)); + RINOK(extractCallback->SetOperationResult(crcOK ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kCRCError)); } /* else @@ -824,8 +827,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, break; } } - RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kCRCError)); + RINOK(extractCallback->SetOperationResult(crcOK ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kCRCError)); } */ } diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp index 4810649b..5ea12c2d 100755 --- a/CPP/7zip/Archive/Rar/RarIn.cpp +++ b/CPP/7zip/Archive/Rar/RarIn.cpp @@ -372,8 +372,9 @@ void CInArchive::AddToSeekValue(UInt64 addValue) m_Position += addValue; } -HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword) +HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError) { + decryptionError = false; if (m_SeekOnArchiveComment) SkipArchiveComment(); for (;;) @@ -469,8 +470,11 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa AddToSeekValue(item.PackSize); // m_Position points to next header; return S_OK; } - if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 12)) - return E_FAIL; // it's for bad passwords + if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10)) + { + decryptionError = true; + return S_FALSE; + } if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) { m_FileHeaderData.EnsureCapacity(7 + 4); @@ -480,7 +484,10 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa UInt32 dataSize = ReadUInt32(); AddToSeekValue(dataSize); if (m_CryptoMode && dataSize > (1 << 27)) - return E_FAIL; // it's for bad passwords + { + decryptionError = true; + return S_FALSE; + } m_CryptoPos = m_BlockHeader.HeadSize; } else diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h index ff97a109..3d446977 100755 --- a/CPP/7zip/Archive/Rar/RarIn.h +++ b/CPP/7zip/Archive/Rar/RarIn.h @@ -111,7 +111,7 @@ protected: public: HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); void Close(); - HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword); + HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword, bool &decryptionError); void SkipArchiveComment(); diff --git a/CPP/7zip/Archive/Rar/RarRegister.cpp b/CPP/7zip/Archive/Rar/RarRegister.cpp index a79fd026..2bcf569e 100755 --- a/CPP/7zip/Archive/Rar/RarRegister.cpp +++ b/CPP/7zip/Archive/Rar/RarRegister.cpp @@ -5,7 +5,7 @@ #include "../../Common/RegisterArc.h" #include "RarHandler.h" -static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; } static CArcInfo g_ArcInfo = { L"Rar", L"rar r00", 0, 3, {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, 7, false, CreateArc, 0, }; diff --git a/CPP/7zip/Archive/RpmHandler.cpp b/CPP/7zip/Archive/RpmHandler.cpp index 13b67390..f533e78f 100755 --- a/CPP/7zip/Archive/RpmHandler.cpp +++ b/CPP/7zip/Archive/RpmHandler.cpp @@ -71,7 +71,7 @@ struct CSigHeaderSig bool MagicCheck() { return Magic[0] == 0x8e && Magic[1] == 0xad && Magic[2] == 0xe8 && Magic[3] == 0x01; }; UInt32 GetLostHeaderLen() - { return IndexLen * kEntryInfoSize + DataLen; }; + { return IndexLen * kEntryInfoSize + DataLen; }; }; static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h) @@ -243,30 +243,25 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - if (numItems == UInt32(-1)) - numItems = 1; if (numItems == 0) return S_OK; - if (numItems != 1 || indices[0] != 0) + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - bool testMode = (_aTestMode != 0); - RINOK(extractCallback->SetTotal(_size)); CMyComPtr<ISequentialOutStream> outStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &outStream, askMode)); if (!testMode && !outStream) return S_OK; RINOK(extractCallback->PrepareOperation(askMode)); - CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; CLocalProgress *lps = new CLocalProgress; @@ -276,7 +271,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(_stream->Seek(_pos, STREAM_SEEK_SET, NULL)); RINOK(copyCoder->Code(_stream, outStream, NULL, NULL, progress)); outStream.Release(); - return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK); + return extractCallback->SetOperationResult(NExtract::NOperationResult::kOK); COM_TRY_END } @@ -287,7 +282,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **strea COM_TRY_END } -static IInArchive *CreateArc() { return new NArchive::NRpm::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NRpm::CHandler; } static CArcInfo g_ArcInfo = { L"Rpm", L"rpm", 0, 0xEB, { 0xED, 0xAB, 0xEE, 0xDB}, 4, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/SplitHandler.cpp b/CPP/7zip/Archive/SplitHandler.cpp index 892e12af..e3129c6a 100755 --- a/CPP/7zip/Archive/SplitHandler.cpp +++ b/CPP/7zip/Archive/SplitHandler.cpp @@ -294,24 +294,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - if (numItems == UInt32(-1)) - numItems = 1; if (numItems == 0) return S_OK; - if (numItems != 1 || indices[0] != 0) + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - bool testMode = (_aTestMode != 0); UInt64 currentTotalSize = 0; RINOK(extractCallback->SetTotal(_totalSize)); CMyComPtr<ISequentialOutStream> outStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &outStream, askMode)); if (!testMode && !outStream) return S_OK; @@ -334,7 +331,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentTotalSize += copyCoderSpec->TotalSize; } outStream.Release(); - return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK); + return extractCallback->SetOperationResult(NExtract::NOperationResult::kOK); COM_TRY_END } @@ -360,7 +357,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) COM_TRY_END } -static IInArchive *CreateArc() { return new CHandler; } +static IInArchive *CreateArc() { return new CHandler; } static CArcInfo g_ArcInfo = { L"Split", L"001", 0, 0xEA, { 0 }, 0, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/SwfHandler.cpp b/CPP/7zip/Archive/SwfHandler.cpp new file mode 100755 index 00000000..dfc0326d --- /dev/null +++ b/CPP/7zip/Archive/SwfHandler.cpp @@ -0,0 +1,706 @@ +// SwfHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "Common/Buffer.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" +#include "Common/MyString.h" + +#include "Windows/PropVariant.h" + +#include "../Common/InBuffer.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" +#include "../Compress/ZlibDecoder.h" +#include "../Compress/ZlibEncoder.h" + +#include "Common/DummyOutStream.h" + +#include "DeflateProps.h" + +using namespace NWindows; + +namespace NArchive { +namespace NSwfc { + +static const UInt32 kHeaderSize = 8; + +static const Byte SWF_UNCOMPRESSED = 'F'; +static const Byte SWF_COMPRESSED = 'C'; +static const Byte SWF_MIN_COMPRESSED_VER = 6; + +struct CItem +{ + Byte Buf[kHeaderSize]; + + UInt32 GetSize() const { return GetUi32(Buf + 4); } + bool IsSwf(Byte c) const { return (Buf[0] == c && Buf[1] == 'W' && Buf[2] == 'S' && Buf[3] < 32); } + bool IsUncompressed() const { return IsSwf(SWF_UNCOMPRESSED); } + bool IsCompressed() const { return IsSwf(SWF_COMPRESSED); } + + void MakeUncompressed() { Buf[0] = SWF_UNCOMPRESSED; } + void MakeCompressed() + { + Buf[0] = SWF_COMPRESSED; + if (Buf[3] < SWF_MIN_COMPRESSED_VER) + Buf[3] = SWF_MIN_COMPRESSED_VER; + } + + HRESULT ReadHeader(ISequentialInStream *stream) { return ReadStream_FALSE(stream, Buf, kHeaderSize); } + HRESULT WriteHeader(ISequentialOutStream *stream) { return WriteStream(stream, Buf, kHeaderSize); } +}; + +class CHandler: + public IInArchive, + public IArchiveOpenSeq, + public IOutArchive, + public ISetProperties, + public CMyUnknownImp +{ + CItem _item; + UInt64 _packSize; + bool _packSizeDefined; + CMyComPtr<ISequentialInStream> _seqStream; + CMyComPtr<IInStream> _stream; + + CDeflateProps _method; + +public: + MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties) + INTERFACE_IInArchive(;) + INTERFACE_IOutArchive(;) + STDMETHOD(OpenSeq)(ISequentialInStream *stream); + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps); +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant prop; + switch(propID) + { + case kpidPhySize: if (_packSizeDefined) prop = _packSize; break; + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidSize: prop = (UInt64)_item.GetSize(); break; + case kpidPackSize: if (_packSizeDefined) prop = _packSize; break; + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) +{ + RINOK(OpenSeq(stream)); + _stream = stream; + return S_OK; +} + +STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +{ + Close(); + HRESULT res = _item.ReadHeader(stream); + if (res == S_OK) + if (_item.IsCompressed()) + _seqStream = stream; + else + res = S_FALSE; + return res; +} + +STDMETHODIMP CHandler::Close() +{ + _packSizeDefined = false; + _seqStream.Release(); + _stream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + extractCallback->SetTotal(_item.GetSize()); + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + if (!testMode && !realOutStream) + return S_OK; + + extractCallback->PrepareOperation(askMode); + + NCompress::NZlib::CDecoder *_decoderSpec = new NCompress::NZlib::CDecoder; + CMyComPtr<ICompressCoder> _decoder = _decoderSpec; + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + lps->InSize = kHeaderSize; + lps->OutSize = outStreamSpec->GetSize(); + RINOK(lps->SetCur()); + + CItem item = _item; + item.MakeUncompressed(); + RINOK(item.WriteHeader(outStream)); + if (_stream) + RINOK(_stream->Seek(kHeaderSize, STREAM_SEEK_SET, NULL)); + HRESULT result = _decoderSpec->Code(_seqStream, outStream, NULL, NULL, progress); + Int32 opRes = NExtract::NOperationResult::kDataError; + if (result == S_OK) + { + if (_item.GetSize() == outStreamSpec->GetSize()) + { + _packSizeDefined = true; + _packSize = _decoderSpec->GetInputProcessedSize() + kHeaderSize; + opRes = NExtract::NOperationResult::kOK; + } + } + else if (result != S_FALSE) + return result; + + outStream.Release(); + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + +static HRESULT UpdateArchive(ISequentialOutStream *outStream, + UInt64 size, CDeflateProps &deflateProps, + IArchiveUpdateCallback *updateCallback) +{ + UInt64 complexity = 0; + RINOK(updateCallback->SetTotal(size)); + RINOK(updateCallback->SetCompleted(&complexity)); + + CMyComPtr<ISequentialInStream> fileInStream; + RINOK(updateCallback->GetStream(0, &fileInStream)); + + CItem item; + HRESULT res = item.ReadHeader(fileInStream); + if (res == S_FALSE) + return E_INVALIDARG; + RINOK(res); + if (!item.IsUncompressed() || size != item.GetSize()) + return E_INVALIDARG; + + item.MakeCompressed(); + item.WriteHeader(outStream); + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(updateCallback, true); + + NCompress::NZlib::CEncoder *encoderSpec = new NCompress::NZlib::CEncoder; + CMyComPtr<ICompressCoder> encoder = encoderSpec; + encoderSpec->Create(); + RINOK(deflateProps.SetCoderProperties(encoderSpec->DeflateEncoderSpec)); + RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, progress)); + if (encoderSpec->GetInputProcessedSize() + kHeaderSize != size) + return E_INVALIDARG; + return updateCallback->SetOperationResult(NUpdate::NOperationResult::kOK); +} + +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) +{ + *timeType = NFileTimeType::kUnix; + return S_OK; +} + +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback) +{ + if (numItems != 1) + return E_INVALIDARG; + + Int32 newData, newProps; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); + + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); + if (prop.vt == VT_BOOL) + { + if (prop.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + } + + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + } + return UpdateArchive(outStream, size, _method, updateCallback); + } + + if (indexInArchive != 0) + return E_INVALIDARG; + + if (!_seqStream) + return E_NOTIMPL; + + if (_stream) + { + RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + } + else + _item.WriteHeader(outStream); + return NCompress::CopyStream(_seqStream, outStream, NULL); +} + +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps) +{ + return _method.SetProperties(names, values, numProps); +} + +static IInArchive *CreateArc() { return new CHandler; } +#ifndef EXTRACT_ONLY +static IOutArchive *CreateArcOut() { return new CHandler; } +#else +#define CreateArcOut 0 +#endif + +static CArcInfo g_ArcInfo = + { L"SWFc", L"swf", L"~.swf", 0xD8, { 'C', 'W', 'S' }, 3, true, CreateArc, CreateArcOut }; + +REGISTER_ARC(Swfc) + +} + +namespace NSwf { + +static const UInt32 kFileSizeMax = (UInt32)1 << 30; +static const int kNumTagsMax = (UInt32)1 << 23; + +struct CTag +{ + UInt32 Type; + CByteBuffer Buf; +}; + +class CHandler: + public IInArchive, + public IArchiveOpenSeq, + public CMyUnknownImp +{ + CObjectVector<CTag> _tags; + NSwfc::CItem _item; + UInt64 _packSize; + + HRESULT OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback); + HRESULT OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback); +public: + MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) + INTERFACE_IInArchive(;) + + STDMETHOD(OpenSeq)(ISequentialInStream *stream); +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidComment, VT_BSTR} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant prop; + switch(propID) + { + case kpidPhySize: prop = _packSize; break; + } + prop.Detach(value); + return S_OK; +} + + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _tags.Size(); + return S_OK; +} + +static const char *g_TagDesc[92] = +{ + "End", + "ShowFrame", + "DefineShape", + NULL, + "PlaceObject", + "RemoveObject", + "DefineBits", + "DefineButton", + "JPEGTables", + "SetBackgroundColor", + "DefineFont", + "DefineText", + "DoAction", + "DefineFontInfo", + "DefineSound", + "StartSound", + NULL, + "DefineButtonSound", + "SoundStreamHead", + "SoundStreamBlock", + "DefineBitsLossless", + "DefineBitsJPEG2", + "DefineShape2", + "DefineButtonCxform", + "Protect", + NULL, + "PlaceObject2", + NULL, + "RemoveObject2", + NULL, + NULL, + NULL, + "DefineShape3", + "DefineText2", + "DefineButton2", + "DefineBitsJPEG3", + "DefineBitsLossless2", + "DefineEditText", + NULL, + "DefineSprite", + NULL, + "41", + NULL, + "FrameLabel", + NULL, + "SoundStreamHead2", + "DefineMorphShape", + NULL, + "DefineFont2", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "ExportAssets", + "ImportAssets", + "EnableDebugger", + "DoInitAction", + "DefineVideoStream", + "VideoFrame", + "DefineFontInfo2", + NULL, + "EnableDebugger2", + "ScriptLimits", + "SetTabIndex", + NULL, + NULL, + "FileAttributes", + "PlaceObject3", + "ImportAssets2", + NULL, + "DefineFontAlignZones", + "CSMTextSettings", + "DefineFont3", + "SymbolClass", + "Metadata", + "DefineScalingGrid", + NULL, + NULL, + NULL, + "DoABC", + "DefineShape4", + "DefineMorphShape2", + NULL, + "DefineSceneAndFrameLabelData", + "DefineBinaryData", + "DefineFontName", + "StartSound2", + "DefineBitsJPEG4", + "DefineFont4" +}; + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + const CTag &tag = _tags[index]; + switch(propID) + { + case kpidPath: + { + char s[32]; + ConvertUInt32ToString(index, s); + size_t i = strlen(s); + s[i++] = '.'; + ConvertUInt32ToString(tag.Type, s + i); + prop = s; + break; + } + case kpidSize: + case kpidPackSize: + prop = (UInt64)tag.Buf.GetCapacity(); break; + case kpidComment: + if (tag.Type < sizeof(g_TagDesc) / sizeof(g_TagDesc[0])) + { + const char *s = g_TagDesc[tag.Type]; + if (s != NULL) + prop = s; + } + break; + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +{ + return OpenSeq2(stream, callback); +} + +static UInt16 Read16(CInBuffer &stream) +{ + UInt16 res = 0; + for (int i = 0; i < 2; i++) + { + Byte b; + if (!stream.ReadByte(b)) + throw 1; + res |= (UInt16)b << (i * 8); + } + return res; +} + +static UInt32 Read32(CInBuffer &stream) +{ + UInt32 res = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + if (!stream.ReadByte(b)) + throw 1; + res |= (UInt32)b << (i * 8); + } + return res; +} + +struct CBitReader +{ + CInBuffer *stream; + unsigned NumBits; + Byte Val; + + CBitReader(): NumBits(0), Val(0) {} + + UInt32 ReadBits(unsigned numBits); +}; + +UInt32 CBitReader::ReadBits(unsigned numBits) +{ + UInt32 res = 0; + while (numBits > 0) + { + if (NumBits == 0) + { + Val = stream->ReadByte(); + NumBits = 8; + } + if (numBits <= NumBits) + { + res <<= numBits; + NumBits -= numBits; + res |= (Val >> NumBits); + Val &= (1 << NumBits) - 1; + break; + } + else + { + res <<= NumBits; + res |= Val; + numBits -= NumBits; + NumBits = 0; + } + } + return res; +} + +HRESULT CHandler::OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback) +{ + RINOK(_item.ReadHeader(stream)) + if (!_item.IsUncompressed()) + return S_FALSE; + + CInBuffer s; + if (!s.Create(1 << 20)) + return E_OUTOFMEMORY; + s.SetStream(stream); + s.Init(); + { + CBitReader br; + br.stream = &s; + unsigned numBits = br.ReadBits(5); + /* UInt32 xMin = */ br.ReadBits(numBits); + /* UInt32 xMax = */ br.ReadBits(numBits); + /* UInt32 yMin = */ br.ReadBits(numBits); + /* UInt32 yMax = */ br.ReadBits(numBits); + } + /* UInt32 frameDelay = */ Read16(s); + /* UInt32 numFrames = */ Read16(s); + + _tags.Clear(); + UInt64 offsetPrev = 0; + for (;;) + { + UInt32 pair = Read16(s); + UInt32 type = pair >> 6; + UInt32 length = pair & 0x3F; + if (length == 0x3F) + length = Read32(s); + if (type == 0) + break; + UInt64 offset = s.GetProcessedSize() + NSwfc::kHeaderSize + length; + if (offset > kFileSizeMax || _tags.Size() >= kNumTagsMax) + return S_FALSE; + _tags.Add(CTag()); + CTag &tag = _tags.Back(); + tag.Type = type; + tag.Buf.SetCapacity(length); + if (s.ReadBytes(tag.Buf, length) != length) + return S_FALSE; + if (callback && offset >= offsetPrev + (1 << 20)) + { + UInt64 numItems = _tags.Size(); + RINOK(callback->SetCompleted(&numItems, &offset)); + offsetPrev = offset; + } + } + _packSize = s.GetProcessedSize() + NSwfc::kHeaderSize; + return S_OK; +} + +HRESULT CHandler::OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback) +{ + HRESULT res; + try { res = OpenSeq3(stream, callback); } + catch(...) { res = S_FALSE; } + return res; +} + +STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +{ + return OpenSeq2(stream, NULL); +} + +STDMETHODIMP CHandler::Close() +{ + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == (UInt32)-1); + if (allFilesMode) + numItems = _tags.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _tags[allFilesMode ? i : indices[i]].Buf.GetCapacity(); + extractCallback->SetTotal(totalSize); + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + totalSize = 0; + + for (i = 0; i < numItems; i++) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()); + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + const CByteBuffer &buf = _tags[index].Buf; + totalSize += buf.GetCapacity(); + + CMyComPtr<ISequentialOutStream> outStream; + RINOK(extractCallback->GetStream(index, &outStream, askMode)); + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + if (outStream) + RINOK(WriteStream(outStream, buf, buf.GetCapacity())); + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + } + return S_OK; + COM_TRY_END +} + +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"SWF", L"swf", 0, 0xD7, { 'F', 'W', 'S' }, 3, true, CreateArc, 0 }; + +REGISTER_ARC(Swf) + +}} diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp index aa4b2aec..31e30573 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.cpp +++ b/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -227,8 +227,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN ISequentialInStream *stream = _seqStream; @@ -236,7 +236,6 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems, if (!seqMode) stream = _stream; - bool testMode = (_aTestMode != 0); bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _items.Size(); @@ -269,8 +268,8 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItemEx *item; if (seqMode) @@ -290,7 +289,7 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item->IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } bool skipMode = false; @@ -299,7 +298,7 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems, if (!seqMode) continue; skipMode = true; - askMode = NArchive::NExtract::NAskMode::kSkip; + askMode = NExtract::NAskMode::kSkip; } RINOK(extractCallback->PrepareOperation(askMode)); @@ -320,8 +319,8 @@ HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems, } outStreamSpec->ReleaseStream(); RINOK(extractCallback->SetOperationResult(outStreamSpec->GetRem() == 0 ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/Tar/TarRegister.cpp b/CPP/7zip/Archive/Tar/TarRegister.cpp index 3cc0d605..e21c0aac 100755 --- a/CPP/7zip/Archive/Tar/TarRegister.cpp +++ b/CPP/7zip/Archive/Tar/TarRegister.cpp @@ -5,14 +5,14 @@ #include "../../Common/RegisterArc.h" #include "TarHandler.h" -static IInArchive *CreateArc() { return new NArchive::NTar::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NTar::CHandler; } #ifndef EXTRACT_ONLY -static IOutArchive *CreateArcOut() { return new NArchive::NTar::CHandler; } +static IOutArchive *CreateArcOut() { return new NArchive::NTar::CHandler; } #else #define CreateArcOut 0 #endif static CArcInfo g_ArcInfo = -{ L"Tar", L"tar", 0, 0xEE, { 'u', 's', 't', 'a', 'r' }, 5, false, CreateArc, CreateArcOut }; +{ L"tar", L"tar", 0, 0xEE, { 'u', 's', 't', 'a', 'r' }, 5, false, CreateArc, CreateArcOut }; REGISTER_ARC(Tar) diff --git a/CPP/7zip/Archive/Udf/UdfHandler.cpp b/CPP/7zip/Archive/Udf/UdfHandler.cpp index 07b61c51..42419a9d 100755 --- a/CPP/7zip/Archive/Udf/UdfHandler.cpp +++ b/CPP/7zip/Archive/Udf/UdfHandler.cpp @@ -10,6 +10,7 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" #include "../../Compress/CopyCoder.h" @@ -200,57 +201,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -class CBufInStream: - public IInStream, - public CMyUnknownImp -{ - CByteBuffer _data; - UInt64 _pos; - -public: - void Init(const CByteBuffer &data) - { - _data = data; - _pos = 0; - } - - MY_UNKNOWN_IMP - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - - -STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize != NULL) - *processedSize = 0; - if (_pos > _data.GetCapacity()) - return E_FAIL; - size_t rem = _data.GetCapacity() - (size_t)_pos; - if (size < rem) - rem = (size_t)size; - memcpy(data, (const Byte *)_data + _pos, rem); - _pos += rem; - if (processedSize != NULL) - *processedSize = (UInt32)rem; - return S_OK; -} - -STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch(seekOrigin) - { - case STREAM_SEEK_SET: _pos = offset; break; - case STREAM_SEEK_CUR: _pos += offset; break; - case STREAM_SEEK_END: _pos = _data.GetCapacity() + offset; break; - default: return STG_E_INVALIDFUNCTION; - } - if (newPosition) - *newPosition = _pos; - return S_OK; -} - struct CSeekExtent { UInt64 Phy; @@ -362,8 +312,11 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) { CBufInStream *inStreamSpec = new CBufInStream; CMyComPtr<ISequentialInStream> inStream = inStreamSpec; - inStreamSpec->Init(item.InlineData); - *stream = inStream .Detach(); + CReferenceBuf *referenceBuf = new CReferenceBuf; + CMyComPtr<IUnknown> ref = referenceBuf; + referenceBuf->Buf = item.InlineData; + inStreamSpec->Init(referenceBuf); + *stream = inStream.Detach(); return S_OK; } @@ -407,12 +360,11 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _refs2.Size(); if (numItems == 0) @@ -450,8 +402,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; UInt32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -464,7 +416,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item.IsDir()) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } currentTotalSize += item.Size; @@ -480,15 +432,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ISequentialInStream> udfInStream; HRESULT res = GetStream(index, &udfInStream); if (res == E_NOTIMPL) - opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + opRes = NExtract::NOperationResult::kUnSupportedMethod; else if (res != S_OK) - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; else { RINOK(copyCoder->Code(udfInStream, outStream, NULL, NULL, progress)); opRes = outStreamSpec->IsFinishedOK() ? - NArchive::NExtract::NOperationResult::kOK: - NArchive::NExtract::NOperationResult::kDataError; + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError; } outStreamSpec->ReleaseStream(); RINOK(extractCallback->SetOperationResult(opRes)); diff --git a/CPP/7zip/Archive/Udf/UdfRegister.cpp b/CPP/7zip/Archive/Udf/UdfRegister.cpp index b3a6c152..5dc7db6a 100755 --- a/CPP/7zip/Archive/Udf/UdfRegister.cpp +++ b/CPP/7zip/Archive/Udf/UdfRegister.cpp @@ -5,7 +5,7 @@ #include "../../Common/RegisterArc.h" #include "UdfHandler.h" -static IInArchive *CreateArc() { return new NArchive::NUdf::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NUdf::CHandler; } static CArcInfo g_ArcInfo = { L"Udf", L"iso", 0, 0xE0, { 0, 'N', 'S', 'R', '0' }, 5, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/VhdHandler.cpp b/CPP/7zip/Archive/VhdHandler.cpp index 5fc2c918..439b8691 100755 --- a/CPP/7zip/Archive/VhdHandler.cpp +++ b/CPP/7zip/Archive/VhdHandler.cpp @@ -641,24 +641,20 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - if (numItems == UInt32(-1)) - numItems = 1; if (numItems == 0) return S_OK; - if (numItems != 1 || indices[0] != 0) + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - bool testMode = (_aTestMode != 0); - RINOK(extractCallback->SetTotal(GetSize())); CMyComPtr<ISequentialOutStream> outStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &outStream, askMode)); if (!testMode && !outStream) return S_OK; @@ -671,11 +667,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(extractCallback, false); - int res = NArchive::NExtract::NOperationResult::kDataError; + int res = NExtract::NOperationResult::kDataError; CMyComPtr<ISequentialInStream> inStream; HRESULT hres = GetStream(0, &inStream); if (hres == S_FALSE) - res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + res = NExtract::NOperationResult::kUnSupportedMethod; else { RINOK(hres); @@ -683,7 +679,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (hres == S_OK) { if (copyCoderSpec->TotalSize == GetSize()) - res = NArchive::NExtract::NOperationResult::kOK; + res = NExtract::NOperationResult::kOK; } else { @@ -721,7 +717,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **strea COM_TRY_END } -static IInArchive *CreateArc() { return new CHandler; } +static IInArchive *CreateArc() { return new CHandler; } static CArcInfo g_ArcInfo = { L"VHD", L"vhd", L".mbr", 0xDC, { 'c', 'o', 'n', 'e', 'c', 't', 'i', 'x', 0, 0 }, 10, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp index 1b8661c9..8093af77 100755 --- a/CPP/7zip/Archive/Wim/WimHandler.cpp +++ b/CPP/7zip/Archive/Wim/WimHandler.cpp @@ -485,17 +485,16 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = m_Database.Items.Size() + m_Xmls.Size(); if (numItems == 0) return S_OK; - bool testMode = (_aTestMode != 0); UInt32 i; UInt64 totalSize = 0; @@ -549,7 +548,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); if (index >= (UInt32)m_Database.Items.Size()) { - if(!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); const CByteBuffer &data = m_Xmls[index - (UInt32)m_Database.Items.Size()].Data; @@ -567,7 +566,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, int streamIndex = item.StreamIndex; if (streamIndex < 0) { - if(!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); @@ -581,7 +580,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentItemUnPacked = si.Resource.UnpackSize; currentItemPacked = si.Resource.PackSize; - if(!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); Int32 opRes = NExtract::NOperationResult::kOK; diff --git a/CPP/7zip/Archive/Wim/WimRegister.cpp b/CPP/7zip/Archive/Wim/WimRegister.cpp index 22344b3a..3c8e216f 100755 --- a/CPP/7zip/Archive/Wim/WimRegister.cpp +++ b/CPP/7zip/Archive/Wim/WimRegister.cpp @@ -5,7 +5,7 @@ #include "../../Common/RegisterArc.h" #include "WimHandler.h" -static IInArchive *CreateArc() { return new NArchive::NWim::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NWim::CHandler; } static CArcInfo g_ArcInfo = { L"Wim", L"wim swm", 0, 0xE6, { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 }, 8, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp index 2dddad9f..5a2489d2 100755 --- a/CPP/7zip/Archive/XarHandler.cpp +++ b/CPP/7zip/Archive/XarHandler.cpp @@ -401,12 +401,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool testMode = (_aTestMode != 0); - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = _files.Size(); if (numItems == 0) @@ -474,8 +473,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(lps->SetCur()); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -485,19 +484,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item.IsDir) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } } - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); outStreamSha1Spec->SetStream(realOutStream); realOutStream.Release(); - Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + Int32 opRes = NExtract::NOperationResult::kOK; #ifdef XAR_SHOW_RAW if (index == _files.Size()) { @@ -526,13 +525,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (item.PackSize == item.Size) coder = copyCoder; else - opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + opRes = NExtract::NOperationResult::kUnSupportedMethod; else if (item.Method == METHOD_NAME_ZLIB) coder = zlibCoder; else if (item.Method == "bzip2") coder = bzip2Coder; else - opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + opRes = NExtract::NOperationResult::kUnSupportedMethod; if (coder) res = coder->Code(inStream, outStream, NULL, NULL, progress); @@ -540,32 +539,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (res != S_OK) { if (!outStreamLimSpec->IsFinishedOK()) - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; else if (res != S_FALSE) return res; - if (opRes == NArchive::NExtract::NOperationResult::kOK) - opRes = NArchive::NExtract::NOperationResult::kDataError; + if (opRes == NExtract::NOperationResult::kOK) + opRes = NExtract::NOperationResult::kDataError; } - if (opRes == NArchive::NExtract::NOperationResult::kOK) + if (opRes == NExtract::NOperationResult::kOK) { if (outStreamLimSpec->IsFinishedOK() && outStreamSha1Spec->GetSize() == item.Size) { if (!outStreamLimSpec->IsFinishedOK()) { - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; } else if (item.Sha1IsDefined) { Byte digest[NCrypto::NSha1::kDigestSize]; outStreamSha1Spec->Final(digest); if (memcmp(digest, item.Sha1, NCrypto::NSha1::kDigestSize) != 0) - opRes = NArchive::NExtract::NOperationResult::kCRCError; + opRes = NExtract::NOperationResult::kCRCError; } } else - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; } } } @@ -576,7 +575,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, COM_TRY_END } -static IInArchive *CreateArc() { return new NArchive::NXar::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NXar::CHandler; } static CArcInfo g_ArcInfo = { L"Xar", L"xar", 0, 0xE1, { 'x', 'a', 'r', '!', 0, 0x1C }, 6, false, CreateArc, 0 }; diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp index 116e96b6..f37a5841 100755 --- a/CPP/7zip/Archive/XzHandler.cpp +++ b/CPP/7zip/Archive/XzHandler.cpp @@ -449,28 +449,22 @@ struct CXzUnpackerCPP } }; -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UInt32(-1)); - if (!allFilesMode) - { - if (numItems == 0) - return S_OK; - if (numItems != 1 || indices[0] != 0) - return E_INVALIDARG; - } - - bool testMode = (_aTestMode != 0); + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; extractCallback->SetTotal(_packSize); UInt64 currentTotalPacked = 0; RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); @@ -567,15 +561,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, switch(res) { case SZ_OK: - opRes = NArchive::NExtract::NOperationResult::kOK; break; + opRes = NExtract::NOperationResult::kOK; break; case SZ_ERROR_UNSUPPORTED: - opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; break; + opRes = NExtract::NOperationResult::kUnSupportedMethod; break; case SZ_ERROR_CRC: - opRes = NArchive::NExtract::NOperationResult::kCRCError; break; + opRes = NExtract::NOperationResult::kCRCError; break; case SZ_ERROR_DATA: case SZ_ERROR_ARCHIVE: case SZ_ERROR_NO_ARCHIVE: - opRes = NArchive::NExtract::NOperationResult::kDataError; break; + opRes = NExtract::NOperationResult::kDataError; break; default: return SResToHRESULT(res); } @@ -699,9 +693,9 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v #endif -static IInArchive *CreateArc() { return new NArchive::NXz::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NXz::CHandler; } #ifndef EXTRACT_ONLY -static IOutArchive *CreateArcOut() { return new NArchive::NXz::CHandler; } +static IOutArchive *CreateArcOut() { return new NArchive::NXz::CHandler; } #else #define CreateArcOut 0 #endif diff --git a/CPP/7zip/Archive/ZHandler.cpp b/CPP/7zip/Archive/ZHandler.cpp index 21432b22..49b76a11 100755 --- a/CPP/7zip/Archive/ZHandler.cpp +++ b/CPP/7zip/Archive/ZHandler.cpp @@ -21,24 +21,15 @@ class CHandler: public IInArchive, public CMyUnknownImp { -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) - -private: CMyComPtr<IInStream> _stream; UInt64 _streamStartPosition; UInt64 _packSize; Byte _properties; +public: + MY_UNKNOWN_IMP1(IInArchive) + INTERFACE_IInArchive(;) }; -static IInArchive *CreateArc() { return new CHandler; } - -static CArcInfo g_ArcInfo = - { L"Z", L"z taz", L"* .tar", 5, { 0x1F, 0x9D }, 2, false, CreateArc, 0 }; - -REGISTER_ARC(Z) - STATPROPSTG kProps[] = { { NULL, kpidPackSize, VT_UI8} @@ -96,22 +87,14 @@ STDMETHODIMP CHandler::Close() } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(-1)); - if (!allFilesMode) - { - if (numItems == 0) - return S_OK; - if (numItems != 1) - return E_INVALIDARG; - if (indices[0] != 0) - return E_INVALIDARG; - } - - bool testMode = (testModeSpec != 0); + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; extractCallback->SetTotal(_packSize); @@ -168,4 +151,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, COM_TRY_END } +static IInArchive *CreateArc() { return new CHandler; } + +static CArcInfo g_ArcInfo = + { L"Z", L"z taz", L"* .tar", 5, { 0x1F, 0x9D }, 2, false, CreateArc, 0 }; + +REGISTER_ARC(Z) + }} diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index 547ecf92..2e551931 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -448,7 +448,7 @@ HRESULT CZipDecoder::Decode( ICompressProgressInfo *compressProgress, UInt32 numThreads, Int32 &res) { - res = NArchive::NExtract::NOperationResult::kDataError; + res = NExtract::NOperationResult::kDataError; CInStreamReleaser inStreamReleaser; bool needCRC = true; @@ -466,7 +466,7 @@ HRESULT CZipDecoder::Decode( } if (!pkAesMode) { - res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + res = NExtract::NOperationResult::kUnSupportedMethod; return S_OK; } } @@ -560,7 +560,7 @@ HRESULT CZipDecoder::Decode( break; if (c >= 0x80) { - res = NArchive::NExtract::NOperationResult::kDataError; + res = NExtract::NOperationResult::kDataError; return S_OK; } charPassword += (char)c; @@ -609,7 +609,7 @@ HRESULT CZipDecoder::Decode( { if (methodId > 0xFF) { - res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + res = NExtract::NOperationResult::kUnSupportedMethod; return S_OK; } szMethodID = kMethodId_ZipBase + (Byte)methodId; @@ -619,7 +619,7 @@ HRESULT CZipDecoder::Decode( if (mi.Coder == 0) { - res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + res = NExtract::NOperationResult::kUnSupportedMethod; return S_OK; } } @@ -699,7 +699,7 @@ HRESULT CZipDecoder::Decode( return S_OK; if (result == E_NOTIMPL) { - res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + res = NExtract::NOperationResult::kUnSupportedMethod; return S_OK; } @@ -717,26 +717,25 @@ HRESULT CZipDecoder::Decode( } res = ((crcOK && authOk) ? - NArchive::NExtract::NOperationResult::kOK : - NArchive::NExtract::NOperationResult::kCRCError); + NExtract::NOperationResult::kOK : + NExtract::NOperationResult::kCRCError); return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, - Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN CZipDecoder myDecoder; - bool testMode = (_aTestMode != 0); UInt64 totalUnPacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)-1); if (allFilesMode) numItems = m_Items.Size(); if(numItems == 0) return S_OK; UInt32 i; - for(i = 0; i < numItems; i++) + for (i = 0; i < numItems; i++) { const CItemEx &item = m_Items[allFilesMode ? i : indices[i]]; totalUnPacked += item.UnPackSize; @@ -763,8 +762,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -779,7 +778,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); } continue; } @@ -792,7 +791,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); } continue; } @@ -800,7 +799,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentItemUnPacked = item.UnPackSize; currentItemPacked = item.PackSize; - if (!testMode && (!realOutStream)) + if (!testMode && !realOutStream) continue; RINOK(extractCallback->PrepareOperation(askMode)); diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp index 2f28d5ec..22d8eeea 100755 --- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -112,7 +112,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt ui.NewData = IntToBool(newData); ui.IndexInArchive = indexInArchive; ui.IndexInClient = i; - bool existInArchive = (indexInArchive != UInt32(-1)); + bool existInArchive = (indexInArchive != (UInt32)-1); if (existInArchive && newData) if (m_Items[indexInArchive].IsAesEncrypted()) thereAreAesUpdates = true; diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp index e396fe5b..6943c9ed 100755 --- a/CPP/7zip/Archive/Zip/ZipIn.cpp +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -318,14 +318,17 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item) RINOK(ReadLocalItem(localItem)); if (item.Flags != localItem.Flags) { - if ( - (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflated || - (item.Flags & 0x7FF9) != (localItem.Flags & 0x7FF9)) && - (item.CompressionMethod != NFileHeader::NCompressionMethod::kStored || - (item.Flags & 0x7FFF) != (localItem.Flags & 0x7FFF)) && - (item.CompressionMethod != NFileHeader::NCompressionMethod::kImploded || - (item.Flags & 0x7FFF) != (localItem.Flags & 0x7FFF)) - ) + UInt32 mask = 0xFFFF; + switch(item.CompressionMethod) + { + case NFileHeader::NCompressionMethod::kDeflated: + mask = 0x7FF9; + break; + default: + if (item.CompressionMethod <= NFileHeader::NCompressionMethod::kImploded) + mask = 0x7FFF; + } + if ((item.Flags & mask) != (localItem.Flags & mask)) return S_FALSE; } @@ -501,7 +504,9 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo) UInt64 endPosition; RINOK(m_Stream->Seek(0, STREAM_SEEK_END, &endPosition)); const UInt32 kBufSizeMax = (1 << 16) + kEcdSize + kZip64EcdLocatorSize; - Byte buf[kBufSizeMax]; + CByteBuffer byteBuffer; + byteBuffer.SetCapacity(kBufSizeMax); + Byte *buf = byteBuffer; UInt32 bufSize = (endPosition < kBufSizeMax) ? (UInt32)endPosition : kBufSizeMax; if (bufSize < kEcdSize) return S_FALSE; @@ -622,10 +627,7 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt RINOK(ReadCdItem(cdItem)); if (i == 0) - { - if (cdItem.LocalHeaderPosition == 0) - m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; - } + m_ArchiveInfo.Base = items[i].LocalHeaderPosition - cdItem.LocalHeaderPosition; int index; int left = 0, right = items.Size(); @@ -733,7 +735,15 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr items.Clear(); UInt64 cdSize, cdStartOffset; - HRESULT res = ReadCd(items, cdStartOffset, cdSize, progress); + HRESULT res; + try + { + res = ReadCd(items, cdStartOffset, cdSize, progress); + } + catch(CInArchiveException &) + { + res = S_FALSE; + } if (res != S_FALSE && res != S_OK) return res; @@ -793,7 +803,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr return S_FALSE; } if (m_Signature != NSignature::kEndOfCentralDir) - return S_FALSE; + return S_FALSE; const int kBufSize = kEcdSize - 4; Byte buf[kBufSize]; @@ -817,7 +827,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr (UInt32)ecd64.cdSize != (UInt32)cdSize || ((UInt32)(ecd64.cdStartOffset) != (UInt32)cdStartOffset && (!items.IsEmpty()))) - return S_FALSE; + return S_FALSE; _inBufMode = false; _inBuffer.Free(); diff --git a/CPP/7zip/Archive/Zip/ZipRegister.cpp b/CPP/7zip/Archive/Zip/ZipRegister.cpp index 2fd36950..3e7aade8 100755 --- a/CPP/7zip/Archive/Zip/ZipRegister.cpp +++ b/CPP/7zip/Archive/Zip/ZipRegister.cpp @@ -5,14 +5,14 @@ #include "../../Common/RegisterArc.h" #include "ZipHandler.h" -static IInArchive *CreateArc() { return new NArchive::NZip::CHandler; } +static IInArchive *CreateArc() { return new NArchive::NZip::CHandler; } #ifndef EXTRACT_ONLY -static IOutArchive *CreateArcOut() { return new NArchive::NZip::CHandler; } +static IOutArchive *CreateArcOut() { return new NArchive::NZip::CHandler; } #else #define CreateArcOut 0 #endif static CArcInfo g_ArcInfo = - { L"Zip", L"zip jar xpi odt ods docx xlsx", 0, 1, { 0x50, 0x4B, 0x03, 0x04 }, 4, false, CreateArc, CreateArcOut }; + { L"zip", L"zip jar xpi odt ods docx xlsx", 0, 1, { 0x50, 0x4B, 0x03, 0x04 }, 4, false, CreateArc, CreateArcOut }; REGISTER_ARC(Zip) |