diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2008-11-23 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:57 +0300 |
commit | b717a4dbfe15fd7540e68e6c5ccbe91901bbadba (patch) | |
tree | c89b25a1f9a690e69cd20e313be9eb4180ee7a6f /CPP/7zip | |
parent | c10e6b16f6d5484ed896b2c614cb7fb77f336d24 (diff) |
4.61 beta
Diffstat (limited to 'CPP/7zip')
26 files changed, 501 insertions, 365 deletions
diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp index 072e4076..2b0a426b 100755 --- a/CPP/7zip/Archive/Cab/CabIn.cpp +++ b/CPP/7zip/Archive/Cab/CabIn.cpp @@ -9,34 +9,6 @@ namespace NArchive { namespace NCab { -/* -static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size) -{ - UInt32 realProcessedSize; - RINOK(ReadStream(inStream, data, size, &realProcessedSize)); - if(realProcessedSize != size) - return S_FALSE; - return S_OK; -} - -static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size) -{ - UInt32 realProcessedSize; - RINOK(ReadStream(inStream, data, size, &realProcessedSize)); - if(realProcessedSize != size) - throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); - return S_OK; -} - -static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size) -{ - UInt32 realProcessedSize; - inBuffer.ReadBytes(data, size, realProcessedSize); - if(realProcessedSize != size) - throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); -} -*/ - Byte CInArchive::ReadByte() { Byte b; @@ -107,43 +79,43 @@ HRESULT CInArchive::Open2(IInStream *stream, inBuffer.SetStream(stream); inBuffer.Init(); - CInArchiveInfo &archiveInfo = database.ArchiveInfo; + CInArchiveInfo &ai = database.ArchiveInfo; - archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes + ai.Size = ReadUInt32(); if (ReadUInt32() != 0) return S_FALSE; - archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry + ai.FileHeadersOffset = ReadUInt32(); if (ReadUInt32() != 0) return S_FALSE; - archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor - archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major - archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet - archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet - archiveInfo.Flags = ReadUInt16(); - if (archiveInfo.Flags > 7) + ai.VersionMinor = ReadByte(); + ai.VersionMajor = ReadByte(); + ai.NumFolders = ReadUInt16(); + ai.NumFiles = ReadUInt16(); + ai.Flags = ReadUInt16(); + if (ai.Flags > 7) return S_FALSE; - archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set - archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set + ai.SetID = ReadUInt16(); + ai.CabinetNumber = ReadUInt16(); - if (archiveInfo.ReserveBlockPresent()) + if (ai.ReserveBlockPresent()) { - archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area - archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area - archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area + ai.PerCabinetAreaSize = ReadUInt16(); + ai.PerFolderAreaSize = ReadByte(); + ai.PerDataBlockAreaSize = ReadByte(); - Skeep(archiveInfo.PerCabinetAreaSize); + Skeep(ai.PerCabinetAreaSize); } { - if (archiveInfo.IsTherePrev()) - ReadOtherArchive(archiveInfo.PreviousArchive); - if (archiveInfo.IsThereNext()) - ReadOtherArchive(archiveInfo.NextArchive); + if (ai.IsTherePrev()) + ReadOtherArchive(ai.PreviousArchive); + if (ai.IsThereNext()) + ReadOtherArchive(ai.NextArchive); } int i; - for(i = 0; i < archiveInfo.NumFolders; i++) + for (i = 0; i < ai.NumFolders; i++) { CFolder folder; @@ -152,15 +124,15 @@ HRESULT CInArchive::Open2(IInStream *stream, folder.CompressionTypeMajor = ReadByte(); folder.CompressionTypeMinor = ReadByte(); - Skeep(archiveInfo.PerFolderAreaSize); + Skeep(ai.PerFolderAreaSize); database.Folders.Add(folder); } - RINOK(stream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL)); + RINOK(stream->Seek(database.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL)); inBuffer.SetStream(stream); inBuffer.Init(); - for(i = 0; i < archiveInfo.NumFiles; i++) + for (i = 0; i < ai.NumFiles; i++) { CItem item; item.Size = ReadUInt32(); @@ -224,16 +196,10 @@ bool CMvDatabaseEx::AreItemsEqual(int i1, int i2) const CDatabaseEx &db2 = Volumes[p2->VolumeIndex]; const CItem &item1 = db1.Items[p1->ItemIndex]; const CItem &item2 = db2.Items[p2->ItemIndex];; - int f1 = GetFolderIndex(p1); - int f2 = GetFolderIndex(p2); - if (f1 != f2) - return false; - if (item1.Offset != item2.Offset) - return false; - if (item1.Size != item2.Size) - return false; - - return true; + return GetFolderIndex(p1) == GetFolderIndex(p2) && + item1.Offset == item2.Offset && + item1.Size == item2.Size && + item1.Name == item2.Name; } void CMvDatabaseEx::FillSortAndShrink() @@ -296,7 +262,7 @@ bool CMvDatabaseEx::Check() } UInt64 maxPos = 0; int prevFolder = -2; - for(int i = 0; i < Items.Size(); i++) + for (int i = 0; i < Items.Size(); i++) { const CMvItem &mvItem = Items[i]; int fIndex = GetFolderIndex(&mvItem); diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h index 4975095f..197017b9 100755 --- a/CPP/7zip/Archive/Cab/CabIn.h +++ b/CPP/7zip/Archive/Cab/CabIn.h @@ -31,13 +31,13 @@ struct COtherArchive struct CArchiveInfo { - Byte VersionMinor; /* cabinet file format version, minor */ - Byte VersionMajor; /* cabinet file format version, major */ - UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */ - UInt16 NumFiles; /* number of CFFILE entries in this cabinet */ - UInt16 Flags; /* cabinet file option indicators */ - UInt16 SetID; /* must be the same for all cabinets in a set */ - UInt16 CabinetNumber; /* number of this cabinet file in a set */ + Byte VersionMinor; /* cabinet file format version, minor */ + Byte VersionMajor; /* cabinet file format version, major */ + UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */ + UInt16 NumFiles; /* number of CFFILE entries in this cabinet */ + UInt16 Flags; /* cabinet file option indicators */ + UInt16 SetID; /* must be the same for all cabinets in a set */ + UInt16 CabinetNumber; /* number of this cabinet file in a set */ bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; } diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp index 37d2798a..dee23395 100755 --- a/CPP/7zip/Archive/Iso/IsoIn.cpp +++ b/CPP/7zip/Archive/Iso/IsoIn.cpp @@ -346,10 +346,8 @@ HRESULT CInArchive::Open2() Clear(); RINOK(_stream->Seek(kStartPos, STREAM_SEEK_CUR, &_position)); - bool primVolDescDefined = false; m_BufferPos = 0; BlockSize = kBlockSize; - VolDescs.Add(CVolumeDescriptor()); for (;;) { Byte sig[7]; @@ -396,42 +394,33 @@ HRESULT CInArchive::Open2() break; } case NVolDescType::kPrimaryVol: - { - if (primVolDescDefined) - return S_FALSE; - primVolDescDefined = true; - CVolumeDescriptor &volDesc = VolDescs[0]; - ReadVolumeDescriptor(volDesc); - // some burners write "Joliet" Escape Sequence to primary volume - memset(volDesc.EscapeSequence, 0, sizeof(volDesc.EscapeSequence)); - break; - } case NVolDescType::kSupplementaryVol: { - CVolumeDescriptor sd; - ReadVolumeDescriptor(sd); - VolDescs.Add(sd); + // some ISOs have two PrimaryVols. + CVolumeDescriptor vd; + ReadVolumeDescriptor(vd); + if (sig[0] == NVolDescType::kPrimaryVol) + { + // some burners write "Joliet" Escape Sequence to primary volume + memset(vd.EscapeSequence, 0, sizeof(vd.EscapeSequence)); + } + VolDescs.Add(vd); break; } default: break; } } - MainVolDescIndex = 0; - if (!primVolDescDefined) + if (VolDescs.IsEmpty()) return S_FALSE; - for (int i = VolDescs.Size() - 1; i >= 0; i--) - { - if (VolDescs[i].IsJoliet()) - { - MainVolDescIndex = i; + for (MainVolDescIndex = VolDescs.Size() - 1; MainVolDescIndex > 0; MainVolDescIndex--) + if (VolDescs[MainVolDescIndex].IsJoliet()) break; - } - } // MainVolDescIndex = 0; // to read primary volume - if (VolDescs[MainVolDescIndex].LogicalBlockSize != kBlockSize) + const CVolumeDescriptor &vd = VolDescs[MainVolDescIndex]; + if (vd.LogicalBlockSize != kBlockSize) return S_FALSE; - (CDirRecord &)_rootDir = VolDescs[MainVolDescIndex].RootDirRecord; + (CDirRecord &)_rootDir = vd.RootDirRecord; ReadDir(_rootDir, 0); CreateRefs(_rootDir); ReadBootInfo(); diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp index 245c30c1..7031db97 100755 --- a/CPP/7zip/Archive/PeHandler.cpp +++ b/CPP/7zip/Archive/PeHandler.cpp @@ -264,6 +264,9 @@ 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 AString GetName(const Byte *name) { const int kNameSize = 8; @@ -726,6 +729,34 @@ HRESULT CHandler::Open2(IInStream *stream) if (fileSize > _totalSize) return S_FALSE; _totalSizeLimited = (_totalSize < fileSize) ? _totalSize : (UInt32)fileSize; + + { + CObjectVector<CSection> sections = _sections; + sections.Sort(); + UInt32 limit = (1 << 12); + int num = 0; + for (int i = 0; i < sections.Size(); i++) + { + const CSection &s = sections[i]; + if (s.Pa > limit) + { + 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 += "]"; + _sections.Add(s2); + } + UInt32 next = s.Pa + s.PSize; + if (next < limit) + break; + limit = next; + } + } + return S_OK; } diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp index ca16ef97..d0b13af4 100755 --- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp +++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp @@ -9,9 +9,13 @@ extern "C" #include "Windows/PropVariant.h" #include "Windows/Defs.h" +#include "../../MyVersion.h" #include "../../ICoder.h" #include "../../IPassword.h" #include "../../Common/CreateCoder.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" +#include "../../Compress/LZMA/LZMAEncoder.h" #include "../Common/InStreamWithCRC.h" #include "ZipAddCommon.h" @@ -23,11 +27,59 @@ namespace NZip { static const CMethodId kMethodId_ZipBase = 0x040100; static const CMethodId kMethodId_BZip2 = 0x040202; +static const UInt32 kLzmaPropsSize = 5; +static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize; + +class CLzmaEncoder: + public ICompressCoder, + public CMyUnknownImp +{ + NCompress::NLZMA::CEncoder *EncoderSpec; + CMyComPtr<ICompressCoder> Encoder; + Byte Header[kLzmaHeaderSize]; +public: + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); + + MY_UNKNOWN_IMP +}; + +HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +{ + if (!Encoder) + { + EncoderSpec = new NCompress::NLZMA::CEncoder; + Encoder = EncoderSpec; + } + CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; + CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); + outStreamSpec->Init(); + RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps)); + RINOK(EncoderSpec->WriteCoderProperties(outStream)); + if (outStreamSpec->GetSize() != kLzmaPropsSize) + return E_FAIL; + Header[0] = MY_VER_MAJOR; + Header[1] = MY_VER_MINOR; + Header[2] = kLzmaPropsSize; + Header[3] = 0; + memcpy(Header + 4, outStreamSpec->GetBuffer(), kLzmaPropsSize); + return S_OK; +} + +HRESULT CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + RINOK(WriteStream(outStream, Header, kLzmaHeaderSize)); + return Encoder->Code(inStream, outStream, inSize, outSize, progress); +} + + CAddCommon::CAddCommon(const CCompressionMethodMode &options): _options(options), _copyCoderSpec(NULL), _cryptoStreamSpec(0) - {} + {} static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC) { @@ -38,7 +90,7 @@ static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC) { UInt32 realProcessedSize; RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize)); - if(realProcessedSize == 0) + if (realProcessedSize == 0) { resultCRC = CRC_GET_DIGEST(crc); return S_OK; @@ -87,7 +139,7 @@ HRESULT CAddCommon::Compress( } Byte method = 0; COutStreamReleaser outStreamReleaser; - for(int i = 0; i < numTestMethods; i++) + for (int i = 0; i < numTestMethods; i++) { if (inCrcStreamSpec != 0) RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL)); @@ -127,7 +179,7 @@ HRESULT CAddCommon::Compress( { case NFileHeader::NCompressionMethod::kStored: { - if(_copyCoderSpec == NULL) + if (_copyCoderSpec == NULL) { _copyCoderSpec = new NCompress::CCopyCoder; _copyCoder = _copyCoderSpec; @@ -143,8 +195,41 @@ HRESULT CAddCommon::Compress( } default: { - if(!_compressEncoder) + if (!_compressEncoder) { + if (method == NFileHeader::NCompressionMethod::kLZMA) + { + CLzmaEncoder *_lzmaEncoder = new CLzmaEncoder(); + _compressEncoder = _lzmaEncoder; + NWindows::NCOM::CPropVariant props[] = + { + #ifdef COMPRESS_MT + _options.NumThreads, + #endif + _options.Algo, + _options.DicSize, + _options.NumFastBytes, + (BSTR)(const wchar_t *)_options.MatchFinder, + _options.NumMatchFinderCycles + }; + PROPID propIDs[] = + { + #ifdef COMPRESS_MT + NCoderPropID::kNumThreads, + #endif + NCoderPropID::kAlgorithm, + NCoderPropID::kDictionarySize, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinder, + NCoderPropID::kMatchFinderCycles + }; + int numProps = sizeof(propIDs) / sizeof(propIDs[0]); + if (!_options.NumMatchFinderCyclesDefined) + numProps--; + RINOK(_lzmaEncoder->SetCoderProperties(propIDs, props, numProps)); + } + else + { CMethodId methodId; switch(method) { @@ -164,7 +249,7 @@ HRESULT CAddCommon::Compress( if (method == NFileHeader::NCompressionMethod::kDeflated || method == NFileHeader::NCompressionMethod::kDeflated64) { - NWindows::NCOM::CPropVariant properties[] = + NWindows::NCOM::CPropVariant props[] = { _options.Algo, _options.NumPasses, @@ -185,12 +270,12 @@ HRESULT CAddCommon::Compress( _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); if (setCoderProperties) { - RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps)); + RINOK(setCoderProperties->SetCoderProperties(propIDs, props, numProps)); } } else if (method == NFileHeader::NCompressionMethod::kBZip2) { - NWindows::NCOM::CPropVariant properties[] = + NWindows::NCOM::CPropVariant props[] = { _options.DicSize, _options.NumPasses @@ -210,9 +295,10 @@ HRESULT CAddCommon::Compress( _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); if (setCoderProperties) { - RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0]))); + RINOK(setCoderProperties->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0]))); } } + } } CMyComPtr<ISequentialOutStream> outStreamNew; if (_options.PasswordIsDefined) diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h index ae29a5a4..de5f5ccd 100755 --- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h +++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h @@ -11,7 +11,7 @@ namespace NZip { struct CCompressionMethodMode { CRecordVector<Byte> MethodSequence; - // bool MaximizeRatio; + UString MatchFinder; UInt32 Algo; UInt32 NumPasses; UInt32 NumFastBytes; diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index aba36b3b..40d131f0 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -16,10 +16,12 @@ #include "../../Common/ProgressUtils.h" #include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" #include "../../Common/CreateCoder.h" #include "../../Common/FilterCoder.h" #include "../../Compress/Copy/CopyCoder.h" +#include "../../Compress/LZMA/LZMADecoder.h" #include "../Common/ItemNameUtils.h" #include "../Common/OutStreamWithCRC.h" @@ -108,13 +110,13 @@ const wchar_t *kMethods[] = L"Tokenizing", L"Deflate", L"Deflate64", - L"PKImploding", - L"Unknown", - L"BZip2" + L"PKImploding" }; const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); -// const wchar_t *kUnknownMethod = L"Unknown"; +const wchar_t *kBZip2Method = L"BZip2"; +const wchar_t *kLZMAMethod = L"LZMA"; +const wchar_t *kJpegMethod = L"Jpeg"; const wchar_t *kWavPackMethod = L"WavPack"; const wchar_t *kPPMdMethod = L"PPMd"; const wchar_t *kAESMethod = L"AES"; @@ -294,15 +296,23 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val } if (methodId < kNumMethods) method += kMethods[methodId]; - else if (methodId == NFileHeader::NCompressionMethod::kPPMd) - method += kPPMdMethod; - else if (methodId == NFileHeader::NCompressionMethod::kWavPack) - method += kWavPackMethod; - else + else switch (methodId) { - wchar_t s[32]; - ConvertUInt64ToString(methodId, s); - method += s; + case NFileHeader::NCompressionMethod::kLZMA: + method += kLZMAMethod; + if (item.IsLzmaEOS()) + method += L":EOS"; + break; + case NFileHeader::NCompressionMethod::kBZip2: method += kBZip2Method; break; + case NFileHeader::NCompressionMethod::kJpeg: method += kJpegMethod; break; + case NFileHeader::NCompressionMethod::kWavPack: method += kWavPackMethod; break; + case NFileHeader::NCompressionMethod::kPPMd: method += kPPMdMethod; break; + default: + { + wchar_t s[32]; + ConvertUInt64ToString(methodId, s); + method += s; + } } prop = method; break; @@ -367,6 +377,37 @@ STDMETHODIMP CHandler::Close() ////////////////////////////////////// // CHandler::DecompressItems +class CLzmaDecoder: + public ICompressCoder, + public CMyUnknownImp +{ + NCompress::NLZMA::CDecoder *DecoderSpec; + CMyComPtr<ICompressCoder> Decoder; +public: + CLzmaDecoder(); + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + MY_UNKNOWN_IMP +}; + +CLzmaDecoder::CLzmaDecoder() +{ + DecoderSpec = new NCompress::NLZMA::CDecoder; + Decoder = DecoderSpec; +} + +HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + Byte buf[9]; + RINOK(ReadStream_FALSE(inStream, buf, 9)); + if (buf[2] != 5 || buf[3] != 0) + return E_NOTIMPL; + RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, 5)); + return Decoder->Code(inStream, outStream, NULL, outSize, progress); +} + struct CMethodItem { UInt16 ZipMethod; @@ -568,6 +609,8 @@ HRESULT CZipDecoder::Decode( mi.Coder = new NCompress::NShrink::CDecoder; else if (methodId == NFileHeader::NCompressionMethod::kImploded) mi.Coder = new NCompress::NImplode::NDecoder::CCoder; + else if (methodId == NFileHeader::NCompressionMethod::kLZMA) + mi.Coder = new CLzmaDecoder; else { CMethodId szMethodID; @@ -656,6 +699,12 @@ HRESULT CZipDecoder::Decode( result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress); if (result == S_FALSE) return S_OK; + if (result == E_NOTIMPL) + { + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + RINOK(result); } bool crcOK = true; diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp index c493b0c9..ea46e131 100755 --- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -25,16 +25,28 @@ using namespace NTime; namespace NArchive { namespace NZip { -static const UInt32 kDeflateAlgoX1 = 0; -static const UInt32 kDeflateAlgoX5 = 1; +static const UInt32 kLzAlgoX1 = 0; +static const UInt32 kLzAlgoX5 = 1; static const UInt32 kDeflateNumPassesX1 = 1; static const UInt32 kDeflateNumPassesX7 = 3; static const UInt32 kDeflateNumPassesX9 = 10; -static const UInt32 kNumFastBytesX1 = 32; -static const UInt32 kNumFastBytesX7 = 64; -static const UInt32 kNumFastBytesX9 = 128; +static const UInt32 kDeflateNumFastBytesX1 = 32; +static const UInt32 kDeflateNumFastBytesX7 = 64; +static const UInt32 kDeflateNumFastBytesX9 = 128; + +static const wchar_t *kLzmaMatchFinderX1 = L"HC4"; +static const wchar_t *kLzmaMatchFinderX5 = L"BT4"; + +static const UInt32 kLzmaNumFastBytesX1 = 32; +static const UInt32 kLzmaNumFastBytesX7 = 64; + +static const UInt32 kLzmaDicSizeX1 = 1 << 16; +static const UInt32 kLzmaDicSizeX3 = 1 << 20; +static const UInt32 kLzmaDicSizeX5 = 1 << 24; +static const UInt32 kLzmaDicSizeX7 = 1 << 25; +static const UInt32 kLzmaDicSizeX9 = 1 << 26; static const UInt32 kBZip2NumPassesX1 = 1; static const UInt32 kBZip2NumPassesX7 = 2; @@ -173,24 +185,20 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { bool defaultCharWasUsed; ui.Name = UnicodeStringToMultiByte(name, CP_OEMCP, '_', defaultCharWasUsed); - tryUtf8 = (!m_ForseLocal && defaultCharWasUsed); + tryUtf8 = (!m_ForseLocal && (defaultCharWasUsed || + MultiByteToUnicodeString(ui.Name, CP_OEMCP) != name)); } if (tryUtf8) { - bool needUtf = false; - for (int i = 0; i < name.Length(); i++) - if ((unsigned)name[i] >= 0x80) - { - needUtf = true; - break; - } - ui.IsUtf8 = needUtf; + int i; + for (i = 0; i < name.Length() && (unsigned)name[i] < 0x80; i++); + ui.IsUtf8 = (i != name.Length()); if (!ConvertUnicodeToUTF8(name, ui.Name)) return E_INVALIDARG; } - if (ui.Name.Length() > 0xFFFF) + if (ui.Name.Length() >= (1 << 16)) return E_INVALIDARG; ui.IndexInClient = i; @@ -272,6 +280,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored); bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) || (mainMethod == NFileHeader::NCompressionMethod::kDeflated64); + bool isLZMA = (mainMethod == NFileHeader::NCompressionMethod::kLZMA); + bool isLz = (isLZMA || isDeflate); bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2); options.NumPasses = m_NumPasses; options.DicSize = m_DicSize; @@ -282,20 +292,41 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt #ifdef COMPRESS_MT options.NumThreads = _numThreads; #endif - if (isDeflate) + if (isLz) { - if (options.NumPasses == 0xFFFFFFFF) - options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 : - (level >= 7 ? kDeflateNumPassesX7 : - kDeflateNumPassesX1)); - if (options.NumFastBytes == 0xFFFFFFFF) - options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : - (level >= 7 ? kNumFastBytesX7 : - kNumFastBytesX1)); + if (isDeflate) + { + if (options.NumPasses == 0xFFFFFFFF) + options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 : + (level >= 7 ? kDeflateNumPassesX7 : + kDeflateNumPassesX1)); + if (options.NumFastBytes == 0xFFFFFFFF) + options.NumFastBytes = (level >= 9 ? kDeflateNumFastBytesX9 : + (level >= 7 ? kDeflateNumFastBytesX7 : + kDeflateNumFastBytesX1)); + } + else if (isLZMA) + { + if (options.DicSize == 0xFFFFFFFF) + options.DicSize = + (level >= 9 ? kLzmaDicSizeX9 : + (level >= 7 ? kLzmaDicSizeX7 : + (level >= 5 ? kLzmaDicSizeX5 : + (level >= 3 ? kLzmaDicSizeX3 : + kLzmaDicSizeX1)))); + + if (options.NumFastBytes == 0xFFFFFFFF) + options.NumFastBytes = (level >= 7 ? kLzmaNumFastBytesX7 : + kLzmaNumFastBytesX1); + + options.MatchFinder = + (level >= 5 ? kLzmaMatchFinderX5 : + kLzmaMatchFinderX1); + } + if (options.Algo == 0xFFFFFFFF) - options.Algo = - (level >= 5 ? kDeflateAlgoX5 : - kDeflateAlgoX1); + options.Algo = (level >= 5 ? kLzAlgoX5 : + kLzAlgoX1); } if (isBZip2) { @@ -343,18 +374,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v { if (prop.vt == VT_BSTR) { - UString valueString = prop.bstrVal; - valueString.MakeUpper(); - if (valueString == L"COPY") - m_MainMethod = NFileHeader::NCompressionMethod::kStored; - else if (valueString == L"DEFLATE") - m_MainMethod = NFileHeader::NCompressionMethod::kDeflated; - else if (valueString == L"DEFLATE64") - m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64; - else if (valueString == L"BZIP2") - m_MainMethod = NFileHeader::NCompressionMethod::kBZip2; - else - return E_INVALIDARG; + UString m = prop.bstrVal; + m.MakeUpper(); + if (m == L"COPY") m_MainMethod = NFileHeader::NCompressionMethod::kStored; + else if (m == L"DEFLATE") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated; + else if (m == L"DEFLATE64") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64; + else if (m == L"BZIP2") m_MainMethod = NFileHeader::NCompressionMethod::kBZip2; + else if (m == L"LZMA") m_MainMethod = NFileHeader::NCompressionMethod::kLZMA; + else return E_INVALIDARG; } else if (prop.vt == VT_UI4) { @@ -364,6 +391,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v case NFileHeader::NCompressionMethod::kDeflated: case NFileHeader::NCompressionMethod::kDeflated64: case NFileHeader::NCompressionMethod::kBZip2: + case NFileHeader::NCompressionMethod::kLZMA: m_MainMethod = (Byte)prop.ulVal; break; default: @@ -414,7 +442,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v } else if (name.Left(2) == L"FB") { - UInt32 num = kNumFastBytesX9; + UInt32 num = kDeflateNumFastBytesX9; RINOK(ParsePropValue(name.Mid(2), prop, num)); m_NumFastBytes = num; } @@ -433,25 +461,25 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v } else if (name.Left(1) == L"A") { - UInt32 num = kDeflateAlgoX5; + UInt32 num = kLzAlgoX5; RINOK(ParsePropValue(name.Mid(1), prop, num)); m_Algo = num; } else if (name.CompareNoCase(L"TC") == 0) - return SetBoolProperty(m_WriteNtfsTimeExtra, prop); + { + RINOK(SetBoolProperty(m_WriteNtfsTimeExtra, prop)); + } else if (name.CompareNoCase(L"CL") == 0) { RINOK(SetBoolProperty(m_ForseLocal, prop)); if (m_ForseLocal) m_ForseUtf8 = false; - return S_OK; } else if (name.CompareNoCase(L"CU") == 0) { RINOK(SetBoolProperty(m_ForseUtf8, prop)); if (m_ForseUtf8) m_ForseLocal = false; - return S_OK; } else return E_INVALIDARG; diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h index 3af72369..e974079d 100755 --- a/CPP/7zip/Archive/Zip/ZipHeader.h +++ b/CPP/7zip/Archive/Zip/ZipHeader.h @@ -69,6 +69,10 @@ namespace NFileHeader kPKImploding = 10, kBZip2 = 12, + kLZMA = 14, + kTerse = 18, + kLz77 = 19, + kJpeg = 0x60, kWavPack = 0x61, kPPMd = 0x62, kWzAES = 0x63 @@ -170,6 +174,7 @@ namespace NFileHeader namespace NFlags { const int kEncrypted = 1 << 0; + const int kLzmaEOS = 1 << 1; const int kDescriptorUsedMask = 1 << 3; const int kStrongEncrypted = 1 << 6; const int kUtf8 = 1 << 11; diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp index 9bbf3882..03472d85 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.cpp +++ b/CPP/7zip/Archive/Zip/ZipItem.cpp @@ -51,20 +51,6 @@ bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const return false; } -bool CLocalItem::IsImplodeBigDictionary() const -{ - if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) - throw 12312212; - return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0; -} - -bool CLocalItem::IsImplodeLiteralsOn() const -{ - if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) - throw 12312213; - return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0; -} - bool CLocalItem::IsDir() const { return NItemName::HasTailSlash(Name, GetCodePage()); diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h index bc1b27c0..c41ba8c8 100755 --- a/CPP/7zip/Archive/Zip/ZipItem.h +++ b/CPP/7zip/Archive/Zip/ZipItem.h @@ -188,8 +188,7 @@ public: bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; } bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; }; - bool IsImplodeBigDictionary() const; - bool IsImplodeLiteralsOn() const; + bool IsLzmaEOS() const { return (Flags & NFileHeader::NFlags::kLzmaEOS) != 0; } bool IsDir() const; bool IgnoreItem() const { return false; } diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp index 3294ad78..403b5efe 100755 --- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp +++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp @@ -1,4 +1,4 @@ -// ZipUpdate.cpp +lzma// ZipUpdate.cpp #include "StdAfx.h" @@ -568,6 +568,14 @@ static HRESULT Update2( if (numThreads <= 1) mtMode = false; } + if (method == NFileHeader::NCompressionMethod::kLZMA) + { + UInt32 numLZMAThreads = (options->Algo > 0 ? 2 : 1); + numThreads /= numLZMAThreads; + options2.NumThreads = numLZMAThreads; + if (numThreads <= 1) + mtMode = false; + } } if (!mtMode) diff --git a/CPP/7zip/Bundles/SFXCon/Main.cpp b/CPP/7zip/Bundles/SFXCon/Main.cpp index 5ae6878d..ac8c1cdf 100755 --- a/CPP/7zip/Bundles/SFXCon/Main.cpp +++ b/CPP/7zip/Bundles/SFXCon/Main.cpp @@ -5,27 +5,30 @@ #include "Common/MyInitGuid.h" #include "Common/CommandLineParser.h" -#include "Common/StdOutStream.h" -#include "Common/Wildcard.h" -#include "Common/StringConvert.h" #include "Common/MyCom.h" #include "Common/MyException.h" +#include "Common/StdOutStream.h" +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" -#include "Windows/FileDir.h" -#include "Windows/FileName.h" #include "Windows/Defs.h" +#include "Windows/FileName.h" +#ifdef _WIN32 +#include "Windows/DLL.h" +#include "Windows/FileDir.h" +#endif #include "../../IPassword.h" #include "../../ICoder.h" -#include "../../UI/Common/OpenArchive.h" #include "../../UI/Common/DefaultName.h" #include "../../UI/Common/ExitCode.h" #include "../../UI/Common/Extract.h" +#include "../../UI/Common/OpenArchive.h" +#include "../../UI/Console/ExtractCallbackConsole.h" #include "../../UI/Console/List.h" #include "../../UI/Console/OpenCallbackConsole.h" -#include "../../UI/Console/ExtractCallbackConsole.h" #include "../../MyVersion.h" @@ -40,11 +43,6 @@ static const char *kCopyrightString = static const int kNumSwitches = 6; -#ifdef _WIN32 -static const wchar_t *kDefaultExt = L".exe"; -static const int kDefaultExtLength = 4; -#endif - namespace NKey { enum Enum { @@ -271,7 +269,25 @@ int Main2( GetArguments(numArguments, arguments, commandStrings); #endif - UString archiveName = commandStrings.Front(); + #ifdef _WIN32 + + UString arcPath; + { + UString path; + NDLL::MyGetModuleFileName(NULL, path); + int fileNamePartStartIndex; + if (!NDirectory::MyGetFullPathName(path, arcPath, fileNamePartStartIndex)) + { + g_StdOut << "GetFullPathName Error"; + return NExitCode::kFatalError; + } + } + + #else + + UString arcPath = commandStrings.Front(); + + #endif commandStrings.Delete(0); @@ -318,11 +334,6 @@ int Main2( bool yesToAll = parser[NKey::kYes].ThereIs; - #ifdef _WIN32 - if (archiveName.Right(kDefaultExtLength).CompareNoCase(kDefaultExt) != 0) - archiveName += kDefaultExt; - #endif - // NExtractMode::EEnum extractMode; // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); @@ -333,13 +344,13 @@ int Main2( password = parser[NKey::kPassword].PostStrings[0]; NFind::CFileInfoW archiveFileInfo; - if (!NFind::FindFile(archiveName, archiveFileInfo)) + if (!NFind::FindFile(arcPath, archiveFileInfo)) throw kCantFindSFX; if (archiveFileInfo.IsDir()) throw kCantFindSFX; UString outputDir; - if(parser[NKey::kOutputDir].ThereIs) + if (parser[NKey::kOutputDir].ThereIs) { outputDir = parser[NKey::kOutputDir].PostStrings[0]; NName::NormalizeDirPathPrefix(outputDir); @@ -347,8 +358,8 @@ int Main2( { UStringVector v1, v2; - v1.Add(archiveName); - v2.Add(archiveName); + v1.Add(arcPath); + v2.Add(arcPath); const NWildcard::CCensorNode &wildcardCensorHead = wildcardCensor.Pairs.Front().Head; diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp index e272d88d..7d1f73a2 100755 --- a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp +++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp @@ -381,6 +381,14 @@ SOURCE=..\..\Crypto\Hash\RotateDefs.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Error.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile index c32b11cd..4bfe7f3d 100755 --- a/CPP/7zip/Bundles/SFXCon/makefile +++ b/CPP/7zip/Bundles/SFXCon/makefile @@ -29,6 +29,7 @@ COMMON_OBJS = \ $O\Wildcard.obj \ WIN_OBJS = \ + $O\DLL.obj \ $O\Error.obj \ $O\FileDir.obj \ $O\FileFind.obj \ diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp index f2af88e6..5ec72dc4 100755 --- a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp +++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp @@ -106,8 +106,6 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, } _filePath = fullPath; - // m_CurrentFilePath = GetSystemString(fullPath, _codePage); - if (askExtractMode == NArchive::NExtract::NAskMode::kExtract) { NCOM::CPropVariant prop; @@ -135,14 +133,9 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)); switch(prop.vt) { - case VT_EMPTY: - _processedFileInfo.MTime = _defaultMTime; - break; - case VT_FILETIME: - _processedFileInfo.MTime = prop.filetime; - break; - default: - return E_FAIL; + case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break; + case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break; + default: return E_FAIL; } UStringVector pathParts; @@ -168,6 +161,8 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, if (isAnti) NDirectory::MyRemoveDirectory(_diskFilePath); + else + NDirectory::SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime); return S_OK; } @@ -204,13 +199,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode) { - _extractMode = false; - switch (askExtractMode) - { - case NArchive::NExtract::NAskMode::kExtract: - _extractMode = true; - break; - }; + _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract); return S_OK; } diff --git a/CPP/7zip/Compress/LZMA/LZMADecoder.cpp b/CPP/7zip/Compress/LZMA/LZMADecoder.cpp index 545b8f1d..ae5da5de 100755 --- a/CPP/7zip/Compress/LZMA/LZMADecoder.cpp +++ b/CPP/7zip/Compress/LZMA/LZMADecoder.cpp @@ -18,6 +18,7 @@ static HRESULT SResToHRESULT(SRes res) case SZ_OK: return S_OK; case SZ_ERROR_MEM: return E_OUTOFMEMORY; case SZ_ERROR_PARAM: return E_INVALIDARG; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; // case SZ_ERROR_PROGRESS: return E_ABORT; case SZ_ERROR_DATA: return S_FALSE; } @@ -29,7 +30,7 @@ namespace NLZMA { static const UInt32 kInBufSize = 1 << 20; -CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false) +CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false), FinishStream(false) { LzmaDec_Construct(&_state); } @@ -104,10 +105,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, if (rem < curSize) { curSize = (SizeT)rem; - /* - // finishMode = LZMA_FINISH_END; - we can't use LZMA_FINISH_END here to allow partial decoding - */ + if (FinishStream) + finishMode = LZMA_FINISH_END; } } diff --git a/CPP/7zip/Compress/LZMA/LZMADecoder.h b/CPP/7zip/Compress/LZMA/LZMADecoder.h index fa140e47..40dc3f36 100755 --- a/CPP/7zip/Compress/LZMA/LZMADecoder.h +++ b/CPP/7zip/Compress/LZMA/LZMADecoder.h @@ -65,6 +65,8 @@ public: STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); #endif + bool FinishStream; + CDecoder(); virtual ~CDecoder(); diff --git a/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp index a09c3069..abfbb237 100755 --- a/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp +++ b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp @@ -179,42 +179,6 @@ SOURCE=..\LZMA\LZMAEncoder.cpp SOURCE=..\LZMA\LZMAEncoder.h # End Source File # End Group -# Begin Group "RangeCoder" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\RangeCoder\RangeCoder.h -# End Source File -# Begin Source File - -SOURCE=..\RangeCoder\RangeCoderBit.cpp -# End Source File -# Begin Source File - -SOURCE=..\RangeCoder\RangeCoderBit.h -# End Source File -# Begin Source File - -SOURCE=..\RangeCoder\RangeCoderBitTree.h -# End Source File -# Begin Source File - -SOURCE=..\RangeCoder\RangeCoderOpt.h -# End Source File -# End Group -# Begin Group "LZ" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\LZ\LZOutWindow.cpp -# End Source File -# Begin Source File - -SOURCE=..\LZ\LZOutWindow.h -# End Source File -# End Group # End Group # Begin Group "Windows" diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp index 1afbec97..d6ead3f4 100755 --- a/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp +++ b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp @@ -31,11 +31,9 @@ #include "../../../Windows/System.h" #endif -#include "../../MyVersion.h" - - extern "C" { + #include "../../../../C/7zVersion.h" #include "../../../../C/Alloc.h" #include "../../../../C/LzmaUtil/Lzma86Dec.h" #include "../../../../C/LzmaUtil/Lzma86Enc.h" @@ -64,13 +62,13 @@ enum Enum { kHelp1 = 0, kHelp2, - kMode, - kDictionary, - kFastBytes, - kMatchFinderCycles, - kLitContext, - kLitPos, - kPosBits, + kAlgo, + kDict, + kFb, + kMc, + kLc, + kLp, + kPb, kMatchFinder, kMultiThread, kEOS, @@ -109,7 +107,7 @@ static void PrintHelp() " b: Benchmark\n" "<Switches>\n" " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" - " -d{N}: set dictionary - [12, 30], default: 23 (8MB)\n" + " -d{N}: set dictionary size - [12, 30], default: 23 (8MB)\n" " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" " -mc{N}: set number of cycles for match finder\n" " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" @@ -157,6 +155,13 @@ static bool GetNumber(const wchar_t *s, UInt32 &value) return true; } +static void ParseUInt32(const CParser &parser, int index, UInt32 &res) +{ + if (parser[index].ThereIs) + if (!GetNumber(parser[index].PostStrings[0], res)) + IncorrectCommand(); +} + int main2(int n, const char *args[]) { #ifdef _WIN32 @@ -202,15 +207,15 @@ int main2(int n, const char *args[]) IncorrectCommand(); const UString &command = nonSwitchStrings[paramIndex++]; - bool dictionaryIsDefined = false; - UInt32 dictionary = (UInt32)-1; - if(parser[NKey::kDictionary].ThereIs) + bool dictDefined = false; + UInt32 dict = (UInt32)-1; + if(parser[NKey::kDict].ThereIs) { UInt32 dicLog; - if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog)) + if (!GetNumber(parser[NKey::kDict].PostStrings[0], dicLog)) IncorrectCommand(); - dictionary = 1 << dicLog; - dictionaryIsDefined = true; + dict = 1 << dicLog; + dictDefined = true; } UString mf = L"BT4"; if (parser[NKey::kMatchFinder].ThereIs) @@ -240,7 +245,7 @@ int main2(int n, const char *args[]) if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations)) numIterations = kNumDefaultItereations; } - return LzmaBenchCon(stderr, numIterations, numThreads, dictionary); + return LzmaBenchCon(stderr, numIterations, numThreads, dict); } if (numThreads == (UInt32)-1) @@ -334,10 +339,10 @@ int main2(int n, const char *args[]) if (outBuffer == 0) throw kCantAllocate; } - if (!dictionaryIsDefined) - dictionary = 1 << 23; + if (!dictDefined) + dict = 1 << 23; int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize, - 5, dictionary, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO); + 5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO); if (res != 0) { fprintf(stderr, "\nEncoder error = %d\n", (int)res); @@ -378,42 +383,30 @@ int main2(int n, const char *args[]) NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder; CMyComPtr<ICompressCoder> encoder = encoderSpec; - if (!dictionaryIsDefined) - dictionary = 1 << 23; + if (!dictDefined) + dict = 1 << 23; - UInt32 posStateBits = 2; - UInt32 litContextBits = 3; // for normal files - // UInt32 litContextBits = 0; // for 32-bit data - UInt32 litPosBits = 0; - // UInt32 litPosBits = 2; // for 32-bit data - UInt32 algorithm = 1; - UInt32 numFastBytes = 128; - UInt32 matchFinderCycles = 16 + numFastBytes / 2; - bool matchFinderCyclesDefined = false; + UInt32 pb = 2; + UInt32 lc = 3; // = 0; for 32-bit data + UInt32 lp = 0; // = 2; for 32-bit data + UInt32 algo = 1; + UInt32 fb = 128; + UInt32 mc = 16 + fb / 2; + bool mcDefined = false; bool eos = parser[NKey::kEOS].ThereIs || stdInMode; - if(parser[NKey::kMode].ThereIs) - if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm)) - IncorrectCommand(); - - if(parser[NKey::kFastBytes].ThereIs) - if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes)) - IncorrectCommand(); - matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs; - if (matchFinderCyclesDefined) - if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles)) - IncorrectCommand(); - if(parser[NKey::kLitContext].ThereIs) - if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits)) - IncorrectCommand(); - if(parser[NKey::kLitPos].ThereIs) - if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits)) + ParseUInt32(parser, NKey::kAlgo, algo); + ParseUInt32(parser, NKey::kFb, fb); + ParseUInt32(parser, NKey::kLc, lc); + ParseUInt32(parser, NKey::kLp, lp); + ParseUInt32(parser, NKey::kPb, pb); + + mcDefined = parser[NKey::kMc].ThereIs; + if (mcDefined) + if (!GetNumber(parser[NKey::kMc].PostStrings[0], mc)) IncorrectCommand(); - if(parser[NKey::kPosBits].ThereIs) - if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits)) - IncorrectCommand(); - + PROPID propIDs[] = { NCoderPropID::kDictionarySize, @@ -429,35 +422,35 @@ int main2(int n, const char *args[]) }; const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]); - PROPVARIANT properties[kNumPropsMax]; + PROPVARIANT props[kNumPropsMax]; for (int p = 0; p < 6; p++) - properties[p].vt = VT_UI4; + props[p].vt = VT_UI4; - properties[0].ulVal = (UInt32)dictionary; - properties[1].ulVal = (UInt32)posStateBits; - properties[2].ulVal = (UInt32)litContextBits; - properties[3].ulVal = (UInt32)litPosBits; - properties[4].ulVal = (UInt32)algorithm; - properties[5].ulVal = (UInt32)numFastBytes; + props[0].ulVal = (UInt32)dict; + props[1].ulVal = (UInt32)pb; + props[2].ulVal = (UInt32)lc; + props[3].ulVal = (UInt32)lp; + props[4].ulVal = (UInt32)algo; + props[5].ulVal = (UInt32)fb; - properties[6].vt = VT_BSTR; - properties[6].bstrVal = (BSTR)(const wchar_t *)mf; + props[6].vt = VT_BSTR; + props[6].bstrVal = (BSTR)(const wchar_t *)mf; - properties[7].vt = VT_BOOL; - properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE; + props[7].vt = VT_BOOL; + props[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE; - properties[8].vt = VT_UI4; - properties[8].ulVal = (UInt32)numThreads; + props[8].vt = VT_UI4; + props[8].ulVal = (UInt32)numThreads; // it must be last in property list - properties[9].vt = VT_UI4; - properties[9].ulVal = (UInt32)matchFinderCycles; + props[9].vt = VT_UI4; + props[9].ulVal = (UInt32)mc; int numProps = kNumPropsMax; - if (!matchFinderCyclesDefined) + if (!mcDefined) numProps--; - if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK) + if (encoderSpec->SetCoderProperties(propIDs, props, numProps) != S_OK) IncorrectCommand(); encoderSpec->WriteCoderProperties(outStream); @@ -491,6 +484,7 @@ int main2(int n, const char *args[]) { NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder; CMyComPtr<ICompressCoder> decoder = decoderSpec; + decoderSpec->FinishStream = true; const UInt32 kPropertiesSize = 5; Byte header[kPropertiesSize + 8]; if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK) diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h index 31b8ea3b..70657739 100755 --- a/CPP/7zip/MyVersion.h +++ b/CPP/7zip/MyVersion.h @@ -1,8 +1,8 @@ #define MY_VER_MAJOR 4 -#define MY_VER_MINOR 60 +#define MY_VER_MINOR 61 #define MY_VER_BUILD 0 -#define MY_VERSION " 4.60 beta" -#define MY_7ZIP_VERSION "7-Zip 4.60 beta" -#define MY_DATE "2008-08-19" +#define MY_VERSION "4.61 beta" +#define MY_7ZIP_VERSION "7-Zip 4.61 beta" +#define MY_DATE "2008-11-23" #define MY_COPYRIGHT "Copyright (c) 1999-2008 Igor Pavlov" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE diff --git a/CPP/7zip/UI/Common/DefaultName.cpp b/CPP/7zip/UI/Common/DefaultName.cpp index 020cb50a..4335e273 100755 --- a/CPP/7zip/UI/Common/DefaultName.cpp +++ b/CPP/7zip/UI/Common/DefaultName.cpp @@ -4,8 +4,6 @@ #include "DefaultName.h" -static const wchar_t *kEmptyFileAlias = L"[Content]"; - static UString GetDefaultName3(const UString &fileName, const UString &extension, const UString &addSubExtension) { @@ -21,7 +19,11 @@ static UString GetDefaultName3(const UString &fileName, int dotPos = fileName.ReverseFind(L'.'); if (dotPos > 0) return fileName.Left(dotPos) + addSubExtension; - return kEmptyFileAlias; + + if (addSubExtension.IsEmpty()) + return fileName + L"~"; + else + return fileName + addSubExtension; } UString GetDefaultName2(const UString &fileName, diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp index 26a1a8de..f6727cbf 100755 --- a/CPP/7zip/UI/Common/UpdatePair.cpp +++ b/CPP/7zip/UI/Common/UpdatePair.cpp @@ -39,25 +39,23 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time } static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:"; +static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):"; -/* -static const char *kNotCensoredCollisionMessaged = "Internal file name collision:\n"; -static const char *kSameTimeChangedSizeCollisionMessaged = - "Collision between files with same date/time and different sizes:\n"; -*/ +static void ThrowError(const UString &message, const UString &s1, const UString &s2) +{ + UString m = message; + m += L'\n'; + m += s1; + m += L'\n'; + m += s2; + throw m; +} static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices) { for(int i = 0; i + 1 < indices.Size(); i++) if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0) - { - UString message = kDuplicateFileNameMessage; - message += L"\n"; - message += strings[indices[i]]; - message += L"\n"; - message += strings[indices[i + 1]]; - throw message; - } + ThrowError(kDuplicateFileNameMessage, strings[indices[i]], strings[indices[i + 1]]); } void GetUpdatePairInfoList( @@ -116,7 +114,7 @@ void GetUpdatePairInfoList( else { if (!ai.Censored) - throw 1082022; + ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name); pair.DirIndex = dirIndex2; pair.ArcIndex = arcIndex2; switch (MyCompareTime( diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp index afb376d0..ed8813c7 100755 --- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp +++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp @@ -164,6 +164,8 @@ static const wchar_t *kStartExtensions[] = L"docx", L"docm", L"dotx", L"dotm", L"xlsx", L"xlsm", L"xltx", L"xltm", L"xlsb", L"xlam", L"pptx", L"pptm", L"potx", L"potm", L"ppam", L"ppsx", L"ppsm", L"xsn", + L"dwf", + L"odt", L"ods", L"wb3", L"pdf" diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp index 0dec5412..1cb71e5f 100755 --- a/CPP/7zip/UI/FileManager/RootFolder.cpp +++ b/CPP/7zip/UI/FileManager/RootFolder.cpp @@ -81,17 +81,24 @@ STDMETHODIMP CRootFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIA return S_OK; } +typedef BOOL (WINAPI *SHGetSpecialFolderPathWp)(HWND hwnd, LPWSTR pszPath, int csidl, BOOL fCreate); +typedef BOOL (WINAPI *SHGetSpecialFolderPathAp)(HWND hwnd, LPSTR pszPath, int csidl, BOOL fCreate); + UString GetMyDocsPath() { UString us; WCHAR s[MAX_PATH + 1]; - if (SHGetSpecialFolderPathW(0, s, CSIDL_PERSONAL, FALSE)) + SHGetSpecialFolderPathWp getW = (SHGetSpecialFolderPathWp) + ::GetProcAddress(::GetModuleHandleA("shell32.dll"), "SHGetSpecialFolderPathW"); + if (getW && getW(0, s, CSIDL_PERSONAL, FALSE)) us = s; #ifndef _UNICODE else { + SHGetSpecialFolderPathAp getA = (SHGetSpecialFolderPathAp) + ::GetProcAddress(::GetModuleHandleA("shell32.dll"), "SHGetSpecialFolderPathA"); CHAR s2[MAX_PATH + 1]; - if (SHGetSpecialFolderPathA(0, s2, CSIDL_PERSONAL, FALSE)) + if (getA && getA(0, s2, CSIDL_PERSONAL, FALSE)) us = GetUnicodeString(s2); } #endif diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp index 468c87c8..69587f3a 100755 --- a/CPP/7zip/UI/GUI/CompressDialog.cpp +++ b/CPP/7zip/UI/GUI/CompressDialog.cpp @@ -146,7 +146,8 @@ static EMethodID g_ZipMethods[] = { kDeflate, kDeflate64, - kBZip2 + kBZip2, + kLZMA }; static EMethodID g_GZipMethods[] = @@ -173,6 +174,8 @@ struct CFormatInfo bool EncryptFileNames; }; +#define METHODS_PAIR(x) x, MY_SIZE_OF_ARRAY(x) + static const CFormatInfo g_Formats[] = { { @@ -184,26 +187,25 @@ static const CFormatInfo g_Formats[] = { k7zFormat, (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - g_7zMethods, MY_SIZE_OF_ARRAY(g_7zMethods), + METHODS_PAIR(g_7zMethods), true, true, true, true, true, true }, { L"Zip", (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - g_ZipMethods, MY_SIZE_OF_ARRAY(g_ZipMethods) , + METHODS_PAIR(g_ZipMethods), false, false, true, false, true, false }, { L"GZip", (1 << 1) | (1 << 5) | (1 << 7) | (1 << 9), - g_GZipMethods, MY_SIZE_OF_ARRAY(g_GZipMethods), + METHODS_PAIR(g_GZipMethods), false, false, false, false, false, false }, { L"BZip2", (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - g_BZip2Methods, - MY_SIZE_OF_ARRAY(g_BZip2Methods), + METHODS_PAIR(g_BZip2Methods), false, false, true, false, false }, { @@ -1289,8 +1291,12 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dictionary, UInt64 &decompressMemo UInt32 numThreads = GetNumThreads2(); if (IsZipFormat()) { - if (numThreads > 1) - size += (UInt64)numThreads << 25; + UInt32 numSubThreads = 1; + if (GetMethodID() == kLZMA && numThreads > 1 && level >= 5) + numSubThreads = 2; + UInt32 numMainThreads = numThreads / numSubThreads; + if (numMainThreads > 1) + size += (UInt64)numMainThreads << 25; } switch (GetMethodID()) { @@ -1306,13 +1312,19 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dictionary, UInt64 &decompressMemo if (hs > (1 << 24)) hs >>= 1; hs++; - size += hs * 4; - size += (UInt64)dictionary * 11 / 2; + UInt64 size1 = (UInt64)hs * 4; + size1 += (UInt64)dictionary * 11 / 2; if (level >= 5) - size += dictionary * 4; - size += (2 << 20); + size1 += dictionary * 4; + size1 += (2 << 20); + + UInt32 numThreads1 = 1; if (numThreads > 1 && level >= 5) - size += (2 << 20) + (4 << 20); + { + size1 += (2 << 20) + (4 << 20); + numThreads1 = 2; + } + size += size1 * numThreads / numThreads1; decompressMemory = dictionary + (2 << 20); return size; |