diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2018-01-30 03:15:34 +0300 |
---|---|---|
committer | Kornel <kornel@geekhood.net> | 2018-01-30 03:35:06 +0300 |
commit | 866a06f5a0c0ede11979504a318e150030aa7a11 (patch) | |
tree | bb8a2795afb445aa46167232254384ed82caf518 /CPP/7zip/UI | |
parent | da28077952faf9e716ed7987b842d31617a10125 (diff) |
18.0118.01
Diffstat (limited to 'CPP/7zip/UI')
-rw-r--r-- | CPP/7zip/UI/Agent/Agent.cpp | 9 | ||||
-rw-r--r-- | CPP/7zip/UI/Agent/Agent.h | 6 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | 100 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/ArchiveExtractCallback.h | 25 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/OpenArchive.cpp | 2 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/OpenArchive.h | 19 | ||||
-rw-r--r-- | CPP/7zip/UI/Common/Update.cpp | 61 |
7 files changed, 135 insertions, 87 deletions
diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp index e52e47d0..1c2e3397 100644 --- a/CPP/7zip/UI/Agent/Agent.cpp +++ b/CPP/7zip/UI/Agent/Agent.cpp @@ -1217,7 +1217,12 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) NWindows::NCOM::CPropVariant prop; if (propID == kpidReadOnly) - prop = _agentSpec->IsThereReadOnlyArc(); + { + if (_agentSpec->Is_Attrib_ReadOnly()) + prop = true; + else + prop = _agentSpec->IsThereReadOnlyArc(); + } else if (_proxy2) { const CProxyDir2 &dir = _proxy2->Dirs[_proxyDirIndex]; @@ -1564,6 +1569,7 @@ STDMETHODIMP CAgent::Open( { COM_TRY_BEGIN _archiveFilePath = filePath; + _attrib = 0; NFile::NFind::CFileInfo fi; _isDeviceFile = false; if (!inStream) @@ -1572,6 +1578,7 @@ STDMETHODIMP CAgent::Open( return ::GetLastError(); if (fi.IsDir()) return E_FAIL; + _attrib = fi.Attrib; _isDeviceFile = fi.IsDevice; } CArcInfoEx archiverInfo0, archiverInfo1; diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h index ae4026d6..7ba96f4a 100644 --- a/CPP/7zip/UI/Agent/Agent.h +++ b/CPP/7zip/UI/Agent/Agent.h @@ -241,6 +241,7 @@ public: CAgentFolder *_agentFolder; UString _archiveFilePath; + DWORD _attrib; bool _isDeviceFile; #ifndef EXTRACT_ONLY @@ -252,6 +253,11 @@ public: IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; } bool CanUpdate() const; + bool Is_Attrib_ReadOnly() const + { + return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY); + } + bool IsThereReadOnlyArc() const { FOR_VECTOR (i, _archiveLink.Arcs) diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp index 0571a452..083e7c84 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -372,6 +372,8 @@ void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPat HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined) { filetimeIsDefined = false; + filetime.dwLowDateTime = 0; + filetime.dwHighDateTime = 0; NCOM::CPropVariant prop; RINOK(_arc->Archive->GetProperty(index, propID, &prop)); if (prop.vt == VT_FILETIME) @@ -1032,14 +1034,36 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) { FString fullPathNew; CreateComplexDirectory(pathParts, fullPathNew); + if (_item.IsDir) { - _extractedFolderPaths.Add(fullPathNew); - _extractedFolderIndices.Add(index); - SetDirTime(fullPathNew, - (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL, - (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL, - (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); + CDirPathTime &pt = _extractedFolders.AddNew(); + + pt.CTime = _fi.CTime; + pt.CTimeDefined = (WriteCTime && _fi.CTimeDefined); + + pt.ATime = _fi.ATime; + pt.ATimeDefined = (WriteATime && _fi.ATimeDefined); + + pt.MTimeDefined = false; + + if (WriteMTime) + { + if (_fi.MTimeDefined) + { + pt.MTime = _fi.MTime; + pt.MTimeDefined = true; + } + else if (_arc->MTimeDefined) + { + pt.MTime = _arc->MTime; + pt.MTimeDefined = true; + } + } + + pt.Path = fullPathNew; + + pt.SetDirTime(); } } } @@ -1602,75 +1626,53 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) } -struct CExtrRefSortPair -{ - unsigned Len; - unsigned Index; - - int Compare(const CExtrRefSortPair &a) const; -}; - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -int CExtrRefSortPair::Compare(const CExtrRefSortPair &a) const -{ - RINOZ(-MyCompare(Len, a.Len)); - return MyCompare(Index, a.Index); -} - -static unsigned GetNumSlashes(const FChar *s) +void CDirPathSortPair::SetNumSlashes(const FChar *s) { for (unsigned numSlashes = 0;;) { FChar c = *s++; if (c == 0) - return numSlashes; + { + Len = numSlashes; + return; + } if (IS_PATH_SEPAR(c)) numSlashes++; } } +bool CDirPathTime::SetDirTime() +{ + return NDir::SetDirTime(Path, + CTimeDefined ? &CTime : NULL, + ATimeDefined ? &ATime : NULL, + MTimeDefined ? &MTime : NULL); +} + + HRESULT CArchiveExtractCallback::SetDirsTimes() { if (!_arc) return S_OK; - CRecordVector<CExtrRefSortPair> pairs; - pairs.ClearAndSetSize(_extractedFolderPaths.Size()); + CRecordVector<CDirPathSortPair> pairs; + pairs.ClearAndSetSize(_extractedFolders.Size()); unsigned i; - for (i = 0; i < _extractedFolderPaths.Size(); i++) + for (i = 0; i < _extractedFolders.Size(); i++) { - CExtrRefSortPair &pair = pairs[i]; + CDirPathSortPair &pair = pairs[i]; pair.Index = i; - pair.Len = GetNumSlashes(_extractedFolderPaths[i]); + pair.SetNumSlashes(_extractedFolders[i].Path); } pairs.Sort2(); for (i = 0; i < pairs.Size(); i++) { - unsigned pairIndex = pairs[i].Index; - UInt32 index = _extractedFolderIndices[pairIndex]; - - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - - RINOK(GetTime(index, kpidCTime, CTime, CTimeDefined)); - RINOK(GetTime(index, kpidATime, ATime, ATimeDefined)); - RINOK(GetTime(index, kpidMTime, MTime, MTimeDefined)); - - // printf("\n%S", _extractedFolderPaths[pairIndex]); - SetDirTime(_extractedFolderPaths[pairIndex], - (WriteCTime && CTimeDefined) ? &CTime : NULL, - (WriteATime && ATimeDefined) ? &ATime : NULL, - (WriteMTime && MTimeDefined) ? &MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); + _extractedFolders[pairs[i].Index].SetDirTime(); + // if (!) return GetLastError(); } ClearExtractedDirsInfo(); diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h index 4b96b523..dd5c98c0 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h @@ -151,6 +151,25 @@ struct CIndexToPathPair #endif + + +struct CDirPathTime +{ + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; + + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + + FString Path; + + bool SetDirTime(); +}; + + + class CArchiveExtractCallback: public IArchiveExtractCallback, public IArchiveExtractCallbackMessage, @@ -241,8 +260,7 @@ class CArchiveExtractCallback: UInt64 _progressTotal; bool _progressTotal_Defined; - FStringVector _extractedFolderPaths; - CRecordVector<UInt32> _extractedFolderIndices; + CObjectVector<CDirPathTime> _extractedFolders; #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) bool _saclEnabled; @@ -348,8 +366,7 @@ public: private: void ClearExtractedDirsInfo() { - _extractedFolderPaths.Clear(); - _extractedFolderIndices.Clear(); + _extractedFolders.Clear(); } HRESULT CloseFile(); diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp index 69817179..b9b4abd9 100644 --- a/CPP/7zip/UI/Common/OpenArchive.cpp +++ b/CPP/7zip/UI/Common/OpenArchive.cpp @@ -857,7 +857,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const if (item.WriteToAltStreamIfColon || needFindAltStream) { - /* Good handler must support GetRawProps::GetParent for alt streams./ + /* Good handler must support GetRawProps::GetParent for alt streams. So the following code currently is not used */ int colon = FindAltStreamColon_in_Path(item.Path); if (colon >= 0) diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h index d46d69e8..6eb0d395 100644 --- a/CPP/7zip/UI/Common/OpenArchive.h +++ b/CPP/7zip/UI/Common/OpenArchive.h @@ -414,4 +414,23 @@ struct CArchiveLink bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types); + +struct CDirPathSortPair +{ + unsigned Len; + unsigned Index; + + void SetNumSlashes(const FChar *s); + + int Compare(const CDirPathSortPair &a) const + { + // We need sorting order where parent items will be after child items + if (Len < a.Len) return 1; + if (Len > a.Len) return -1; + if (Index < a.Index) return -1; + if (Index > a.Index) return 1; + return 0; + } +}; + #endif diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp index f1826957..5d3c4484 100644 --- a/CPP/7zip/UI/Common/Update.cpp +++ b/CPP/7zip/UI/Common/Update.cpp @@ -1046,32 +1046,6 @@ static HRESULT EnumerateInArchiveItems( #endif -struct CRefSortPair -{ - unsigned Len; - unsigned Index; -}; - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -static int CompareRefSortPair(const CRefSortPair *a1, const CRefSortPair *a2, void *) -{ - RINOZ(-MyCompare(a1->Len, a2->Len)); - return MyCompare(a1->Index, a2->Index); -} - -static unsigned GetNumSlashes(const FChar *s) -{ - for (unsigned numSlashes = 0;;) - { - FChar c = *s++; - if (c == 0) - return numSlashes; - if (IS_PATH_SEPAR(c)) - numSlashes++; - } -} - #ifdef _WIN32 void ConvertToLongNames(NWildcard::CCensor &censor); #endif @@ -1190,6 +1164,16 @@ HRESULT UpdateArchive( throw "there is no such archive"; if (fi.IsDevice) return E_NOTIMPL; + + if (!options.StdOutMode && options.UpdateArchiveItself) + if (fi.IsReadOnly()) + { + errorInfo.SystemError = ERROR_ACCESS_DENIED; + errorInfo.Message = "The file is read-only"; + errorInfo.FileNames.Add(arcPath); + return errorInfo.Get_HRESULT_Error(); + } + if (options.VolumesSizes.Size() > 0) { errorInfo.FileNames.Add(us2fs(arcPath)); @@ -1510,9 +1494,13 @@ HRESULT UpdateArchive( CArchivePath &ap = options.Commands[0].ArchivePath; const FString &tempPath = ap.GetTempPath(); + // DWORD attrib = 0; if (thereIsInArchive) + { + // attrib = NFind::GetFileAttrib(us2fs(arcPath)); if (!DeleteFileAlways(us2fs(arcPath))) return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath)); + } if (!MyMoveFile(tempPath, us2fs(arcPath))) { @@ -1520,6 +1508,15 @@ HRESULT UpdateArchive( errorInfo.FileNames.Add(us2fs(arcPath)); return errorInfo.Get_HRESULT_Error(); } + + /* + if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) + { + DWORD attrib2 = NFind::GetFileAttrib(us2fs(arcPath)); + if (attrib2 != INVALID_FILE_ATTRIBUTES) + NDir::SetFileAttrib(us2fs(arcPath), attrib2 | FILE_ATTRIBUTE_READONLY); + } + */ } catch(...) { @@ -1609,7 +1606,7 @@ HRESULT UpdateArchive( if (options.DeleteAfterCompressing) { - CRecordVector<CRefSortPair> pairs; + CRecordVector<CDirPathSortPair> pairs; FStringVector foldersNames; unsigned i; @@ -1617,12 +1614,12 @@ HRESULT UpdateArchive( for (i = 0; i < dirItems.Items.Size(); i++) { const CDirItem &dirItem = dirItems.Items[i]; - FString phyPath = dirItems.GetPhyPath(i); + const FString phyPath = dirItems.GetPhyPath(i); if (dirItem.IsDir()) { - CRefSortPair pair; + CDirPathSortPair pair; pair.Index = i; - pair.Len = GetNumSlashes(phyPath); + pair.SetNumSlashes(phyPath); pairs.Add(pair); } else @@ -1655,11 +1652,11 @@ HRESULT UpdateArchive( } } - pairs.Sort(CompareRefSortPair, NULL); + pairs.Sort2(); for (i = 0; i < pairs.Size(); i++) { - FString phyPath = dirItems.GetPhyPath(pairs[i].Index); + const FString phyPath = dirItems.GetPhyPath(pairs[i].Index); if (NFind::DoesDirExist(phyPath)) { RINOK(callback->DeletingAfterArchiving(phyPath, true)); |