diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2010-04-15 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:03 +0300 |
commit | 3dacb5eb8afda99aad81f4723cb966c0fa91ba1d (patch) | |
tree | 1e1f05aaadf64b4ff99d21bcd4282e8ab4365396 /CPP/7zip/Archive | |
parent | 76b173af78d09dea806d3ed35c0f67a09b496357 (diff) |
9.139.13
Diffstat (limited to 'CPP/7zip/Archive')
-rwxr-xr-x | CPP/7zip/Archive/7z/7zDecode.cpp | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/7z/7zUpdate.cpp | 6 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Cab/CabHandler.cpp | 141 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderMixer2MT.cpp | 28 | ||||
-rwxr-xr-x | CPP/7zip/Archive/MachoHandler.cpp | 61 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Nsis/NsisHandler.cpp | 55 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Nsis/NsisHandler.h | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Nsis/NsisIn.cpp | 1 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Nsis/NsisIn.h | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/PeHandler.cpp | 35 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Zip/ZipHandler.cpp | 10 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Zip/ZipHandler.h | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Zip/ZipIn.cpp | 52 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Zip/ZipIn.h | 6 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Zip/ZipOut.cpp | 8 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Zip/ZipOut.h | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Zip/ZipUpdate.cpp | 31 |
17 files changed, 271 insertions, 173 deletions
diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp index ab3db913..425a3415 100755 --- a/CPP/7zip/Archive/7z/7zDecode.cpp +++ b/CPP/7zip/Archive/7z/7zDecode.cpp @@ -232,7 +232,7 @@ HRESULT CDecoder::Decode( size_t size = props.GetCapacity(); if (size > 0xFFFFFFFF) return E_NOTIMPL; - if (size > 0) + // if (size > 0) { RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size)); } diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp index 7b9e49e1..ee7f55c0 100755 --- a/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -382,6 +382,12 @@ static void MakeExeMethod(const CCompressionMethodMode &method, prop.Value = kNumFastBytesForBCJ2_LZMA; methodFull.Props.Add(prop); } + { + CProp prop; + prop.Id = NCoderPropID::kNumThreads; + prop.Value = (UInt32)1; + methodFull.Props.Add(prop); + } exeMethod.Methods.Add(methodFull); exeMethod.Methods.Add(methodFull); diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp index 672172a6..9fb91423 100755 --- a/CPP/7zip/Archive/Cab/CabHandler.cpp +++ b/CPP/7zip/Archive/Cab/CabHandler.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../../C/Alloc.h" + #include "Common/Buffer.h" #include "Common/ComTry.h" #include "Common/Defs.h" @@ -32,8 +34,6 @@ namespace NCab { // #define _CAB_DETAILS -static const UInt32 kMaxTempBufSize = 1 << 20; - #ifdef _CAB_DETAILS enum { @@ -344,9 +344,10 @@ private: const CMvDatabaseEx *m_Database; const CRecordVector<bool> *m_ExtractStatuses; - CByteBuffer TempBuf; + Byte *TempBuf; + UInt32 TempBufSize; + int NumIdenticalFiles; bool TempBufMode; - bool IsSupported; UInt32 m_BufStartFolderOffset; int m_StartIndex; @@ -362,12 +363,21 @@ private: UInt64 m_FolderSize; UInt64 m_PosInFolder; + void FreeTempBuf() + { + ::MyFree(TempBuf); + TempBuf = NULL; + } + HRESULT OpenFile(); + HRESULT CloseFileWithResOp(Int32 resOp); HRESULT CloseFile(); HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); public: HRESULT WriteEmptyFiles(); + CFolderOutStream(): TempBuf(NULL) {} + ~CFolderOutStream() { FreeTempBuf(); } void Init( const CMvDatabaseEx *database, const CRecordVector<bool> *extractStatuses, @@ -403,54 +413,80 @@ void CFolderOutStream::Init( m_FileIsOpen = false; m_IsOk = true; TempBufMode = false; + NumIdenticalFiles = 0; } -HRESULT CFolderOutStream::CloseFile() +HRESULT CFolderOutStream::CloseFileWithResOp(Int32 resOp) { m_RealOutStream.Release(); - HRESULT res = m_ExtractCallback->SetOperationResult(m_IsOk ? + m_FileIsOpen = false; + NumIdenticalFiles--; + return m_ExtractCallback->SetOperationResult(resOp); +} + +HRESULT CFolderOutStream::CloseFile() +{ + return CloseFileWithResOp(m_IsOk ? NExtract::NOperationResult::kOK: NExtract::NOperationResult::kDataError); - m_FileIsOpen = false; - return res; } HRESULT CFolderOutStream::OpenFile() { - Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : - NExtract::NAskMode::kSkip; - - if (!TempBufMode) + if (NumIdenticalFiles == 0) { 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) + int numExtractItems = 0; + int curIndex; + for (curIndex = m_CurrentIndex; curIndex < m_ExtractStatuses->Size(); 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 (!m_TestMode && (*m_ExtractStatuses)[curIndex]) + numExtractItems++; + } + NumIdenticalFiles = (curIndex - m_CurrentIndex); + if (NumIdenticalFiles == 0) + NumIdenticalFiles = 1; + TempBufMode = false; + if (numExtractItems > 1) { - size_t oldCapacity = TempBuf.GetCapacity(); - IsSupported = (item.Size <= kMaxTempBufSize); - if (item.Size > oldCapacity && IsSupported) + if (!TempBuf || item.Size > TempBufSize) { - TempBuf.SetCapacity(0); - TempBuf.SetCapacity(item.Size); + FreeTempBuf(); + TempBuf = (Byte *)MyAlloc(item.Size); + TempBufSize = item.Size; + if (TempBuf == NULL) + return E_OUTOFMEMORY; } TempBufMode = true; m_BufStartFolderOffset = item.Offset; } + else if (numExtractItems == 1) + { + while (NumIdenticalFiles && !(*m_ExtractStatuses)[m_CurrentIndex]) + { + CMyComPtr<ISequentialOutStream> stream; + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &stream, NExtract::NAskMode::kSkip)); + if (stream) + return E_FAIL; + RINOK(m_ExtractCallback->PrepareOperation(NExtract::NAskMode::kSkip)); + m_CurrentIndex++; + m_FileIsOpen = true; + CloseFile(); + } + } } + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kSkip; RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); if (!m_RealOutStream && !m_TestMode) askMode = NExtract::NAskMode::kSkip; @@ -499,7 +535,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); numBytesToWrite = processedSizeLocal; } - if (TempBufMode && IsSupported) + if (TempBufMode && TempBuf) memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite); } realProcessed += numBytesToWrite; @@ -513,38 +549,27 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe return res; if (m_RemainFileSize == 0) { - m_RealOutStream.Release(); RINOK(CloseFile()); - if (TempBufMode) + while (NumIdenticalFiles) { - while (m_CurrentIndex < m_ExtractStatuses->Size()) + HRESULT result = OpenFile(); + m_FileIsOpen = true; + m_CurrentIndex++; + if (result == S_OK && m_RealOutStream && TempBuf) + result = WriteStream(m_RealOutStream, TempBuf, (size_t)(m_PosInFolder - m_BufStartFolderOffset)); + + if (!TempBuf && TempBufMode && m_RealOutStream) + { + RINOK(CloseFileWithResOp(NExtract::NOperationResult::kUnSupportedMethod)); + } + else { - 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; - } + RINOK(CloseFile()); } - TempBufMode = false; + RINOK(result); } + TempBufMode = false; } if (realProcessed > 0) break; // with this break this function works as Write-Part diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp index 1265dfcd..d76450bd 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -54,7 +54,7 @@ static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, { sizes.Clear(); sizePointers.Clear(); - for(UInt32 i = 0; i < numItems; i++) + for (UInt32 i = 0; i < numItems; i++) { if (srcSizes == 0 || srcSizes[i] == NULL) { @@ -83,7 +83,7 @@ HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) { _bindInfo = bindInfo; _streamBinders.Clear(); - for(int i = 0; i < _bindInfo.BindPairs.Size(); i++) + for (int i = 0; i < _bindInfo.BindPairs.Size(); i++) { _streamBinders.Add(CStreamBinder()); RINOK(_streamBinders.Back().CreateEvents()); @@ -113,7 +113,7 @@ void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder) void CCoderMixer2MT::ReInit() { - for(int i = 0; i < _streamBinders.Size(); i++) + for (int i = 0; i < _streamBinders.Size(); i++) _streamBinders[i].ReInit(); } @@ -125,20 +125,20 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre throw 0; */ int i; - for(i = 0; i < _coders.Size(); i++) + for (i = 0; i < _coders.Size(); i++) { CCoder2 &coderInfo = _coders[i]; const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i]; coderInfo.InStreams.Clear(); UInt32 j; - for(j = 0; j < coderStreamsInfo.NumInStreams; j++) + for (j = 0; j < coderStreamsInfo.NumInStreams; j++) coderInfo.InStreams.Add(NULL); coderInfo.OutStreams.Clear(); - for(j = 0; j < coderStreamsInfo.NumOutStreams; j++) + for (j = 0; j < coderStreamsInfo.NumOutStreams; j++) coderInfo.OutStreams.Add(NULL); } - for(i = 0; i < _bindInfo.BindPairs.Size(); i++) + for (i = 0; i < _bindInfo.BindPairs.Size(); i++) { const CBindPair &bindPair = _bindInfo.BindPairs[i]; UInt32 inCoderIndex, inCoderStreamIndex; @@ -149,16 +149,26 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre _streamBinders[i].CreateStreams( &_coders[inCoderIndex].InStreams[inCoderStreamIndex], &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]); + + CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize; + _coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize); + _coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize); + if (inSetSize && outSetSize) + { + const UInt32 kBufSize = 1 << 19; + inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize); + outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize); + } } - for(i = 0; i < _bindInfo.InStreams.Size(); i++) + for (i = 0; i < _bindInfo.InStreams.Size(); i++) { UInt32 inCoderIndex, inCoderStreamIndex; _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex); _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; } - for(i = 0; i < _bindInfo.OutStreams.Size(); i++) + for (i = 0; i < _bindInfo.OutStreams.Size(); i++) { UInt32 outCoderIndex, outCoderStreamIndex; _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex); diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp index 8d313b54..ad4a5afb 100755 --- a/CPP/7zip/Archive/MachoHandler.cpp +++ b/CPP/7zip/Archive/MachoHandler.cpp @@ -41,7 +41,7 @@ namespace NMacho { #define MACH_SECT_ATTR_ZEROFILL 1 -const char *g_SectTypes[] = +static const char *g_SectTypes[] = { "REGULAR", "ZEROFILL", @@ -60,7 +60,7 @@ const char *g_SectTypes[] = "16BYTE_LITERALS" }; -const char *g_FileTypes[] = +static const char *g_FileTypes[] = { "0", "OBJECT", @@ -111,11 +111,18 @@ struct CSection char Name[kNameSize]; char SegName[kNameSize]; UInt64 Va; - UInt64 Size; - UInt32 Pa; + UInt64 Pa; + UInt64 VSize; + UInt64 PSize; + UInt32 Flags; int SegmentIndex; - UInt64 GetPackSize() const { return Flags == MACH_SECT_ATTR_ZEROFILL ? 0 : Size; } + + bool IsDummy; + + CSection(): IsDummy(false) {} + // UInt64 GetPackSize() const { return Flags == MACH_SECT_ATTR_ZEROFILL ? 0 : Size; } + UInt64 GetPackSize() const { return PSize; } }; @@ -195,8 +202,9 @@ bool CHandler::Parse(const Byte *buf, UInt32 size) if (cmdSize < offs) break; + UInt64 vmAddr, vmSize, phAddr, phSize; + { - UInt64 vmAddr, vmSize, phAddr, phSize; if (cmd == MACH_CMD_SEGMENT_64) { vmAddr = Get64(buf + 0x18, be); @@ -226,7 +234,19 @@ bool CHandler::Parse(const Byte *buf, UInt32 size) if (numSections > (1 << 8)) return false; - while (numSections-- != 0) + if (numSections == 0) + { + CSection section; + section.IsDummy = true; + section.SegmentIndex = _segments.Size() - 1; + section.Va = vmAddr; + section.PSize = phSize; + section.VSize = vmSize; + section.Pa = phAddr; + section.Flags = 0; + _sections.Add(section); + } + else do { CSection section; UInt32 headerSize = (cmd == MACH_CMD_SEGMENT_64) ? 0x50 : 0x44; @@ -236,23 +256,29 @@ bool CHandler::Parse(const Byte *buf, UInt32 size) if (cmd == MACH_CMD_SEGMENT_64) { section.Va = Get64(p + 0x20, be); - section.Size = Get64(p + 0x28, be); + section.VSize = Get64(p + 0x28, be); section.Pa = Get32(p + 0x30, be); section.Flags = Get32(p + 0x40, be); } else { section.Va = Get32(p + 0x20, be); - section.Size = Get32(p + 0x24, be); + section.VSize = Get32(p + 0x24, be); section.Pa = Get32(p + 0x28, be); section.Flags = Get32(p + 0x38, be); } + if (section.Flags == MACH_SECT_ATTR_ZEROFILL) + section.PSize = 0; + else + section.PSize = section.VSize; memcpy(section.Name, p, kNameSize); memcpy(section.SegName, p + kNameSize, kNameSize); section.SegmentIndex = _segments.Size() - 1; _sections.Add(section); offs += headerSize; } + while (--numSections); + if (offs != cmdSize) return false; } @@ -263,7 +289,7 @@ bool CHandler::Parse(const Byte *buf, UInt32 size) return reduceCommands || (size == 0); } -STATPROPSTG kArcProps[] = +static STATPROPSTG kArcProps[] = { { NULL, kpidCpu, VT_BSTR}, { NULL, kpidBit64, VT_BOOL}, @@ -273,7 +299,7 @@ STATPROPSTG kArcProps[] = { NULL, kpidHeadersSize, VT_UI4} }; -STATPROPSTG kProps[] = +static STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidSize, VT_UI8}, @@ -333,10 +359,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val const CSection &item = _sections[index]; switch(propID) { - case kpidPath: StringToProp(GetName(_segments[item.SegmentIndex].Name) + GetName(item.Name), prop); break; - case kpidSize: prop = (UInt64)item.Size; break; + case kpidPath: + { + AString s = GetName(_segments[item.SegmentIndex].Name); + if (!item.IsDummy) + s += GetName(item.Name); + StringToProp(s, prop); + break; + } + case kpidSize: /* prop = (UInt64)item.VSize; break; */ case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; - case kpidCharacts: StringToProp(SectFlagsToString(item.Flags), prop); break; + case kpidCharacts: if (!item.IsDummy) StringToProp(SectFlagsToString(item.Flags), prop); break; case kpidOffset: prop = item.Pa; break; case kpidVa: prop = item.Va; break; } diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp index 9a5daadf..8005ddbc 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp +++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp @@ -23,20 +23,20 @@ using namespace NWindows; namespace NArchive { namespace NNsis { -static const wchar_t *kBcjMethod = L"BCJ"; -static const wchar_t *kUnknownMethod = L"Unknown"; +static const char *kBcjMethod = "BCJ"; +static const char *kUnknownMethod = "Unknown"; -static const wchar_t *kMethods[] = +static const char *kMethods[] = { - L"Copy", - L"Deflate", - L"BZip2", - L"LZMA" + "Copy", + "Deflate", + "BZip2", + "LZMA" }; static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); -STATPROPSTG kProps[] = +static STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidSize, VT_UI8}, @@ -46,7 +46,7 @@ STATPROPSTG kProps[] = { NULL, kpidSolid, VT_BOOL} }; -STATPROPSTG kArcProps[] = +static STATPROPSTG kArcProps[] = { { NULL, kpidMethod, VT_BSTR}, { NULL, kpidSolid, VT_BOOL} @@ -116,50 +116,45 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -static UString ConvertUInt32ToString(UInt32 value) +static AString UInt32ToString(UInt32 value) { - wchar_t buffer[32]; - ConvertUInt64ToString(value, buffer); + char buffer[16]; + ConvertUInt32ToString(value, buffer); return buffer; } -static UString GetStringForSizeValue(UInt32 value) +static AString GetStringForSizeValue(UInt32 value) { for (int i = 31; i >= 0; i--) - if ((UInt32(1) << i) == value) - return ConvertUInt32ToString(i); - UString result; + if (((UInt32)1 << i) == value) + return UInt32ToString(i); + char c = 'b'; if (value % (1 << 20) == 0) { - result += ConvertUInt32ToString(value >> 20); - result += L"m"; + value >>= 20; + c = 'm'; } else if (value % (1 << 10) == 0) { - result += ConvertUInt32ToString(value >> 10); - result += L"k"; + value >>= 10; + c = 'k'; } - else - { - result += ConvertUInt32ToString(value); - result += L"b"; - } - return result; + return UInt32ToString(value) + c; } -UString CHandler::GetMethod(bool useItemFilter, UInt32 dictionary) const +AString CHandler::GetMethod(bool useItemFilter, UInt32 dictionary) const { NMethodType::EEnum methodIndex = _archive.Method; - UString method; + AString method; if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter) { method += kBcjMethod; - method += L" "; + method += ' '; } method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod; if (methodIndex == NMethodType::kLZMA) { - method += L":"; + method += ':'; method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary); } return method; diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.h b/CPP/7zip/Archive/Nsis/NsisHandler.h index 95fea5d0..6de493df 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.h +++ b/CPP/7zip/Archive/Nsis/NsisHandler.h @@ -26,7 +26,7 @@ class CHandler: bool GetUncompressedSize(int index, UInt32 &size); bool GetCompressedSize(int index, UInt32 &size); - UString GetMethod(bool useItemFilter, UInt32 dictionary) const; + AString GetMethod(bool useItemFilter, UInt32 dictionary) const; public: MY_QUERYINTERFACE_BEGIN2(IInArchive) QUERY_ENTRY_ISetCompressCodecsInfo diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp index 06cc38eb..290349aa 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.cpp +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -1290,6 +1290,7 @@ HRESULT CInArchive::Open2( _headerIsCompressed = true; IsSolid = true; FilterFlag = false; + DictionarySize = 1; UInt32 compressedHeaderSize = Get32(sig); diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h index 3fc08440..87ae3f1c 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.h +++ b/CPP/7zip/Archive/Nsis/NsisIn.h @@ -72,7 +72,7 @@ struct CItem UInt32 DictionarySize; CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false), - CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0) {} + CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0), DictionarySize(1) {} bool IsINSTDIR() const { diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp index 97c374d0..5732e1f5 100755 --- a/CPP/7zip/Archive/PeHandler.cpp +++ b/CPP/7zip/Archive/PeHandler.cpp @@ -145,7 +145,7 @@ struct COptHeader // UInt32 AddressOfEntryPoint; // UInt32 BaseOfCode; // UInt32 BaseOfData32; - // UInt64 ImageBase; + UInt64 ImageBase; UInt32 SectAlign; UInt32 FileAlign; @@ -202,8 +202,8 @@ bool COptHeader::Parse(const Byte *p, UInt32 size) // AddressOfEntryPoint = Get32(p + 16); // BaseOfCode = Get32(p + 20); - // BaseOfData32 = Get32(p + 24); - // ImageBase = hdr64 ? GetUi64(p + 24) :Get32(p + 28); + // BaseOfData32 = hdr64 ? 0: Get32(p + 24); + ImageBase = hdr64 ? GetUi64(p + 24) : Get32(p + 28); SectAlign = Get32(p + 32); FileAlign = Get32(p + 36); @@ -625,6 +625,10 @@ enum kpidStackCommit, kpidHeapReserve, kpidHeapCommit, + kpidImageBase + // kpidAddressOfEntryPoint, + // kpidBaseOfCode, + // kpidBaseOfData32, }; STATPROPSTG kArcProps[] = @@ -652,6 +656,10 @@ STATPROPSTG kArcProps[] = { L"Stack Commit", kpidStackCommit, VT_UI8}, { L"Heap Reserve", kpidHeapReserve, VT_UI8}, { L"Heap Commit", kpidHeapCommit, VT_UI8}, + { L"Image Base", kpidImageBase, VT_UI8} + // { L"Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8}, + // { L"Base Of Code", kpidBaseOfCode, VT_UI8}, + // { L"Base Of Data", kpidBaseOfData32, VT_UI8}, }; STATPROPSTG kProps[] = @@ -720,6 +728,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) case kpidStackCommit: prop = _optHeader.StackCommit; break; case kpidHeapReserve: prop = _optHeader.HeapReserve; break; case kpidHeapCommit: prop = _optHeader.HeapCommit; break; + + case kpidImageBase: prop = _optHeader.ImageBase; break; + // case kpidAddressOfEntryPoint: prop = _optHeader.AddressOfEntryPoint; break; + // case kpidBaseOfCode: prop = _optHeader.BaseOfCode; break; + // case kpidBaseOfData32: if (!_optHeader.Is64Bit()) prop = _optHeader.BaseOfData32; break; + case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; } prop.Detach(value); @@ -1393,7 +1407,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) _parseResources = true; UInt64 mainSize = 0, mainSize2 = 0; - for (int i = 0; i < _sections.Size(); i++) + int i; + for (i = 0; i < _sections.Size(); i++) { const CSection § = _sections[i]; CMixItem mixItem; @@ -1469,8 +1484,20 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) } _mixItems.Add(mixItem); } + if (mainSize2 >= (1 << 20) && mainSize < mainSize2 * 2) _mainSubfile = -1; + + for (i = 0; i < _mixItems.Size(); i++) + { + const CMixItem &mixItem = _mixItems[i]; + if (mixItem.StringIndex < 0 && mixItem.ResourceIndex < 0 && _sections[mixItem.SectionIndex].Name == "_winzip_") + { + _mainSubfile = i; + break; + } + } + return S_OK; } diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index 64477766..e54b15ba 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -128,7 +128,9 @@ static STATPROPSTG kProps[] = static STATPROPSTG kArcProps[] = { { NULL, kpidBit64, VT_BOOL}, - { NULL, kpidComment, VT_BSTR} + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidPhySize, VT_UI8}, + { NULL, kpidOffset, VT_UI8} }; CHandler::CHandler() @@ -160,9 +162,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) switch(propID) { case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break; - case kpidComment: - prop = MultiByteToUnicodeString(BytesToString(m_Archive.m_ArchiveInfo.Comment), CP_ACP); - break; + case kpidComment: prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break; + case kpidPhySize: prop = m_Archive.ArcInfo.GetPhySize(); break; + case kpidOffset: if (m_Archive.ArcInfo.StartPosition != 0) prop = m_Archive.ArcInfo.StartPosition; break; } prop.Detach(value); COM_TRY_END diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h index 55ebff25..68dd60dc 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.h +++ b/CPP/7zip/Archive/Zip/ZipHandler.h @@ -87,7 +87,7 @@ private: m_ForceAesMode = false; m_IsAesMode = false; m_AesKeyMode = 3; // aes-256 - m_WriteNtfsTimeExtra = false; + m_WriteNtfsTimeExtra = true; m_ForseLocal = false; m_ForseUtf8 = false; #ifndef _7ZIP_ST diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp index a311e7f3..1048b57d 100755 --- a/CPP/7zip/Archive/Zip/ZipIn.cpp +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -63,7 +63,7 @@ static inline bool TestMarkerCandidate2(const Byte *p, UInt32 &value) HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { - m_ArchiveInfo.Clear(); + ArcInfo.Clear(); m_Position = m_StreamStartPosition; Byte marker[NSignature::kMarkerSize]; @@ -99,7 +99,7 @@ HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHea if (TestMarkerCandidate2(buffer + pos, m_Signature)) { curTestPos += pos; - m_ArchiveInfo.StartPosition = curTestPos; + ArcInfo.StartPosition = curTestPos; m_Position = curTestPos + NSignature::kMarkerSize; return S_OK; } @@ -208,11 +208,6 @@ void CInArchive::ReadFileName(UInt32 nameSize, AString &dest) dest.ReleaseBuffer(); } -void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const -{ - archiveInfo = m_ArchiveInfo; -} - void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) { @@ -332,7 +327,7 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item) return S_OK; try { - RINOK(Seek(m_ArchiveInfo.Base + item.LocalHeaderPosition)); + RINOK(Seek(ArcInfo.Base + item.LocalHeaderPosition)); CItemEx localItem; if (ReadUInt32() != NSignature::kLocalFileHeader) return S_FALSE; @@ -419,7 +414,7 @@ HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item) RINOK(ReadLocalItemAfterCdItem(item)); if (item.HasDescriptor()) { - RINOK(Seek(m_ArchiveInfo.Base + item.GetDataPosition() + item.PackSize)); + RINOK(Seek(ArcInfo.Base + item.GetDataPosition() + item.PackSize)); if (ReadUInt32() != NSignature::kDataDescriptor) return S_FALSE; UInt32 crc = ReadUInt32(); @@ -534,9 +529,9 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo) UInt64 ecd64Offset = Get64(locator + 8); if (TryEcd64(ecd64Offset, cdInfo) == S_OK) return S_OK; - if (TryEcd64(m_ArchiveInfo.StartPosition + ecd64Offset, cdInfo) == S_OK) + if (TryEcd64(ArcInfo.StartPosition + ecd64Offset, cdInfo) == S_OK) { - m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + ArcInfo.Base = ArcInfo.StartPosition; return S_OK; } } @@ -548,8 +543,8 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo) cdInfo.Offset = Get32(buf + i + 16); UInt64 curPos = endPosition - bufSize + i; UInt64 cdEnd = cdInfo.Size + cdInfo.Offset; - if (curPos > cdEnd) - m_ArchiveInfo.Base = curPos - cdEnd; + if (curPos != cdEnd) + ArcInfo.Base = curPos - cdEnd; return S_OK; } } @@ -585,18 +580,18 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UI HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress) { - m_ArchiveInfo.Base = 0; + ArcInfo.Base = 0; CCdInfo cdInfo; RINOK(FindCd(cdInfo)); HRESULT res = S_FALSE; cdSize = cdInfo.Size; cdOffset = cdInfo.Offset; - res = TryReadCd(items, m_ArchiveInfo.Base + cdOffset, cdSize, progress); - if (res == S_FALSE && m_ArchiveInfo.Base == 0) + res = TryReadCd(items, ArcInfo.Base + cdOffset, cdSize, progress); + if (res == S_FALSE && ArcInfo.Base == 0) { - res = TryReadCd(items, cdInfo.Offset + m_ArchiveInfo.StartPosition, cdSize, progress); + res = TryReadCd(items, cdInfo.Offset + ArcInfo.StartPosition, cdSize, progress); if (res == S_OK) - m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + ArcInfo.Base = ArcInfo.StartPosition; } if (!ReadUInt32(m_Signature)) return S_FALSE; @@ -645,7 +640,7 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt CItemEx &item = items[j]; if (item.Name == cdItem.Name) { - m_ArchiveInfo.Base = item.LocalHeaderPosition - cdItem.LocalHeaderPosition; + ArcInfo.Base = item.LocalHeaderPosition - cdItem.LocalHeaderPosition; break; } } @@ -660,7 +655,7 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt if (left >= right) return S_FALSE; index = (left + right) / 2; - UInt64 position = items[index].LocalHeaderPosition - m_ArchiveInfo.Base; + UInt64 position = items[index].LocalHeaderPosition - ArcInfo.Base; if (cdItem.LocalHeaderPosition == position) break; if (cdItem.LocalHeaderPosition < position) @@ -693,7 +688,7 @@ HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt return S_FALSE; } for (i = 0; i < items.Size(); i++) - items[i].LocalHeaderPosition -= m_ArchiveInfo.Base; + items[i].LocalHeaderPosition -= ArcInfo.Base; return S_OK; } @@ -781,20 +776,20 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr if (res == S_FALSE) { _inBufMode = false; - m_ArchiveInfo.Base = 0; - RINOK(m_Stream->Seek(m_ArchiveInfo.StartPosition, STREAM_SEEK_SET, &m_Position)); - if (m_Position != m_ArchiveInfo.StartPosition) + ArcInfo.Base = 0; + RINOK(m_Stream->Seek(ArcInfo.StartPosition, STREAM_SEEK_SET, &m_Position)); + if (m_Position != ArcInfo.StartPosition) return S_FALSE; if (!ReadUInt32(m_Signature)) return S_FALSE; RINOK(ReadLocalsAndCd(items, progress, cdStartOffset, numCdItems)); cdSize = (m_Position - 4) - cdStartOffset; - cdStartOffset -= m_ArchiveInfo.Base; + cdStartOffset -= ArcInfo.Base; } CEcd64 ecd64; bool isZip64 = false; - UInt64 zip64EcdStartOffset = m_Position - 4 - m_ArchiveInfo.Base; + UInt64 zip64EcdStartOffset = m_Position - 4 - ArcInfo.Base; if (m_Signature == NSignature::kZip64EndOfCentralDir) { IsZip64 = isZip64 = true; @@ -843,7 +838,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr COPY_ECD_ITEM_32(cdSize); COPY_ECD_ITEM_32(cdStartOffset); - ReadBuffer(m_ArchiveInfo.Comment, ecd.commentSize); + ReadBuffer(ArcInfo.Comment, ecd.commentSize); if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0) throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); @@ -857,6 +852,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr _inBufMode = false; _inBuffer.Free(); IsOkHeaders = (numCdItems == items.Size()); + ArcInfo.FinishPosition = m_Position; return S_OK; } @@ -864,7 +860,7 @@ ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 siz { CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> stream(streamSpec); - SeekInArchive(m_ArchiveInfo.Base + position); + SeekInArchive(ArcInfo.Base + position); streamSpec->SetStream(m_Stream); streamSpec->Init(size); return stream.Detach(); diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h index f0e88b03..0565339a 100755 --- a/CPP/7zip/Archive/Zip/ZipIn.h +++ b/CPP/7zip/Archive/Zip/ZipIn.h @@ -38,8 +38,11 @@ class CInArchiveInfo public: UInt64 Base; UInt64 StartPosition; + UInt64 FinishPosition; CByteBuffer Comment; + CInArchiveInfo(): Base(0), StartPosition(0) {} + UInt64 GetPhySize() const { return FinishPosition - StartPosition; } void Clear() { Base = 0; @@ -101,7 +104,7 @@ class CInArchive HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress); HRESULT ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset, int &numCdItems); public: - CInArchiveInfo m_ArchiveInfo; + CInArchiveInfo ArcInfo; bool IsZip64; bool IsOkHeaders; @@ -110,7 +113,6 @@ public: HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); void Close(); - void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; bool SeekInArchive(UInt64 position); ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); IInStream* CreateStream(); diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp index 0807369c..aa82143e 100755 --- a/CPP/7zip/Archive/Zip/ZipOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipOut.cpp @@ -221,7 +221,7 @@ void COutArchive::WriteCentralHeader(const CItem &item) WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity()); } -void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment) +void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer *comment) { SeekTo(m_BasePosition); @@ -260,10 +260,10 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByte WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size())); WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize); WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset); - UInt16 commentSize = (UInt16)comment.GetCapacity(); - WriteUInt16(commentSize); + UInt32 commentSize = (UInt32)(comment ? comment->GetCapacity() : 0); + WriteUInt16((UInt16)commentSize); if (commentSize > 0) - WriteBytes((const Byte *)comment, commentSize); + WriteBytes((const Byte *)*comment, commentSize); m_OutBuffer.FlushWithCheck(); } diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h index 24bc83a1..2f6349e5 100755 --- a/CPP/7zip/Archive/Zip/ZipOut.h +++ b/CPP/7zip/Archive/Zip/ZipOut.h @@ -44,7 +44,7 @@ public: void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption); void WriteLocalHeader(const CLocalItem &item); - void WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment); + void WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer *comment); void CreateStreamForCompressing(IOutStream **outStream); void CreateStreamForCopying(ISequentialOutStream **outStream); diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp index 004e67f8..6dd20f94 100755 --- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp +++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp @@ -398,7 +398,7 @@ static HRESULT Update2St( const CObjectVector<CItemEx> &inputItems, const CObjectVector<CUpdateItem> &updateItems, const CCompressionMethodMode *options, - const CByteBuffer &comment, + const CByteBuffer *comment, IArchiveUpdateCallback *updateCallback) { CLocalProgress *lps = new CLocalProgress; @@ -482,7 +482,7 @@ static HRESULT Update2( const CObjectVector<CItemEx> &inputItems, const CObjectVector<CUpdateItem> &updateItems, const CCompressionMethodMode *options, - const CByteBuffer &comment, + const CByteBuffer *comment, IArchiveUpdateCallback *updateCallback) { UInt64 complexity = 0; @@ -515,8 +515,8 @@ static HRESULT Update2( complexity += NFileHeader::kCentralBlockSize; } - if (comment != 0) - complexity += comment.GetCapacity(); + if (comment) + complexity += comment->GetCapacity(); complexity++; // end of central updateCallback->SetTotal(complexity); @@ -812,27 +812,27 @@ HRESULT Update( if (!outStream) return E_NOTIMPL; - CInArchiveInfo archiveInfo; - if(inArchive != 0) + if (inArchive) { - inArchive->GetArchiveInfo(archiveInfo); - if (archiveInfo.Base != 0 || !inArchive->IsOkHeaders) + if (inArchive->ArcInfo.Base != 0 || + inArchive->ArcInfo.StartPosition != 0 || + !inArchive->IsOkHeaders) return E_NOTIMPL; } - else - archiveInfo.StartPosition = 0; COutArchive outArchive; outArchive.Create(outStream); - if (archiveInfo.StartPosition > 0) + /* + if (inArchive && inArchive->ArcInfo.StartPosition > 0) { CMyComPtr<ISequentialInStream> inStream; - inStream.Attach(inArchive->CreateLimitedStream(0, archiveInfo.StartPosition)); + inStream.Attach(inArchive->CreateLimitedStream(0, inArchive->ArcInfo.StartPosition)); RINOK(CopyBlockToArchive(inStream, outArchive, NULL)); - outArchive.MoveBasePosition(archiveInfo.StartPosition); + outArchive.MoveBasePosition(inArchive->ArcInfo.StartPosition); } + */ CMyComPtr<IInStream> inStream; - if(inArchive != 0) + if (inArchive) inStream.Attach(inArchive->CreateStream()); return Update2( @@ -840,7 +840,8 @@ HRESULT Update( outArchive, inArchive, inStream, inputItems, updateItems, compressionMethodMode, - archiveInfo.Comment, updateCallback); + inArchive ? &inArchive->ArcInfo.Comment : NULL, + updateCallback); } }} |