diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2015-08-16 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:55 +0300 |
commit | cba375916fb18db8b9101aedf4fa079e019311b3 (patch) | |
tree | 6275ae5fc2a8dd337ab0327180c871807e6ba5d4 /CPP/7zip/UI/Common | |
parent | 54490d51d5c6b0d794dcbad2d634d4c95fc25b6c (diff) |
15.0615.06
Diffstat (limited to 'CPP/7zip/UI/Common')
-rw-r--r-- | CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | 165 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/ArchiveExtractCallback.h | 9 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/ArchiveOpenCallback.h | 19 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/Bench.cpp | 3 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/LoadCodecs.cpp | 4 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/OpenArchive.cpp | 84 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/UpdateAction.h | 2 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/UpdateCallback.cpp | 2 |
8 files changed, 229 insertions, 59 deletions
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp index 8410756a..8e4936a9 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -5,6 +5,8 @@ #undef sprintf #undef printf +#include "../../../../C/Alloc.h" + #include "../../../Common/ComTry.h" #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" @@ -23,6 +25,7 @@ #endif #include "../../Common/FilePathAutoRename.h" +// #include "../../Common/StreamUtils.h" #include "../Common/ExtractingFilePath.h" #include "../Common/PropIDUtils.h" @@ -541,11 +544,54 @@ static FString MakePath_from_2_Parts(const FString &prefix, const FString &path) return s; } + +/* +#ifdef SUPPORT_LINKS + +struct CTempMidBuffer +{ + void *Buf; + + CTempMidBuffer(size_t size): Buf(NULL) { Buf = ::MidAlloc(size); } + ~CTempMidBuffer() { ::MidFree(Buf); } +}; + +HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream) +{ + const size_t kBufSize = 1 << 16; + CTempMidBuffer buf(kBufSize); + if (!buf.Buf) + return E_OUTOFMEMORY; + + NIO::CInFile inFile; + NIO::COutFile outFile; + + if (!inFile.Open(_CopyFile_Path)) + return SendMessageError_with_LastError("Open error", _CopyFile_Path); + + for (;;) + { + UInt32 num; + + if (!inFile.Read(buf.Buf, kBufSize, num)) + return SendMessageError_with_LastError("Read error", _CopyFile_Path); + + if (num == 0) + return S_OK; + + + RINOK(WriteStream(outStream, buf.Buf, num)); + } +} + +#endif +*/ + STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) { COM_TRY_BEGIN - *outStream = 0; + *outStream = NULL; #ifndef _SFX if (_hashStream) @@ -563,6 +609,11 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre _curSizeDefined = false; _index = index; + #ifdef SUPPORT_LINKS + // _CopyFile_Path.Empty(); + linkPath.Empty(); + #endif + IInArchive *archive = _arc->Archive; #ifndef _SFX @@ -596,46 +647,56 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre #ifdef SUPPORT_LINKS + // bool isCopyLink = false; bool isHardLink = false; bool isJunction = false; bool isRelative = false; - UString linkPath; - // RINOK(Archive_GetItemBoolProp(archive, index, kpidIsHardLink, isHardLink)); - // if (isHardLink) { NCOM::CPropVariant prop; RINOK(archive->GetProperty(index, kpidHardLink, &prop)); if (prop.vt == VT_BSTR) { isHardLink = true; + // isCopyLink = false; + isRelative = false; // RAR5, TAR: hard links are from root folder of archive linkPath.SetFromBstr(prop.bstrVal); - isRelative = false; // TAR: hard links are from root folder of archive } - else if (prop.vt == VT_EMPTY) + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + + /* + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidCopyLink, &prop)); + if (prop.vt == VT_BSTR) { - // linkPath.Empty(); + isHardLink = false; + isCopyLink = true; + isRelative = false; // RAR5: copy links are from root folder of archive + linkPath.SetFromBstr(prop.bstrVal); } - else + else if (prop.vt != VT_EMPTY) return E_FAIL; } + */ + { NCOM::CPropVariant prop; RINOK(archive->GetProperty(index, kpidSymLink, &prop)); if (prop.vt == VT_BSTR) { isHardLink = false; + // isCopyLink = false; + isRelative = true; // RAR5, TAR: symbolic links can be relative linkPath.SetFromBstr(prop.bstrVal); - isRelative = true; // TAR: symbolic links are relative } - else if (prop.vt == VT_EMPTY) - { - // linkPath.Empty(); - } - else + else if (prop.vt != VT_EMPTY) return E_FAIL; } + bool isOkReparse = false; if (linkPath.IsEmpty() && _arc->GetRawProps) @@ -643,7 +704,9 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre const void *data; UInt32 dataSize; UInt32 propType; + _arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType); + if (dataSize != 0) { if (propType != NPropDataType::kRaw) @@ -654,6 +717,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre if (isOkReparse) { isHardLink = false; + // isCopyLink = false; linkPath = reparse.GetPath(); isJunction = reparse.IsMountPoint(); isRelative = reparse.IsRelative(); @@ -669,6 +733,13 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre #ifdef _WIN32 linkPath.Replace(L'/', WCHAR_PATH_SEPARATOR); #endif + + // rar5 uses "\??\" prefix for absolute links + if (linkPath.IsPrefixedBy(WSTRING_PATH_SEPARATOR L"??" WSTRING_PATH_SEPARATOR)) + { + isRelative = false; + linkPath.DeleteFrontal(4); + } for (;;) // while (NName::IsAbsolutePath(linkPath)) @@ -1108,7 +1179,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) else { FString existPath; - if (isHardLink || !isRelative) + if (isHardLink /* || isCopyLink */ || !isRelative) { if (!NName::GetFullPath(_dirPathPrefix_Full, us2fs(relatPath), existPath)) { @@ -1122,13 +1193,37 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) if (!existPath.IsEmpty()) { - if (isHardLink) + if (isHardLink /* || isCopyLink */) { - if (!MyCreateHardLink(fullProcessedPath, existPath)) + // if (isHardLink) { - RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, existPath)); - // return S_OK; + if (!MyCreateHardLink(fullProcessedPath, existPath)) + { + RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, existPath)); + // return S_OK; + } } + /* + else + { + NFind::CFileInfo fi; + if (!fi.Find(existPath)) + { + RINOK(SendMessageError2("Can not find the file for copying", existPath, fullProcessedPath)); + } + else + { + if (_curSizeDefined && _curSize == fi.Size) + _CopyFile_Path = existPath; + else + { + RINOK(SendMessageError2("File size collision for file copying", existPath, fullProcessedPath)); + } + + // RINOK(MyCopyFile(existPath, fullProcessedPath)); + } + } + */ } else if (_ntOptions.SymLinks.Val) { @@ -1161,7 +1256,8 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) #endif } - else + + if (linkPath.IsEmpty() /* || !_CopyFile_Path.IsEmpty() */) #endif // SUPPORT_LINKS { bool needWriteFile = true; @@ -1225,6 +1321,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) { RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL)); } + _outFileStream = outStreamLoc; } } @@ -1250,12 +1347,34 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) #endif + if (outStreamLoc) + { + /* + #ifdef SUPPORT_LINKS + + if (!_CopyFile_Path.IsEmpty()) + { + RINOK(PrepareOperation(askExtractMode)); + RINOK(MyCopyFile(outStreamLoc)); + return SetOperationResult(NArchive::NExtract::NOperationResult::kOK); + } + + if (isCopyLink && _testMode) + return S_OK; + + #endif + */ + *outStream = outStreamLoc.Detach(); + } + return S_OK; + COM_TRY_END } + STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) { COM_TRY_BEGIN @@ -1266,6 +1385,7 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) #endif _extractMode = false; + switch (askExtractMode) { case NArchive::NExtract::NAskMode::kExtract: @@ -1282,6 +1402,7 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) COM_TRY_END } + STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) { COM_TRY_BEGIN @@ -1346,6 +1467,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) if (!_curSizeDefined) GetUnpackSize(); + if (_curSizeDefined) { #ifdef SUPPORT_ALT_STREAMS @@ -1367,8 +1489,11 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) if (_extractMode && _fi.AttribDefined) SetFileAttrib(_diskFilePath, _fi.Attrib); + RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted))); + return S_OK; + COM_TRY_END } diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h index 561a6e42..7d4155fe 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h @@ -299,14 +299,23 @@ public: const UStringVector &removePathParts, bool removePartsForAltStreams, UInt64 packSize); + #ifdef SUPPORT_LINKS + private: CHardLinks _hardLinks; + UString linkPath; + + // FString _CopyFile_Path; + // HRESULT MyCopyFile(ISequentialOutStream *outStream); + public: // call PrepareHardLinks() after Init() HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices); // NULL means all items + #endif + #ifdef SUPPORT_ALT_STREAMS CObjectVector<CIndexToPathPair> _renamedFiles; #endif diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/CPP/7zip/UI/Common/ArchiveOpenCallback.h index afa03766..e9575f56 100644 --- a/CPP/7zip/UI/Common/ArchiveOpenCallback.h +++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.h @@ -48,18 +48,13 @@ class COpenCallbackImp: public CMyUnknownImp { public: + MY_QUERYINTERFACE_BEGIN2(IArchiveOpenVolumeCallback) + MY_QUERYINTERFACE_ENTRY(IArchiveOpenSetSubArchiveName) #ifndef _NO_CRYPTO - MY_UNKNOWN_IMP3( - IArchiveOpenVolumeCallback, - ICryptoGetTextPassword, - IArchiveOpenSetSubArchiveName - ) - #else - MY_UNKNOWN_IMP2( - IArchiveOpenVolumeCallback, - IArchiveOpenSetSubArchiveName - ) + MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE INTERFACE_IArchiveOpenCallback(;) INTERFACE_IArchiveOpenVolumeCallback(;) @@ -93,7 +88,8 @@ public: CMyComPtr<IArchiveOpenCallback> ReOpenCallback; // UInt64 TotalSize; - COpenCallbackImp(): Callback(NULL) {} + COpenCallbackImp(): Callback(NULL), _subArchiveMode(false) {} + void Init(const FString &folderPrefix, const FString &fileName) { _folderPrefix = folderPrefix; @@ -106,6 +102,7 @@ public: // TotalSize = 0; PasswordWasAsked = false; } + bool SetSecondFileInfo(CFSTR newName) { return _fileInfo.Find(newName) && !_fileInfo.IsDir(); diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp index c38b132c..5f6373f4 100644 --- a/CPP/7zip/UI/Common/Bench.cpp +++ b/CPP/7zip/UI/Common/Bench.cpp @@ -1566,7 +1566,8 @@ static const CBenchHash g_Hash[] = { 10, 339, 0x8F8FEDAB, "CRC32:8" }, { 10, 512, 0xDF1C17CC, "CRC64" }, { 10, 5100, 0x2D79FF2E, "SHA256" }, - { 10, 2340, 0x4C25132B, "SHA1" } + { 10, 2340, 0x4C25132B, "SHA1" }, + { 2, 5500, 0xE084E913, "BLAKE2sp" } }; struct CTotalBenchRes diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp index 696b6749..5435499b 100644 --- a/CPP/7zip/UI/Common/LoadCodecs.cpp +++ b/CPP/7zip/UI/Common/LoadCodecs.cpp @@ -865,7 +865,7 @@ STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder) { const CCodecLib &lib = Libs[ci.LibIndex]; if (lib.CreateDecoder) - return lib.CreateDecoder(index - NUM_EXPORT_CODECS, iid, (void **)coder); + return lib.CreateDecoder(ci.CodecIndex, iid, (void **)coder); return lib.CreateObject(&ci.Decoder, iid, (void **)coder); } return S_OK; @@ -887,7 +887,7 @@ STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder) { const CCodecLib &lib = Libs[ci.LibIndex]; if (lib.CreateEncoder) - return lib.CreateEncoder(index - NUM_EXPORT_CODECS, iid, (void **)coder); + return lib.CreateEncoder(ci.CodecIndex, iid, (void **)coder); return lib.CreateObject(&ci.Encoder, iid, (void **)coder); } return S_OK; diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp index acc10876..a7488044 100644 --- a/CPP/7zip/UI/Common/OpenArchive.cpp +++ b/CPP/7zip/UI/Common/OpenArchive.cpp @@ -1083,6 +1083,7 @@ static bool IsNewStyleSignature(const CArcInfoEx &ai) class CArchiveOpenCallback_Offset: public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, #ifndef _NO_CRYPTO public ICryptoGetTextPassword, #endif @@ -1090,19 +1091,24 @@ class CArchiveOpenCallback_Offset: { public: CMyComPtr<IArchiveOpenCallback> Callback; + CMyComPtr<IArchiveOpenVolumeCallback> OpenVolumeCallback; UInt64 Files; UInt64 Offset; #ifndef _NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> GetTextPassword; - MY_UNKNOWN_IMP2( - IArchiveOpenCallback, - ICryptoGetTextPassword) - #else - MY_UNKNOWN_IMP1(IArchiveOpenCallback) #endif - STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); - STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); + + MY_QUERYINTERFACE_BEGIN2(IArchiveOpenCallback) + MY_QUERYINTERFACE_ENTRY(IArchiveOpenVolumeCallback) + #ifndef _NO_CRYPTO + MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) + #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + INTERFACE_IArchiveOpenCallback(;) + INTERFACE_IArchiveOpenVolumeCallback(;) #ifndef _NO_CRYPTO STDMETHOD(CryptoGetTextPassword)(BSTR *password); #endif @@ -1119,12 +1125,12 @@ STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password) } #endif -STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) +STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *) { return S_OK; } -STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 * /* files */, const UInt64 *bytes) +STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes) { if (!Callback) return S_OK; @@ -1134,8 +1140,25 @@ STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 * /* files * return Callback->SetCompleted(&Files, &value); } +STDMETHODIMP CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value) +{ + if (OpenVolumeCallback) + return OpenVolumeCallback->GetProperty(propID, value); + NCOM::PropVariant_Clear(value); + return S_OK; + // return E_NOTIMPL; +} + +STDMETHODIMP CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream) +{ + if (OpenVolumeCallback) + return OpenVolumeCallback->GetStream(name, inStream); + return S_FALSE; +} + #endif + UInt32 GetOpenArcErrorFlags(const NCOM::CPropVariant &prop, bool *isDefinedProp) { if (isDefinedProp != NULL) @@ -2208,9 +2231,6 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } { - CArchiveOpenCallback_Offset *openCallback_Offset_Spec = new CArchiveOpenCallback_Offset; - CMyComPtr<IArchiveOpenCallback> openCallback_Offset = openCallback_Offset_Spec; - const size_t kBeforeSize = 1 << 16; const size_t kAfterSize = 1 << 20; const size_t kBufSize = 1 << 22; // it must be more than kBeforeSize + kAfterSize @@ -2288,14 +2308,18 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) CMyComPtr<IInStream> limitedStream = limitedStreamSpec; limitedStreamSpec->SetStream(op.stream); - openCallback_Offset_Spec->Callback = op.callback; - - #ifndef _NO_CRYPTO + CArchiveOpenCallback_Offset *openCallback_Offset_Spec = NULL; + CMyComPtr<IArchiveOpenCallback> openCallback_Offset; if (op.callback) { + openCallback_Offset_Spec = new CArchiveOpenCallback_Offset; + openCallback_Offset = openCallback_Offset_Spec; + openCallback_Offset_Spec->Callback = op.callback; + openCallback_Offset_Spec->Callback.QueryInterface(IID_IArchiveOpenVolumeCallback, &openCallback_Offset_Spec->OpenVolumeCallback); + #ifndef _NO_CRYPTO openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword); + #endif } - #endif if (op.callback) RINOK(op.callback->SetTotal(NULL, &fileSize)); @@ -2382,12 +2406,19 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } } - if (pos >= callbackPrev + (1 << 23)) + bool useOffsetCallback = false; + if (openCallback_Offset) { openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); openCallback_Offset_Spec->Offset = pos; - RINOK(openCallback_Offset->SetCompleted(NULL, NULL)); - callbackPrev = pos; + + useOffsetCallback = (!op.openType.CanReturnArc || handlerSpec->_items.Size() > 1); + + if (pos >= callbackPrev + (1 << 23)) + { + RINOK(openCallback_Offset_Spec->SetCompleted(NULL, NULL)); + callbackPrev = pos; + } } { @@ -2557,14 +2588,21 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } UInt64 maxCheckStartPosition = 0; - openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); - openCallback_Offset_Spec->Offset = startArcPos; + + if (openCallback_Offset) + { + openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); + openCallback_Offset_Spec->Offset = startArcPos; + } + // HRESULT result = archive->Open(limitedStream, &maxCheckStartPosition, openCallback_Offset); extractCallback_To_OpenCallback_Spec->Files = 0; extractCallback_To_OpenCallback_Spec->Offset = startArcPos; - HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition, openCallback_Offset, extractCallback_To_OpenCallback); - + HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition, + useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback, + extractCallback_To_OpenCallback); + RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)); bool isOpen = false; diff --git a/CPP/7zip/UI/Common/UpdateAction.h b/CPP/7zip/UI/Common/UpdateAction.h index 28dd28c3..bc53fcdb 100644 --- a/CPP/7zip/UI/Common/UpdateAction.h +++ b/CPP/7zip/UI/Common/UpdateAction.h @@ -35,7 +35,7 @@ namespace NUpdateArchive { { NPairAction::EEnum StateActions[NPairState::kNumValues]; - const bool IsEqualTo(const CActionSet &a) const + bool IsEqualTo(const CActionSet &a) const { for (unsigned i = 0; i < NPairState::kNumValues; i++) if (StateActions[i] != a.StateActions[i]) diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp index 993ab266..058e9153 100644 --- a/CPP/7zip/UI/Common/UpdateCallback.cpp +++ b/CPP/7zip/UI/Common/UpdateCallback.cpp @@ -413,7 +413,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR { case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break; case kpidIsDir: prop = di.IsDir(); break; - case kpidSize: prop = di.Size; break; + case kpidSize: prop = di.IsDir() ? (UInt64)0 : di.Size; break; case kpidAttrib: prop = di.Attrib; break; case kpidCTime: prop = di.CTime; break; case kpidATime: prop = di.ATime; break; |