diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2018-05-03 00:28:04 +0300 |
---|---|---|
committer | Kornel <kornel@geekhood.net> | 2018-05-03 00:28:04 +0300 |
commit | 18dc2b41613055f0daf7f6a1d4311368798ea12a (patch) | |
tree | 866f6e6a50406fe822cb78f80728b7aebfd79786 /CPP/7zip | |
parent | f19b649c73cd8b74c4e0b8a3a728a82c6bda47b4 (diff) |
18.0518.05
Diffstat (limited to 'CPP/7zip')
91 files changed, 1990 insertions, 902 deletions
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp index c62efbd8..4395ae1a 100644 --- a/CPP/7zip/Archive/Cab/CabHandler.cpp +++ b/CPP/7zip/Archive/Cab/CabHandler.cpp @@ -549,9 +549,9 @@ private: Byte *TempBuf; UInt32 TempBufSize; + UInt32 TempBufWritten; unsigned NumIdenticalFiles; bool TempBufMode; - UInt32 m_BufStartFolderOffset; unsigned m_StartIndex; unsigned m_CurrentIndex; @@ -575,7 +575,6 @@ private: HRESULT OpenFile(); HRESULT CloseFileWithResOp(Int32 resOp); HRESULT CloseFile(); - HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); public: HRESULT WriteEmptyFiles(); @@ -672,11 +671,11 @@ HRESULT CFolderOutStream::OpenFile() FreeTempBuf(); TempBuf = (Byte *)MyAlloc(item.Size); TempBufSize = item.Size; - if (TempBuf == NULL) + if (!TempBuf) return E_OUTOFMEMORY; } TempBufMode = true; - m_BufStartFolderOffset = item.Offset; + TempBufWritten = 0; } else if (numExtractItems == 1) { @@ -725,8 +724,9 @@ HRESULT CFolderOutStream::WriteEmptyFiles() } -HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) +HRESULT CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { + // (data == NULL) means Error_Data for solid folder flushing COM_TRY_BEGIN UInt32 realProcessed = 0; @@ -741,21 +741,34 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe HRESULT res = S_OK; if (numBytesToWrite != 0) { - if (!isOK) + if (!data) m_IsOk = false; + if (m_RealOutStream) { UInt32 processedSizeLocal = 0; - res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); + // 18.01 : we don't want ZEROs instead of missing data + if (data) + res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); + else + processedSizeLocal = numBytesToWrite; numBytesToWrite = processedSizeLocal; } + if (TempBufMode && TempBuf) - memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite); + { + if (data) + { + memcpy(TempBuf + TempBufWritten, data, numBytesToWrite); + TempBufWritten += numBytesToWrite; + } + } } realProcessed += numBytesToWrite; if (processedSize) *processedSize = realProcessed; - data = (const void *)((const Byte *)data + numBytesToWrite); + if (data) + data = (const void *)((const Byte *)data + numBytesToWrite); size -= numBytesToWrite; m_RemainFileSize -= numBytesToWrite; m_PosInFolder += numBytesToWrite; @@ -773,7 +786,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe m_FileIsOpen = true; m_CurrentIndex++; if (result == S_OK && m_RealOutStream && TempBuf) - result = WriteStream(m_RealOutStream, TempBuf, (size_t)(m_PosInFolder - m_BufStartFolderOffset)); + result = WriteStream(m_RealOutStream, TempBuf, TempBufWritten); if (!TempBuf && TempBufMode && m_RealOutStream) { @@ -822,7 +835,8 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe realProcessed += numBytesToWrite; if (processedSize) *processedSize = realProcessed; - data = (const void *)((const Byte *)data + numBytesToWrite); + if (data) + data = (const void *)((const Byte *)data + numBytesToWrite); size -= numBytesToWrite; m_PosInFolder += numBytesToWrite; } @@ -843,12 +857,6 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe } -STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write2(data, size, processedSize, true); -} - - HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex) { if (!NeedMoreWrite()) @@ -862,19 +870,16 @@ HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex) return S_OK; } - const unsigned kBufSize = (1 << 12); - Byte buf[kBufSize]; - for (unsigned i = 0; i < kBufSize; i++) - buf[i] = 0; - for (;;) { if (!NeedMoreWrite()) return S_OK; UInt64 remain = GetRemain(); - UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize); + UInt32 size = (UInt32)1 << 20; + if (size > remain) + size = (UInt32)remain; UInt32 processedSizeLocal = 0; - RINOK(Write2(buf, size, &processedSizeLocal, false)); + RINOK(Write(NULL, size, &processedSizeLocal)); } } diff --git a/CPP/7zip/Archive/DmgHandler.cpp b/CPP/7zip/Archive/DmgHandler.cpp index 608ad4c4..5fe372dd 100644 --- a/CPP/7zip/Archive/DmgHandler.cpp +++ b/CPP/7zip/Archive/DmgHandler.cpp @@ -219,6 +219,7 @@ class CHandler: bool _masterCrcError; bool _headersError; + UInt32 _dataStartOffset; UInt64 _startPos; UInt64 _phySize; @@ -333,6 +334,7 @@ static const Byte kProps[] = kpidCRC, kpidComment, kpidMethod + // kpidOffset }; IMP_IInArchive_Props @@ -631,17 +633,40 @@ bool CHandler::ParseBlob(const CByteBuffer &data) HRESULT CHandler::Open2(IInStream *stream) { + /* + - usual dmg contains Koly Header at the end: + - rare case dmg contains Koly Header at the start. + */ + + _dataStartOffset = 0; RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos)); + UInt64 fileSize = 0; + RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(stream->Seek(_startPos, STREAM_SEEK_SET, NULL)); + Byte buf[HEADER_SIZE]; RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)); UInt64 headerPos; + bool startKolyMode = false; + if (IsKoly(buf)) + { + // it can be normal koly-at-the-end or koly-at-the-start headerPos = _startPos; + if (_startPos <= (1 << 8)) + { + // we want to support startKolyMode, even if there is + // some data before dmg file, like 128 bytes MacBin header + _dataStartOffset = HEADER_SIZE; + startKolyMode = true; + } + } else { - RINOK(stream->Seek(0, STREAM_SEEK_END, &headerPos)); + // we check only koly-at-the-end + headerPos = fileSize; if (headerPos < HEADER_SIZE) return S_FALSE; headerPos -= HEADER_SIZE; @@ -667,24 +692,35 @@ HRESULT CHandler::Open2(IInStream *stream) // CChecksum dataForkChecksum; // dataForkChecksum.Parse(buf + 0x50); - _startPos = 0; - UInt64 top = 0; - if (!dataForkPair.UpdateTop(headerPos, top)) return S_FALSE; - if (!xmlPair.UpdateTop(headerPos, top)) return S_FALSE; - if (!rsrcPair.UpdateTop(headerPos, top)) return S_FALSE; + UInt64 limit = startKolyMode ? fileSize : headerPos; + + if (!dataForkPair.UpdateTop(limit, top)) return S_FALSE; + if (!xmlPair.UpdateTop(limit, top)) return S_FALSE; + if (!rsrcPair.UpdateTop(limit, top)) return S_FALSE; /* Some old dmg files contain garbage data in blobPair field. So we need to ignore such garbage case; And we still need to detect offset of start of archive for "parser" mode. */ - bool useBlob = blobPair.UpdateTop(headerPos, top); + bool useBlob = blobPair.UpdateTop(limit, top); - _startPos = 0; - _phySize = headerPos + HEADER_SIZE; - if (top != headerPos) + if (startKolyMode) + _phySize = top; + else { + _phySize = headerPos + HEADER_SIZE; + _startPos = 0; + if (top != headerPos) + { + /* + if expected absolute offset is not equal to real header offset, + 2 cases are possible: + - additional (unknown) headers + - archive with offset. + So we try to read XML with absolute offset to select from these two ways. + */ CForkPair xmlPair2 = xmlPair; const char *sz = "<?xml version"; const unsigned len = (unsigned)strlen(sz); @@ -694,9 +730,11 @@ HRESULT CHandler::Open2(IInStream *stream) if (ReadData(stream, xmlPair2, buf2) != S_OK || memcmp(buf2, sz, len) != 0) { + // if absolute offset is not OK, probably it's archive with offset _startPos = headerPos - top; _phySize = top + HEADER_SIZE; } + } } // Byte reserved[0x78] @@ -1041,6 +1079,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val break; } + /* + case kpidOffset: + { + prop = item.StartPos; + break; + } + */ + case kpidMethod: { CMethods m; @@ -1384,7 +1430,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, break; } - RINOK(_inStream->Seek(_startPos + item.StartPos + block.PackPos, STREAM_SEEK_SET, NULL)); + RINOK(_inStream->Seek(_startPos + _dataStartOffset + item.StartPos + block.PackPos, STREAM_SEEK_SET, NULL)); streamSpec->Init(block.PackSize); bool realMethod = true; outStreamSpec->Init(block.UnpSize); @@ -1781,7 +1827,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) spec->Stream = _inStream; spec->Size = spec->File->Size; - RINOK(spec->InitAndSeek(_startPos)); + RINOK(spec->InitAndSeek(_startPos + _dataStartOffset)); *stream = specStream.Detach(); return S_OK; diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp index 62674774..c5ce279e 100644 --- a/CPP/7zip/Archive/ElfHandler.cpp +++ b/CPP/7zip/Archive/ElfHandler.cpp @@ -567,6 +567,7 @@ static const char * const g_Machines[] = static const CUInt32PCharPair g_MachinePairs[] = { + { 243, "RISC-V" }, { 47787, "Xilinx MicroBlaze" } // { 0x9026, "Alpha" } }; diff --git a/CPP/7zip/Archive/HfsHandler.cpp b/CPP/7zip/Archive/HfsHandler.cpp index d02f0725..3ff2e86e 100644 --- a/CPP/7zip/Archive/HfsHandler.cpp +++ b/CPP/7zip/Archive/HfsHandler.cpp @@ -317,11 +317,15 @@ public: // bool CaseSensetive; UString ResFileName; + UInt64 SpecOffset; UInt64 PhySize; + UInt64 PhySize2; void Clear() { + SpecOffset = 0; PhySize = 0; + PhySize2 = 0; HeadersError = false; ThereAreAltStreams = false; // CaseSensetive = false; @@ -444,7 +448,7 @@ HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inSt e.NumBlocks > fork.NumBlocks - curBlock || e.NumBlocks > Header.NumBlocks - e.Pos) return S_FALSE; - RINOK(inStream->Seek((UInt64)e.Pos << Header.BlockSizeLog, STREAM_SEEK_SET, NULL)); + RINOK(inStream->Seek(SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog), STREAM_SEEK_SET, NULL)); RINOK(ReadStream_FALSE(inStream, (Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog), (size_t)e.NumBlocks << Header.BlockSizeLog)); @@ -1154,13 +1158,36 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents } static const unsigned kHeaderPadSize = (1 << 10); +static const unsigned kMainHeaderSize = 512; +static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize; + +API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size) +{ + if (size < kHfsHeaderSize) + return k_IsArc_Res_NEED_MORE; + p += kHeaderPadSize; + if (p[0] == 'B' && p[1] == 'D') + { + if (p[0x7C] != 'H' || p[0x7C + 1] != '+') + return k_IsArc_Res_NO; + } + else + { + if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) + return k_IsArc_Res_NO; + UInt32 version = Get16(p + 2); + if (version < 4 || version > 5) + return k_IsArc_Res_NO; + } + return k_IsArc_Res_YES; +} +} HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) { Clear(); - static const unsigned kHeaderSize = kHeaderPadSize + 512; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); + Byte buf[kHfsHeaderSize]; + RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize)); { for (unsigned i = 0; i < kHeaderPadSize; i++) if (buf[i] != 0) @@ -1171,6 +1198,67 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) h.Header[0] = p[0]; h.Header[1] = p[1]; + + if (p[0] == 'B' && p[1] == 'D') + { + /* + It's header for old HFS format. + We don't support old HFS format, but we support + special HFS volume that contains embedded HFS+ volume + */ + + if (p[0x7C] != 'H' || p[0x7C + 1] != '+') + return S_FALSE; + + /* + h.CTime = Get32(p + 0x2); + h.MTime = Get32(p + 0x6); + + h.NumFiles = Get32(p + 0x54); + h.NumFolders = Get32(p + 0x58); + + if (h.NumFolders > ((UInt32)1 << 29) || + h.NumFiles > ((UInt32)1 << 30)) + return S_FALSE; + if (progress) + { + UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; + RINOK(progress->SetTotal(&numFiles, NULL)); + } + h.NumFreeBlocks = Get16(p + 0x22); + */ + + UInt32 blockSize = Get32(p + 0x14); + + { + unsigned i; + for (i = 9; ((UInt32)1 << i) != blockSize; i++) + if (i == 31) + return S_FALSE; + h.BlockSizeLog = i; + } + + h.NumBlocks = Get16(p + 0x12); + /* + we suppose that it has the follwing layout + { + start block with header + [h.NumBlocks] + end block with header + } + */ + PhySize2 = ((UInt64)h.NumBlocks + 2) << h.BlockSizeLog; + + UInt32 startBlock = Get16(p + 0x7C + 2); + UInt32 blockCount = Get16(p + 0x7C + 4); + SpecOffset = (UInt64)(1 + startBlock) << h.BlockSizeLog; + UInt64 phy = SpecOffset + ((UInt64)blockCount << h.BlockSizeLog); + if (PhySize2 < phy) + PhySize2 = phy; + RINOK(inStream->Seek(SpecOffset, STREAM_SEEK_SET, NULL)); + RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize)); + } + if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) return S_FALSE; h.Version = Get16(p + 2); @@ -1330,7 +1418,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { case kpidExtension: prop = Header.IsHfsX() ? "hfsx" : "hfs"; break; case kpidMethod: prop = Header.IsHfsX() ? "HFSX" : "HFS+"; break; - case kpidPhySize: prop = PhySize; break; + case kpidPhySize: + { + UInt64 v = SpecOffset + PhySize; + if (v < PhySize2) + v = PhySize2; + prop = v; + break; + } case kpidClusterSize: prop = (UInt32)1 << Header.BlockSizeLog; break; case kpidFreeSpace: prop = (UInt64)Header.GetFreeSize(); break; case kpidMTime: HfsTimeToProp(Header.MTime, prop); break; @@ -1754,7 +1849,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, if (fork.Size == pos) break; const CExtent &e = fork.Extents[extentIndex]; - RINOK(_stream->Seek((UInt64)e.Pos << Header.BlockSizeLog, STREAM_SEEK_SET, NULL)); + RINOK(_stream->Seek(SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog), STREAM_SEEK_SET, NULL)); UInt64 extentRem = (UInt64)e.NumBlocks << Header.BlockSizeLog; while (extentRem != 0) { @@ -1865,6 +1960,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) } static const Byte k_Signature[] = { + 2, 'B', 'D', 4, 'H', '+', 0, 4, 4, 'H', 'X', 0, 5 }; @@ -1873,6 +1969,6 @@ REGISTER_ARC_I( k_Signature, kHeaderPadSize, NArcInfoFlags::kMultiSignature, - NULL) + IsArc_HFS) }} diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp index cb0836cc..a751351c 100644 --- a/CPP/7zip/Archive/PeHandler.cpp +++ b/CPP/7zip/Archive/PeHandler.cpp @@ -2201,6 +2201,11 @@ bool CHeader::ParseCoff(const Byte *p) return false; if (OptHeaderSize != 0 && OptHeaderSize < k_OptHeader32_Size_MIN) return false; + + // 18.04: we reduce false detections + if (NumSections == 0 && OptHeaderSize == 0) + return false; + for (unsigned i = 0; i < ARRAY_SIZE(g_MachinePairs); i++) if (Machine == g_MachinePairs[i].Value) return true; diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp index ab8c70e3..17fcccc3 100644 --- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp +++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp @@ -139,11 +139,10 @@ static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val) { *val = 0; - for (unsigned i = 0; i < maxSize;) + for (unsigned i = 0; i < maxSize && i < 10;) { Byte b = p[i]; - if (i < 10) - *val |= (UInt64)(b & 0x7F) << (7 * i); + *val |= (UInt64)(b & 0x7F) << (7 * i); i++; if ((b & 0x80) == 0) return i; @@ -1363,7 +1362,9 @@ static const Byte kProps[] = kpidCharacts, kpidSymLink, kpidHardLink, - kpidCopyLink + kpidCopyLink, + + kpidVolumeIndex }; @@ -1794,6 +1795,18 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidSplitBefore: prop = item.IsSplitBefore(); break; case kpidSplitAfter: prop = lastItem.IsSplitAfter(); break; + + case kpidVolumeIndex: + { + if (item.VolIndex < _arcs.Size()) + { + const CInArcInfo &arcInfo = _arcs[item.VolIndex].Info; + if (arcInfo.IsVolume()) + prop = (UInt64)arcInfo.GetVolIndex(); + } + break; + } + case kpidCRC: { const CItem *item2 = (lastItem.IsSplitAfter() ? &item : &lastItem); diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.h b/CPP/7zip/Archive/Rar/Rar5Handler.h index d3e33d7c..3b3b940a 100644 --- a/CPP/7zip/Archive/Rar/Rar5Handler.h +++ b/CPP/7zip/Archive/Rar/Rar5Handler.h @@ -180,7 +180,7 @@ struct CItem AString Name; - int VolIndex; + unsigned VolIndex; int NextItem; UInt32 UnixMTime; diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index fb5ef756..4b54e071 100644 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -777,7 +777,9 @@ static const Byte kProps[] = kpidCRC, kpidHostOS, kpidMethod, - kpidUnpackVer + kpidUnpackVer, + + kpidVolumeIndex }; static const Byte kArcProps[] = @@ -995,6 +997,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidCommented: prop = item.IsCommented(); break; case kpidSplitBefore: prop = item.IsSplitBefore(); break; case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break; + + case kpidVolumeIndex: + if (_arcInfo.Is_VolNumber_Defined()) + prop = (UInt32)(_arcInfo.VolNumber + refItem.VolumeIndex); + break; + case kpidCRC: { prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h index 901406d4..e444bd77 100644 --- a/CPP/7zip/Archive/Rar/RarHandler.h +++ b/CPP/7zip/Archive/Rar/RarHandler.h @@ -26,7 +26,7 @@ struct CInArcInfo UInt32 DataCRC; bool EndOfArchive_was_Read; - CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false) {} + CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false), VolNumber(0) {} UInt64 GetPhySize() const { return EndPos - StartPos; } diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp index 760bfa92..d432c318 100644 --- a/CPP/7zip/Archive/Tar/TarIn.cpp +++ b/CPP/7zip/Archive/Tar/TarIn.cpp @@ -94,7 +94,9 @@ static bool ParseInt64(const char *p, Int64 &val) static bool ParseInt64_MTime(const char *p, Int64 &val) { - // rare case tar contains spaces instead of MTime + // rare case tar : ZEROs in Docker-Windows TARs + // rare case tar : spaces + if (GetUi32(p) != 0) for (unsigned i = 0; i < 12; i++) if (p[i] != ' ') return ParseInt64(p, val); diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp index 9e9918dc..aa7184af 100644 --- a/CPP/7zip/Archive/Zip/ZipIn.cpp +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -1993,6 +1993,13 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback) } else if (ext.IsEqualTo_Ascii_NoCase("exe")) { + /* possible cases: + - exe with zip inside + - sfx: a.exe, a.z02, a.z03,... , a.zip + a.exe is start volume. + - zip renamed to exe + */ + StartIsExe = true; BaseName = name; StartVolIndex = 0; @@ -2000,7 +2007,22 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback) We can open arc.zip, if it was requesed to open arc.exe. But it's possible that arc.exe and arc.zip are not parts of same archive. So we can disable such operation */ - return S_FALSE; // don't open arc.zip instead of arc.exe + + // 18.04: we still want to open zip renamed to exe. + /* + { + UString volName = name; + volName += IsUpperCase ? "Z01" : "z01"; + { + CMyComPtr<IInStream> stream; + HRESULT res2 = volCallback->GetStream(volName, &stream); + if (res2 == S_OK) + DisableVolsSearch = true; + } + } + */ + DisableVolsSearch = true; + return S_OK; } else if (ext[0] == 'z' || ext[0] == 'Z') { @@ -2040,6 +2062,9 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback) HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback, unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols) { + if (Vols.DisableVolsSearch) + return S_OK; + numMissingVols = 0; for (unsigned i = start;; i++) @@ -2090,6 +2115,8 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback, } if (res == S_FALSE || !stream) { + if (i == 1 && Vols.StartIsExe) + return S_OK; if (Vols.MissingName.IsEmpty()) Vols.MissingName = volName; numMissingVols++; diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h index e67bce42..88f29569 100644 --- a/CPP/7zip/Archive/Zip/ZipIn.h +++ b/CPP/7zip/Archive/Zip/ZipIn.h @@ -162,6 +162,7 @@ struct CVols bool NeedSeek; + bool DisableVolsSearch; bool StartIsExe; // is .exe bool StartIsZ; // is .zip or .zNN bool StartIsZip; // is .zip @@ -201,6 +202,7 @@ struct CVols StreamIndex = -1; NeedSeek = false; + DisableVolsSearch = false; StartIsExe = false; StartIsZ = false; StartIsZip = false; diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp index 71715aae..733635bd 100644 --- a/CPP/7zip/Bundles/Alone/Alone.dsp +++ b/CPP/7zip/Bundles/Alone/Alone.dsp @@ -1112,18 +1112,6 @@ SOURCE=..\..\Compress\ShrinkDecoder.cpp SOURCE=..\..\Compress\ShrinkDecoder.h # End Source File # End Group -# Begin Group "Z" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\Compress\ZDecoder.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\Compress\ZDecoder.h -# End Source File -# End Group # Begin Group "BWT" # PROP Default_Filter "" @@ -1648,10 +1636,6 @@ SOURCE=..\..\Archive\SplitHandler.cpp SOURCE=..\..\Archive\XzHandler.cpp # End Source File -# Begin Source File - -SOURCE=..\..\Archive\ZHandler.cpp -# End Source File # End Group # Begin Group "UI Common" diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile index ba68fe54..8229103c 100644 --- a/CPP/7zip/Bundles/Alone/makefile +++ b/CPP/7zip/Bundles/Alone/makefile @@ -75,7 +75,6 @@ AR_OBJS = \ $O\LzmaHandler.obj \ $O\SplitHandler.obj \ $O\XzHandler.obj \ - $O\ZHandler.obj \ AR_COMMON_OBJS = \ $O\CoderMixer2.obj \ @@ -169,7 +168,6 @@ COMPRESS_OBJS = \ $O\ShrinkDecoder.obj \ $O\XzDecoder.obj \ $O\XzEncoder.obj \ - $O\ZDecoder.obj \ CRYPTO_OBJS = \ $O\7zAes.obj \ diff --git a/CPP/7zip/Bundles/Alone/resource.rc b/CPP/7zip/Bundles/Alone/resource.rc index fc9063c1..c85acaa9 100644 --- a/CPP/7zip/Bundles/Alone/resource.rc +++ b/CPP/7zip/Bundles/Alone/resource.rc @@ -1,3 +1,7 @@ #include "../../MyVersionInfo.rc" MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp index 65308db4..eeab209e 100644 --- a/CPP/7zip/Bundles/Alone7z/Alone.dsp +++ b/CPP/7zip/Bundles/Alone7z/Alone.dsp @@ -44,7 +44,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /FAc /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAc /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -94,7 +94,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -121,7 +121,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c -# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -482,6 +482,14 @@ SOURCE=..\..\..\Windows\FileName.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Handle.h # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile index 98600154..da305780 100644 --- a/CPP/7zip/Bundles/Alone7z/makefile +++ b/CPP/7zip/Bundles/Alone7z/makefile @@ -3,7 +3,7 @@ MY_CONSOLE = 1 CFLAGS = $(CFLAGS) -DPROG_VARIANT_R !IFNDEF UNDER_CE -CFLAGS = $(CFLAGS) -DWIN_LONG_PATH +CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE !ENDIF COMMON_OBJS = \ @@ -33,6 +33,7 @@ WIN_OBJS = \ $O\FileIO.obj \ $O\FileLink.obj \ $O\FileName.obj \ + $O\FileSystem.obj \ $O\MemoryLock.obj \ $O\PropVariant.obj \ $O\PropVariantConv.obj \ diff --git a/CPP/7zip/Bundles/Alone7z/resource.rc b/CPP/7zip/Bundles/Alone7z/resource.rc index b3fb079a..59378500 100644 --- a/CPP/7zip/Bundles/Alone7z/resource.rc +++ b/CPP/7zip/Bundles/Alone7z/resource.rc @@ -1,3 +1,7 @@ #include "../../../../C/7zVersion.rc" MY_VERSION_INFO_APP("7-Zip Reduced Standalone Console", "7zr") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff --git a/CPP/7zip/Bundles/Fm/FM.dsp b/CPP/7zip/Bundles/Fm/FM.dsp index 82ac7fa4..38770405 100644 --- a/CPP/7zip/Bundles/Fm/FM.dsp +++ b/CPP/7zip/Bundles/Fm/FM.dsp @@ -677,6 +677,14 @@ SOURCE=..\..\UI\FileManager\DialogSize.h # End Source File # Begin Source File +SOURCE=..\..\UI\FileManager\EditDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\EditDialog.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\FileManager\LinkDialog.cpp # End Source File # Begin Source File @@ -1567,14 +1575,6 @@ SOURCE=..\..\..\Common\Wildcard.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Common\ArchiveCommandLine.h -# End Source File -# Begin Source File - SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/Fm/makefile b/CPP/7zip/Bundles/Fm/makefile index 8ae5f4f6..367b30d5 100644 --- a/CPP/7zip/Bundles/Fm/makefile +++ b/CPP/7zip/Bundles/Fm/makefile @@ -48,7 +48,6 @@ WIN_CTRL_OBJS = \ $O\FileStreams.obj \ UI_COMMON_OBJS = \ - $O\ArchiveCommandLine.obj \ $O\ArchiveExtractCallback.obj \ $O\ArchiveName.obj \ $O\ArchiveOpenCallback.obj \ diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp index c5a0ceff..0f032d81 100644 --- a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp +++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp @@ -117,10 +117,6 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h # End Source File # Begin Source File -SOURCE=..\..\Archive\Common\HandlerOut.cpp -# End Source File -# Begin Source File - SOURCE=..\..\Archive\Common\HandlerOut.h # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile index 01d1bf60..67fc5896 100644 --- a/CPP/7zip/Bundles/SFXCon/makefile +++ b/CPP/7zip/Bundles/SFXCon/makefile @@ -1,5 +1,7 @@ PROG = 7zCon.sfx MY_CONSOLE = 1 +MY_FIXED = 1 + CFLAGS = $(CFLAGS) \ -DEXTRACT_ONLY \ -DNO_READ_FROM_CODER \ diff --git a/CPP/7zip/Bundles/SFXSetup/makefile b/CPP/7zip/Bundles/SFXSetup/makefile index 19afc3b3..9fddbc07 100644 --- a/CPP/7zip/Bundles/SFXSetup/makefile +++ b/CPP/7zip/Bundles/SFXSetup/makefile @@ -1,4 +1,6 @@ PROG = 7zS.sfx +MY_FIXED = 1 + CFLAGS = $(CFLAGS) \ -DNO_REGISTRY \ -DEXTRACT_ONLY \ diff --git a/CPP/7zip/Bundles/SFXWin/makefile b/CPP/7zip/Bundles/SFXWin/makefile index d6556961..b3b4546f 100644 --- a/CPP/7zip/Bundles/SFXWin/makefile +++ b/CPP/7zip/Bundles/SFXWin/makefile @@ -1,4 +1,6 @@ PROG = 7z.sfx +MY_FIXED = 1 + CFLAGS = $(CFLAGS) \ -DNO_REGISTRY \ -DEXTRACT_ONLY \ diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp index a3ef4b57..caecbc09 100644 --- a/CPP/7zip/Compress/Lzma2Encoder.cpp +++ b/CPP/7zip/Compress/Lzma2Encoder.cpp @@ -22,7 +22,7 @@ namespace NLzma2 { CEncoder::CEncoder() { _encoder = NULL; - _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc); + _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc); if (!_encoder) throw 1; } diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp index c64f580a..e47f776b 100644 --- a/CPP/7zip/Compress/LzmaEncoder.cpp +++ b/CPP/7zip/Compress/LzmaEncoder.cpp @@ -15,7 +15,7 @@ namespace NLzma { CEncoder::CEncoder() { _encoder = NULL; - _encoder = LzmaEnc_Create(&g_Alloc); + _encoder = LzmaEnc_Create(&g_AlignedAlloc); if (!_encoder) throw 1; } @@ -23,7 +23,7 @@ CEncoder::CEncoder() CEncoder::~CEncoder() { if (_encoder) - LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc); + LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc); } static inline wchar_t GetUpperChar(wchar_t c) @@ -168,7 +168,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream progressWrap.Init(progress); SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, - progress ? &progressWrap.vt : NULL, &g_Alloc, &g_BigAlloc); + progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc); _inputProcessed = inWrap.Processed; diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp index f5f3a79d..6b55705b 100644 --- a/CPP/7zip/Compress/Rar1Decoder.cpp +++ b/CPP/7zip/Compress/Rar1Decoder.cpp @@ -9,77 +9,85 @@ namespace NCompress { namespace NRar1 { -static const UInt32 PosL1[] = {0,0,0,2,3,5,7,11,16,20,24,32,32, 256}; -static const UInt32 PosL2[] = {0,0,0,0,5,7,9,13,18,22,26,34,36, 256}; -static const UInt32 PosHf0[] = {0,0,0,0,0,8,16,24,33,33,33,33,33, 257}; -static const UInt32 PosHf1[] = {0,0,0,0,0,0,4,44,60,76,80,80,127, 257}; -static const UInt32 PosHf2[] = {0,0,0,0,0,0,2,7,53,117,233, 257,0}; -static const UInt32 PosHf3[] = {0,0,0,0,0,0,0,2,16,218,251, 257,0}; -static const UInt32 PosHf4[] = {0,0,0,0,0,0,0,0,0,255, 257,0,0}; +static const unsigned kNumBits = 12; -static const UInt32 kHistorySize = (1 << 16); +static const Byte kShortLen1[16 * 3] = +{ + 0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0,0, + 1,3,4,4,5,6,7,8,8,4,4,5,6,6,0,0, + 1,4,4,4,5,6,7,8,8,4,4,5,6,6,4,0 +}; -/* -class CCoderReleaser +static const Byte kShortLen2[16 * 3] = { - CDecoder *m_Coder; -public: - CCoderReleaser(CDecoder *coder): m_Coder(coder) {} - ~CCoderReleaser() { m_Coder->ReleaseStreams(); } + 0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0,0, + 2,3,3,3,4,4,5,6,6,4,4,5,6,6,0,0, + 2,3,3,4,4,4,5,6,6,4,4,5,6,6,4,0 }; -*/ -CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } +static const Byte PosL1[kNumBits + 1] = { 0,0,2,1,2,2,4,5,4,4,8,0,224 }; +static const Byte PosL2[kNumBits + 1] = { 0,0,0,5,2,2,4,5,4,4,8,2,220 }; -void CDecoder::InitStructures() -{ - for (int i = 0; i < kNumRepDists; i++) - m_RepDists[i] = 0; - m_RepDistPtr = 0; - LastLength = 0; - LastDist = 0; -} +static const Byte PosHf0[kNumBits + 1] = { 0,0,0,0,8,8,8,9,0,0,0,0,224 }; +static const Byte PosHf1[kNumBits + 1] = { 0,0,0,0,0,4,40,16,16,4,0,47,130 }; +static const Byte PosHf2[kNumBits + 1] = { 0,0,0,0,0,2,5,46,64,116,24,0,0 }; +static const Byte PosHf3[kNumBits + 1] = { 0,0,0,0,0,0,2,14,202,33,6,0,0 }; +static const Byte PosHf4[kNumBits + 1] = { 0,0,0,0,0,0,0,0,255,2,0,0,0 }; + +static const UInt32 kHistorySize = (1 << 16); + +CDecoder::CDecoder(): + _isSolid(false), + _solidAllowed(false) + { } -UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } +UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numBits); } HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len) { if (len == 0) return S_FALSE; + if (m_UnpackSize < len) + return S_FALSE; m_UnpackSize -= len; return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE; } -UInt32 CDecoder::DecodeNum(const UInt32 *posTab) +UInt32 CDecoder::DecodeNum(const Byte *numTab) { - UInt32 startPos = 2; - UInt32 num = m_InBitStream.GetValue(12); + /* + { + // we can check that tables are correct + UInt32 sum = 0; + for (unsigned i = 0; i <= kNumBits; i++) + sum += ((UInt32)numTab[i] << (kNumBits - i)); + if (sum != (1 << kNumBits)) + throw 111; + } + */ + + UInt32 val = m_InBitStream.GetValue(kNumBits); + UInt32 sum = 0; + unsigned i = 2; + for (;;) { - UInt32 cur = (posTab[(size_t)startPos + 1] - posTab[startPos]) << (12 - startPos); - if (num < cur) + UInt32 num = numTab[i]; + UInt32 cur = num << (kNumBits - i); + if (val < cur) break; - startPos++; - num -= cur; + i++; + val -= cur; + sum += num; } - m_InBitStream.MovePos(startPos); - return((num >> (12 - startPos)) + posTab[startPos]); + m_InBitStream.MovePos(i); + return ((val >> (kNumBits - i)) + sum); } -static const Byte kShortLen1 [] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 }; -static const Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 }; -static const Byte kShortLen2 [] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 }; -static const Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 }; -static const UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; -static const UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; HRESULT CDecoder::ShortLZ() { - UInt32 len, saveLen, dist; - int distancePlace; - const Byte *kShortLen; - const UInt32 *kShortXor; NumHuf = 0; if (LCount == 2) @@ -91,20 +99,14 @@ HRESULT CDecoder::ShortLZ() UInt32 bitField = m_InBitStream.GetValue(8); - if (AvrLn1 < 37) + UInt32 len, dist; { - kShortLen = Buf60 ? kShortLen1a : kShortLen1; - kShortXor = kShortXor1; + const Byte *xors = (AvrLn1 < 37) ? kShortLen1 : kShortLen2; + const Byte *lens = xors + 16 + Buf60; + for (len = 0; ((bitField ^ xors[len]) >> (8 - lens[len])) != 0; len++); + m_InBitStream.MovePos(lens[len]); } - else - { - kShortLen = Buf60 ? kShortLen2a : kShortLen2; - kShortXor = kShortXor2; - } - - for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++); - m_InBitStream.MovePos(kShortLen[len]); - + if (len >= 9) { if (len == 9) @@ -112,9 +114,11 @@ HRESULT CDecoder::ShortLZ() LCount++; return CopyBlock(LastDist, LastLength); } + + LCount = 0; + if (len == 14) { - LCount = 0; len = DecodeNum(PosL2) + 5; dist = 0x8000 + ReadBits(15) - 1; LastLength = len; @@ -122,19 +126,22 @@ HRESULT CDecoder::ShortLZ() return CopyBlock(dist, len); } - LCount = 0; - saveLen = len; + UInt32 saveLen = len; dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3]; - len = DecodeNum(PosL1) + 2; - if (len == 0x101 && saveLen == 10) + + len = DecodeNum(PosL1); + + if (len == 0xff && saveLen == 10) { - Buf60 ^= 1; + Buf60 ^= 16; return S_OK; } if (dist >= 256) + { len++; - if (dist >= MaxDist3 - 1) - len++; + if (dist >= MaxDist3 - 1) + len++; + } } else { @@ -142,21 +149,23 @@ HRESULT CDecoder::ShortLZ() AvrLn1 += len; AvrLn1 -= AvrLn1 >> 4; - distancePlace = DecodeNum(PosHf2) & 0xff; - dist = ChSetA[(unsigned)distancePlace]; - if (--distancePlace != -1) + unsigned distancePlace = DecodeNum(PosHf2) & 0xff; + + dist = ChSetA[distancePlace]; + + if (distancePlace != 0) { PlaceA[dist]--; - UInt32 lastDistance = ChSetA[(unsigned)distancePlace]; + UInt32 lastDistance = ChSetA[(size_t)distancePlace - 1]; PlaceA[lastDistance]++; - ChSetA[(size_t)(unsigned)distancePlace + 1] = lastDistance; - ChSetA[(unsigned)distancePlace] = dist; + ChSetA[distancePlace] = lastDistance; + ChSetA[(size_t)distancePlace - 1] = dist; } - len += 2; } m_RepDists[m_RepDistPtr++] = dist; m_RepDistPtr &= 3; + len += 2; LastLength = len; LastDist = dist; return CopyBlock(dist, len); @@ -177,12 +186,10 @@ HRESULT CDecoder::LongLZ() Nlzb = 0x90; Nhfb >>= 1; } - oldAvr2=AvrLn2; + oldAvr2 = AvrLn2; - if (AvrLn2 >= 122) - len = DecodeNum(PosL2); - else if (AvrLn2 >= 64) - len = DecodeNum(PosL1); + if (AvrLn2 >= 64) + len = DecodeNum(AvrLn2 < 122 ? PosL1 : PosL2); else { UInt32 bitField = m_InBitStream.GetValue(16); @@ -193,8 +200,8 @@ HRESULT CDecoder::LongLZ() } else { - for (len = 0; ((bitField << len) & 0x8000) == 0; len++) - ; + for (len = 0; ((bitField << len) & 0x8000) == 0; len++); + m_InBitStream.MovePos(len + 1); } } @@ -202,24 +209,26 @@ HRESULT CDecoder::LongLZ() AvrLn2 += len; AvrLn2 -= AvrLn2 >> 5; - if (AvrPlcB > 0x28ff) - distancePlace = DecodeNum(PosHf2); - else if (AvrPlcB > 0x6ff) - distancePlace = DecodeNum(PosHf1); - else - distancePlace = DecodeNum(PosHf0); + { + const Byte *tab; + if (AvrPlcB >= 0x2900) tab = PosHf2; + else if (AvrPlcB >= 0x0700) tab = PosHf1; + else tab = PosHf0; + distancePlace = DecodeNum(tab); // [0, 256] + } AvrPlcB += distancePlace; AvrPlcB -= AvrPlcB >> 8; + + distancePlace &= 0xff; for (;;) { - dist = ChSetB[distancePlace & 0xff]; + dist = ChSetB[distancePlace]; newDistancePlace = NToPlB[dist++ & 0xff]++; - if (!(dist & 0xff)) - CorrHuff(ChSetB,NToPlB); - else + if (dist & 0xff) break; + CorrHuff(ChSetB,NToPlB); } ChSetB[distancePlace] = ChSetB[newDistancePlace]; @@ -235,9 +244,8 @@ HRESULT CDecoder::LongLZ() AvrLn3++; AvrLn3 -= AvrLn3 >> 8; } - else - if (AvrLn3 > 0) - AvrLn3--; + else if (AvrLn3 > 0) + AvrLn3--; len += 3; @@ -265,57 +273,62 @@ HRESULT CDecoder::HuffDecode() UInt32 curByte, newBytePlace; UInt32 len; UInt32 dist; - int bytePlace; - - if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4); - else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3); - else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2); - else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1); - else bytePlace = DecodeNum(PosHf0); + unsigned bytePlace; + { + const Byte *tab; + + if (AvrPlc >= 0x7600) tab = PosHf4; + else if (AvrPlc >= 0x5e00) tab = PosHf3; + else if (AvrPlc >= 0x3600) tab = PosHf2; + else if (AvrPlc >= 0x0e00) tab = PosHf1; + else tab = PosHf0; + + bytePlace = DecodeNum(tab); // [0, 256] + } if (StMode) { - if (--bytePlace == -1) + if (bytePlace == 0) { if (ReadBits(1)) { - NumHuf = StMode = 0; + NumHuf = 0; + StMode = false; return S_OK; } - else - { - len = (ReadBits(1)) ? 4 : 3; - dist = DecodeNum(PosHf2); - dist = (dist << 5) | ReadBits(5); - return CopyBlock(dist - 1, len); - } + len = ReadBits(1) + 3; + dist = DecodeNum(PosHf2); + dist = (dist << 5) | ReadBits(5); + if (dist == 0) + return S_FALSE; + return CopyBlock(dist - 1, len); } + bytePlace--; // bytePlace is [0, 255] } else if (NumHuf++ >= 16 && FlagsCnt == 0) - StMode = 1; + StMode = true; bytePlace &= 0xff; AvrPlc += bytePlace; AvrPlc -= AvrPlc >> 8; - Nhfb+=16; + Nhfb += 16; if (Nhfb > 0xff) { - Nhfb=0x90; + Nhfb = 0x90; Nlzb >>= 1; } - m_UnpackSize --; + m_UnpackSize--; m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8)); for (;;) { curByte = ChSet[bytePlace]; newBytePlace = NToPl[curByte++ & 0xff]++; - if ((curByte & 0xff) > 0xa1) - CorrHuff(ChSet, NToPl); - else + if ((curByte & 0xff) <= 0xa1) break; + CorrHuff(ChSet, NToPl); } ChSet[bytePlace] = ChSet[newBytePlace]; @@ -327,7 +340,10 @@ HRESULT CDecoder::HuffDecode() void CDecoder::GetFlagsBuf() { UInt32 flags, newFlagsPlace; - UInt32 flagsPlace = DecodeNum(PosHf2); + UInt32 flagsPlace = DecodeNum(PosHf2); // [0, 256] + + if (flagsPlace >= ARRAY_SIZE(ChSetC)) + return; for (;;) { @@ -343,20 +359,6 @@ void CDecoder::GetFlagsBuf() ChSetC[newFlagsPlace] = flags; } -void CDecoder::InitData() -{ - if (!m_IsSolid) - { - AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; - AvrPlc = 0x3500; - MaxDist3 = 0x2001; - Nhfb = Nlzb = 0x80; - } - FlagsCnt = 0; - FlagBuf = 0; - StMode = 0; - LCount = 0; -} void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace) { @@ -369,129 +371,145 @@ void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace) NumToPlace[i] = (7 - i) * 32; } -void CDecoder::InitHuff() -{ - for (UInt32 i = 0; i < 256; i++) - { - Place[i] = PlaceA[i] = PlaceB[i] = i; - PlaceC[i] = (~i + 1) & 0xff; - ChSet[i] = ChSetB[i] = i << 8; - ChSetA[i] = i; - ChSetC[i] = ((~i + 1) & 0xff) << 8; - } - memset(NToPl, 0, sizeof(NToPl)); - memset(NToPlB, 0, sizeof(NToPlB)); - memset(NToPlC, 0, sizeof(NToPlC)); - CorrHuff(ChSetB, NToPlB); -} + HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /* progress */) { - if (inSize == NULL || outSize == NULL) + if (!inSize || !outSize) return E_INVALIDARG; + if (_isSolid && !_solidAllowed) + return S_FALSE; + + _solidAllowed = false; + if (!m_OutWindowStream.Create(kHistorySize)) return E_OUTOFMEMORY; if (!m_InBitStream.Create(1 << 20)) return E_OUTOFMEMORY; - m_UnpackSize = (Int64)*outSize; + m_UnpackSize = *outSize; + m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(m_IsSolid); + m_OutWindowStream.Init(_isSolid); m_InBitStream.SetStream(inStream); m_InBitStream.Init(); - // CCoderReleaser coderReleaser(this); - InitData(); - if (!m_IsSolid) + // InitData + + FlagsCnt = 0; + FlagBuf = 0; + StMode = false; + LCount = 0; + + if (!_isSolid) { - _errorMode = false; - InitStructures(); - InitHuff(); - } - - if (_errorMode) - return S_FALSE; + AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; + AvrPlc = 0x3500; + MaxDist3 = 0x2001; + Nhfb = Nlzb = 0x80; + + { + // InitStructures + for (int i = 0; i < kNumRepDists; i++) + m_RepDists[i] = 0; + m_RepDistPtr = 0; + LastLength = 0; + LastDist = 0; + } + + // InitHuff + for (UInt32 i = 0; i < 256; i++) + { + Place[i] = PlaceA[i] = PlaceB[i] = i; + UInt32 c = (~i + 1) & 0xff; + PlaceC[i] = c; + ChSet[i] = ChSetB[i] = i << 8; + ChSetA[i] = i; + ChSetC[i] = c << 8; + } + memset(NToPl, 0, sizeof(NToPl)); + memset(NToPlB, 0, sizeof(NToPlB)); + memset(NToPlC, 0, sizeof(NToPlC)); + CorrHuff(ChSetB, NToPlB); + } + if (m_UnpackSize > 0) { GetFlagsBuf(); FlagsCnt = 8; } - while (m_UnpackSize > 0) + while (m_UnpackSize != 0) { - if (StMode) + if (!StMode) { - RINOK(HuffDecode()); - continue; - } - - if (--FlagsCnt < 0) - { - GetFlagsBuf(); - FlagsCnt=7; - } - - if (FlagBuf & 0x80) - { - FlagBuf <<= 1; - if (Nlzb > Nhfb) - { - RINOK(LongLZ()); - } - else - { - RINOK(HuffDecode()); - } - } - else - { - FlagBuf <<= 1; if (--FlagsCnt < 0) { GetFlagsBuf(); FlagsCnt = 7; } + if (FlagBuf & 0x80) { FlagBuf <<= 1; if (Nlzb > Nhfb) { - RINOK(HuffDecode()); - } - else - { RINOK(LongLZ()); + continue; } } else { FlagBuf <<= 1; - RINOK(ShortLZ()); + + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt = 7; + } + + if ((FlagBuf & 0x80) == 0) + { + FlagBuf <<= 1; + RINOK(ShortLZ()); + continue; + } + + FlagBuf <<= 1; + + if (Nlzb <= Nhfb) + { + RINOK(LongLZ()); + continue; + } } } + + RINOK(HuffDecode()); } - if (m_UnpackSize < 0) - return S_FALSE; + + _solidAllowed = true; return m_OutWindowStream.Flush(); } + STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } - catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; } - catch(...) { _errorMode = true; return S_FALSE; } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } } STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) { if (size < 1) return E_INVALIDARG; - m_IsSolid = ((data[0] & 1) != 0); + _isSolid = ((data[0] & 1) != 0); return S_OK; } diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h index 01b606b3..52907e5c 100644 --- a/CPP/7zip/Compress/Rar1Decoder.h +++ b/CPP/7zip/Compress/Rar1Decoder.h @@ -20,49 +20,45 @@ namespace NRar1 { const UInt32 kNumRepDists = 4; -typedef NBitm::CDecoder<CInBuffer> CBitDecoder; - class CDecoder : public ICompressCoder, public ICompressSetDecoderProperties2, public CMyUnknownImp { -public: CLzOutWindow m_OutWindowStream; - CBitDecoder m_InBitStream; + NBitm::CDecoder<CInBuffer> m_InBitStream; - UInt32 m_RepDists[kNumRepDists]; - UInt32 m_RepDistPtr; + UInt64 m_UnpackSize; UInt32 LastDist; UInt32 LastLength; - Int64 m_UnpackSize; - bool m_IsSolid; - bool _errorMode; + UInt32 m_RepDistPtr; + UInt32 m_RepDists[kNumRepDists]; - UInt32 ReadBits(int numBits); - HRESULT CopyBlock(UInt32 distance, UInt32 len); + bool _isSolid; + bool _solidAllowed; - UInt32 DecodeNum(const UInt32 *posTab); + bool StMode; + int FlagsCnt; + UInt32 FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3; + unsigned Buf60, NumHuf, LCount; + UInt32 Nhfb, Nlzb, MaxDist3; + + UInt32 ChSet[256], ChSetA[256], ChSetB[256], ChSetC[256]; + UInt32 Place[256], PlaceA[256], PlaceB[256], PlaceC[256]; + UInt32 NToPl[256], NToPlB[256], NToPlC[256]; + + UInt32 ReadBits(unsigned numBits); + HRESULT CopyBlock(UInt32 distance, UInt32 len); + UInt32 DecodeNum(const Byte *numTab); HRESULT ShortLZ(); HRESULT LongLZ(); HRESULT HuffDecode(); void GetFlagsBuf(); - void InitData(); - void InitHuff(); void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace); void OldUnpWriteBuf(); - UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256]; - UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256]; - UInt32 NToPl[256],NToPlB[256],NToPlC[256]; - UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3; - int Buf60,NumHuf,StMode,LCount,FlagsCnt; - UInt32 Nhfb,Nlzb,MaxDist3; - - void InitStructures(); - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); @@ -71,14 +67,6 @@ public: MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - /* - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - } - */ - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp index 1488444e..fe458c85 100644 --- a/CPP/7zip/Compress/Rar2Decoder.cpp +++ b/CPP/7zip/Compress/Rar2Decoder.cpp @@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20; static const UInt32 kWindowReservSize = (1 << 22) + 256; CDecoder::CDecoder(): - m_IsSolid(false), + _isSolid(false), + _solidAllowed(false), m_TablesOK(false) { } @@ -227,18 +228,6 @@ bool CDecoder::ReadLastTables() return true; } -/* -class CCoderReleaser -{ - CDecoder *m_Coder; -public: - CCoderReleaser(CDecoder *coder): m_Coder(coder) {} - ~CCoderReleaser() - { - m_Coder->ReleaseStreams(); - } -}; -*/ bool CDecoder::DecodeMm(UInt32 pos) { @@ -343,9 +332,13 @@ bool CDecoder::DecodeLz(Int32 pos) HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - if (inSize == NULL || outSize == NULL) + if (!inSize || !outSize) return E_INVALIDARG; + if (_isSolid && !_solidAllowed) + return S_FALSE; + _solidAllowed = false; + if (!m_OutWindowStream.Create(kHistorySize)) return E_OUTOFMEMORY; if (!m_InBitStream.Create(1 << 20)) @@ -356,12 +349,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * UInt64 pos = 0, unPackSize = *outSize; m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(m_IsSolid); + m_OutWindowStream.Init(_isSolid); m_InBitStream.SetStream(inStream); m_InBitStream.Init(); // CCoderReleaser coderReleaser(this); - if (!m_IsSolid) + if (!_isSolid) { InitStructures(); if (unPackSize == 0) @@ -369,6 +362,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; if (!ReadTables()) return S_FALSE; + _solidAllowed = true; return S_OK; } ReadTables(); @@ -415,6 +409,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * if (!ReadLastTables()) return S_FALSE; + + _solidAllowed = true; + return m_OutWindowStream.Flush(); } @@ -431,7 +428,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) { if (size < 1) return E_INVALIDARG; - m_IsSolid = ((data[0] & 1) != 0); + _isSolid = ((data[0] & 1) != 0); return S_OK; } diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h index 0d8142b5..f42f228d 100644 --- a/CPP/7zip/Compress/Rar2Decoder.h +++ b/CPP/7zip/Compress/Rar2Decoder.h @@ -125,7 +125,8 @@ class CDecoder : UInt32 m_LastLength; - bool m_IsSolid; + bool _isSolid; + bool _solidAllowed; bool m_TablesOK; bool m_AudioMode; @@ -159,14 +160,6 @@ public: MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - /* - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - } - */ - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp index 4da89a65..10e8bff6 100644 --- a/CPP/7zip/Compress/Rar3Decoder.cpp +++ b/CPP/7zip/Compress/Rar3Decoder.cpp @@ -94,8 +94,8 @@ CDecoder::CDecoder(): _writtenFileSize(0), _vmData(0), _vmCode(0), - m_IsSolid(false), - _errorMode(false) + _isSolid(false), + _solidAllowed(false) { Ppmd7_Construct(&_ppmd); } @@ -829,7 +829,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) _writtenFileSize = 0; _unsupportedFilter = false; - if (!m_IsSolid) + if (!_isSolid) { _lzSize = 0; _winPos = 0; @@ -842,18 +842,23 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) PpmEscChar = 2; PpmError = true; InitFilters(); - _errorMode = false; + // _errorMode = false; } + /* if (_errorMode) return S_FALSE; + */ - if (!m_IsSolid || !TablesRead) + if (!_isSolid || !TablesRead) { bool keepDecompressing; RINOK(ReadTables(keepDecompressing)); if (!keepDecompressing) + { + _solidAllowed = true; return S_OK; + } } for (;;) @@ -878,6 +883,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) if (!keepDecompressing) break; } + + _solidAllowed = true; + RINOK(WriteBuf()); UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); @@ -898,6 +906,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream if (!inSize) return E_INVALIDARG; + if (_isSolid && !_solidAllowed) + return S_FALSE; + _solidAllowed = false; + if (!_vmData) { _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); @@ -926,8 +938,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1; return CodeReal(progress); } - catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } - catch(...) { _errorMode = true; return S_FALSE; } + catch(const CInBufferException &e) { /* _errorMode = true; */ return e.ErrorCode; } + catch(...) { /* _errorMode = true; */ return S_FALSE; } // CNewException is possible here. But probably CNewException is caused // by error in data stream. } @@ -936,7 +948,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) { if (size < 1) return E_INVALIDARG; - m_IsSolid = ((data[0] & 1) != 0); + _isSolid = ((data[0] & 1) != 0); return S_OK; } diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h index f3c1528c..fbc5ac2e 100644 --- a/CPP/7zip/Compress/Rar3Decoder.h +++ b/CPP/7zip/Compress/Rar3Decoder.h @@ -191,8 +191,9 @@ class CDecoder: CRecordVector<CTempFilter *> _tempFilters; UInt32 _lastFilter; - bool m_IsSolid; - bool _errorMode; + bool _isSolid; + bool _solidAllowed; + // bool _errorMode; bool _lzMode; bool _unsupportedFilter; diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp index e6c3e467..d7c68e21 100644 --- a/CPP/7zip/Compress/Rar5Decoder.cpp +++ b/CPP/7zip/Compress/Rar5Decoder.cpp @@ -72,6 +72,7 @@ CDecoder::CDecoder(): _writtenFileSize(0), _dictSizeLog(0), _isSolid(false), + _solidAllowed(false), _wasInit(false), _inputBuf(NULL) { @@ -334,58 +335,63 @@ HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream) { if (_progress) { - UInt64 packSize = _bitStream.GetProcessedSize(); + const UInt64 packSize = _bitStream.GetProcessedSize(); RINOK(_progress->SetRatioInfo(&packSize, &_writtenFileSize)); } _bitStream.AlignToByte(); _bitStream.Prepare(); - unsigned flags = _bitStream.ReadByteInAligned(); - unsigned checkSum = _bitStream.ReadByteInAligned(); - checkSum ^= flags; - - UInt32 blockSize; { + unsigned flags = _bitStream.ReadByteInAligned(); + unsigned checkSum = _bitStream.ReadByteInAligned(); + checkSum ^= flags; unsigned num = (flags >> 3) & 3; if (num == 3) return S_FALSE; - blockSize = _bitStream.ReadByteInAligned(); - if (num > 0) + UInt32 blockSize = _bitStream.ReadByteInAligned(); + checkSum ^= blockSize; + + if (num != 0) { - blockSize += (UInt32)_bitStream.ReadByteInAligned() << 8; + unsigned b = _bitStream.ReadByteInAligned(); + checkSum ^= b; + blockSize += (UInt32)b << 8; if (num > 1) - blockSize += (UInt32)_bitStream.ReadByteInAligned() << 16; + { + b = _bitStream.ReadByteInAligned(); + checkSum ^= b; + blockSize += (UInt32)b << 16; + } } - } - - checkSum ^= blockSize ^ (blockSize >> 8) ^ (blockSize >> 16); - if ((Byte)checkSum != 0x5A) - return S_FALSE; - - unsigned blockSizeBits7 = (flags & 7) + 1; - - if (blockSize == 0 && blockSizeBits7 != 8) - return S_FALSE; - - blockSize += (blockSizeBits7 >> 3); - blockSize--; - - _bitStream._blockEndBits7 = (Byte)(blockSizeBits7 & 7); - _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize; - - _bitStream.SetCheck2(); - - _isLastBlock = ((flags & 0x40) != 0); + + if (checkSum != 0x5A) + return S_FALSE; - if ((flags & 0x80) == 0) - { - if (!_tableWasFilled && blockSize != 0) + unsigned blockSizeBits7 = (flags & 7) + 1; + blockSize += (blockSizeBits7 >> 3); + if (blockSize == 0) return S_FALSE; - return S_OK; - } + blockSize--; + blockSizeBits7 &= 7; - _tableWasFilled = false; + _bitStream._blockEndBits7 = (Byte)blockSizeBits7; + _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize; + + _bitStream.SetCheck2(); + + _isLastBlock = ((flags & 0x40) != 0); + + if ((flags & 0x80) == 0) + { + if (!_tableWasFilled) + if (blockSize != 0 || blockSizeBits7 != 0) + return S_FALSE; + return S_OK; + } + + _tableWasFilled = false; + } { Byte lens2[kLevelTableSize]; @@ -596,6 +602,10 @@ HRESULT CDecoder::DecodeLZ() } } } + + // that check is not required, but it can help, if there is BUG in another code + if (!_tableWasFilled) + break; // return S_FALSE; } UInt32 sym = m_MainDecoder.Decode(&_bitStream); @@ -797,7 +807,10 @@ HRESULT CDecoder::CodeReal() */ if (res == S_OK) + { + _solidAllowed = true; res = res2; + } if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize) return S_FALSE; @@ -817,6 +830,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream { try { + if (_isSolid && !_solidAllowed) + return S_FALSE; + _solidAllowed = false; + if (_dictSizeLog >= sizeof(size_t) * 8) return E_NOTIMPL; diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h index c37cb0e0..8174c4af 100644 --- a/CPP/7zip/Compress/Rar5Decoder.h +++ b/CPP/7zip/Compress/Rar5Decoder.h @@ -127,7 +127,7 @@ public: return *_buf++; } - UInt32 GetValue(unsigned numBits) + UInt32 GetValue(unsigned numBits) const { UInt32 v = ((UInt32)_buf[0] << 16) | ((UInt32)_buf[1] << 8) | (UInt32)_buf[2]; v >>= (24 - numBits - _bitPos); @@ -218,6 +218,13 @@ class CDecoder: bool _unsupportedFilter; bool _lzError; bool _writeError; + + bool _isSolid; + bool _solidAllowed; + bool _tableWasFilled; + bool _wasInit; + + Byte _dictSizeLog; // CBitDecoder _bitStream; Byte *_window; @@ -238,11 +245,6 @@ class CDecoder: UInt64 _writtenFileSize; size_t _winSizeAllocated; - Byte _dictSizeLog; - bool _tableWasFilled; - bool _isSolid; - bool _wasInit; - UInt32 _reps[kNumReps]; UInt32 _lastLen; diff --git a/CPP/7zip/Crypto/Rar5Aes.cpp b/CPP/7zip/Crypto/Rar5Aes.cpp index dc1f4ce6..005fa6bc 100644 --- a/CPP/7zip/Crypto/Rar5Aes.cpp +++ b/CPP/7zip/Crypto/Rar5Aes.cpp @@ -30,14 +30,13 @@ CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {} static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val) { - unsigned i; *val = 0; - for (i = 0; i < maxSize;) + for (unsigned i = 0; i < maxSize && i < 10;) { Byte b = p[i]; - if (i < 10) - *val |= (UInt64)(b & 0x7F) << (7 * i++); + *val |= (UInt64)(b & 0x7F) << (7 * i); + i++; if ((b & 0x80) == 0) return i; } diff --git a/CPP/7zip/GuiCommon.rc b/CPP/7zip/GuiCommon.rc index 6b26ddd8..b67409b9 100644 --- a/CPP/7zip/GuiCommon.rc +++ b/CPP/7zip/GuiCommon.rc @@ -71,6 +71,9 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \ PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +#define MY_BUTTON__CLOSE \ + DEFPUSHBUTTON "&Close", IDCLOSE, bx1, by, bxs, bys + #define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP #define MY_COMBO_SORTED MY_COMBO | CBS_SORT diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index 56f4fbd8..c0a7bcd0 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -8,9 +8,17 @@ #ifndef UNDER_CE #include <io.h> #endif +#else +// for isatty() +#include <unistd.h> #endif + #include <stdio.h> +#ifdef _7ZIP_LARGE_PAGES +#include "../../../../C/Alloc.h" +#endif + #include "../../../Common/ListFileUtils.h" #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" @@ -19,18 +27,20 @@ #include "../../../Windows/FileName.h" #ifdef _WIN32 #include "../../../Windows/FileMapping.h" +#include "../../../Windows/MemoryLock.h" #include "../../../Windows/Synchronization.h" #endif #include "ArchiveCommandLine.h" #include "EnumDirItems.h" -#include "SortUtils.h" #include "Update.h" #include "UpdateAction.h" extern bool g_CaseSensitive; extern bool g_PathTrailReplaceMode; +bool g_LargePagesMode = false; + #ifdef UNDER_CE #define MY_IS_TERMINAL(x) false; @@ -60,15 +70,6 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v) return *end == 0; } -CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u) -{ - (*this) += a; - if (u) - { - Add_LF(); - (*this) += u; - } -} int g_CodePage = -1; @@ -240,7 +241,7 @@ static const CSwitchForm kSwitchForms[] = { "si", NSwitchType::kString }, { "so" }, - { "slp", NSwitchType::kMinus }, + { "slp", NSwitchType::kString }, { "scs", NSwitchType::kString }, { "scc", NSwitchType::kString }, { "slt" }, @@ -282,7 +283,6 @@ static const char * const kIncorrectListFile = "Incorrect item in listfile.\nChe static const char * const kTerminalOutError = "I won't write compressed data to a terminal"; static const char * const kSameTerminalError = "I won't write data and program's messages to same stream"; static const char * const kEmptyFilePath = "Empty file path"; -static const char * const kCannotFindArchive = "Cannot find archive"; bool CArcCommand::IsFromExtractGroup() const { @@ -615,84 +615,6 @@ static void AddSwitchWildcardsToCensor( throw CArcCmdLineException(errorMessage, strings[i]); } -#ifdef _WIN32 - -// This code converts all short file names to long file names. - -static void ConvertToLongName(const UString &prefix, UString &name) -{ - if (name.IsEmpty() || DoesNameContainWildcard(name)) - return; - NFind::CFileInfo fi; - const FString path (us2fs(prefix + name)); - #ifndef UNDER_CE - if (NFile::NName::IsDevicePath(path)) - return; - #endif - if (fi.Find(path)) - name = fs2us(fi.Name); -} - -static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items) -{ - FOR_VECTOR (i, items) - { - NWildcard::CItem &item = items[i]; - if (item.Recursive || item.PathParts.Size() != 1) - continue; - if (prefix.IsEmpty() && item.IsDriveItem()) - continue; - ConvertToLongName(prefix, item.PathParts.Front()); - } -} - -static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) -{ - ConvertToLongNames(prefix, node.IncludeItems); - ConvertToLongNames(prefix, node.ExcludeItems); - unsigned i; - for (i = 0; i < node.SubNodes.Size(); i++) - { - UString &name = node.SubNodes[i].Name; - if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name)) - continue; - ConvertToLongName(prefix, name); - } - // mix folders with same name - for (i = 0; i < node.SubNodes.Size(); i++) - { - NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; - for (unsigned j = i + 1; j < node.SubNodes.Size();) - { - const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; - if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name)) - { - nextNode1.IncludeItems += nextNode2.IncludeItems; - nextNode1.ExcludeItems += nextNode2.ExcludeItems; - node.SubNodes.Delete(j); - } - else - j++; - } - } - for (i = 0; i < node.SubNodes.Size(); i++) - { - NWildcard::CCensorNode &nextNode = node.SubNodes[i]; - ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode); - } -} - -void ConvertToLongNames(NWildcard::CCensor &censor) -{ - FOR_VECTOR (i, censor.Pairs) - { - NWildcard::CPair &pair = censor.Pairs[i]; - ConvertToLongNames(pair.Prefix, pair.Head); - } -} - -#endif - /* static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) { @@ -922,9 +844,45 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, options.CaseSensitive = g_CaseSensitive; } - options.LargePages = false; + + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_SymLink(); + #endif + + // options.LargePages = false; + if (parser[NKey::kLargePages].ThereIs) - options.LargePages = !parser[NKey::kLargePages].WithMinus; + { + unsigned slp = 0; + const UString &s = parser[NKey::kLargePages].PostStrings[0]; + if (s.IsEmpty()) + slp = 1; + else if (s != L"-") + { + if (!StringToUInt32(s, slp)) + throw CArcCmdLineException("Unsupported switch postfix for -slp", s); + } + + #ifdef _7ZIP_LARGE_PAGES + if (slp > + #ifndef UNDER_CE + (unsigned)NSecurity::Get_LargePages_RiskLevel() + #else + 0 + #endif + ) + { + SetLargePageSize(); + // note: this process also can inherit that Privilege from parent process + g_LargePagesMode = + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_LockMemory(); + #else + true; + #endif + } + #endif + } #ifndef UNDER_CE @@ -996,64 +954,6 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key } } -HRESULT EnumerateDirItemsAndSort( - NWildcard::CCensor &censor, - NWildcard::ECensorPathMode censorPathMode, - const UString &addPathPrefix, - UStringVector &sortedPaths, - UStringVector &sortedFullPaths, - CDirItemsStat &st, - IDirItemsCallback *callback) -{ - FStringVector paths; - - { - CDirItems dirItems; - dirItems.Callback = callback; - { - HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); - st = dirItems.Stat; - RINOK(res); - } - - FOR_VECTOR (i, dirItems.Items) - { - const CDirItem &dirItem = dirItems.Items[i]; - if (!dirItem.IsDir()) - paths.Add(dirItems.GetPhyPath(i)); - } - } - - if (paths.Size() == 0) - throw CArcCmdLineException(kCannotFindArchive); - - UStringVector fullPaths; - - unsigned i; - - for (i = 0; i < paths.Size(); i++) - { - FString fullPath; - NFile::NDir::MyGetFullPathName(paths[i], fullPath); - fullPaths.Add(fs2us(fullPath)); - } - - CUIntVector indices; - SortFileNames(fullPaths, indices); - sortedPaths.ClearAndReserve(indices.Size()); - sortedFullPaths.ClearAndReserve(indices.Size()); - - for (i = 0; i < indices.Size(); i++) - { - unsigned index = indices[i]; - sortedPaths.AddInReserved(fs2us(paths[index])); - sortedFullPaths.AddInReserved(fullPaths[index]); - if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0) - throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]); - } - - return S_OK; -} static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp) { diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h index 1c96601a..9ed0825f 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.h +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h @@ -6,14 +6,13 @@ #include "../../../Common/CommandLineParser.h" #include "../../../Common/Wildcard.h" +#include "EnumDirItems.h" + #include "Extract.h" #include "HashCalc.h" #include "Update.h" -struct CArcCmdLineException: public UString -{ - CArcCmdLineException(const char *a, const wchar_t *u = NULL); -}; +typedef CMessagePathException CArcCmdLineException; namespace NCommandType { enum EEnum { @@ -51,7 +50,7 @@ struct CArcCmdLineOptions { bool HelpMode; - bool LargePages; + // bool LargePages; bool CaseSensitiveChange; bool CaseSensitive; @@ -110,7 +109,7 @@ struct CArcCmdLineOptions UInt32 NumIterations; CArcCmdLineOptions(): - LargePages(false), + // LargePages(false), CaseSensitiveChange(false), CaseSensitive(false), @@ -134,13 +133,4 @@ public: void Parse2(CArcCmdLineOptions &options); }; -HRESULT EnumerateDirItemsAndSort( - NWildcard::CCensor &censor, - NWildcard::ECensorPathMode pathMode, - const UString &addPathPrefix, - UStringVector &sortedPaths, - UStringVector &sortedFullPaths, - CDirItemsStat &st, - IDirItemsCallback *callback); - #endif diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp index e4ac64ec..e86db15d 100644 --- a/CPP/7zip/UI/Common/Bench.cpp +++ b/CPP/7zip/UI/Common/Bench.cpp @@ -2602,7 +2602,8 @@ static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si) PrintHex(s, si.wProcessorLevel); s += "."; PrintHex(s, si.wProcessorRevision); - if (si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors)) + if ((UInt64)si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors)) + if ((UInt64)si.dwActiveProcessorMask + 1 != 0 || si.dwNumberOfProcessors != sizeof(UInt64) * 8) { s += " act:"; PrintHex(s, si.dwActiveProcessorMask); @@ -2686,13 +2687,15 @@ void GetCpuName(AString &s) AString s2; x86cpuid_to_String(cpuid, s2); s += s2; - return; } + else + { #ifdef MY_CPU_AMD64 s += "x64"; #else s += "x86"; #endif + } } #else @@ -2703,6 +2706,9 @@ void GetCpuName(AString &s) #endif #endif + + if (g_LargePagesMode) + s += " (LP)"; } @@ -2725,6 +2731,27 @@ void GetCpuFeatures(AString &s) } +#ifdef _WIN32 +#ifndef UNDER_CE + +typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *); + +static BOOL My_RtlGetVersion(OSVERSIONINFOEXW *vi) +{ + HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); + if (!ntdll) + return FALSE; + Func_RtlGetVersion func = (Func_RtlGetVersion)GetProcAddress(ntdll, "RtlGetVersion"); + if (!func) + return FALSE; + func(vi); + return TRUE; +} + +#endif +#endif + + HRESULT Bench( DECL_EXTERNAL_CODECS_LOC_VARS IBenchPrintCallback *printCallback, @@ -2859,6 +2886,30 @@ HRESULT Bench( if (printCallback) { + #ifdef _WIN32 + #ifndef UNDER_CE + { + AString s; + // OSVERSIONINFO vi; + OSVERSIONINFOEXW vi; + vi.dwOSVersionInfoSize = sizeof(vi); + // if (::GetVersionEx(&vi)) + if (My_RtlGetVersion(&vi)) + { + s += "Windows"; + if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) + s.Add_UInt32(vi.dwPlatformId); + s += " "; s.Add_UInt32(vi.dwMajorVersion); + s += "."; s.Add_UInt32(vi.dwMinorVersion); + s += " "; s.Add_UInt32(vi.dwBuildNumber); + // s += " "; s += GetAnsiString(vi.szCSDVersion); + } + printCallback->Print(s); + printCallback->NewLine(); + } + #endif + #endif + { AString s1, s2; GetSysInfo(s1, s2); diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp index c9aa5fdf..42cb0d23 100644 --- a/CPP/7zip/UI/Common/CompressCall.cpp +++ b/CPP/7zip/UI/Common/CompressCall.cpp @@ -13,6 +13,7 @@ #include "../../../Windows/ErrorMsg.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileMapping.h" +#include "../../../Windows/MemoryLock.h" #include "../../../Windows/ProcessUtils.h" #include "../../../Windows/Synchronization.h" @@ -94,6 +95,9 @@ static HRESULT Call7zGui(const UString ¶ms, static void AddLagePagesSwitch(UString ¶ms) { if (ReadLockMemoryEnable()) + #ifndef UNDER_CE + if (NSecurity::Get_LargePages_RiskLevel() == 0) + #endif params += " -slp"; } diff --git a/CPP/7zip/UI/Common/CompressCall2.cpp b/CPP/7zip/UI/Common/CompressCall2.cpp index fb67ed12..5bad774b 100644 --- a/CPP/7zip/UI/Common/CompressCall2.cpp +++ b/CPP/7zip/UI/Common/CompressCall2.cpp @@ -1,10 +1,10 @@ -// CompressCall.cpp +// CompressCall2.cpp #include "StdAfx.h" #include "../../../Common/MyException.h" -#include "../../UI/common/ArchiveCommandLine.h" +#include "../../UI/Common/EnumDirItems.h" #include "../../UI/GUI/BenchmarkDialog.h" #include "../../UI/GUI/ExtractGUI.h" @@ -20,6 +20,7 @@ extern HWND g_HWND; #define MY_TRY_BEGIN HRESULT result; try { #define MY_TRY_FINISH } \ catch(CSystemException &e) { result = e.ErrorCode; } \ + catch(UString &s) { ErrorMessage(s); result = E_FAIL; } \ catch(...) { result = E_FAIL; } \ if (result != S_OK && result != E_ABORT) \ ErrorMessageHRESULT(result); diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp index 0eee7443..0828dfbc 100644 --- a/CPP/7zip/UI/Common/EnumDirItems.cpp +++ b/CPP/7zip/UI/Common/EnumDirItems.cpp @@ -16,6 +16,7 @@ #endif #include "EnumDirItems.h" +#include "SortUtils.h" using namespace NWindows; using namespace NFile; @@ -925,3 +926,161 @@ void CDirItems::FillFixedReparse() } #endif + + + +static const char * const kCannotFindArchive = "Cannot find archive"; + +HRESULT EnumerateDirItemsAndSort( + NWildcard::CCensor &censor, + NWildcard::ECensorPathMode censorPathMode, + const UString &addPathPrefix, + UStringVector &sortedPaths, + UStringVector &sortedFullPaths, + CDirItemsStat &st, + IDirItemsCallback *callback) +{ + FStringVector paths; + + { + CDirItems dirItems; + dirItems.Callback = callback; + { + HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); + st = dirItems.Stat; + RINOK(res); + } + + FOR_VECTOR (i, dirItems.Items) + { + const CDirItem &dirItem = dirItems.Items[i]; + if (!dirItem.IsDir()) + paths.Add(dirItems.GetPhyPath(i)); + } + } + + if (paths.Size() == 0) + { + // return S_OK; + throw CMessagePathException(kCannotFindArchive); + } + + UStringVector fullPaths; + + unsigned i; + + for (i = 0; i < paths.Size(); i++) + { + FString fullPath; + NFile::NDir::MyGetFullPathName(paths[i], fullPath); + fullPaths.Add(fs2us(fullPath)); + } + + CUIntVector indices; + SortFileNames(fullPaths, indices); + sortedPaths.ClearAndReserve(indices.Size()); + sortedFullPaths.ClearAndReserve(indices.Size()); + + for (i = 0; i < indices.Size(); i++) + { + unsigned index = indices[i]; + sortedPaths.AddInReserved(fs2us(paths[index])); + sortedFullPaths.AddInReserved(fullPaths[index]); + if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0) + throw CMessagePathException("Duplicate archive path:", sortedFullPaths[i]); + } + + return S_OK; +} + + + + +#ifdef _WIN32 + +// This code converts all short file names to long file names. + +static void ConvertToLongName(const UString &prefix, UString &name) +{ + if (name.IsEmpty() || DoesNameContainWildcard(name)) + return; + NFind::CFileInfo fi; + const FString path (us2fs(prefix + name)); + #ifndef UNDER_CE + if (NFile::NName::IsDevicePath(path)) + return; + #endif + if (fi.Find(path)) + name = fs2us(fi.Name); +} + +static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items) +{ + FOR_VECTOR (i, items) + { + NWildcard::CItem &item = items[i]; + if (item.Recursive || item.PathParts.Size() != 1) + continue; + if (prefix.IsEmpty() && item.IsDriveItem()) + continue; + ConvertToLongName(prefix, item.PathParts.Front()); + } +} + +static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) +{ + ConvertToLongNames(prefix, node.IncludeItems); + ConvertToLongNames(prefix, node.ExcludeItems); + unsigned i; + for (i = 0; i < node.SubNodes.Size(); i++) + { + UString &name = node.SubNodes[i].Name; + if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name)) + continue; + ConvertToLongName(prefix, name); + } + // mix folders with same name + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; + for (unsigned j = i + 1; j < node.SubNodes.Size();) + { + const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; + if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name)) + { + nextNode1.IncludeItems += nextNode2.IncludeItems; + nextNode1.ExcludeItems += nextNode2.ExcludeItems; + node.SubNodes.Delete(j); + } + else + j++; + } + } + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode = node.SubNodes[i]; + ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode); + } +} + +void ConvertToLongNames(NWildcard::CCensor &censor) +{ + FOR_VECTOR (i, censor.Pairs) + { + NWildcard::CPair &pair = censor.Pairs[i]; + ConvertToLongNames(pair.Prefix, pair.Head); + } +} + +#endif + + +CMessagePathException::CMessagePathException(const char *a, const wchar_t *u) +{ + (*this) += a; + if (u) + { + Add_LF(); + (*this) += u; + } +} diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h index 7afb800a..37ebed4c 100644 --- a/CPP/7zip/UI/Common/EnumDirItems.h +++ b/CPP/7zip/UI/Common/EnumDirItems.h @@ -18,4 +18,24 @@ HRESULT EnumerateItems( const UString &addPathPrefix, CDirItems &dirItems); + +struct CMessagePathException: public UString +{ + CMessagePathException(const char *a, const wchar_t *u = NULL); +}; + + +HRESULT EnumerateDirItemsAndSort( + NWildcard::CCensor &censor, + NWildcard::ECensorPathMode pathMode, + const UString &addPathPrefix, + UStringVector &sortedPaths, + UStringVector &sortedFullPaths, + CDirItemsStat &st, + IDirItemsCallback *callback); + +#ifdef _WIN32 +void ConvertToLongNames(NWildcard::CCensor &censor); +#endif + #endif diff --git a/CPP/7zip/UI/Common/HashCalc.h b/CPP/7zip/UI/Common/HashCalc.h index 38908e2e..3b4ec30d 100644 --- a/CPP/7zip/UI/Common/HashCalc.h +++ b/CPP/7zip/UI/Common/HashCalc.h @@ -9,7 +9,6 @@ #include "../../Common/MethodProps.h" #include "DirItem.h" -#include "Property.h" const unsigned k_HashCalc_DigestSize_Max = 64; diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp index b9b4abd9..11d512ae 100644 --- a/CPP/7zip/UI/Common/OpenArchive.cpp +++ b/CPP/7zip/UI/Common/OpenArchive.cpp @@ -992,7 +992,7 @@ static void MakeCheckOrder(CCodecs *codecs, int index = orderIndices[i]; if (index < 0) continue; - const CArcInfoEx &ai = codecs->Formats[index]; + const CArcInfoEx &ai = codecs->Formats[(unsigned)index]; if (ai.SignatureOffset != 0) { orderIndices2.Add(index); @@ -2295,7 +2295,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) int index = orderIndices[i]; if (index < 0) continue; - const CArcInfoEx &ai = op.codecs->Formats[index]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; bool isDifficult = false; // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31) if (!ai.NewInterface) @@ -2327,7 +2327,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) if (isDifficult) { difficultFormats.Add(index); - difficultBools[index] = true; + difficultBools[(unsigned)index] = true; } } diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp index 8a194840..7702e222 100644 --- a/CPP/7zip/UI/Common/PropIDUtils.cpp +++ b/CPP/7zip/UI/Common/PropIDUtils.cpp @@ -369,7 +369,7 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) int index = FindPairIndex(sid_32_Names, ARRAY_SIZE(sid_32_Names), v1); if (index >= 0) { - s += sid_32_Names[index].sz; + s += sid_32_Names[(unsigned)index].sz; return; } } @@ -379,7 +379,7 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) int index = FindPairIndex(sid_21_Names, ARRAY_SIZE(sid_21_Names), v4); if (index >= 0) { - s += sid_21_Names[index].sz; + s += sid_21_Names[(unsigned)index].sz; return; } } @@ -630,7 +630,7 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s) { int index = FindPairIndex(k_ReparseTags, ARRAY_SIZE(k_ReparseTags), tag); if (index >= 0) - s += k_ReparseTags[index].sz; + s += k_ReparseTags[(unsigned)index].sz; else { s += "REPARSE:"; diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp index 5d3c4484..081d38eb 100644 --- a/CPP/7zip/UI/Common/Update.cpp +++ b/CPP/7zip/UI/Common/Update.cpp @@ -1046,10 +1046,6 @@ static HRESULT EnumerateInArchiveItems( #endif -#ifdef _WIN32 -void ConvertToLongNames(NWildcard::CCensor &censor); -#endif - HRESULT UpdateArchive( CCodecs *codecs, const CObjectVector<COpenType> &types, diff --git a/CPP/7zip/UI/Console/Console.manifest b/CPP/7zip/UI/Console/Console.manifest new file mode 100644 index 00000000..58b68ced --- /dev/null +++ b/CPP/7zip/UI/Console/Console.manifest @@ -0,0 +1,13 @@ +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7z" type="win32"></assemblyIdentity> +<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> +<security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false"> +</requestedExecutionLevel></requestedPrivileges></security></trustInfo> +<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application> +<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> +<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> +<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> +<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> +<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> +</application></compatibility> +</assembly>
\ No newline at end of file diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp index 897a2757..21c2f071 100644 --- a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp +++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp @@ -60,8 +60,9 @@ HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError) if (_se) { - *_se << endl << kError << NError::MyFormatMessage(systemError) << endl << - fs2us(path) << endl << endl; + *_se << endl << kError << NError::MyFormatMessage(systemError) << endl; + _se->NormalizePrint_UString(fs2us(path)); + *_se << endl << endl; _se->Flush(); } return HRESULT_FROM_WIN32(systemError); @@ -251,7 +252,9 @@ static const char * const kTab = " "; static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size) { - *_so << kTab << "Path: " << path << endl; + *_so << kTab << "Path: "; + _so->NormalizePrint_wstr(path); + *_so << endl; if (size && *size != (UInt64)(Int64)-1) { AString s; @@ -340,7 +343,10 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3 _tempU.Empty(); if (name) + { _tempU = name; + _so->Normalize_UString(_tempU); + } _so->PrintUString(_tempU, _tempA); if (position) *_so << " <" << *position << ">"; @@ -461,7 +467,10 @@ STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encr *_se << s; if (!_currentName.IsEmpty()) - *_se << " : " << _currentName; + { + *_se << " : "; + _se->NormalizePrint_UString(_currentName); + } *_se << endl; _se->Flush(); } @@ -513,7 +522,11 @@ HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode) ClosePercents_for_so(); if (_so) - *_so << endl << (testMode ? kTesting : kExtracting) << name << endl; + { + *_so << endl << (testMode ? kTesting : kExtracting); + _so->NormalizePrint_wstr(name); + *_so << endl; + } if (NeedPercents()) _percent.Command = "Open"; @@ -573,8 +586,9 @@ void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, c { const CArcErrorInfo &er = arc.ErrorInfo; - UString s ("WARNING:\n"); - s += arc.Path; + *_so << "WARNING:\n"; + _so->NormalizePrint_UString(arc.Path); + UString s; if (arc.FormatIndex == er.ErrorFormatIndex) { s.Add_LF(); @@ -619,7 +633,10 @@ HRESULT CExtractCallbackConsole::OpenResult( { *_se << endl; if (level != 0) - *_se << arc.Path << endl; + { + _se->NormalizePrint_UString(arc.Path); + *_se << endl; + } } if (errorFlags != 0) @@ -653,7 +670,10 @@ HRESULT CExtractCallbackConsole::OpenResult( { *_so << endl; if (level != 0) - *_so << arc.Path << endl; + { + _so->NormalizePrint_UString(arc.Path); + *_so << endl; + } } if (warningFlags != 0) @@ -708,7 +728,9 @@ HRESULT CExtractCallbackConsole::OpenResult( _so->Flush(); if (_se) { - *_se << kError << name << endl; + *_se << kError; + _se->NormalizePrint_wstr(name); + *_se << endl; HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); RINOK(res); if (result == S_FALSE) diff --git a/CPP/7zip/UI/Console/HashCon.cpp b/CPP/7zip/UI/Console/HashCon.cpp index 8ff90753..ab80ce37 100644 --- a/CPP/7zip/UI/Console/HashCon.cpp +++ b/CPP/7zip/UI/Console/HashCon.cpp @@ -269,7 +269,7 @@ HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBun if (_fileName.IsEmpty()) *_so << kEmptyFileAlias; else - *_so << _fileName; + _so->NormalizePrint_UString(_fileName); } *_so << endl; } diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp index 57d1d1bc..38e23e21 100644 --- a/CPP/7zip/UI/Console/List.cpp +++ b/CPP/7zip/UI/Console/List.cpp @@ -560,7 +560,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) { if (!techMode) g_StdOut << temp; - g_StdOut.PrintUString(FilePath, TempAString); + g_StdOut.NormalizePrint_UString(FilePath, TempWString, TempAString); if (techMode) g_StdOut << MY_ENDL; continue; @@ -671,9 +671,10 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) else if (prop.vt == VT_BSTR) { TempWString.SetFromBstr(prop.bstrVal); + // do we need multi-line support here ? + g_StdOut.Normalize_UString(TempWString); if (techMode) { - // replace CR/LF here. g_StdOut.PrintUString(TempWString, TempAString); } else @@ -815,9 +816,63 @@ static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int6 so << val << endl; } -static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val) + +static void UString_Replace_CRLF_to_LF(UString &s) +{ + // s.Replace(L"\r\n", L"\n"); + wchar_t *src = s.GetBuf(); + wchar_t *dest = src; + for (;;) + { + wchar_t c = *src++; + if (c == 0) + break; + if (c == '\r' && *src == '\n') + { + src++; + c = '\n'; + } + *dest++ = c; + } + s.ReleaseBuf_SetEnd((unsigned)(dest - s.GetBuf())); +} + + +static void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val) { - so << name << " = " << val << endl; + UString s = val; + if (s.Find(L'\n') >= 0) + { + so << endl; + so << "{"; + so << endl; + UString_Replace_CRLF_to_LF(s); + so.Normalize_UString__LF_Allowed(s); + so << s; + so << endl; + so << "}"; + } + else + { + so.Normalize_UString(s); + so << s; + } + so << endl; +} + + +static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine) +{ + so << name << " = "; + if (multiLine) + { + PrintPropVal_MultiLine(so, val); + return; + } + UString s = val; + so.Normalize_UString(s); + so << s; + so << endl; } @@ -831,9 +886,11 @@ static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t * UString nameU; GetPropName(propID, name, nameA, nameU); if (!nameA.IsEmpty()) - PrintPropPair(so, nameA, s); + so << nameA; else - so << nameU << " = " << s << endl; + so << nameU; + so << " = "; + PrintPropVal_MultiLine(so, s); } } @@ -862,11 +919,11 @@ static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er) { PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags()); if (!er.ErrorMessage.IsEmpty()) - PrintPropPair(so, "ERROR", er.ErrorMessage); + PrintPropPair(so, "ERROR", er.ErrorMessage, true); PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags()); if (!er.WarningMessage.IsEmpty()) - PrintPropPair(so, "WARNING", er.WarningMessage); + PrintPropPair(so, "WARNING", er.WarningMessage, true); } HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) @@ -877,7 +934,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const const CArcErrorInfo &er = arc.ErrorInfo; so << "--\n"; - PrintPropPair(so, "Path", arc.Path); + PrintPropPair(so, "Path", arc.Path, false); if (er.ErrorFormatIndex >= 0) { if (er.ErrorFormatIndex == arc.FormatIndex) @@ -885,7 +942,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const else PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true); } - PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex)); + PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex), false); ErrorInfo_Print(so, er); @@ -943,7 +1000,8 @@ HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const { if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) { - so << arcLink.NonOpen_ArcPath << endl; + so.NormalizePrint_UString(arcLink.NonOpen_ArcPath); + so << endl; PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); } else @@ -1014,15 +1072,18 @@ HRESULT ListArchives(CCodecs *codecs, errorCode = ERROR_FILE_NOT_FOUND; lastError = HRESULT_FROM_WIN32(lastError);; g_StdOut.Flush(); - *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << - endl << arcPath << endl << endl; + *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << endl << endl; numErrors++; continue; } if (fi.IsDir()) { g_StdOut.Flush(); - *g_ErrStream << endl << kError << arcPath << " is not a file" << endl << endl; + *g_ErrStream << endl << kError; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << " is not a file" << endl << endl; numErrors++; continue; } @@ -1061,7 +1122,9 @@ HRESULT ListArchives(CCodecs *codecs, if (enableHeaders) { - g_StdOut << endl << kListing << arcPath << endl << endl; + g_StdOut << endl << kListing; + g_StdOut.NormalizePrint_UString(arcPath); + g_StdOut << endl << endl; } HRESULT result = arcLink.Open_Strict(options, &openCallback); @@ -1071,7 +1134,9 @@ HRESULT ListArchives(CCodecs *codecs, if (result == E_ABORT) return result; g_StdOut.Flush(); - *g_ErrStream << endl << kError << arcPath << " : "; + *g_ErrStream << endl << kError; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << " : "; if (result == S_FALSE) { Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); @@ -1255,7 +1320,7 @@ HRESULT ListArchives(CCodecs *codecs, if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) { g_StdOut << "----------\n"; - PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath); + PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath, false); PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); } } diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp index 436a6cd1..a632c1b4 100644 --- a/CPP/7zip/UI/Console/Main.cpp +++ b/CPP/7zip/UI/Console/Main.cpp @@ -10,10 +10,6 @@ #include "../../../../C/CpuArch.h" -#if defined( _7ZIP_LARGE_PAGES) -#include "../../../../C/Alloc.h" -#endif - #include "../../../Common/MyInitGuid.h" #include "../../../Common/CommandLineParser.h" @@ -25,10 +21,6 @@ #include "../../../Windows/ErrorMsg.h" -#ifdef _WIN32 -#include "../../../Windows/MemoryLock.h" -#endif - #include "../../../Windows/TimeUtils.h" #include "../Common/ArchiveCommandLine.h" @@ -64,7 +56,7 @@ using namespace NCommandLineParser; HINSTANCE g_hInstance = 0; #endif -bool g_LargePagesMode = false; +extern bool g_LargePagesMode; extern CStdOutStream *g_StdStream; extern CStdOutStream *g_ErrStream; @@ -244,7 +236,8 @@ static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) { FOR_VECTOR(i, pc.Paths) { - so << pc.Paths[i] << " : "; + so.NormalizePrint_UString(pc.Paths[i]); + so << " : "; so << NError::MyFormatMessage(pc.Codes[i]) << endl; } so << "----------------" << endl; @@ -383,6 +376,8 @@ static void PrintMemUsage(const char *s, UInt64 val) *g_StdStream << " " << s << " Memory ="; PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); *g_StdStream << " MB"; + if (g_LargePagesMode) + *g_StdStream << " (LP)"; } EXTERN_C_BEGIN @@ -524,6 +519,8 @@ int Main2( parser.Parse1(commandStrings, options); + g_StdOut.IsTerminalMode = options.IsStdOutTerminal; + g_StdErr.IsTerminalMode = options.IsStdErrTerminal; if (options.Number_for_Out != k_OutStream_stdout) g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL); @@ -541,24 +538,6 @@ int Main2( return 0; } - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_SymLink(); - #endif - - #ifdef _7ZIP_LARGE_PAGES - if (options.LargePages) - { - SetLargePageSize(); - // note: this process also can inherit that Privilege from parent process - g_LargePagesMode = - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_LockMemory(); - #else - true; - #endif - } - #endif - if (options.EnableHeaders) ShowCopyrightAndHelp(g_StdStream, false); diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp index 68e5fe97..d257e6a8 100644 --- a/CPP/7zip/UI/Console/MainAr.cpp +++ b/CPP/7zip/UI/Console/MainAr.cpp @@ -79,7 +79,7 @@ int MY_CDECL main PrintError(kUserBreakMessage); return (NExitCode::kUserBreak); } - catch(const CArcCmdLineException &e) + catch(const CMessagePathException &e) { PrintError(kException_CmdLine_Error_Message); if (g_ErrStream) diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp index e3e8d599..b2426878 100644 --- a/CPP/7zip/UI/Console/PercentPrinter.cpp +++ b/CPP/7zip/UI/Console/PercentPrinter.cpp @@ -141,8 +141,9 @@ void CPercentPrinter::Print() { _s += ' '; - StdOut_Convert_UString_to_AString(FileName, _temp); - _temp.Replace('\n', ' '); + _tempU = FileName; + _so->Normalize_UString(_tempU); + StdOut_Convert_UString_to_AString(_tempU, _temp); if (_s.Len() + _temp.Len() > MaxLen) { unsigned len = FileName.Len(); @@ -153,8 +154,9 @@ void CPercentPrinter::Print() delta = 1; len -= delta; _tempU = FileName; - _tempU.Delete(len / 2, FileName.Len() - len); + _tempU.Delete(len / 2, _tempU.Len() - len); _tempU.Insert(len / 2, L" . "); + _so->Normalize_UString(_tempU); StdOut_Convert_UString_to_AString(_tempU, _temp); if (_s.Len() + _temp.Len() <= MaxLen) break; diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp index e58e22d7..cd232fff 100644 --- a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp @@ -143,7 +143,9 @@ HRESULT CUpdateCallbackConsole::OpenResult( _so->Flush(); if (_se) { - *_se << kError << name << endl; + *_se << kError; + _se->NormalizePrint_wstr(name); + *_se << endl; HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); RINOK(res); _se->Flush(); @@ -185,7 +187,9 @@ void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, b *_se << endl << (isWarning ? kWarning : kError) << NError::MyFormatMessage(systemError) - << endl << fs2us(path) << endl << endl; + << endl; + _se->NormalizePrint_UString(fs2us(path)); + *_se << endl << endl; _se->Flush(); } } @@ -281,8 +285,8 @@ HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating) if (_so) { *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage); - if (name != 0) - *_so << name; + if (name) + _so->NormalizePrint_wstr(name); else *_so << k_StdOut_ArcName; *_so << endl << endl; @@ -343,6 +347,7 @@ HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool _tempA.Add_Space(); *_so << _tempA; _tempU = fs2us(path); + _so->Normalize_UString(_tempU); _so->PrintUString(_tempU, _tempA); *_so << endl; if (NeedFlush) @@ -475,7 +480,10 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *com _tempU.Empty(); if (name) + { _tempU = name; + _so->Normalize_UString(_tempU); + } _so->PrintUString(_tempU, _tempA); *_so << endl; if (NeedFlush) @@ -568,7 +576,9 @@ HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypt AString s; SetExtractErrorMessage(opRes, isEncrypted, s); - *_se << s << " : " << endl << name << endl << endl; + *_se << s << " : " << endl; + _se->NormalizePrint_wstr(name); + *_se << endl << endl; _se->Flush(); } return S_OK; diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc index 2f7ef073..414427fb 100644 --- a/CPP/7zip/UI/Console/resource.rc +++ b/CPP/7zip/UI/Console/resource.rc @@ -1,3 +1,7 @@ #include "../../MyVersionInfo.rc" MY_VERSION_INFO_APP("7-Zip Console" , "7z") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "Console.manifest" +#endif diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp index 2a6166ee..c156b3d6 100644 --- a/CPP/7zip/UI/Explorer/Explorer.dsp +++ b/CPP/7zip/UI/Explorer/Explorer.dsp @@ -479,6 +479,14 @@ SOURCE=..\..\..\Windows\MemoryGlobal.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Menu.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile index 1c8639be..7f50f20c 100644 --- a/CPP/7zip/UI/Explorer/makefile +++ b/CPP/7zip/UI/Explorer/makefile @@ -34,6 +34,7 @@ WIN_OBJS = \ $O\FileFind.obj \ $O\FileIO.obj \ $O\FileName.obj \ + $O\MemoryLock.obj \ $O\Menu.obj \ $O\ProcessUtils.obj \ $O\Registry.obj \ diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp index 04bad724..3567c048 100644 --- a/CPP/7zip/UI/Far/ExtractEngine.cpp +++ b/CPP/7zip/UI/Far/ExtractEngine.cpp @@ -209,6 +209,8 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s) s = "Is not archive"; else if (opRes == NArchive::NExtract::NOperationResult::kHeadersError) s = "kHeaders Error"; + else if (opRes == NArchive::NExtract::NOperationResult::kWrongPassword) + s = "Wrong Password"; else { s = "Error #"; diff --git a/CPP/7zip/UI/FileManager/7zFM.exe.manifest b/CPP/7zip/UI/FileManager/7zFM.exe.manifest index e8237451..6a13c923 100644 --- a/CPP/7zip/UI/FileManager/7zFM.exe.manifest +++ b/CPP/7zip/UI/FileManager/7zFM.exe.manifest @@ -5,6 +5,13 @@ <dependency> <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly> </dependency> +<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application> +<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> +<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> +<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> +<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> +<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> +</application></compatibility> <asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true</dpiAware> diff --git a/CPP/7zip/UI/FileManager/EditDialog.cpp b/CPP/7zip/UI/FileManager/EditDialog.cpp new file mode 100644 index 00000000..7f596722 --- /dev/null +++ b/CPP/7zip/UI/FileManager/EditDialog.cpp @@ -0,0 +1,57 @@ +// EditDialog.cpp + +#include "StdAfx.h" + +#include "EditDialog.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +bool CEditDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItems(*this, NULL, 0); + #endif + _edit.Attach(GetItem(IDE_EDIT)); + + SetText(Title); + _edit.SetText(Text); + + NormalizeSize(); + return CModalDialog::OnInit(); +} + +// #define MY_CLOSE_BUTTON__ID IDCANCEL +#define MY_CLOSE_BUTTON__ID IDCLOSE + +bool CEditDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx1, by; + GetItemSizes(MY_CLOSE_BUTTON__ID, bx1, by); + + // int bx2; + // GetItemSizes(IDOK, bx2, by); + + int y = ySize - my - by; + int x = xSize - mx - bx1; + + /* + RECT rect; + GetClientRect(&rect); + rect.top = y - my; + InvalidateRect(&rect); + */ + InvalidateRect(NULL); + + MoveItem(MY_CLOSE_BUTTON__ID, x, y, bx1, by); + // MoveItem(IDOK, x - mx - bx2, y, bx2, by); + /* + if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE) + mx = 0; + */ + _edit.Move(mx, my, xSize - mx * 2, y - my * 2); + return false; +} diff --git a/CPP/7zip/UI/FileManager/EditDialog.h b/CPP/7zip/UI/FileManager/EditDialog.h new file mode 100644 index 00000000..d820516a --- /dev/null +++ b/CPP/7zip/UI/FileManager/EditDialog.h @@ -0,0 +1,25 @@ +// EditDialog.h + +#ifndef __EDIT_DIALOG_H +#define __EDIT_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/Edit.h" + +#include "EditDialogRes.h" + +class CEditDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CEdit _edit; + virtual bool OnInit(); + virtual bool OnSize(WPARAM wParam, int xSize, int ySize); +public: + UString Title; + UString Text; + + INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_EDIT_DLG, wndParent); } + + CEditDialog() {} +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/EditDialog.rc b/CPP/7zip/UI/FileManager/EditDialog.rc new file mode 100644 index 00000000..cdb0b445 --- /dev/null +++ b/CPP/7zip/UI/FileManager/EditDialog.rc @@ -0,0 +1,15 @@ +#include "EditDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 320 +#define yc 240 + +IDD_EDIT_DLG DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Edit" +{ + // OK_CANCEL + MY_BUTTON__CLOSE + + EDITTEXT IDE_EDIT, m, m, xc, yc - bys - m, + ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | ES_WANTRETURN +} diff --git a/CPP/7zip/UI/FileManager/EditDialogRes.h b/CPP/7zip/UI/FileManager/EditDialogRes.h new file mode 100644 index 00000000..58c5ca91 --- /dev/null +++ b/CPP/7zip/UI/FileManager/EditDialogRes.h @@ -0,0 +1,2 @@ +#define IDD_EDIT_DLG 94 +#define IDE_EDIT 100 diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp index ddde804b..4dac07e3 100644 --- a/CPP/7zip/UI/FileManager/FM.cpp +++ b/CPP/7zip/UI/FileManager/FM.cpp @@ -383,6 +383,7 @@ static void SetMemoryLock() NSecurity::AddLockMemoryPrivilege(); if (ReadLockMemoryEnable()) + if (NSecurity::Get_LargePages_RiskLevel() == 0) { // note: child processes can inherit that Privilege g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory(); diff --git a/CPP/7zip/UI/FileManager/FM.dsp b/CPP/7zip/UI/FileManager/FM.dsp index 3b2fb2e3..6bf74436 100644 --- a/CPP/7zip/UI/FileManager/FM.dsp +++ b/CPP/7zip/UI/FileManager/FM.dsp @@ -491,6 +491,14 @@ SOURCE=.\DialogSize.h # End Source File # Begin Source File +SOURCE=.\EditDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\EditDialog.h +# End Source File +# Begin Source File + SOURCE=.\LinkDialog.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/UI/FileManager/FM.mak b/CPP/7zip/UI/FileManager/FM.mak index 6a85ea2f..e6545113 100644 --- a/CPP/7zip/UI/FileManager/FM.mak +++ b/CPP/7zip/UI/FileManager/FM.mak @@ -46,6 +46,7 @@ FM_OBJS = \ $O\AboutDialog.obj \ $O\ComboDialog.obj \ $O\CopyDialog.obj \ + $O\EditDialog.obj \ $O\EditPage.obj \ $O\LangPage.obj \ $O\ListViewDialog.obj \ diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp index 94e9ecba..bcaa5f1e 100644 --- a/CPP/7zip/UI/FileManager/LangUtils.cpp +++ b/CPP/7zip/UI/FileManager/LangUtils.cpp @@ -58,6 +58,7 @@ static const CIDLangPair kLangPairs[] = { IDCANCEL, 402 }, { IDYES, 406 }, { IDNO, 407 }, + { IDCLOSE, 408 }, { IDHELP, 409 } }; diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp index 80cdd7f6..9ad7bcc5 100644 --- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp +++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp @@ -2,6 +2,9 @@ #include "StdAfx.h" +#include "../../../Windows/Clipboard.h" + +#include "EditDialog.h" #include "ListViewDialog.h" #include "RegistryUtils.h" @@ -11,6 +14,23 @@ using namespace NWindows; +static const unsigned kOneStringMaxSize = 1024; + + +static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector) +{ + vector.Clear(); + int index = -1; + for (;;) + { + index = listView.GetNextSelectedItem(index); + if (index < 0) + break; + vector.Add(index); + } +} + + bool CListViewDialog::OnInit() { #ifdef LANG @@ -18,28 +38,92 @@ bool CListViewDialog::OnInit() #endif _listView.Attach(GetItem(IDL_LISTVIEW)); + if (NumColumns > 1) + { + LONG_PTR style = _listView.GetStyle(); + style &= ~(LONG_PTR)LVS_NOCOLUMNHEADER; + _listView.SetStyle(style); + } + CFmSettings st; st.Load(); + + DWORD exStyle = 0; + if (st.SingleClick) - _listView.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT); + exStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT; + + exStyle |= LVS_EX_FULLROWSELECT; + if (exStyle != 0) + _listView.SetExtendedListViewStyle(exStyle); + SetText(Title); + const int kWidth = 400; + LVCOLUMN columnInfo; columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; columnInfo.fmt = LVCFMT_LEFT; columnInfo.iSubItem = 0; - columnInfo.cx = 200; + columnInfo.cx = kWidth; + columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Property" + + if (NumColumns > 1) + { + columnInfo.cx = 100; + /* + // Windows always uses LVCFMT_LEFT for first column. + // if we need LVCFMT_RIGHT, we can create dummy column and then remove it + + // columnInfo.mask |= LVCF_TEXT; + _listView.InsertColumn(0, &columnInfo); + + columnInfo.iSubItem = 1; + columnInfo.fmt = LVCFMT_RIGHT; + _listView.InsertColumn(1, &columnInfo); + _listView.DeleteColumn(0); + */ + } + // else + _listView.InsertColumn(0, &columnInfo); + + if (NumColumns > 1) + { + // columnInfo.fmt = LVCFMT_LEFT; + columnInfo.cx = kWidth - columnInfo.cx; + columnInfo.iSubItem = 1; + // columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Value" + _listView.InsertColumn(1, &columnInfo); + } - _listView.InsertColumn(0, &columnInfo); + UString s; + FOR_VECTOR (i, Strings) + { _listView.InsertItem(i, Strings[i]); - if (Strings.Size() > 0) + if (NumColumns > 1 && i < Values.Size()) + { + s = Values[i]; + if (s.Len() > kOneStringMaxSize) + { + s.DeleteFrom(kOneStringMaxSize); + s += " ..."; + } + s.Replace(L"\r\n", L" "); + s.Replace(L"\n", L" "); + _listView.SetSubItem(i, 1, s); + } + } + + if (SelectFirst && Strings.Size() > 0) _listView.SetItemState_FocusedSelected(0); _listView.SetColumnWidthAuto(0); + if (NumColumns > 1) + _listView.SetColumnWidthAuto(1); StringsWereChanged = false; NormalizeSize(); @@ -74,8 +158,97 @@ bool CListViewDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) return false; } + extern bool g_LVN_ITEMACTIVATE_Support; +void CListViewDialog::CopyToClipboard() +{ + CUIntVector indexes; + ListView_GetSelected(_listView, indexes); + UString s; + + FOR_VECTOR (i, indexes) + { + unsigned index = indexes[i]; + s += Strings[index]; + if (NumColumns > 1 && index < Values.Size()) + { + const UString &v = Values[index]; + // if (!v.IsEmpty()) + { + s += ": "; + s += v; + } + } + // if (indexes.Size() > 1) + { + s += + #ifdef _WIN32 + "\r\n" + #else + "\n" + #endif + ; + } + } + + ClipboardSetText(*this, s); +} + + +void CListViewDialog::ShowItemInfo() +{ + CUIntVector indexes; + ListView_GetSelected(_listView, indexes); + if (indexes.Size() != 1) + return; + unsigned index = indexes[0]; + + CEditDialog dlg; + if (NumColumns == 1) + dlg.Text = Strings[index]; + else + { + dlg.Title = Strings[index]; + if (index < Values.Size()) + dlg.Text = Values[index]; + } + dlg.Create(*this); +} + + +void CListViewDialog::DeleteItems() +{ + for (;;) + { + int index = _listView.GetNextSelectedItem(-1); + if (index < 0) + break; + StringsWereChanged = true; + _listView.DeleteItem(index); + if ((unsigned)index < Strings.Size()) + Strings.Delete(index); + if ((unsigned)index < Values.Size()) + Values.Delete(index); + } + int focusedIndex = _listView.GetFocusedItem(); + if (focusedIndex >= 0) + _listView.SetItemState_FocusedSelected(focusedIndex); + _listView.SetColumnWidthAuto(0); +} + + +void CListViewDialog::OnEnter() +{ + if (IsKeyDown(VK_MENU) + || NumColumns > 1) + { + ShowItemInfo(); + return; + } + OnOK(); +} + bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) { if (header->hwndFrom != _listView) @@ -85,7 +258,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) case LVN_ITEMACTIVATE: if (g_LVN_ITEMACTIVATE_Support) { - OnOK(); + OnEnter(); return true; } break; @@ -93,7 +266,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) case NM_RETURN: // probabably it's unused if (!g_LVN_ITEMACTIVATE_Support) { - OnOK(); + OnEnter(); return true; } break; @@ -107,19 +280,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) { if (!DeleteIsAllowed) return false; - for (;;) - { - int index = _listView.GetNextSelectedItem(-1); - if (index < 0) - break; - StringsWereChanged = true; - _listView.DeleteItem(index); - Strings.Delete(index); - } - int focusedIndex = _listView.GetFocusedItem(); - if (focusedIndex >= 0) - _listView.SetItemState_FocusedSelected(focusedIndex); - _listView.SetColumnWidthAuto(0); + DeleteItems(); return true; } case 'A': @@ -129,6 +290,17 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) _listView.SelectAll(); return true; } + break; + } + case VK_INSERT: + case 'C': + { + if (IsKeyDown(VK_CONTROL)) + { + CopyToClipboard(); + return true; + } + break; } } } diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.h b/CPP/7zip/UI/FileManager/ListViewDialog.h index b7ba3830..00206afd 100644 --- a/CPP/7zip/UI/FileManager/ListViewDialog.h +++ b/CPP/7zip/UI/FileManager/ListViewDialog.h @@ -15,16 +15,32 @@ class CListViewDialog: public NWindows::NControl::CModalDialog virtual bool OnInit(); virtual bool OnSize(WPARAM wParam, int xSize, int ySize); virtual bool OnNotify(UINT controlID, LPNMHDR header); + void CopyToClipboard(); + void DeleteItems(); + void ShowItemInfo(); + void OnEnter(); public: UString Title; + + bool SelectFirst; bool DeleteIsAllowed; bool StringsWereChanged; + UStringVector Strings; + UStringVector Values; + int FocusedItemIndex; + unsigned NumColumns; INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_LISTVIEW, wndParent); } - CListViewDialog(): DeleteIsAllowed(false) {} + CListViewDialog(): + SelectFirst(false), + DeleteIsAllowed(false), + StringsWereChanged(false), + FocusedItemIndex(-1), + NumColumns(1) + {} }; #endif diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.rc b/CPP/7zip/UI/FileManager/ListViewDialog.rc index 14d3b2e6..961d224a 100644 --- a/CPP/7zip/UI/FileManager/ListViewDialog.rc +++ b/CPP/7zip/UI/FileManager/ListViewDialog.rc @@ -1,8 +1,8 @@ #include "ListViewDialogRes.h" #include "../../GuiCommon.rc" -#define xc 320 -#define yc 240 +#define xc 440 +#define yc 320 IDD_LISTVIEW DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT CAPTION "ListView" diff --git a/CPP/7zip/UI/FileManager/PanelCopy.cpp b/CPP/7zip/UI/FileManager/PanelCopy.cpp index d07def1d..5715d9de 100644 --- a/CPP/7zip/UI/FileManager/PanelCopy.cpp +++ b/CPP/7zip/UI/FileManager/PanelCopy.cpp @@ -16,7 +16,11 @@ using namespace NWindows; class CPanelCopyThread: public CProgressThreadVirt { + bool ResultsWereShown; + bool NeedShowRes; + HRESULT ProcessVirt(); + virtual void ProcessWasFinished_GuiVirt(); public: const CCopyToOptions *options; CMyComPtr<IFolderOperations> FolderOperations; @@ -28,11 +32,31 @@ public: UString FirstFilePath; HRESULT Result; - - CPanelCopyThread(): Result(E_FAIL) {} + void ShowFinalResults(HWND hwnd); + + CPanelCopyThread(): + Result(E_FAIL), + ResultsWereShown(false), + NeedShowRes(false) + {} }; + +void CPanelCopyThread::ShowFinalResults(HWND hwnd) +{ + if (NeedShowRes) + if (!ResultsWereShown) + { + ResultsWereShown = true; + ShowHashResults(Hash, fs2us(FirstFilePath), hwnd); + } +} +void CPanelCopyThread::ProcessWasFinished_GuiVirt() +{ + ShowFinalResults(*this); +} + HRESULT CPanelCopyThread::ProcessVirt() { /* @@ -69,11 +93,15 @@ HRESULT CPanelCopyThread::ProcessVirt() BoolToInt(options->replaceAltStreamChars), options->folder, ExtractCallback); - if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors && - (!options->hashMethods.IsEmpty() || options->testMode)) + if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors) { - CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0); - AddHashBundleRes(pair.Message, Hash, FirstFilePath); + if (!options->hashMethods.IsEmpty()) + NeedShowRes = true; + else if (options->testMode) + { + CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0); + AddHashBundleRes(pair.Message, Hash, FirstFilePath); + } } return Result; @@ -92,7 +120,6 @@ static void ThrowException_if_Error(HRESULT res) #endif */ - HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &indices, UStringVector *messages, bool &usePassword, UString &password) @@ -102,7 +129,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED); if (options.showErrorMessages) MessageBox_Error(errorMessage); - else if (messages != 0) + else if (messages) messages->Add(errorMessage); return E_FAIL; } @@ -124,8 +151,8 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind extracter.ExtractCallback = extracter.ExtractCallbackSpec; extracter.options = &options; - extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; - extracter.ProgressDialog.CompressingMode = false; + extracter.ExtractCallbackSpec->ProgressDialog = &extracter; + extracter.CompressingMode = false; extracter.ExtractCallbackSpec->StreamMode = options.streamMode; @@ -185,9 +212,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE); - extracter.ProgressDialog.MainWindow = GetParent(); - extracter.ProgressDialog.MainTitle = progressWindowTitle; - extracter.ProgressDialog.MainAddTitle = title + L' '; + extracter.MainWindow = GetParent(); + extracter.MainTitle = progressWindowTitle; + extracter.MainAddTitle = title + L' '; extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk; extracter.ExtractCallbackSpec->Init(); @@ -199,8 +226,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind RINOK(extracter.Create(title, GetParent())); - if (messages != 0) - *messages = extracter.ProgressDialog.Sync.Messages; + + if (messages) + *messages = extracter.Sync.Messages; res = extracter.Result; if (res == S_OK && extracter.ExtractCallbackSpec->IsOK()) @@ -208,6 +236,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind usePassword = extracter.ExtractCallbackSpec->PasswordIsDefined; password = extracter.ExtractCallbackSpec->Password; } + + extracter.ShowFinalResults(_window); + } RefreshTitleAlways(); @@ -296,8 +327,8 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri NWindows::CThread thread; RINOK(thread.Create(CThreadUpdate::MyThreadFunction, &updater)); updater.ProgressDialog.Create(title, thread, GetParent()); - - if (messages != 0) + + if (messages) *messages = updater.ProgressDialog.Sync.Messages; res = updater.Result; @@ -308,7 +339,7 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED); if (showErrorMessages) MessageBox_Error(errorMessage); - else if (messages != 0) + else if (messages) messages->Add(errorMessage); return E_ABORT; } diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp index 227c4533..7b918a02 100644 --- a/CPP/7zip/UI/FileManager/PanelCrc.cpp +++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp @@ -139,18 +139,44 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r class CThreadCrc: public CProgressThreadVirt { + bool ResultsWereShown; + bool WasFinished; + HRESULT ProcessVirt(); + virtual void ProcessWasFinished_GuiVirt(); public: CDirEnumerator Enumerator; CHashBundle Hash; + FString FirstFilePath; void SetStatus(const UString &s); void AddErrorMessage(DWORD systemError, const FChar *name); + void ShowFinalResults(HWND hwnd); + + CThreadCrc(): + ResultsWereShown(false), + WasFinished(false) + {} }; +void CThreadCrc::ShowFinalResults(HWND hwnd) +{ + if (WasFinished) + if (!ResultsWereShown) + { + ResultsWereShown = true; + ShowHashResults(Hash, fs2us(FirstFilePath), hwnd); + } +} + +void CThreadCrc::ProcessWasFinished_GuiVirt() +{ + ShowFinalResults(*this); +} + void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name) { - ProgressDialog.Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name)); + Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name)); Hash.NumErrors++; } @@ -162,7 +188,7 @@ void CThreadCrc::SetStatus(const UString &s2) s.Add_Space_if_NotEmpty(); s += fs2us(Enumerator.BasePrefix); } - ProgressDialog.Sync.Set_Status(s); + Sync.Set_Status(s); } HRESULT CThreadCrc::ProcessVirt() @@ -173,7 +199,7 @@ HRESULT CThreadCrc::ProcessVirt() if (!buf.Allocate(kBufSize)) return E_OUTOFMEMORY; - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; SetStatus(LangString(IDS_SCANNING)); @@ -233,7 +259,6 @@ HRESULT CThreadCrc::ProcessVirt() Enumerator.Init(); FString tempPath; - FString firstFilePath; bool isFirstFile = true; UInt64 errorsFilesSize = 0; @@ -264,7 +289,7 @@ HRESULT CThreadCrc::ProcessVirt() } if (isFirstFile) { - firstFilePath = path; + FirstFilePath = path; isFirstFile = false; } sync.Set_FilePath(fs2us(path)); @@ -303,12 +328,13 @@ HRESULT CThreadCrc::ProcessVirt() SetStatus(L""); CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0); - AddHashBundleRes(pair.Message, Hash, fs2us(firstFilePath)); + WasFinished = true; LangString(IDS_CHECKSUM_INFORMATION, pair.Title); return S_OK; } + HRESULT CApp::CalculateCrc2(const UString &methodName) { unsigned srcPanelIndex = GetFocusedPanelIndex(); @@ -338,6 +364,7 @@ HRESULT CApp::CalculateCrc2(const UString &methodName) { CThreadCrc t; + { UStringVector methods; methods.Add(methodName); @@ -360,17 +387,20 @@ HRESULT CApp::CalculateCrc2(const UString &methodName) t.Enumerator.EnterToDirs = !GetFlatMode(); - t.ProgressDialog.ShowCompressionInfo = false; + t.ShowCompressionInfo = false; UString title = LangString(IDS_CHECKSUM_CALCULATING); - t.ProgressDialog.MainWindow = _window; - t.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); - t.ProgressDialog.MainAddTitle = title; - t.ProgressDialog.MainAddTitle.Add_Space(); + t.MainWindow = _window; + t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); + t.MainAddTitle = title; + t.MainAddTitle.Add_Space(); RINOK(t.Create(title, _window)); + + t.ShowFinalResults(_window); } + RefreshTitleAlways(); return S_OK; } diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp index b6fca594..9f64c2c8 100644 --- a/CPP/7zip/UI/FileManager/PanelDrag.cpp +++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp @@ -81,15 +81,17 @@ CDataObject::CDataObject() STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL /* release */) { - if (etc->cfFormat == m_SetFolderFormat && etc->tymed == TYMED_HGLOBAL && - etc->dwAspect == DVASPECT_CONTENT && medium->tymed == TYMED_HGLOBAL) + if (etc->cfFormat == m_SetFolderFormat + && etc->tymed == TYMED_HGLOBAL + && etc->dwAspect == DVASPECT_CONTENT + && medium->tymed == TYMED_HGLOBAL) { Path.Empty(); - if (medium->hGlobal == 0) + if (!medium->hGlobal) return S_OK; size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t); const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal); - if (src != 0) + if (src) { for (size_t i = 0; i < size; i++) { @@ -109,13 +111,13 @@ static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal) { SIZE_T size = GlobalSize(srcGlobal); const void *src = GlobalLock(srcGlobal); - if (src == 0) + if (!src) return 0; HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size); - if (destGlobal != 0) + if (destGlobal) { void *dest = GlobalLock(destGlobal); - if (dest == 0) + if (!dest) { GlobalFree(destGlobal); destGlobal = 0; @@ -136,7 +138,7 @@ STDMETHODIMP CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium) medium->tymed = m_Etc.tymed; medium->pUnkForRelease = 0; medium->hGlobal = DuplicateGlobalMem(hGlobal); - if (medium->hGlobal == 0) + if (!medium->hGlobal) return E_OUTOFMEMORY; return S_OK; } @@ -261,7 +263,7 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na NMemory::CGlobalLock dropLock(hgDrop); DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); - if (dropFiles == 0) + if (!dropFiles) return false; dropFiles->fNC = FALSE; dropFiles->pt.x = 0; @@ -291,7 +293,7 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na NMemory::CGlobalLock dropLock(hgDrop); DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); - if (dropFiles == 0) + if (!dropFiles) return false; dropFiles->fNC = FALSE; dropFiles->pt.x = 0; @@ -336,7 +338,11 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */) dirPrefix = us2fs(GetFsPath()); else { - tempDirectory.Create(kTempDirPrefix); + if (!tempDirectory.Create(kTempDirPrefix)) + { + MessageBox_Error(L"Can't create temp folder"); + return; + } dirPrefix = tempDirectory.GetPath(); // dirPrefix2 = dirPrefix; NFile::NName::NormalizeDirPathPrefix(dirPrefix); @@ -394,11 +400,67 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */) dropSourceSpec->DataObjectSpec = dataObjectSpec; dropSourceSpec->DataObject = dataObjectSpec; - bool moveIsAllowed = isFSFolder; + + /* + CTime - file creation timestamp. + There are two operations in Windows with Drag and Drop: + COPY_OPERATION - icon with Plus sign - CTime will be set as current_time. + MOVE_OPERATION - icon without Plus sign - CTime will be preserved + + Note: if we call DoDragDrop() with (effectsOK = DROPEFFECT_MOVE), then + it will use MOVE_OPERATION and CTime will be preserved. + But MoveFile() function doesn't preserve CTime, if different volumes are used. + Why it's so? + Does DoDragDrop() use some another function (not MoveFile())? + + if (effectsOK == DROPEFFECT_COPY) it works as COPY_OPERATION + + if (effectsOK == DROPEFFECT_MOVE) drag works as MOVE_OPERATION + + if (effectsOK == (DROPEFFECT_COPY | DROPEFFECT_MOVE)) + { + if we drag file to same volume, then Windows suggests: + CTRL - COPY_OPERATION + [default] - MOVE_OPERATION + + if we drag file to another volume, then Windows suggests + [default] - COPY_OPERATION + SHIFT - MOVE_OPERATION + } + + We want to use MOVE_OPERATION for extracting from archive (open in 7-Zip) to Explorer: + It has the following advantages: + 1) it uses fast MOVE_OPERATION instead of slow COPY_OPERATION and DELETE, if same volume. + 2) it preserved CTime + + Some another programs support only COPY_OPERATION. + So we can use (DROPEFFECT_COPY | DROPEFFECT_MOVE) + + Also another program can return from DoDragDrop() before + files using. But we delete temp folder after DoDragDrop(), + and another program can't open input files in that case. + + We create objects: + IDropSource *dropSource + IDataObject *dataObject + if DropTarget is 7-Zip window, then 7-Zip's + IDropTarget::DragOver() sets Path in IDataObject. + and + IDropSource::QueryContinueDrag() sets NeedPostCopy, if Path is not epmty. + So we can detect destination path after DoDragDrop(). + Now we don't know any good way to detect destination path for D&D to Explorer. + */ + bool moveIsAllowed = isFSFolder; + /* DWORD effectsOK = DROPEFFECT_COPY; if (moveIsAllowed) effectsOK |= DROPEFFECT_MOVE; + */ + + // 18.04: was changed + DWORD effectsOK = DROPEFFECT_MOVE | DROPEFFECT_COPY; + DWORD effect; _panelCallback->DragBegin(); @@ -418,7 +480,8 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */) NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path); CCopyToOptions options; options.folder = dataObjectSpec->Path; - options.moveMode = (effect == DROPEFFECT_MOVE); + // if MOVE is not allowed, we just use COPY operation + options.moveMode = (effect == DROPEFFECT_MOVE && moveIsAllowed); res = CopyTo(options, indices, &dropSourceSpec->Messages); } /* @@ -475,7 +538,7 @@ static void MySetDropHighlighted(HWND hWnd, int index, bool enable) void CDropTarget::RemoveSelection() { - if (m_SelectionIndex >= 0 && m_Panel != 0) + if (m_SelectionIndex >= 0 && m_Panel) MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false); m_SelectionIndex = -1; } @@ -555,7 +618,7 @@ void CDropTarget::PositionCursor(POINTL ptl) bool CDropTarget::IsFsFolderPath() const { - if (!m_IsAppTarget && m_Panel != 0) + if (!m_IsAppTarget && m_Panel) return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0)); return false; } @@ -614,7 +677,7 @@ static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names size_t blockSize = GlobalSize(medium.hGlobal); NMemory::CGlobalLock dropLock(medium.hGlobal); const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); - if (dropFiles == 0) + if (!dropFiles) return; if (blockSize < dropFiles->pFiles) return; @@ -629,7 +692,7 @@ static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names bool CDropTarget::IsItSameDrive() const { - if (m_Panel == 0) + if (!m_Panel) return false; if (!IsFsFolderPath()) return false; @@ -662,6 +725,21 @@ bool CDropTarget::IsItSameDrive() const return true; } + +/* + There are 2 different actions, when we drag to 7-Zip: + 1) Drag from any external program except of Explorer to "7-Zip" FS folder. + We want to create new archive for that operation. + 2) all another operation work as usual file COPY/MOVE + - Drag from "7-Zip" FS to "7-Zip" FS. + COPY/MOVE are supported. + - Drag to open archive in 7-Zip. + We want to update archive. + We replace COPY to MOVE. + - Drag from "7-Zip" archive to "7-Zip" FS. + We replace COPY to MOVE. +*/ + DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect) { if (!m_DropIsAllowed || !m_PanelDropIsAllowed) @@ -671,10 +749,12 @@ DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffec allowedEffect &= ~DROPEFFECT_MOVE; DWORD effect = 0; + if (keyState & MK_CONTROL) effect = allowedEffect & DROPEFFECT_COPY; else if (keyState & MK_SHIFT) effect = allowedEffect & DROPEFFECT_MOVE; + if (effect == 0) { if (allowedEffect & DROPEFFECT_COPY) @@ -716,10 +796,10 @@ bool CDropTarget::SetPath(bool enablePath) const path = GetTargetPath(); size_t size = path.Len() + 1; medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t)); - if (medium.hGlobal == 0) + if (!medium.hGlobal) return false; wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal); - if (dest == 0) + if (!dest) { GlobalUnlock(medium.hGlobal); return false; diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp index 1f93f862..38b83124 100644 --- a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp +++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp @@ -625,6 +625,7 @@ void CPanel::FoldersHistory() { CListViewDialog listViewDialog; listViewDialog.DeleteIsAllowed = true; + listViewDialog.SelectFirst = true; LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title); _appState->FolderHistory.GetList(listViewDialog.Strings); if (listViewDialog.Create(GetParent()) != IDOK) diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp index f7c05a39..89f49bf6 100644 --- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp +++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp @@ -674,7 +674,7 @@ static const char * const kStartExtensions = #endif " exe bat ps1 com" " chm" - " msi doc xls ppt pps wps wpt wks xlr wdb vsd pub" + " msi doc dot xls ppt pps wps wpt wks xlr wdb vsd pub" " docx docm dotx dotm xlsx xlsm xltx xltm xlsb xps" " xlam pptx pptm potx potm ppam ppsx ppsm xsn" @@ -1151,7 +1151,7 @@ HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath, CThreadCopyFrom t; t.UpdateCallbackSpec = new CUpdateCallback100Imp; t.UpdateCallback = t.UpdateCallbackSpec; - t.UpdateCallbackSpec->ProgressDialog = &t.ProgressDialog; + t.UpdateCallbackSpec->ProgressDialog = &t; t.ItemIndex = index; t.FullPath = fullFilePath; t.FolderOperations = _folderOperations; diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp index 3db65be4..11c6d7c1 100644 --- a/CPP/7zip/UI/FileManager/PanelMenu.cpp +++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp @@ -16,6 +16,7 @@ #include "App.h" #include "FormatUtils.h" #include "LangUtils.h" +#include "ListViewDialog.h" #include "MyLoadMenu.h" #include "PropertyName.h" @@ -50,17 +51,40 @@ void CPanel::InvokeSystemCommand(const char *command) contextMenu->InvokeCommand(&ci); } -static const char * const kSeparator = "----------------------------\n"; -static const char * const kSeparatorSmall = "----\n"; -static const char * const kPropValueSeparator = ": "; +static const char * const kSeparator = "------------------------"; +static const char * const kSeparatorSmall = "----------------"; extern UString ConvertSizeToString(UInt64 value) throw(); bool IsSizeProp(UINT propID) throw(); UString GetOpenArcErrorMessage(UInt32 errorFlags); + +static void AddListAscii(CListViewDialog &dialog, const char *s) +{ + dialog.Strings.Add((UString)s); + dialog.Values.AddNew(); +} + +static void AddSeparator(CListViewDialog &dialog) +{ + AddListAscii(dialog, kSeparator); +} + +static void AddSeparatorSmall(CListViewDialog &dialog) +{ + AddListAscii(dialog, kSeparatorSmall); +} + +static void AddPropertyPair(const UString &name, const UString &val, CListViewDialog &dialog) +{ + dialog.Strings.Add(name); + dialog.Values.Add(val); +} + + static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR, - const NCOM::CPropVariant &prop, UString &s) + const NCOM::CPropVariant &prop, CListViewDialog &dialog) { if (prop.vt != VT_EMPTY) { @@ -87,23 +111,16 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR, if (!val.IsEmpty()) { - s += GetNameOfProperty(propID, nameBSTR); - s += kPropValueSeparator; - /* - if (propID == kpidComment) - s.Add_LF(); - */ - s += val; - s.Add_LF(); + AddPropertyPair(GetNameOfProperty(propID, nameBSTR), val, dialog); } } } -static void AddPropertyString(PROPID propID, UInt64 val, UString &s) +static void AddPropertyString(PROPID propID, UInt64 val, CListViewDialog &dialog) { NCOM::CPropVariant prop = val; - AddPropertyString(propID, NULL, prop, s); + AddPropertyString(propID, NULL, prop, dialog); } @@ -137,7 +154,9 @@ void CPanel::Properties() } { - UString message; + CListViewDialog message; + // message.DeleteIsAllowed = false; + // message.SelectFirst = false; CRecordVector<UInt32> operatedIndices; GetOperatedItemIndices(operatedIndices); @@ -205,15 +224,12 @@ void CPanel::Properties() } } } - message += GetNameOfProperty(propID, name); - message += kPropValueSeparator; - message += s.Ptr(); - message.Add_LF(); + AddPropertyPair(GetNameOfProperty(propID, name), (UString)s.Ptr(), message); } } } - message += kSeparator; + AddSeparator(message); } else if (operatedIndices.Size() >= 1) { @@ -239,8 +255,7 @@ void CPanel::Properties() { wchar_t temp[32]; ConvertUInt32ToString(operatedIndices.Size(), temp); - message += MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp); - message.Add_LF(); + AddPropertyPair(L"", MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp), message); } if (numDirs != 0) @@ -250,7 +265,7 @@ void CPanel::Properties() AddPropertyString(kpidSize, unpackSize, message); AddPropertyString(kpidPackSize, packSize, message); - message += kSeparator; + AddSeparator(message); } @@ -309,7 +324,7 @@ void CPanel::Properties() { const int kNumSpecProps = ARRAY_SIZE(kSpecProps); - message += kSeparator; + AddSeparator(message); for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++) { @@ -334,7 +349,7 @@ void CPanel::Properties() UInt32 numProps; if (getProps->GetArcNumProps2(level, &numProps) == S_OK) { - message += kSeparatorSmall; + AddSeparatorSmall(message); for (Int32 i = 0; i < (Int32)numProps; i++) { CMyComBSTR name; @@ -352,10 +367,15 @@ void CPanel::Properties() } } } - ::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES), MB_OK); + + message.Title = LangString(IDS_PROPERTIES); + message.NumColumns = 2; + message.Create(GetParent()); } } + + void CPanel::EditCut() { // InvokeSystemCommand("cut"); diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp index d049a3ce..00bda1a9 100644 --- a/CPP/7zip/UI/FileManager/PanelOperations.cpp +++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp @@ -79,10 +79,10 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr { UpdateCallbackSpec = new CUpdateCallback100Imp; UpdateCallback = UpdateCallbackSpec; - UpdateCallbackSpec->ProgressDialog = &ProgressDialog; + UpdateCallbackSpec->ProgressDialog = this; - ProgressDialog.WaitMode = true; - ProgressDialog.Sync.FinalMessage.ErrorMessage.Title = titleError; + WaitMode = true; + Sync.FinalMessage.ErrorMessage.Title = titleError; Result = S_OK; UpdateCallbackSpec->Init(); @@ -95,11 +95,11 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr } - ProgressDialog.MainWindow = panel._mainWindow; // panel.GetParent() - ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); - ProgressDialog.MainAddTitle = progressTitle + L' '; + MainWindow = panel._mainWindow; // panel.GetParent() + MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); + MainAddTitle = progressTitle + L' '; - RINOK(Create(progressTitle, ProgressDialog.MainWindow)); + RINOK(Create(progressTitle, MainWindow)); return Result; } diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp index 7cab2cf9..7c633323 100644 --- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp +++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp @@ -157,7 +157,7 @@ HRESULT CThreadSplit::ProcessVirt() if (!inFile.GetLength(length)) return GetLastError(); - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; sync.Set_NumBytesTotal(length); UInt64 pos = 0; @@ -306,7 +306,7 @@ void CApp::Split() CThreadSplit spliter; spliter.NumVolumes = numVolumes; - CProgressDialog &progressDialog = spliter.ProgressDialog; + CProgressDialog &progressDialog = spliter; UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000); UString title = LangString(IDS_SPLITTING); @@ -362,7 +362,7 @@ HRESULT CThreadCombine::ProcessVirt() return res; } - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; sync.Set_NumBytesTotal(TotalSize); CMyBuffer bufferObject; @@ -534,7 +534,7 @@ void CApp::Combine() return; } - CProgressDialog &progressDialog = combiner.ProgressDialog; + CProgressDialog &progressDialog = combiner; progressDialog.ShowCompressionInfo = false; UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000); diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp index 762f2492..28e3eae7 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -236,7 +236,10 @@ void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name) AddError_Message_Name(s, name); } -CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0) +CProgressDialog::CProgressDialog(): + _timer(0), + CompressingMode(true), + MainWindow(0) { _isDir = false; @@ -974,7 +977,9 @@ bool CProgressDialog::OnExternalCloseMessage() ::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); HideItem(IDB_PROGRESS_BACKGROUND); HideItem(IDB_PAUSE); - + + ProcessWasFinished_GuiVirt(); + bool thereAreMessages; CProgressFinalMessage fm; { @@ -982,6 +987,7 @@ bool CProgressDialog::OnExternalCloseMessage() thereAreMessages = !Sync.Messages.IsEmpty(); fm = Sync.FinalMessage; } + if (!fm.ErrorMessage.Message.IsEmpty()) { MessagesDisplayed = true; @@ -992,6 +998,7 @@ bool CProgressDialog::OnExternalCloseMessage() else if (!thereAreMessages) { MessagesDisplayed = true; + if (!fm.OkMessage.Message.IsEmpty()) { if (fm.OkMessage.Title.IsEmpty()) @@ -1245,11 +1252,24 @@ void CProgressDialog::ProcessWasFinished() } +static THREAD_FUNC_DECL MyThreadFunction(void *param) +{ + CProgressThreadVirt *p = (CProgressThreadVirt *)param; + try + { + p->Process(); + p->ThreadFinishedOK = true; + } + catch (...) { p->Result = E_FAIL; } + return 0; +} + + HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow) { NWindows::CThread thread; RINOK(thread.Create(MyThreadFunction, this)); - ProgressDialog.Create(title, thread, parentWindow); + CProgressDialog::Create(title, thread, parentWindow); return S_OK; } @@ -1265,7 +1285,7 @@ static void AddMessageToString(UString &dest, const UString &src) void CProgressThreadVirt::Process() { - CProgressCloser closer(ProgressDialog); + CProgressCloser closer(*this); UString m; try { Result = ProcessVirt(); } catch(const wchar_t *s) { m = s; } @@ -1293,7 +1313,7 @@ void CProgressThreadVirt::Process() } } - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; NSynchronization::CCriticalSectionLock lock(sync._cs); if (m.IsEmpty()) { diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h index 03f836da..6c4213ac 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h @@ -261,7 +261,18 @@ public: INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0); + + /* how it works: + 1) the working thread calls ProcessWasFinished() + that sends kCloseMessage message to CProgressDialog (GUI) thread + 2) CProgressDialog (GUI) thread receives kCloseMessage message and + calls ProcessWasFinished_GuiVirt(); + So we can implement ProcessWasFinished_GuiVirt() and show special + results window in GUI thread with CProgressDialog as parent window + */ + void ProcessWasFinished(); + virtual void ProcessWasFinished_GuiVirt() {} }; @@ -273,7 +284,8 @@ public: ~CProgressCloser() { _p->ProcessWasFinished(); } }; -class CProgressThreadVirt + +class CProgressThreadVirt: public CProgressDialog { protected: FStringVector ErrorPaths; @@ -281,33 +293,59 @@ protected: // error if any of HRESULT, ErrorMessage, ErrorPath virtual HRESULT ProcessVirt() = 0; - void Process(); public: HRESULT Result; bool ThreadFinishedOK; // if there is no fatal exception - CProgressDialog ProgressDialog; - - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - CProgressThreadVirt *p = (CProgressThreadVirt *)param; - try - { - p->Process(); - p->ThreadFinishedOK = true; - } - catch (...) { p->Result = E_FAIL; } - return 0; - } + void Process(); void AddErrorPath(const FString &path) { ErrorPaths.Add(path); } HRESULT Create(const UString &title, HWND parentWindow = 0); CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; } - }; UString HResultToMessage(HRESULT errorCode); +/* +how it works: + +client code inherits CProgressThreadVirt and calls +CProgressThreadVirt::Create() +{ + it creates new thread that calls CProgressThreadVirt::Process(); + it creates modal progress dialog window with ProgressDialog.Create() +} + +CProgressThreadVirt::Process() +{ + { + ProcessVirt(); // virtual function that must implement real work + } + if (exceptions) or FinalMessage.ErrorMessage.Message + { + set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message + } + else if (FinalMessage.OkMessage.Message) + { + set message to ProgressDialog.Sync.FinalMessage.OkMessage + } + + PostMsg(kCloseMessage); +} + + +CProgressDialog::OnExternalCloseMessage() +{ + if (ProgressDialog.Sync.FinalMessage) + { + WorkWasFinishedVirt(); + Show (ProgressDialog.Sync.FinalMessage) + MessagesDisplayed = true; + } +} + +*/ + #endif diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc index a166129b..6d259eb0 100644 --- a/CPP/7zip/UI/FileManager/resource.rc +++ b/CPP/7zip/UI/FileManager/resource.rc @@ -247,6 +247,7 @@ END #include "BrowseDialog.rc" #include "ComboDialog.rc" #include "CopyDialog.rc" +#include "EditDialog.rc" #include "EditPage.rc" #include "FoldersPage.rc" #include "LangPage.rc" diff --git a/CPP/7zip/UI/GUI/7zG.exe.manifest b/CPP/7zip/UI/GUI/7zG.exe.manifest index 68c6047e..39f516cd 100644 --- a/CPP/7zip/UI/GUI/7zG.exe.manifest +++ b/CPP/7zip/UI/GUI/7zG.exe.manifest @@ -5,6 +5,13 @@ <dependency> <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly> </dependency> +<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application> +<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> +<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> +<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> +<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> +<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> +</application></compatibility> <asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true</dpiAware> diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp index 5071d1f0..814415f6 100644 --- a/CPP/7zip/UI/GUI/ExtractGUI.cpp +++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp @@ -52,22 +52,9 @@ static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColo static void AddSizePair(UString &s, UINT resourceID, UInt64 value) { - { - wchar_t sz[32]; - AddLangString(s, resourceID); - s += ": "; - ConvertUInt64ToString(value, sz); - s += MyFormatNew(IDS_FILE_SIZE, sz); - } - // s += sz; - if (value >= (1 << 20)) - { - char sz[32]; - ConvertUInt64ToString(value >> 20, sz); - s += " ("; - s += sz; - s += " MB)"; - } + AddLangString(s, resourceID); + s += ": "; + AddSizeValue(s, value); s.Add_LF(); } @@ -86,16 +73,31 @@ public: UStringVector *ArchivePathsFull; const NWildcard::CCensorNode *WildcardCensor; const CExtractOptions *Options; + #ifndef _SFX CHashBundle *HashBundle; + virtual void ProcessWasFinished_GuiVirt(); #endif + CMyComPtr<IExtractCallbackUI> ExtractCallback; UString Title; + + CPropNameValPairs Pairs; }; + +#ifndef _SFX +void CThreadExtracting::ProcessWasFinished_GuiVirt() +{ + if (HashBundle && !Pairs.IsEmpty()) + ShowHashResults(Pairs, *this); +} +#endif + HRESULT CThreadExtracting::ProcessVirt() { CDecompressStat Stat; + #ifndef _SFX if (HashBundle) HashBundle->Init(); @@ -109,16 +111,23 @@ HRESULT CThreadExtracting::ProcessVirt() HashBundle, #endif FinalMessage.ErrorMessage.Message, Stat); + #ifndef _SFX - if (res == S_OK && Options->TestMode && ExtractCallbackSpec->IsOK()) + if (res == S_OK && ExtractCallbackSpec->IsOK()) { - UString s; + if (HashBundle) + { + AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives); + AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize); + AddHashBundleRes(Pairs, *HashBundle, UString()); + } + else if (Options->TestMode) + { + UString s; - AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false); - AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize); + AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false); + AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize); - if (!HashBundle) - { if (Stat.NumFolders != 0) AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders); AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles); @@ -129,24 +138,19 @@ HRESULT CThreadExtracting::ProcessVirt() AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams); AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize); } - } - - if (HashBundle) - { s.Add_LF(); - AddHashBundleRes(s, *HashBundle, UString()); + AddLangString(s, IDS_MESSAGE_NO_ERRORS); + FinalMessage.OkMessage.Title = Title; + FinalMessage.OkMessage.Message = s; } - - s.Add_LF(); - AddLangString(s, IDS_MESSAGE_NO_ERRORS); - - FinalMessage.OkMessage.Title = Title; - FinalMessage.OkMessage.Message = s; } #endif + return res; } + + HRESULT ExtractGUI( CCodecs *codecs, const CObjectVector<COpenType> &formatIndices, @@ -252,11 +256,11 @@ HRESULT ExtractGUI( extracter.Title = title; extracter.ExtractCallbackSpec = extractCallback; - extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; + extracter.ExtractCallbackSpec->ProgressDialog = &extracter; extracter.ExtractCallback = extractCallback; extracter.ExtractCallbackSpec->Init(); - extracter.ProgressDialog.CompressingMode = false; + extracter.CompressingMode = false; extracter.ArchivePaths = &archivePaths; extracter.ArchivePathsFull = &archivePathsFull; @@ -266,10 +270,9 @@ HRESULT ExtractGUI( extracter.HashBundle = hb; #endif - extracter.ProgressDialog.IconID = IDI_ICON; + extracter.IconID = IDI_ICON; RINOK(extracter.Create(title, hwndParent)); - messageWasDisplayed = extracter.ThreadFinishedOK & - extracter.ProgressDialog.MessagesDisplayed; + messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed; return extracter.Result; } diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp index 6bbfb740..2708fbd7 100644 --- a/CPP/7zip/UI/GUI/GUI.cpp +++ b/CPP/7zip/UI/GUI/GUI.cpp @@ -6,8 +6,6 @@ #include <shlwapi.h> -#include "../../../../C/Alloc.h" - #include "../../../Common/MyInitGuid.h" #include "../../../Common/CommandLineParser.h" @@ -16,9 +14,6 @@ #include "../../../Windows/FileDir.h" #include "../../../Windows/NtCheck.h" -#ifdef _WIN32 -#include "../../../Windows/MemoryLock.h" -#endif #include "../Common/ArchiveCommandLine.h" #include "../Common/ExitCode.h" @@ -37,8 +32,6 @@ using namespace NWindows; HINSTANCE g_hInstance; -bool g_LargePagesMode = false; - #ifndef UNDER_CE DWORD g_ComCtl32Version; @@ -126,24 +119,6 @@ static int Main2() parser.Parse1(commandStrings, options); parser.Parse2(options); - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_SymLink(); - #endif - - #ifdef _7ZIP_LARGE_PAGES - if (options.LargePages) - { - SetLargePageSize(); - // note: this process also can inherit that Privilege from parent process - g_LargePagesMode = - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_LockMemory(); - #else - true; - #endif - } - #endif - CREATE_CODECS_OBJECT codecs->CaseSensitiveChange = options.CaseSensitiveChange; @@ -403,7 +378,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, { return ShowMemErrorMessage(); } - catch(const CArcCmdLineException &e) + catch(const CMessagePathException &e) { ErrorMessage(e); return NExitCode::kUserError; diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp index c022088e..52d6ac46 100644 --- a/CPP/7zip/UI/GUI/GUI.dsp +++ b/CPP/7zip/UI/GUI/GUI.dsp @@ -425,6 +425,14 @@ SOURCE=.\CompressDialog.h # End Source File # Begin Source File +SOURCE=..\FileManager\EditDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\EditDialog.h +# End Source File +# Begin Source File + SOURCE=.\ExtractDialog.cpp # End Source File # Begin Source File @@ -433,6 +441,14 @@ SOURCE=.\ExtractDialog.h # End Source File # Begin Source File +SOURCE=..\FileManager\ListViewDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ListViewDialog.h +# End Source File +# Begin Source File + SOURCE=..\FileManager\OverwriteDialog.cpp # End Source File # Begin Source File @@ -975,6 +991,14 @@ SOURCE=..\..\..\Windows\Control\Static.h # End Group # Begin Source File +SOURCE=..\..\..\Windows\Clipboard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\COM.h # End Source File # Begin Source File @@ -1051,6 +1075,14 @@ SOURCE=..\..\..\Windows\FileSystem.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\MemoryGlobal.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\MemoryLock.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/UI/GUI/HashGUI.cpp b/CPP/7zip/UI/GUI/HashGUI.cpp index cc93f07e..7cb00973 100644 --- a/CPP/7zip/UI/GUI/HashGUI.cpp +++ b/CPP/7zip/UI/GUI/HashGUI.cpp @@ -9,6 +9,7 @@ #include "../FileManager/FormatUtils.h" #include "../FileManager/LangUtils.h" +#include "../FileManager/ListViewDialog.h" #include "../FileManager/OverwriteDialogRes.h" #include "../FileManager/ProgressDialog2.h" #include "../FileManager/ProgressDialog2Res.h" @@ -19,13 +20,18 @@ using namespace NWindows; + + class CHashCallbackGUI: public CProgressThreadVirt, public IHashCallbackUI { UInt64 NumFiles; bool _curIsFolder; UString FirstFileName; + CPropNameValPairs PropNameValPairs; + HRESULT ProcessVirt(); + virtual void ProcessWasFinished_GuiVirt(); public: const NWildcard::CCensor *censor; @@ -40,49 +46,62 @@ public: void AddErrorMessage(DWORD systemError, const wchar_t *name) { - ProgressDialog.Sync.AddError_Code_Name(systemError, name); + Sync.AddError_Code_Name(systemError, name); } }; -static void AddValuePair(UString &s, UINT resourceID, UInt64 value) + +void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value) { - AddLangString(s, resourceID); - s += ": "; + CProperty &pair = pairs.AddNew(); + AddLangString(pair.Name, resourceID); char sz[32]; ConvertUInt64ToString(value, sz); - s += sz; - s.Add_LF(); + pair.Value = sz; } -static void AddSizeValuePair(UString &s, UINT resourceID, UInt64 value) + +void AddSizeValue(UString &s, UInt64 value) { - AddLangString(s, resourceID); - s += ": "; { wchar_t sz[32]; ConvertUInt64ToString(value, sz); s += MyFormatNew(IDS_FILE_SIZE, sz); } + if (value >= (1 << 10)) { + char c; + if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; } + if (value >= (10 << 20)) { value >>= 20; c = 'M'; } + else { value >>= 10; c = 'K'; } char sz[32]; - ConvertUInt64ToString(value >> 20, sz); + ConvertUInt64ToString(value, sz); s += " ("; s += sz; - s += " MB)"; - s.Add_LF(); + s += " "; + s += (wchar_t)c; + s += "iB)"; } } +void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value) +{ + CProperty &pair = pairs.AddNew(); + LangString(resourceID, pair.Name); + AddSizeValue(pair.Value, value); +} + + HRESULT CHashCallbackGUI::StartScanning() { - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; sync.Set_Status(LangString(IDS_SCANNING)); return CheckBreak(); } HRESULT CHashCallbackGUI::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) { - return ProgressDialog.Sync.ScanProgress(st.NumFiles, st.GetTotalBytes(), path, isDir); + return Sync.ScanProgress(st.NumFiles, st.GetTotalBytes(), path, isDir); } HRESULT CHashCallbackGUI::ScanError(const FString &path, DWORD systemError) @@ -98,26 +117,26 @@ HRESULT CHashCallbackGUI::FinishScanning(const CDirItemsStat &st) HRESULT CHashCallbackGUI::CheckBreak() { - return ProgressDialog.Sync.CheckStop(); + return Sync.CheckStop(); } HRESULT CHashCallbackGUI::SetNumFiles(UInt64 numFiles) { - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; sync.Set_NumFilesTotal(numFiles); return CheckBreak(); } HRESULT CHashCallbackGUI::SetTotal(UInt64 size) { - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; sync.Set_NumBytesTotal(size); return CheckBreak(); } HRESULT CHashCallbackGUI::SetCompleted(const UInt64 *completed) { - return ProgressDialog.Sync.Set_NumBytesCur(completed); + return Sync.Set_NumBytesCur(completed); } HRESULT CHashCallbackGUI::BeforeFirstFile(const CHashBundle & /* hb */) @@ -130,7 +149,7 @@ HRESULT CHashCallbackGUI::GetStream(const wchar_t *name, bool isFolder) if (NumFiles == 0) FirstFileName = name; _curIsFolder = isFolder; - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; sync.Set_FilePath(name, isFolder); return CheckBreak(); } @@ -147,49 +166,47 @@ HRESULT CHashCallbackGUI::OpenFileError(const FString &path, DWORD systemError) HRESULT CHashCallbackGUI::SetOperationResult(UInt64 /* fileSize */, const CHashBundle & /* hb */, bool /* showHash */) { - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; if (!_curIsFolder) NumFiles++; sync.Set_NumFilesCur(NumFiles); return CheckBreak(); } -static void AddHashString(UString &s, const CHasherState &h, unsigned digestIndex, const wchar_t *title) +static void AddHashString(CProperty &s, const CHasherState &h, unsigned digestIndex) { - s += title; - s.Add_Space(); char temp[k_HashCalc_DigestSize_Max * 2 + 4]; AddHashHexToString(temp, h.Digests[digestIndex], h.DigestSize); - s += temp; - s.Add_LF(); + s.Value = temp; } -static void AddHashResString(UString &s, const CHasherState &h, unsigned digestIndex, UInt32 resID) +static void AddHashResString(CPropNameValPairs &s, const CHasherState &h, unsigned digestIndex, UInt32 resID) { - UString s2 = LangString(resID); + CProperty &pair = s.AddNew(); + UString &s2 = pair.Name; + LangString(resID, s2); UString name (h.Name); s2.Replace(L"CRC", name); - AddHashString(s, h, digestIndex, s2); + s2.Replace(L":", L""); + AddHashString(pair, h, digestIndex); } -void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName) + +void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName) { if (hb.NumErrors != 0) - { AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors); - s.Add_LF(); - } if (hb.NumFiles == 1 && hb.NumDirs == 0 && !firstFileName.IsEmpty()) { - AddLangString(s, IDS_PROP_NAME); - s += ": "; - s += firstFileName; - s.Add_LF(); + CProperty &pair = s.AddNew(); + LangString(IDS_PROP_NAME, pair.Name); + pair.Value = firstFileName; } else { - AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs); + if (hb.NumDirs != 0) + AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs); AddValuePair(s, IDS_PROP_FILES, hb.NumFiles); } @@ -197,25 +214,18 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil if (hb.NumAltStreams != 0) { - s.Add_LF(); AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, hb.NumAltStreams); AddSizeValuePair(s, IDS_PROP_ALT_STREAMS_SIZE, hb.AltStreamsSize); } - if (hb.NumErrors == 0 && hb.Hashers.IsEmpty()) - { - s.Add_LF(); - AddLangString(s, IDS_MESSAGE_NO_ERRORS); - } - FOR_VECTOR (i, hb.Hashers) { - s.Add_LF(); const CHasherState &h = hb.Hashers[i]; if (hb.NumFiles == 1 && hb.NumDirs == 0) { - s += h.Name; - AddHashString(s, h, k_HashCalc_Index_DataSum, L":"); + CProperty &pair = s.AddNew(); + pair.Name += h.Name; + AddHashString(pair, h, k_HashCalc_Index_DataSum); } else { @@ -229,32 +239,55 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil } } + +void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName) +{ + CPropNameValPairs pairs; + AddHashBundleRes(pairs, hb, firstFileName); + + FOR_VECTOR (i, pairs) + { + const CProperty &pair = pairs[i]; + s += pair.Name; + s += ": "; + s += pair.Value; + s.Add_LF(); + } + + if (hb.NumErrors == 0 && hb.Hashers.IsEmpty()) + { + s.Add_LF(); + AddLangString(s, IDS_MESSAGE_NO_ERRORS); + s.Add_LF(); + } +} + + HRESULT CHashCallbackGUI::AfterLastFile(const CHashBundle &hb) { - UString s; - AddHashBundleRes(s, hb, FirstFileName); + AddHashBundleRes(PropNameValPairs, hb, FirstFileName); - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; sync.Set_NumFilesCur(hb.NumFiles); - CProgressMessageBoxPair &pair = GetMessagePair(hb.NumErrors != 0); - pair.Message = s; - LangString(IDS_CHECKSUM_INFORMATION, pair.Title); + // CProgressMessageBoxPair &pair = GetMessagePair(hb.NumErrors != 0); + // pair.Message = s; + // LangString(IDS_CHECKSUM_INFORMATION, pair.Title); return S_OK; } + HRESULT CHashCallbackGUI::ProcessVirt() { NumFiles = 0; - AString errorInfo; HRESULT res = HashCalc(EXTERNAL_CODECS_LOC_VARS *censor, *options, errorInfo, this); - return res; } + HRESULT HashCalcGUI( DECL_EXTERNAL_CODECS_LOC_VARS const NWildcard::CCensor &censor, @@ -268,15 +301,49 @@ HRESULT HashCalcGUI( t.censor = &censor; t.options = &options; - t.ProgressDialog.ShowCompressionInfo = false; + t.ShowCompressionInfo = false; const UString title = LangString(IDS_CHECKSUM_CALCULATING); - t.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); - t.ProgressDialog.MainAddTitle = title; - t.ProgressDialog.MainAddTitle.Add_Space(); + t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); + t.MainAddTitle = title; + t.MainAddTitle.Add_Space(); RINOK(t.Create(title)); - messageWasDisplayed = t.ThreadFinishedOK && t.ProgressDialog.MessagesDisplayed; + messageWasDisplayed = t.ThreadFinishedOK && t.MessagesDisplayed; return S_OK; } + + +void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd) +{ + CListViewDialog lv; + + FOR_VECTOR (i, propPairs) + { + const CProperty &pair = propPairs[i]; + lv.Strings.Add(pair.Name); + lv.Values.Add(pair.Value); + } + + lv.Title = LangString(IDS_CHECKSUM_INFORMATION); + lv.DeleteIsAllowed = true; + lv.SelectFirst = false; + lv.NumColumns = 2; + + lv.Create(hwnd); +} + + +void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd) +{ + CPropNameValPairs propPairs; + AddHashBundleRes(propPairs, hb, firstFileName); + ShowHashResults(propPairs, hwnd); +} + + +void CHashCallbackGUI::ProcessWasFinished_GuiVirt() +{ + ShowHashResults(PropNameValPairs, *this); +} diff --git a/CPP/7zip/UI/GUI/HashGUI.h b/CPP/7zip/UI/GUI/HashGUI.h index 40340365..4035abf1 100644 --- a/CPP/7zip/UI/GUI/HashGUI.h +++ b/CPP/7zip/UI/GUI/HashGUI.h @@ -4,6 +4,7 @@ #define __HASH_GUI_H #include "../Common/HashCalc.h" +#include "../Common/Property.h" HRESULT HashCalcGUI( DECL_EXTERNAL_CODECS_LOC_VARS @@ -11,6 +12,16 @@ HRESULT HashCalcGUI( const CHashOptions &options, bool &messageWasDisplayed); +typedef CObjectVector<CProperty> CPropNameValPairs; + +void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value); +void AddSizeValue(UString &s, UInt64 value); +void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value); + +void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName); void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName); +void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd); +void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd); + #endif diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp index 261b1e2b..2e738d3a 100644 --- a/CPP/7zip/UI/GUI/UpdateGUI.cpp +++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp @@ -460,7 +460,7 @@ HRESULT UpdateGUI( tu.cmdArcPath = &cmdArcPath; tu.UpdateCallbackGUI = callback; - tu.UpdateCallbackGUI->ProgressDialog = &tu.ProgressDialog; + tu.UpdateCallbackGUI->ProgressDialog = &tu; tu.UpdateCallbackGUI->Init(); UString title = LangString(IDS_PROGRESS_COMPRESSING); @@ -476,10 +476,10 @@ HRESULT UpdateGUI( tu.WildcardCensor = &censor; tu.Options = &options; - tu.ProgressDialog.IconID = IDI_ICON; + tu.IconID = IDI_ICON; RINOK(tu.Create(title, hwndParent)); - messageWasDisplayed = tu.ThreadFinishedOK && tu.ProgressDialog.MessagesDisplayed; + messageWasDisplayed = tu.ThreadFinishedOK && tu.MessagesDisplayed; return tu.Result; } diff --git a/CPP/7zip/UI/GUI/makefile b/CPP/7zip/UI/GUI/makefile index bcafa0e5..ffab9abb 100644 --- a/CPP/7zip/UI/GUI/makefile +++ b/CPP/7zip/UI/GUI/makefile @@ -36,6 +36,7 @@ COMMON_OBJS = \ $O\Wildcard.obj \ WIN_OBJS = \ + $O\Clipboard.obj \ $O\CommonDialog.obj \ $O\DLL.obj \ $O\ErrorMsg.obj \ @@ -45,6 +46,7 @@ WIN_OBJS = \ $O\FileLink.obj \ $O\FileName.obj \ $O\FileSystem.obj \ + $O\MemoryGlobal.obj \ $O\MemoryLock.obj \ $O\PropVariant.obj \ $O\PropVariantConv.obj \ @@ -102,10 +104,12 @@ AR_COMMON_OBJS = \ $O\OutStreamWithCRC.obj \ FM_OBJS = \ + $O\EditDialog.obj \ $O\ExtractCallback.obj \ $O\FormatUtils.obj \ $O\HelpUtils.obj \ $O\LangUtils.obj \ + $O\ListViewDialog.obj \ $O\OpenCallback.obj \ $O\ProgramLocation.obj \ $O\PropertyName.obj \ diff --git a/CPP/7zip/UI/GUI/resource.rc b/CPP/7zip/UI/GUI/resource.rc index 13a09c64..04af8157 100644 --- a/CPP/7zip/UI/GUI/resource.rc +++ b/CPP/7zip/UI/GUI/resource.rc @@ -21,3 +21,5 @@ IDI_ICON ICON "FM.ico" #include "Extract.rc" #include "../FileManager/BrowseDialog.rc" #include "../FileManager/ComboDialog.rc" +#include "../FileManager/EditDialog.rc" +#include "../FileManager/ListViewDialog.rc" |