diff options
Diffstat (limited to '')
30 files changed, 1796 insertions, 440 deletions
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index 91ef038..d88c851 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp | |||
@@ -160,7 +160,11 @@ enum Enum | |||
160 | kSymLinks_AllowDangerous, | 160 | kSymLinks_AllowDangerous, |
161 | kSymLinks, | 161 | kSymLinks, |
162 | kNtSecurity, | 162 | kNtSecurity, |
163 | |||
164 | kStoreOwnerId, | ||
165 | kStoreOwnerName, | ||
163 | 166 | ||
167 | kZoneFile, | ||
164 | kAltStreams, | 168 | kAltStreams, |
165 | kReplaceColonForAltStream, | 169 | kReplaceColonForAltStream, |
166 | kWriteToAltStreamIfColon, | 170 | kWriteToAltStreamIfColon, |
@@ -304,7 +308,11 @@ static const CSwitchForm kSwitchForms[] = | |||
304 | { "snld", SWFRM_MINUS }, | 308 | { "snld", SWFRM_MINUS }, |
305 | { "snl", SWFRM_MINUS }, | 309 | { "snl", SWFRM_MINUS }, |
306 | { "sni", SWFRM_SIMPLE }, | 310 | { "sni", SWFRM_SIMPLE }, |
311 | |||
312 | { "snoi", SWFRM_MINUS }, | ||
313 | { "snon", SWFRM_MINUS }, | ||
307 | 314 | ||
315 | { "snz", SWFRM_STRING_SINGL(0) }, | ||
308 | { "sns", SWFRM_MINUS }, | 316 | { "sns", SWFRM_MINUS }, |
309 | { "snr", SWFRM_SIMPLE }, | 317 | { "snr", SWFRM_SIMPLE }, |
310 | { "snc", SWFRM_SIMPLE }, | 318 | { "snc", SWFRM_SIMPLE }, |
@@ -1032,9 +1040,9 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, | |||
1032 | 1040 | ||
1033 | if (parser[NKey::kCaseSensitive].ThereIs) | 1041 | if (parser[NKey::kCaseSensitive].ThereIs) |
1034 | { | 1042 | { |
1043 | options.CaseSensitive = | ||
1035 | g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus; | 1044 | g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus; |
1036 | options.CaseSensitiveChange = true; | 1045 | options.CaseSensitive_Change = true; |
1037 | options.CaseSensitive = g_CaseSensitive; | ||
1038 | } | 1046 | } |
1039 | 1047 | ||
1040 | 1048 | ||
@@ -1367,6 +1375,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) | |||
1367 | SetBoolPair(parser, NKey::kAltStreams, options.AltStreams); | 1375 | SetBoolPair(parser, NKey::kAltStreams, options.AltStreams); |
1368 | SetBoolPair(parser, NKey::kHardLinks, options.HardLinks); | 1376 | SetBoolPair(parser, NKey::kHardLinks, options.HardLinks); |
1369 | SetBoolPair(parser, NKey::kSymLinks, options.SymLinks); | 1377 | SetBoolPair(parser, NKey::kSymLinks, options.SymLinks); |
1378 | |||
1379 | SetBoolPair(parser, NKey::kStoreOwnerId, options.StoreOwnerId); | ||
1380 | SetBoolPair(parser, NKey::kStoreOwnerName, options.StoreOwnerName); | ||
1370 | 1381 | ||
1371 | CBoolPair symLinks_AllowDangerous; | 1382 | CBoolPair symLinks_AllowDangerous; |
1372 | SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous); | 1383 | SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous); |
@@ -1420,12 +1431,28 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) | |||
1420 | nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs; | 1431 | nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs; |
1421 | nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs; | 1432 | nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs; |
1422 | 1433 | ||
1434 | nt.ExtractOwner = options.StoreOwnerId.Val; // StoreOwnerName | ||
1435 | |||
1423 | if (parser[NKey::kPreserveATime].ThereIs) | 1436 | if (parser[NKey::kPreserveATime].ThereIs) |
1424 | nt.PreserveATime = true; | 1437 | nt.PreserveATime = true; |
1425 | if (parser[NKey::kShareForWrite].ThereIs) | 1438 | if (parser[NKey::kShareForWrite].ThereIs) |
1426 | nt.OpenShareForWrite = true; | 1439 | nt.OpenShareForWrite = true; |
1427 | } | 1440 | } |
1428 | 1441 | ||
1442 | if (parser[NKey::kZoneFile].ThereIs) | ||
1443 | { | ||
1444 | eo.ZoneMode = NExtract::NZoneIdMode::kAll; | ||
1445 | const UString &s = parser[NKey::kZoneFile].PostStrings[0]; | ||
1446 | if (!s.IsEmpty()) | ||
1447 | { | ||
1448 | if (s == L"0") eo.ZoneMode = NExtract::NZoneIdMode::kNone; | ||
1449 | else if (s == L"1") eo.ZoneMode = NExtract::NZoneIdMode::kAll; | ||
1450 | else if (s == L"2") eo.ZoneMode = NExtract::NZoneIdMode::kOffice; | ||
1451 | else | ||
1452 | throw CArcCmdLineException("Unsupported -snz:", s); | ||
1453 | } | ||
1454 | } | ||
1455 | |||
1429 | options.Censor.AddPathsToCensor(NWildcard::k_AbsPath); | 1456 | options.Censor.AddPathsToCensor(NWildcard::k_AbsPath); |
1430 | options.Censor.ExtendExclude(); | 1457 | options.Censor.ExtendExclude(); |
1431 | 1458 | ||
@@ -1549,6 +1576,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) | |||
1549 | updateOptions.NtSecurity = options.NtSecurity; | 1576 | updateOptions.NtSecurity = options.NtSecurity; |
1550 | updateOptions.HardLinks = options.HardLinks; | 1577 | updateOptions.HardLinks = options.HardLinks; |
1551 | updateOptions.SymLinks = options.SymLinks; | 1578 | updateOptions.SymLinks = options.SymLinks; |
1579 | |||
1580 | updateOptions.StoreOwnerId = options.StoreOwnerId; | ||
1581 | updateOptions.StoreOwnerName = options.StoreOwnerName; | ||
1552 | 1582 | ||
1553 | updateOptions.EMailMode = parser[NKey::kEmail].ThereIs; | 1583 | updateOptions.EMailMode = parser[NKey::kEmail].ThereIs; |
1554 | if (updateOptions.EMailMode) | 1584 | if (updateOptions.EMailMode) |
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h index ff4f28c..745f999 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.h +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h | |||
@@ -51,7 +51,7 @@ struct CArcCmdLineOptions | |||
51 | bool HelpMode; | 51 | bool HelpMode; |
52 | 52 | ||
53 | // bool LargePages; | 53 | // bool LargePages; |
54 | bool CaseSensitiveChange; | 54 | bool CaseSensitive_Change; |
55 | bool CaseSensitive; | 55 | bool CaseSensitive; |
56 | 56 | ||
57 | bool IsInTerminal; | 57 | bool IsInTerminal; |
@@ -97,6 +97,9 @@ struct CArcCmdLineOptions | |||
97 | CBoolPair AltStreams; | 97 | CBoolPair AltStreams; |
98 | CBoolPair HardLinks; | 98 | CBoolPair HardLinks; |
99 | CBoolPair SymLinks; | 99 | CBoolPair SymLinks; |
100 | |||
101 | CBoolPair StoreOwnerId; | ||
102 | CBoolPair StoreOwnerName; | ||
100 | 103 | ||
101 | CUpdateOptions UpdateOptions; | 104 | CUpdateOptions UpdateOptions; |
102 | CHashOptions HashOptions; | 105 | CHashOptions HashOptions; |
@@ -117,7 +120,7 @@ struct CArcCmdLineOptions | |||
117 | CArcCmdLineOptions(): | 120 | CArcCmdLineOptions(): |
118 | HelpMode(false), | 121 | HelpMode(false), |
119 | // LargePages(false), | 122 | // LargePages(false), |
120 | CaseSensitiveChange(false), | 123 | CaseSensitive_Change(false), |
121 | CaseSensitive(false), | 124 | CaseSensitive(false), |
122 | 125 | ||
123 | IsInTerminal(false), | 126 | IsInTerminal(false), |
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp index 73c191e..a574f13 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | |||
@@ -95,6 +95,83 @@ bool InitLocalPrivileges() | |||
95 | #endif // _USE_SECURITY_CODE | 95 | #endif // _USE_SECURITY_CODE |
96 | 96 | ||
97 | 97 | ||
98 | |||
99 | #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) | ||
100 | |||
101 | static const char * const kOfficeExtensions = | ||
102 | " doc dot wbk" | ||
103 | " docx docm dotx dotm docb wll wwl" | ||
104 | " xls xlt xlm" | ||
105 | " xlsx xlsm xltx xltm xlsb xla xlam" | ||
106 | " ppt pot pps ppa ppam" | ||
107 | " pptx pptm potx potm ppam ppsx ppsm sldx sldm" | ||
108 | " "; | ||
109 | |||
110 | static bool FindExt2(const char *p, const UString &name) | ||
111 | { | ||
112 | const int pathPos = name.ReverseFind_PathSepar(); | ||
113 | const int dotPos = name.ReverseFind_Dot(); | ||
114 | if (dotPos < 0 | ||
115 | || dotPos < pathPos | ||
116 | || dotPos == (int)name.Len() - 1) | ||
117 | return false; | ||
118 | |||
119 | AString s; | ||
120 | for (unsigned pos = dotPos + 1;; pos++) | ||
121 | { | ||
122 | const wchar_t c = name[pos]; | ||
123 | if (c <= 0) | ||
124 | break; | ||
125 | if (c >= 0x80) | ||
126 | return false; | ||
127 | s += (char)MyCharLower_Ascii((char)c); | ||
128 | } | ||
129 | for (unsigned i = 0; p[i] != 0;) | ||
130 | { | ||
131 | unsigned j; | ||
132 | for (j = i; p[j] != ' '; j++); | ||
133 | if (s.Len() == j - i && memcmp(p + i, (const char *)s, s.Len()) == 0) | ||
134 | return true; | ||
135 | i = j + 1; | ||
136 | } | ||
137 | return false; | ||
138 | } | ||
139 | |||
140 | |||
141 | static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier"); | ||
142 | |||
143 | void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf) | ||
144 | { | ||
145 | FString fileName = fileName2; | ||
146 | fileName += k_ZoneId_StreamName; | ||
147 | |||
148 | buf.Free(); | ||
149 | NIO::CInFile file; | ||
150 | if (!file.Open(fileName)) | ||
151 | return; | ||
152 | UInt64 fileSize; | ||
153 | if (!file.GetLength(fileSize)) | ||
154 | return; | ||
155 | if (fileSize == 0 || fileSize >= ((UInt32)1 << 16)) | ||
156 | return; | ||
157 | buf.Alloc((size_t)fileSize); | ||
158 | size_t processed; | ||
159 | if (file.ReadFull(buf, (size_t)fileSize, processed) && processed == fileSize) | ||
160 | return; | ||
161 | buf.Free(); | ||
162 | } | ||
163 | |||
164 | static bool WriteZoneFile(CFSTR fileName, const CByteBuffer &buf) | ||
165 | { | ||
166 | NIO::COutFile file; | ||
167 | if (!file.Create(fileName, true)) | ||
168 | return false; | ||
169 | return file.WriteFull(buf, buf.Size()); | ||
170 | } | ||
171 | |||
172 | #endif | ||
173 | |||
174 | |||
98 | #ifdef SUPPORT_LINKS | 175 | #ifdef SUPPORT_LINKS |
99 | 176 | ||
100 | int CHardLinkNode::Compare(const CHardLinkNode &a) const | 177 | int CHardLinkNode::Compare(const CHardLinkNode &a) const |
@@ -190,9 +267,9 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r | |||
190 | 267 | ||
191 | CArchiveExtractCallback::CArchiveExtractCallback(): | 268 | CArchiveExtractCallback::CArchiveExtractCallback(): |
192 | _arc(NULL), | 269 | _arc(NULL), |
193 | WriteCTime(true), | 270 | Write_CTime(true), |
194 | WriteATime(true), | 271 | Write_ATime(true), |
195 | WriteMTime(true), | 272 | Write_MTime(true), |
196 | _multiArchives(false) | 273 | _multiArchives(false) |
197 | { | 274 | { |
198 | LocalProgressSpec = new CLocalProgress(); | 275 | LocalProgressSpec = new CLocalProgress(); |
@@ -204,6 +281,13 @@ CArchiveExtractCallback::CArchiveExtractCallback(): | |||
204 | } | 281 | } |
205 | 282 | ||
206 | 283 | ||
284 | void CArchiveExtractCallback::InitBeforeNewArchive() | ||
285 | { | ||
286 | #if defined(_WIN32) && !defined(UNDER_CE) | ||
287 | ZoneBuf.Free(); | ||
288 | #endif | ||
289 | } | ||
290 | |||
207 | void CArchiveExtractCallback::Init( | 291 | void CArchiveExtractCallback::Init( |
208 | const CExtractNtOptions &ntOptions, | 292 | const CExtractNtOptions &ntOptions, |
209 | const NWildcard::CCensorNode *wildcardCensor, | 293 | const NWildcard::CCensorNode *wildcardCensor, |
@@ -240,13 +324,19 @@ void CArchiveExtractCallback::Init( | |||
240 | _progressTotal_Defined = true; | 324 | _progressTotal_Defined = true; |
241 | 325 | ||
242 | _extractCallback2 = extractCallback2; | 326 | _extractCallback2 = extractCallback2; |
327 | |||
243 | _compressProgress.Release(); | 328 | _compressProgress.Release(); |
244 | _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); | 329 | _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); |
330 | |||
331 | _callbackMessage.Release(); | ||
245 | _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage, &_callbackMessage); | 332 | _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage, &_callbackMessage); |
333 | |||
334 | _folderArchiveExtractCallback2.Release(); | ||
246 | _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2); | 335 | _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2); |
247 | 336 | ||
248 | #ifndef _SFX | 337 | #ifndef _SFX |
249 | 338 | ||
339 | ExtractToStreamCallback.Release(); | ||
250 | _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback); | 340 | _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback); |
251 | if (ExtractToStreamCallback) | 341 | if (ExtractToStreamCallback) |
252 | { | 342 | { |
@@ -416,26 +506,22 @@ void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPat | |||
416 | } | 506 | } |
417 | 507 | ||
418 | 508 | ||
419 | HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined) | 509 | HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, CArcTime &ft) |
420 | { | 510 | { |
421 | filetimeIsDefined = false; | 511 | ft.Clear(); |
422 | filetime.dwLowDateTime = 0; | ||
423 | filetime.dwHighDateTime = 0; | ||
424 | NCOM::CPropVariant prop; | 512 | NCOM::CPropVariant prop; |
425 | RINOK(_arc->Archive->GetProperty(index, propID, &prop)); | 513 | RINOK(_arc->Archive->GetProperty(index, propID, &prop)); |
426 | if (prop.vt == VT_FILETIME) | 514 | if (prop.vt == VT_FILETIME) |
427 | { | 515 | ft.Set_From_Prop(prop); |
428 | filetime = prop.filetime; | ||
429 | filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0); | ||
430 | } | ||
431 | else if (prop.vt != VT_EMPTY) | 516 | else if (prop.vt != VT_EMPTY) |
432 | return E_FAIL; | 517 | return E_FAIL; |
433 | return S_OK; | 518 | return S_OK; |
434 | } | 519 | } |
435 | 520 | ||
521 | |||
436 | HRESULT CArchiveExtractCallback::GetUnpackSize() | 522 | HRESULT CArchiveExtractCallback::GetUnpackSize() |
437 | { | 523 | { |
438 | return _arc->GetItemSize(_index, _curSize, _curSizeDefined); | 524 | return _arc->GetItem_Size(_index, _curSize, _curSizeDefined); |
439 | } | 525 | } |
440 | 526 | ||
441 | static void AddPathToMessage(UString &s, const FString &path) | 527 | static void AddPathToMessage(UString &s, const FString &path) |
@@ -454,8 +540,9 @@ HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FSt | |||
454 | HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path) | 540 | HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path) |
455 | { | 541 | { |
456 | DWORD errorCode = GetLastError(); | 542 | DWORD errorCode = GetLastError(); |
543 | if (errorCode == 0) | ||
544 | errorCode = (DWORD)E_FAIL; | ||
457 | UString s (message); | 545 | UString s (message); |
458 | if (errorCode != 0) | ||
459 | { | 546 | { |
460 | s += " : "; | 547 | s += " : "; |
461 | s += NError::MyFormatMessage(errorCode); | 548 | s += NError::MyFormatMessage(errorCode); |
@@ -843,13 +930,58 @@ HRESULT CArchiveExtractCallback::ReadLink() | |||
843 | #endif // SUPPORT_LINKS | 930 | #endif // SUPPORT_LINKS |
844 | 931 | ||
845 | 932 | ||
933 | #ifndef _WIN32 | ||
934 | |||
935 | static HRESULT GetOwner(IInArchive *archive, | ||
936 | UInt32 index, UInt32 pidName, UInt32 pidId, COwnerInfo &res) | ||
937 | { | ||
938 | { | ||
939 | NWindows::NCOM::CPropVariant prop; | ||
940 | RINOK(archive->GetProperty(index, pidId, &prop)); | ||
941 | if (prop.vt == VT_UI4) | ||
942 | { | ||
943 | res.Id_Defined = true; | ||
944 | res.Id = prop.ulVal; // for debug | ||
945 | // res.Id++; // for debug | ||
946 | // if (pidId == kpidGroupId) res.Id += 7; // for debug | ||
947 | // res.Id = 0; // for debug | ||
948 | } | ||
949 | else if (prop.vt != VT_EMPTY) | ||
950 | return E_INVALIDARG; | ||
951 | } | ||
952 | { | ||
953 | NWindows::NCOM::CPropVariant prop; | ||
954 | RINOK(archive->GetProperty(index, pidName, &prop)); | ||
955 | if (prop.vt == VT_BSTR) | ||
956 | { | ||
957 | const UString s = prop.bstrVal; | ||
958 | ConvertUnicodeToUTF8(s, res.Name); | ||
959 | } | ||
960 | else if (prop.vt == VT_UI4) | ||
961 | { | ||
962 | res.Id_Defined = true; | ||
963 | res.Id = prop.ulVal; | ||
964 | } | ||
965 | else if (prop.vt != VT_EMPTY) | ||
966 | return E_INVALIDARG; | ||
967 | } | ||
968 | return S_OK; | ||
969 | } | ||
970 | |||
971 | #endif | ||
972 | |||
846 | 973 | ||
847 | HRESULT CArchiveExtractCallback::Read_fi_Props() | 974 | HRESULT CArchiveExtractCallback::Read_fi_Props() |
848 | { | 975 | { |
849 | IInArchive *archive = _arc->Archive; | 976 | IInArchive *archive = _arc->Archive; |
850 | const UInt32 index = _index; | 977 | const UInt32 index = _index; |
851 | 978 | ||
852 | _fi.AttribDefined = false; | 979 | _fi.Attrib_Defined = false; |
980 | |||
981 | #ifndef _WIN32 | ||
982 | _fi.Owner.Clear(); | ||
983 | _fi.Group.Clear(); | ||
984 | #endif | ||
853 | 985 | ||
854 | { | 986 | { |
855 | NCOM::CPropVariant prop; | 987 | NCOM::CPropVariant prop; |
@@ -868,15 +1000,25 @@ HRESULT CArchiveExtractCallback::Read_fi_Props() | |||
868 | if (prop.vt == VT_UI4) | 1000 | if (prop.vt == VT_UI4) |
869 | { | 1001 | { |
870 | _fi.Attrib = prop.ulVal; | 1002 | _fi.Attrib = prop.ulVal; |
871 | _fi.AttribDefined = true; | 1003 | _fi.Attrib_Defined = true; |
872 | } | 1004 | } |
873 | else if (prop.vt != VT_EMPTY) | 1005 | else if (prop.vt != VT_EMPTY) |
874 | return E_FAIL; | 1006 | return E_FAIL; |
875 | } | 1007 | } |
876 | 1008 | ||
877 | RINOK(GetTime(index, kpidCTime, _fi.CTime, _fi.CTimeDefined)); | 1009 | RINOK(GetTime(index, kpidCTime, _fi.CTime)); |
878 | RINOK(GetTime(index, kpidATime, _fi.ATime, _fi.ATimeDefined)); | 1010 | RINOK(GetTime(index, kpidATime, _fi.ATime)); |
879 | RINOK(GetTime(index, kpidMTime, _fi.MTime, _fi.MTimeDefined)); | 1011 | RINOK(GetTime(index, kpidMTime, _fi.MTime)); |
1012 | |||
1013 | #ifndef _WIN32 | ||
1014 | if (_ntOptions.ExtractOwner) | ||
1015 | { | ||
1016 | // SendMessageError_with_LastError("_ntOptions.ExtractOwner", _diskFilePath); | ||
1017 | GetOwner(archive, index, kpidUser, kpidUserId, _fi.Owner); | ||
1018 | GetOwner(archive, index, kpidGroup, kpidGroupId, _fi.Group); | ||
1019 | } | ||
1020 | #endif | ||
1021 | |||
880 | return S_OK; | 1022 | return S_OK; |
881 | } | 1023 | } |
882 | 1024 | ||
@@ -923,6 +1065,39 @@ void CArchiveExtractCallback::CorrectPathParts() | |||
923 | } | 1065 | } |
924 | 1066 | ||
925 | 1067 | ||
1068 | void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt) | ||
1069 | { | ||
1070 | pt.CTime_Defined = false; | ||
1071 | pt.ATime_Defined = false; | ||
1072 | pt.MTime_Defined = false; | ||
1073 | |||
1074 | if (Write_MTime) | ||
1075 | { | ||
1076 | if (_fi.MTime.Def) | ||
1077 | { | ||
1078 | _fi.MTime.Write_To_FiTime(pt.MTime); | ||
1079 | pt.MTime_Defined = true; | ||
1080 | } | ||
1081 | else if (_arc->MTime.Def) | ||
1082 | { | ||
1083 | _arc->MTime.Write_To_FiTime(pt.MTime); | ||
1084 | pt.MTime_Defined = true; | ||
1085 | } | ||
1086 | } | ||
1087 | |||
1088 | if (Write_CTime && _fi.CTime.Def) | ||
1089 | { | ||
1090 | _fi.CTime.Write_To_FiTime(pt.CTime); | ||
1091 | pt.CTime_Defined = true; | ||
1092 | } | ||
1093 | |||
1094 | if (Write_ATime && _fi.ATime.Def) | ||
1095 | { | ||
1096 | _fi.ATime.Write_To_FiTime(pt.ATime); | ||
1097 | pt.ATime_Defined = true; | ||
1098 | } | ||
1099 | } | ||
1100 | |||
926 | 1101 | ||
927 | void CArchiveExtractCallback::CreateFolders() | 1102 | void CArchiveExtractCallback::CreateFolders() |
928 | { | 1103 | { |
@@ -948,30 +1123,9 @@ void CArchiveExtractCallback::CreateFolders() | |||
948 | return; | 1123 | return; |
949 | 1124 | ||
950 | CDirPathTime pt; | 1125 | CDirPathTime pt; |
951 | 1126 | GetFiTimesCAM(pt); | |
952 | pt.CTime = _fi.CTime; | 1127 | |
953 | pt.CTimeDefined = (WriteCTime && _fi.CTimeDefined); | 1128 | if (pt.IsSomeTimeDefined()) |
954 | |||
955 | pt.ATime = _fi.ATime; | ||
956 | pt.ATimeDefined = (WriteATime && _fi.ATimeDefined); | ||
957 | |||
958 | pt.MTimeDefined = false; | ||
959 | |||
960 | if (WriteMTime) | ||
961 | { | ||
962 | if (_fi.MTimeDefined) | ||
963 | { | ||
964 | pt.MTime = _fi.MTime; | ||
965 | pt.MTimeDefined = true; | ||
966 | } | ||
967 | else if (_arc->MTimeDefined) | ||
968 | { | ||
969 | pt.MTime = _arc->MTime; | ||
970 | pt.MTimeDefined = true; | ||
971 | } | ||
972 | } | ||
973 | |||
974 | if (pt.MTimeDefined || pt.ATimeDefined || pt.CTimeDefined) | ||
975 | { | 1129 | { |
976 | pt.Path = fullPathNew; | 1130 | pt.Path = fullPathNew; |
977 | pt.SetDirTime(); | 1131 | pt.SetDirTime(); |
@@ -1006,10 +1160,13 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool | |||
1006 | /* (fileInfo) can be symbolic link. | 1160 | /* (fileInfo) can be symbolic link. |
1007 | we can show final file properties here. */ | 1161 | we can show final file properties here. */ |
1008 | 1162 | ||
1163 | FILETIME ft1; | ||
1164 | FiTime_To_FILETIME(fileInfo.MTime, ft1); | ||
1165 | |||
1009 | Int32 overwriteResult; | 1166 | Int32 overwriteResult; |
1010 | RINOK(_extractCallback2->AskOverwrite( | 1167 | RINOK(_extractCallback2->AskOverwrite( |
1011 | fs2us(realFullProcessedPath), &fileInfo.MTime, &fileInfo.Size, _item.Path, | 1168 | fs2us(realFullProcessedPath), &ft1, &fileInfo.Size, _item.Path, |
1012 | _fi.MTimeDefined ? &_fi.MTime : NULL, | 1169 | _fi.MTime.Def ? &_fi.MTime.FT : NULL, |
1013 | _curSizeDefined ? &_curSize : NULL, | 1170 | _curSizeDefined ? &_curSize : NULL, |
1014 | &overwriteResult)) | 1171 | &overwriteResult)) |
1015 | 1172 | ||
@@ -1126,7 +1283,7 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream | |||
1126 | const UInt32 index = _index; | 1283 | const UInt32 index = _index; |
1127 | 1284 | ||
1128 | bool isAnti = false; | 1285 | bool isAnti = false; |
1129 | RINOK(_arc->IsItemAnti(index, isAnti)); | 1286 | RINOK(_arc->IsItem_Anti(index, isAnti)); |
1130 | 1287 | ||
1131 | CorrectPathParts(); | 1288 | CorrectPathParts(); |
1132 | UString processedPath (MakePathFromParts(_item.PathParts)); | 1289 | UString processedPath (MakePathFromParts(_item.PathParts)); |
@@ -1147,8 +1304,8 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream | |||
1147 | #ifdef SUPPORT_ALT_STREAMS | 1304 | #ifdef SUPPORT_ALT_STREAMS |
1148 | if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1) | 1305 | if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1) |
1149 | { | 1306 | { |
1150 | int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex)); | 1307 | const int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex)); |
1151 | if (renIndex >= 0) | 1308 | if (renIndex != -1) |
1152 | { | 1309 | { |
1153 | const CIndexToPathPair &pair = _renamedFiles[(unsigned)renIndex]; | 1310 | const CIndexToPathPair &pair = _renamedFiles[(unsigned)renIndex]; |
1154 | fullProcessedPath = pair.Path; | 1311 | fullProcessedPath = pair.Path; |
@@ -1224,8 +1381,8 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream | |||
1224 | RINOK(Archive_Get_HardLinkNode(archive, index, h, defined)); | 1381 | RINOK(Archive_Get_HardLinkNode(archive, index, h, defined)); |
1225 | if (defined) | 1382 | if (defined) |
1226 | { | 1383 | { |
1227 | int linkIndex = _hardLinks.IDs.FindInSorted2(h); | 1384 | const int linkIndex = _hardLinks.IDs.FindInSorted2(h); |
1228 | if (linkIndex >= 0) | 1385 | if (linkIndex != -1) |
1229 | { | 1386 | { |
1230 | FString &hl = _hardLinks.Links[(unsigned)linkIndex]; | 1387 | FString &hl = _hardLinks.Links[(unsigned)linkIndex]; |
1231 | if (hl.IsEmpty()) | 1388 | if (hl.IsEmpty()) |
@@ -1733,11 +1890,34 @@ HRESULT CArchiveExtractCallback::CloseFile() | |||
1733 | _curSize = processedSize; | 1890 | _curSize = processedSize; |
1734 | _curSizeDefined = true; | 1891 | _curSizeDefined = true; |
1735 | 1892 | ||
1893 | #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) | ||
1894 | if (ZoneBuf.Size() != 0 | ||
1895 | && !_item.IsAltStream) | ||
1896 | { | ||
1897 | // if (NFind::DoesFileExist_Raw(tempFilePath)) | ||
1898 | if (ZoneMode != NExtract::NZoneIdMode::kOffice || | ||
1899 | FindExt2(kOfficeExtensions, _diskFilePath)) | ||
1900 | { | ||
1901 | // we must write zone file before setting of timestamps | ||
1902 | const FString path = _diskFilePath + k_ZoneId_StreamName; | ||
1903 | if (!WriteZoneFile(path, ZoneBuf)) | ||
1904 | { | ||
1905 | // we can't write it in FAT | ||
1906 | // SendMessageError_with_LastError("Can't write Zone.Identifier stream", path); | ||
1907 | } | ||
1908 | } | ||
1909 | } | ||
1910 | #endif | ||
1911 | |||
1912 | CFiTimesCAM t; | ||
1913 | GetFiTimesCAM(t); | ||
1914 | |||
1736 | // #ifdef _WIN32 | 1915 | // #ifdef _WIN32 |
1737 | _outFileStreamSpec->SetTime( | 1916 | if (t.IsSomeTimeDefined()) |
1738 | (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL, | 1917 | _outFileStreamSpec->SetTime( |
1739 | (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL, | 1918 | t.CTime_Defined ? &t.CTime : NULL, |
1740 | (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); | 1919 | t.ATime_Defined ? &t.ATime : NULL, |
1920 | t.MTime_Defined ? &t.MTime : NULL); | ||
1741 | // #endif | 1921 | // #endif |
1742 | 1922 | ||
1743 | RINOK(_outFileStreamSpec->Close()); | 1923 | RINOK(_outFileStreamSpec->Close()); |
@@ -2065,19 +2245,30 @@ HRESULT CArchiveExtractCallback::CloseReparseAndFile() | |||
2065 | 2245 | ||
2066 | void CArchiveExtractCallback::SetAttrib() | 2246 | void CArchiveExtractCallback::SetAttrib() |
2067 | { | 2247 | { |
2068 | #ifndef _WIN32 | 2248 | #ifndef _WIN32 |
2069 | // Linux now doesn't support permissions for symlinks | 2249 | // Linux now doesn't support permissions for symlinks |
2070 | if (_isSymLinkCreated) | 2250 | if (_isSymLinkCreated) |
2071 | return; | 2251 | return; |
2072 | #endif | 2252 | #endif |
2073 | 2253 | ||
2074 | if (_itemFailure | 2254 | if (_itemFailure |
2075 | || _diskFilePath.IsEmpty() | 2255 | || _diskFilePath.IsEmpty() |
2076 | || _stdOutMode | 2256 | || _stdOutMode |
2077 | || !_extractMode | 2257 | || !_extractMode) |
2078 | || !_fi.AttribDefined) | ||
2079 | return; | 2258 | return; |
2080 | 2259 | ||
2260 | #ifndef _WIN32 | ||
2261 | if (_fi.Owner.Id_Defined && | ||
2262 | _fi.Group.Id_Defined) | ||
2263 | { | ||
2264 | if (my_chown(_diskFilePath, _fi.Owner.Id, _fi.Group.Id) != 0) | ||
2265 | { | ||
2266 | SendMessageError_with_LastError("Cannot set owner", _diskFilePath); | ||
2267 | } | ||
2268 | } | ||
2269 | #endif | ||
2270 | |||
2271 | if (_fi.Attrib_Defined) | ||
2081 | { | 2272 | { |
2082 | // const AString s = GetAnsiString(_diskFilePath); | 2273 | // const AString s = GetAnsiString(_diskFilePath); |
2083 | // printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib); | 2274 | // printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib); |
@@ -2276,7 +2467,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStre | |||
2276 | 2467 | ||
2277 | CInFileStream *inStreamSpec = new CInFileStream; | 2468 | CInFileStream *inStreamSpec = new CInFileStream; |
2278 | CMyComPtr<ISequentialInStream> inStreamRef = inStreamSpec; | 2469 | CMyComPtr<ISequentialInStream> inStreamRef = inStreamSpec; |
2279 | inStreamSpec->File.PreserveATime = _ntOptions.PreserveATime; | 2470 | inStreamSpec->Set_PreserveATime(_ntOptions.PreserveATime); |
2280 | if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite)) | 2471 | if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite)) |
2281 | { | 2472 | { |
2282 | RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath)); | 2473 | RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath)); |
@@ -2318,9 +2509,9 @@ void CDirPathSortPair::SetNumSlashes(const FChar *s) | |||
2318 | bool CDirPathTime::SetDirTime() const | 2509 | bool CDirPathTime::SetDirTime() const |
2319 | { | 2510 | { |
2320 | return NDir::SetDirTime(Path, | 2511 | return NDir::SetDirTime(Path, |
2321 | CTimeDefined ? &CTime : NULL, | 2512 | CTime_Defined ? &CTime : NULL, |
2322 | ATimeDefined ? &ATime : NULL, | 2513 | ATime_Defined ? &ATime : NULL, |
2323 | MTimeDefined ? &MTime : NULL); | 2514 | MTime_Defined ? &MTime : NULL); |
2324 | } | 2515 | } |
2325 | 2516 | ||
2326 | 2517 | ||
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h index fe9cb32..fe70bc9 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h | |||
@@ -60,6 +60,8 @@ struct CExtractNtOptions | |||
60 | bool ReplaceColonForAltStream; | 60 | bool ReplaceColonForAltStream; |
61 | bool WriteToAltStreamIfColon; | 61 | bool WriteToAltStreamIfColon; |
62 | 62 | ||
63 | bool ExtractOwner; | ||
64 | |||
63 | bool PreAllocateOutFile; | 65 | bool PreAllocateOutFile; |
64 | 66 | ||
65 | // used for hash arcs only, when we open external files | 67 | // used for hash arcs only, when we open external files |
@@ -69,6 +71,7 @@ struct CExtractNtOptions | |||
69 | CExtractNtOptions(): | 71 | CExtractNtOptions(): |
70 | ReplaceColonForAltStream(false), | 72 | ReplaceColonForAltStream(false), |
71 | WriteToAltStreamIfColon(false), | 73 | WriteToAltStreamIfColon(false), |
74 | ExtractOwner(false), | ||
72 | PreserveATime(false), | 75 | PreserveATime(false), |
73 | OpenShareForWrite(false) | 76 | OpenShareForWrite(false) |
74 | { | 77 | { |
@@ -163,16 +166,27 @@ struct CIndexToPathPair | |||
163 | 166 | ||
164 | 167 | ||
165 | 168 | ||
166 | struct CDirPathTime | 169 | struct CFiTimesCAM |
167 | { | 170 | { |
168 | FILETIME CTime; | 171 | CFiTime CTime; |
169 | FILETIME ATime; | 172 | CFiTime ATime; |
170 | FILETIME MTime; | 173 | CFiTime MTime; |
174 | |||
175 | bool CTime_Defined; | ||
176 | bool ATime_Defined; | ||
177 | bool MTime_Defined; | ||
171 | 178 | ||
172 | bool CTimeDefined; | 179 | bool IsSomeTimeDefined() const |
173 | bool ATimeDefined; | 180 | { |
174 | bool MTimeDefined; | 181 | return |
182 | CTime_Defined | | ||
183 | ATime_Defined | | ||
184 | MTime_Defined; | ||
185 | } | ||
186 | }; | ||
175 | 187 | ||
188 | struct CDirPathTime: public CFiTimesCAM | ||
189 | { | ||
176 | FString Path; | 190 | FString Path; |
177 | 191 | ||
178 | bool SetDirTime() const; | 192 | bool SetDirTime() const; |
@@ -216,6 +230,25 @@ struct CLinkInfo | |||
216 | #endif // SUPPORT_LINKS | 230 | #endif // SUPPORT_LINKS |
217 | 231 | ||
218 | 232 | ||
233 | #ifndef _WIN32 | ||
234 | |||
235 | struct COwnerInfo | ||
236 | { | ||
237 | bool Id_Defined; | ||
238 | UInt32 Id; | ||
239 | AString Name; | ||
240 | |||
241 | void Clear() | ||
242 | { | ||
243 | Id_Defined = false; | ||
244 | Id = 0; | ||
245 | Name.Empty(); | ||
246 | } | ||
247 | }; | ||
248 | |||
249 | #endif | ||
250 | |||
251 | |||
219 | class CArchiveExtractCallback: | 252 | class CArchiveExtractCallback: |
220 | public IArchiveExtractCallback, | 253 | public IArchiveExtractCallback, |
221 | public IArchiveExtractCallbackMessage, | 254 | public IArchiveExtractCallbackMessage, |
@@ -256,32 +289,33 @@ class CArchiveExtractCallback: | |||
256 | 289 | ||
257 | bool _extractMode; | 290 | bool _extractMode; |
258 | 291 | ||
259 | bool WriteCTime; | 292 | bool Write_CTime; |
260 | bool WriteATime; | 293 | bool Write_ATime; |
261 | bool WriteMTime; | 294 | bool Write_MTime; |
262 | 295 | ||
263 | bool _encrypted; | 296 | bool _encrypted; |
264 | 297 | ||
265 | struct CProcessedFileInfo | 298 | struct CProcessedFileInfo |
266 | { | 299 | { |
267 | FILETIME CTime; | 300 | CArcTime CTime; |
268 | FILETIME ATime; | 301 | CArcTime ATime; |
269 | FILETIME MTime; | 302 | CArcTime MTime; |
270 | UInt32 Attrib; | 303 | UInt32 Attrib; |
271 | 304 | bool Attrib_Defined; | |
272 | bool CTimeDefined; | 305 | |
273 | bool ATimeDefined; | 306 | #ifndef _WIN32 |
274 | bool MTimeDefined; | 307 | COwnerInfo Owner; |
275 | bool AttribDefined; | 308 | COwnerInfo Group; |
309 | #endif | ||
276 | 310 | ||
277 | bool IsReparse() const | 311 | bool IsReparse() const |
278 | { | 312 | { |
279 | return (AttribDefined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0); | 313 | return (Attrib_Defined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0); |
280 | } | 314 | } |
281 | 315 | ||
282 | bool IsLinuxSymLink() const | 316 | bool IsLinuxSymLink() const |
283 | { | 317 | { |
284 | return (AttribDefined && MY_LIN_S_ISLNK(Attrib >> 16)); | 318 | return (Attrib_Defined && MY_LIN_S_ISLNK(Attrib >> 16)); |
285 | } | 319 | } |
286 | 320 | ||
287 | void SetFromPosixAttrib(UInt32 a) | 321 | void SetFromPosixAttrib(UInt32 a) |
@@ -294,10 +328,14 @@ class CArchiveExtractCallback: | |||
294 | FILE_ATTRIBUTE_ARCHIVE; | 328 | FILE_ATTRIBUTE_ARCHIVE; |
295 | if ((a & 0222) == 0) // (& S_IWUSR) in p7zip | 329 | if ((a & 0222) == 0) // (& S_IWUSR) in p7zip |
296 | Attrib |= FILE_ATTRIBUTE_READONLY; | 330 | Attrib |= FILE_ATTRIBUTE_READONLY; |
331 | // 22.00 : we need type bits for (MY_LIN_S_IFLNK) for IsLinuxSymLink() | ||
332 | a &= MY_LIN_S_IFMT; | ||
333 | if (a == MY_LIN_S_IFLNK) | ||
334 | Attrib |= (a << 16); | ||
297 | #else | 335 | #else |
298 | Attrib = (a << 16) | FILE_ATTRIBUTE_UNIX_EXTENSION; | 336 | Attrib = (a << 16) | FILE_ATTRIBUTE_UNIX_EXTENSION; |
299 | #endif | 337 | #endif |
300 | AttribDefined = true; | 338 | Attrib_Defined = true; |
301 | } | 339 | } |
302 | } _fi; | 340 | } _fi; |
303 | 341 | ||
@@ -359,7 +397,7 @@ class CArchiveExtractCallback: | |||
359 | #endif | 397 | #endif |
360 | 398 | ||
361 | void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); | 399 | void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); |
362 | HRESULT GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined); | 400 | HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft); |
363 | HRESULT GetUnpackSize(); | 401 | HRESULT GetUnpackSize(); |
364 | 402 | ||
365 | FString Hash_GetFullFilePath(); | 403 | FString Hash_GetFullFilePath(); |
@@ -372,6 +410,10 @@ public: | |||
372 | HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2); | 410 | HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2); |
373 | 411 | ||
374 | public: | 412 | public: |
413 | #if defined(_WIN32) && !defined(UNDER_CE) | ||
414 | NExtract::NZoneIdMode::EEnum ZoneMode; | ||
415 | CByteBuffer ZoneBuf; | ||
416 | #endif | ||
375 | 417 | ||
376 | CLocalProgress *LocalProgressSpec; | 418 | CLocalProgress *LocalProgressSpec; |
377 | 419 | ||
@@ -405,11 +447,17 @@ public: | |||
405 | void InitForMulti(bool multiArchives, | 447 | void InitForMulti(bool multiArchives, |
406 | NExtract::NPathMode::EEnum pathMode, | 448 | NExtract::NPathMode::EEnum pathMode, |
407 | NExtract::NOverwriteMode::EEnum overwriteMode, | 449 | NExtract::NOverwriteMode::EEnum overwriteMode, |
450 | NExtract::NZoneIdMode::EEnum zoneMode, | ||
408 | bool keepAndReplaceEmptyDirPrefixes) | 451 | bool keepAndReplaceEmptyDirPrefixes) |
409 | { | 452 | { |
410 | _multiArchives = multiArchives; | 453 | _multiArchives = multiArchives; |
411 | _pathMode = pathMode; | 454 | _pathMode = pathMode; |
412 | _overwriteMode = overwriteMode; | 455 | _overwriteMode = overwriteMode; |
456 | #if defined(_WIN32) && !defined(UNDER_CE) | ||
457 | ZoneMode = zoneMode; | ||
458 | #else | ||
459 | UNUSED_VAR(zoneMode) | ||
460 | #endif | ||
413 | _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes; | 461 | _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes; |
414 | NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0; | 462 | NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0; |
415 | } | 463 | } |
@@ -427,6 +475,8 @@ public: | |||
427 | 475 | ||
428 | #endif | 476 | #endif |
429 | 477 | ||
478 | void InitBeforeNewArchive(); | ||
479 | |||
430 | void Init( | 480 | void Init( |
431 | const CExtractNtOptions &ntOptions, | 481 | const CExtractNtOptions &ntOptions, |
432 | const NWildcard::CCensorNode *wildcardCensor, | 482 | const NWildcard::CCensorNode *wildcardCensor, |
@@ -483,6 +533,7 @@ private: | |||
483 | 533 | ||
484 | HRESULT Read_fi_Props(); | 534 | HRESULT Read_fi_Props(); |
485 | void CorrectPathParts(); | 535 | void CorrectPathParts(); |
536 | void GetFiTimesCAM(CFiTimesCAM &pt); | ||
486 | void CreateFolders(); | 537 | void CreateFolders(); |
487 | 538 | ||
488 | bool _isRenamed; | 539 | bool _isRenamed; |
@@ -533,4 +584,6 @@ struct CArchiveExtractCallback_Closer | |||
533 | 584 | ||
534 | bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); | 585 | bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); |
535 | 586 | ||
587 | void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf); | ||
588 | |||
536 | #endif | 589 | #endif |
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp index d5926f8..64aa987 100644 --- a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp +++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp | |||
@@ -34,7 +34,8 @@ STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *b | |||
34 | return Callback->Open_SetCompleted(files, bytes); | 34 | return Callback->Open_SetCompleted(files, bytes); |
35 | COM_TRY_END | 35 | COM_TRY_END |
36 | } | 36 | } |
37 | 37 | ||
38 | |||
38 | STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) | 39 | STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) |
39 | { | 40 | { |
40 | COM_TRY_BEGIN | 41 | COM_TRY_BEGIN |
@@ -51,10 +52,11 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) | |||
51 | case kpidName: prop = fs2us(_fileInfo.Name); break; | 52 | case kpidName: prop = fs2us(_fileInfo.Name); break; |
52 | case kpidIsDir: prop = _fileInfo.IsDir(); break; | 53 | case kpidIsDir: prop = _fileInfo.IsDir(); break; |
53 | case kpidSize: prop = _fileInfo.Size; break; | 54 | case kpidSize: prop = _fileInfo.Size; break; |
54 | case kpidAttrib: prop = (UInt32)_fileInfo.Attrib; break; | 55 | case kpidAttrib: prop = (UInt32)_fileInfo.GetWinAttrib(); break; |
55 | case kpidCTime: prop = _fileInfo.CTime; break; | 56 | case kpidPosixAttrib: prop = (UInt32)_fileInfo.GetPosixAttrib(); break; |
56 | case kpidATime: prop = _fileInfo.ATime; break; | 57 | case kpidCTime: PropVariant_SetFrom_FiTime(prop, _fileInfo.CTime); break; |
57 | case kpidMTime: prop = _fileInfo.MTime; break; | 58 | case kpidATime: PropVariant_SetFrom_FiTime(prop, _fileInfo.ATime); break; |
59 | case kpidMTime: PropVariant_SetFrom_FiTime(prop, _fileInfo.MTime); break; | ||
58 | } | 60 | } |
59 | prop.Detach(value); | 61 | prop.Detach(value); |
60 | return S_OK; | 62 | return S_OK; |
diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp index c7efa99..3ef047f 100644 --- a/CPP/7zip/UI/Common/CompressCall.cpp +++ b/CPP/7zip/UI/Common/CompressCall.cpp | |||
@@ -252,7 +252,7 @@ static void ExtractGroupCommand(const UStringVector &arcPaths, UString ¶ms, | |||
252 | ErrorMessageHRESULT(result); | 252 | ErrorMessageHRESULT(result); |
253 | } | 253 | } |
254 | 254 | ||
255 | void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup) | 255 | void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup, UInt32 writeZone) |
256 | { | 256 | { |
257 | MY_TRY_BEGIN | 257 | MY_TRY_BEGIN |
258 | UString params ('x'); | 258 | UString params ('x'); |
@@ -263,6 +263,11 @@ void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bo | |||
263 | } | 263 | } |
264 | if (elimDup) | 264 | if (elimDup) |
265 | params += " -spe"; | 265 | params += " -spe"; |
266 | if (writeZone != (UInt32)(Int32)-1) | ||
267 | { | ||
268 | params += " -snz"; | ||
269 | params.Add_UInt32(writeZone); | ||
270 | } | ||
266 | if (showDialog) | 271 | if (showDialog) |
267 | params += kShowDialogSwitch; | 272 | params += kShowDialogSwitch; |
268 | ExtractGroupCommand(arcPaths, params, false); | 273 | ExtractGroupCommand(arcPaths, params, false); |
diff --git a/CPP/7zip/UI/Common/CompressCall.h b/CPP/7zip/UI/Common/CompressCall.h index b817df0..2697fda 100644 --- a/CPP/7zip/UI/Common/CompressCall.h +++ b/CPP/7zip/UI/Common/CompressCall.h | |||
@@ -15,7 +15,7 @@ HRESULT CompressFiles( | |||
15 | const UStringVector &names, | 15 | const UStringVector &names, |
16 | bool email, bool showDialog, bool waitFinish); | 16 | bool email, bool showDialog, bool waitFinish); |
17 | 17 | ||
18 | void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup); | 18 | void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup, UInt32 writeZone); |
19 | void TestArchives(const UStringVector &arcPaths, bool hashMode = false); | 19 | void TestArchives(const UStringVector &arcPaths, bool hashMode = false); |
20 | 20 | ||
21 | void CalcChecksum(const UStringVector &paths, | 21 | void CalcChecksum(const UStringVector &paths, |
diff --git a/CPP/7zip/UI/Common/CompressCall2.cpp b/CPP/7zip/UI/Common/CompressCall2.cpp index 762342d..5d617e1 100644 --- a/CPP/7zip/UI/Common/CompressCall2.cpp +++ b/CPP/7zip/UI/Common/CompressCall2.cpp | |||
@@ -152,19 +152,12 @@ HRESULT CompressFiles( | |||
152 | 152 | ||
153 | 153 | ||
154 | static HRESULT ExtractGroupCommand(const UStringVector &arcPaths, | 154 | static HRESULT ExtractGroupCommand(const UStringVector &arcPaths, |
155 | bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false, | 155 | bool showDialog, CExtractOptions &eo, const char *kType = NULL) |
156 | const char *kType = NULL) | ||
157 | { | 156 | { |
158 | MY_TRY_BEGIN | 157 | MY_TRY_BEGIN |
159 | 158 | ||
160 | CREATE_CODECS | 159 | CREATE_CODECS |
161 | 160 | ||
162 | CExtractOptions eo; | ||
163 | eo.OutputDir = us2fs(outFolder); | ||
164 | eo.TestMode = testMode; | ||
165 | eo.ElimDup.Val = elimDup; | ||
166 | eo.ElimDup.Def = elimDup; | ||
167 | |||
168 | CExtractCallbackImp *ecs = new CExtractCallbackImp; | 161 | CExtractCallbackImp *ecs = new CExtractCallbackImp; |
169 | CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; | 162 | CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; |
170 | 163 | ||
@@ -228,15 +221,26 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths, | |||
228 | return result; | 221 | return result; |
229 | } | 222 | } |
230 | 223 | ||
231 | void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup) | 224 | void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, |
225 | bool showDialog, bool elimDup, UInt32 writeZone) | ||
232 | { | 226 | { |
233 | ExtractGroupCommand(arcPaths, showDialog, outFolder, false, elimDup); | 227 | CExtractOptions eo; |
228 | eo.OutputDir = us2fs(outFolder); | ||
229 | eo.TestMode = false; | ||
230 | eo.ElimDup.Val = elimDup; | ||
231 | eo.ElimDup.Def = elimDup; | ||
232 | if (writeZone != (UInt32)(Int32)-1) | ||
233 | eo.ZoneMode = (NExtract::NZoneIdMode::EEnum)writeZone; | ||
234 | ExtractGroupCommand(arcPaths, showDialog, eo); | ||
234 | } | 235 | } |
235 | 236 | ||
236 | void TestArchives(const UStringVector &arcPaths, bool hashMode) | 237 | void TestArchives(const UStringVector &arcPaths, bool hashMode) |
237 | { | 238 | { |
238 | ExtractGroupCommand(arcPaths, true, UString(), true, | 239 | CExtractOptions eo; |
239 | false, // elimDup | 240 | eo.TestMode = true; |
241 | ExtractGroupCommand(arcPaths, | ||
242 | true, // showDialog | ||
243 | eo, | ||
240 | hashMode ? "hash" : NULL); | 244 | hashMode ? "hash" : NULL); |
241 | } | 245 | } |
242 | 246 | ||
diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h index e5f578d..86e385f 100644 --- a/CPP/7zip/UI/Common/DirItem.h +++ b/CPP/7zip/UI/Common/DirItem.h | |||
@@ -10,6 +10,8 @@ | |||
10 | #include "../../../Common/MyString.h" | 10 | #include "../../../Common/MyString.h" |
11 | 11 | ||
12 | #include "../../../Windows/FileFind.h" | 12 | #include "../../../Windows/FileFind.h" |
13 | #include "../../../Windows/PropVariant.h" | ||
14 | #include "../../../Windows/TimeUtils.h" | ||
13 | 15 | ||
14 | #include "../../Common/UniqBlocks.h" | 16 | #include "../../Common/UniqBlocks.h" |
15 | 17 | ||
@@ -80,50 +82,213 @@ struct IDirItemsCallback | |||
80 | INTERFACE_IDirItemsCallback(=0) | 82 | INTERFACE_IDirItemsCallback(=0) |
81 | }; | 83 | }; |
82 | 84 | ||
83 | struct CDirItem | 85 | |
86 | struct CArcTime | ||
87 | { | ||
88 | FILETIME FT; | ||
89 | UInt16 Prec; | ||
90 | Byte Ns100; | ||
91 | bool Def; | ||
92 | |||
93 | CArcTime() | ||
94 | { | ||
95 | Clear(); | ||
96 | } | ||
97 | |||
98 | void Clear() | ||
99 | { | ||
100 | FT.dwHighDateTime = FT.dwLowDateTime = 0; | ||
101 | Prec = 0; | ||
102 | Ns100 = 0; | ||
103 | Def = false; | ||
104 | } | ||
105 | |||
106 | bool IsZero() const | ||
107 | { | ||
108 | return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0; | ||
109 | } | ||
110 | |||
111 | int CompareWith(const CArcTime &a) const | ||
112 | { | ||
113 | const int res = CompareFileTime(&FT, &a.FT); | ||
114 | if (res != 0) | ||
115 | return res; | ||
116 | if (Ns100 < a.Ns100) return -1; | ||
117 | if (Ns100 > a.Ns100) return 1; | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | UInt64 Get_FILETIME_as_UInt64() const | ||
122 | { | ||
123 | return (((UInt64)FT.dwHighDateTime) << 32) + FT.dwLowDateTime; | ||
124 | } | ||
125 | |||
126 | UInt32 Get_DosTime() const | ||
127 | { | ||
128 | FILETIME ft2 = FT; | ||
129 | if ((Prec == k_PropVar_TimePrec_Base + 8 || | ||
130 | Prec == k_PropVar_TimePrec_Base + 9) | ||
131 | && Ns100 != 0) | ||
132 | { | ||
133 | UInt64 u64 = Get_FILETIME_as_UInt64(); | ||
134 | // we round up even small (ns < 100ns) as FileTimeToDosTime() | ||
135 | if (u64 % 20000000 == 0) | ||
136 | { | ||
137 | u64++; | ||
138 | ft2.dwHighDateTime = (DWORD)(u64 >> 32); | ||
139 | ft2.dwHighDateTime = (DWORD)u64; | ||
140 | } | ||
141 | } | ||
142 | // FileTimeToDosTime() is expected to round up in Windows | ||
143 | UInt32 dosTime; | ||
144 | // we use simplified code with utctime->dos. | ||
145 | // do we need local time instead here? | ||
146 | NWindows::NTime::FileTime_To_DosTime(ft2, dosTime); | ||
147 | return dosTime; | ||
148 | } | ||
149 | |||
150 | int GetNumDigits() const | ||
151 | { | ||
152 | if (Prec == k_PropVar_TimePrec_Unix || | ||
153 | Prec == k_PropVar_TimePrec_DOS) | ||
154 | return 0; | ||
155 | if (Prec == k_PropVar_TimePrec_HighPrec) | ||
156 | return 9; | ||
157 | if (Prec == k_PropVar_TimePrec_0) | ||
158 | return 7; | ||
159 | int digits = (int)Prec - (int)k_PropVar_TimePrec_Base; | ||
160 | if (digits < 0) | ||
161 | digits = 0; | ||
162 | return digits; | ||
163 | } | ||
164 | |||
165 | void Write_To_FiTime(CFiTime &dest) const | ||
166 | { | ||
167 | #ifdef _WIN32 | ||
168 | dest = FT; | ||
169 | #else | ||
170 | if (FILETIME_To_timespec(FT, dest)) | ||
171 | if ((Prec == k_PropVar_TimePrec_Base + 8 || | ||
172 | Prec == k_PropVar_TimePrec_Base + 9) | ||
173 | && Ns100 != 0) | ||
174 | { | ||
175 | dest.tv_nsec += Ns100; | ||
176 | } | ||
177 | #endif | ||
178 | } | ||
179 | |||
180 | // (Def) is not set | ||
181 | void Set_From_FILETIME(const FILETIME &ft) | ||
182 | { | ||
183 | FT = ft; | ||
184 | // Prec = k_PropVar_TimePrec_CompatNTFS; | ||
185 | Prec = k_PropVar_TimePrec_Base + 7; | ||
186 | Ns100 = 0; | ||
187 | } | ||
188 | |||
189 | // (Def) is not set | ||
190 | // it set full form precision: k_PropVar_TimePrec_Base + numDigits | ||
191 | void Set_From_FiTime(const CFiTime &ts) | ||
192 | { | ||
193 | #ifdef _WIN32 | ||
194 | FT = ts; | ||
195 | Prec = k_PropVar_TimePrec_Base + 7; | ||
196 | // Prec = k_PropVar_TimePrec_Base; // for debug | ||
197 | // Prec = 0; // for debug | ||
198 | Ns100 = 0; | ||
199 | #else | ||
200 | unsigned ns100; | ||
201 | FiTime_To_FILETIME_ns100(ts, FT, ns100); | ||
202 | Ns100 = (Byte)ns100; | ||
203 | Prec = k_PropVar_TimePrec_Base + 9; | ||
204 | #endif | ||
205 | } | ||
206 | |||
207 | void Set_From_Prop(const PROPVARIANT &prop) | ||
208 | { | ||
209 | FT = prop.filetime; | ||
210 | unsigned prec = 0; | ||
211 | unsigned ns100 = 0; | ||
212 | const unsigned prec_Temp = prop.wReserved1; | ||
213 | if (prec_Temp != 0 | ||
214 | && prec_Temp <= k_PropVar_TimePrec_1ns | ||
215 | && prop.wReserved3 == 0) | ||
216 | { | ||
217 | const unsigned ns100_Temp = prop.wReserved2; | ||
218 | if (ns100_Temp < 100) | ||
219 | { | ||
220 | ns100 = ns100_Temp; | ||
221 | prec = prec_Temp; | ||
222 | } | ||
223 | } | ||
224 | Prec = (UInt16)prec; | ||
225 | Ns100 = (Byte)ns100; | ||
226 | Def = true; | ||
227 | } | ||
228 | }; | ||
229 | |||
230 | |||
231 | struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase | ||
84 | { | 232 | { |
85 | UInt64 Size; | ||
86 | FILETIME CTime; | ||
87 | FILETIME ATime; | ||
88 | FILETIME MTime; | ||
89 | UString Name; | 233 | UString Name; |
90 | 234 | ||
91 | #ifndef UNDER_CE | 235 | #ifndef UNDER_CE |
92 | CByteBuffer ReparseData; | 236 | CByteBuffer ReparseData; |
93 | 237 | ||
94 | #ifdef _WIN32 | 238 | #ifdef _WIN32 |
95 | // UString ShortName; | 239 | // UString ShortName; |
96 | CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format | 240 | CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format |
97 | bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; } | 241 | bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; } |
98 | #else | 242 | #else |
99 | bool AreReparseData() const { return ReparseData.Size() != 0; } | 243 | bool AreReparseData() const { return ReparseData.Size() != 0; } |
100 | #endif // _WIN32 | 244 | #endif // _WIN32 |
101 | 245 | ||
102 | #endif // !UNDER_CE | 246 | #endif // !UNDER_CE |
103 | 247 | ||
104 | UInt32 Attrib; | 248 | void Copy_From_FileInfoBase(const NWindows::NFile::NFind::CFileInfoBase &fi) |
249 | { | ||
250 | (NWindows::NFile::NFind::CFileInfoBase &)*this = fi; | ||
251 | } | ||
252 | |||
105 | int PhyParent; | 253 | int PhyParent; |
106 | int LogParent; | 254 | int LogParent; |
107 | int SecureIndex; | 255 | int SecureIndex; |
108 | 256 | ||
109 | bool IsAltStream; | 257 | #ifdef _WIN32 |
110 | 258 | #else | |
111 | CDirItem(): PhyParent(-1), LogParent(-1), SecureIndex(-1), IsAltStream(false) {} | 259 | int OwnerNameIndex; |
112 | 260 | int OwnerGroupIndex; | |
113 | bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; } | 261 | #endif |
114 | bool IsReadOnly() const { return (Attrib & FILE_ATTRIBUTE_READONLY) != 0; } | 262 | |
115 | bool Has_Attrib_ReparsePoint() const { return (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0; } | 263 | CDirItem(): |
116 | 264 | PhyParent(-1) | |
117 | #ifdef _WIN32 | 265 | , LogParent(-1) |
118 | UInt32 GetPosixAttrib() const | 266 | , SecureIndex(-1) |
267 | #ifdef _WIN32 | ||
268 | #else | ||
269 | , OwnerNameIndex(-1) | ||
270 | , OwnerGroupIndex(-1) | ||
271 | #endif | ||
119 | { | 272 | { |
120 | UInt32 v = IsDir() ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG; | ||
121 | /* 21.06: as WSL we allow write permissions (0222) for directories even for (FILE_ATTRIBUTE_READONLY). | ||
122 | So extracting at Linux will be allowed to write files inside (0777) directories. */ | ||
123 | v |= ((IsReadOnly() && !IsDir()) ? 0555 : 0777); | ||
124 | return v; | ||
125 | } | 273 | } |
126 | #endif | 274 | |
275 | |||
276 | CDirItem(const NWindows::NFile::NFind::CFileInfo &fi, | ||
277 | int phyParent, int logParent, int secureIndex): | ||
278 | CFileInfoBase(fi) | ||
279 | , Name(fs2us(fi.Name)) | ||
280 | #if defined(_WIN32) && !defined(UNDER_CE) | ||
281 | // , ShortName(fs2us(fi.ShortName)) | ||
282 | #endif | ||
283 | , PhyParent(phyParent) | ||
284 | , LogParent(logParent) | ||
285 | , SecureIndex(secureIndex) | ||
286 | #ifdef _WIN32 | ||
287 | #else | ||
288 | , OwnerNameIndex(-1) | ||
289 | , OwnerGroupIndex(-1) | ||
290 | #endif | ||
291 | {} | ||
127 | }; | 292 | }; |
128 | 293 | ||
129 | 294 | ||
@@ -145,6 +310,7 @@ public: | |||
145 | bool ScanAltStreams; | 310 | bool ScanAltStreams; |
146 | bool ExcludeDirItems; | 311 | bool ExcludeDirItems; |
147 | bool ExcludeFileItems; | 312 | bool ExcludeFileItems; |
313 | bool ShareForWrite; | ||
148 | 314 | ||
149 | /* it must be called after anotrher checks */ | 315 | /* it must be called after anotrher checks */ |
150 | bool CanIncludeItem(bool isDir) const | 316 | bool CanIncludeItem(bool isDir) const |
@@ -160,7 +326,7 @@ public: | |||
160 | const FString &phyPrefix); | 326 | const FString &phyPrefix); |
161 | #endif | 327 | #endif |
162 | 328 | ||
163 | #if defined(_WIN32) && !defined(UNDER_CE) | 329 | #if defined(_WIN32) && !defined(UNDER_CE) |
164 | 330 | ||
165 | CUniqBlocks SecureBlocks; | 331 | CUniqBlocks SecureBlocks; |
166 | CByteBuffer TempSecureBuf; | 332 | CByteBuffer TempSecureBuf; |
@@ -170,7 +336,17 @@ public: | |||
170 | HRESULT AddSecurityItem(const FString &path, int &secureIndex); | 336 | HRESULT AddSecurityItem(const FString &path, int &secureIndex); |
171 | HRESULT FillFixedReparse(); | 337 | HRESULT FillFixedReparse(); |
172 | 338 | ||
173 | #endif | 339 | #endif |
340 | |||
341 | #ifndef _WIN32 | ||
342 | |||
343 | C_UInt32_UString_Map OwnerNameMap; | ||
344 | C_UInt32_UString_Map OwnerGroupMap; | ||
345 | bool StoreOwnerName; | ||
346 | |||
347 | HRESULT FillDeviceSizes(); | ||
348 | |||
349 | #endif | ||
174 | 350 | ||
175 | IDirItemsCallback *Callback; | 351 | IDirItemsCallback *Callback; |
176 | 352 | ||
@@ -204,20 +380,25 @@ public: | |||
204 | }; | 380 | }; |
205 | 381 | ||
206 | 382 | ||
383 | |||
384 | |||
207 | struct CArcItem | 385 | struct CArcItem |
208 | { | 386 | { |
209 | UInt64 Size; | 387 | UInt64 Size; |
210 | FILETIME MTime; | ||
211 | UString Name; | 388 | UString Name; |
389 | CArcTime MTime; // it can be mtime of archive file, if MTime is not defined for item in archive | ||
212 | bool IsDir; | 390 | bool IsDir; |
213 | bool IsAltStream; | 391 | bool IsAltStream; |
214 | bool SizeDefined; | 392 | bool Size_Defined; |
215 | bool MTimeDefined; | ||
216 | bool Censored; | 393 | bool Censored; |
217 | UInt32 IndexInServer; | 394 | UInt32 IndexInServer; |
218 | int TimeType; | ||
219 | 395 | ||
220 | CArcItem(): IsDir(false), IsAltStream(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {} | 396 | CArcItem(): |
397 | IsDir(false), | ||
398 | IsAltStream(false), | ||
399 | Size_Defined(false), | ||
400 | Censored(false) | ||
401 | {} | ||
221 | }; | 402 | }; |
222 | 403 | ||
223 | #endif | 404 | #endif |
diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp index 89cce2b..a4ac413 100644 --- a/CPP/7zip/UI/Common/EnumDirItems.cpp +++ b/CPP/7zip/UI/Common/EnumDirItems.cpp | |||
@@ -5,6 +5,12 @@ | |||
5 | #include <wchar.h> | 5 | #include <wchar.h> |
6 | // #include <stdio.h> | 6 | // #include <stdio.h> |
7 | 7 | ||
8 | #ifndef _WIN32 | ||
9 | #include <grp.h> | ||
10 | #include <pwd.h> | ||
11 | #include "../../../Common/UTFConvert.h" | ||
12 | #endif | ||
13 | |||
8 | #include "../../../Common/Wildcard.h" | 14 | #include "../../../Common/Wildcard.h" |
9 | 15 | ||
10 | #include "../../../Windows/FileDir.h" | 16 | #include "../../../Windows/FileDir.h" |
@@ -23,32 +29,60 @@ using namespace NWindows; | |||
23 | using namespace NFile; | 29 | using namespace NFile; |
24 | using namespace NName; | 30 | using namespace NName; |
25 | 31 | ||
32 | |||
33 | static bool FindFile_KeepDots(NFile::NFind::CFileInfo &fi, const FString &path, bool followLink) | ||
34 | { | ||
35 | const bool res = fi.Find(path, followLink); | ||
36 | if (!res) | ||
37 | return res; | ||
38 | if (path.IsEmpty()) | ||
39 | return res; | ||
40 | // we keep name "." and "..", if it's without tail slash | ||
41 | const FChar *p = path.RightPtr(1); | ||
42 | if (*p != '.') | ||
43 | return res; | ||
44 | if (p != path.Ptr()) | ||
45 | { | ||
46 | FChar c = p[-1]; | ||
47 | if (!IS_PATH_SEPAR(c)) | ||
48 | { | ||
49 | if (c != '.') | ||
50 | return res; | ||
51 | p--; | ||
52 | if (p != path.Ptr()) | ||
53 | { | ||
54 | c = p[-1]; | ||
55 | if (!IS_PATH_SEPAR(c)) | ||
56 | return res; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | fi.Name = p; | ||
61 | return res; | ||
62 | } | ||
63 | |||
64 | |||
26 | void CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex, | 65 | void CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex, |
27 | const NFind::CFileInfo &fi) | 66 | const NFind::CFileInfo &fi) |
28 | { | 67 | { |
29 | CDirItem di; | 68 | /* |
30 | di.Size = fi.Size; | 69 | CDirItem di(fi); |
31 | di.CTime = fi.CTime; | ||
32 | di.ATime = fi.ATime; | ||
33 | di.MTime = fi.MTime; | ||
34 | di.Attrib = fi.Attrib; | ||
35 | di.IsAltStream = fi.IsAltStream; | ||
36 | di.PhyParent = phyParent; | 70 | di.PhyParent = phyParent; |
37 | di.LogParent = logParent; | 71 | di.LogParent = logParent; |
38 | di.SecureIndex = secureIndex; | 72 | di.SecureIndex = secureIndex; |
39 | di.Name = fs2us(fi.Name); | ||
40 | #if defined(_WIN32) && !defined(UNDER_CE) | ||
41 | // di.ShortName = fs2us(fi.ShortName); | ||
42 | #endif | ||
43 | Items.Add(di); | 73 | Items.Add(di); |
74 | */ | ||
75 | VECTOR_ADD_NEW_OBJECT (Items, CDirItem(fi, phyParent, logParent, secureIndex)) | ||
44 | 76 | ||
45 | if (fi.IsDir()) | 77 | if (fi.IsDir()) |
46 | Stat.NumDirs++; | 78 | Stat.NumDirs++; |
79 | #ifdef _WIN32 | ||
47 | else if (fi.IsAltStream) | 80 | else if (fi.IsAltStream) |
48 | { | 81 | { |
49 | Stat.NumAltStreams++; | 82 | Stat.NumAltStreams++; |
50 | Stat.AltStreamsSize += fi.Size; | 83 | Stat.AltStreamsSize += fi.Size; |
51 | } | 84 | } |
85 | #endif | ||
52 | else | 86 | else |
53 | { | 87 | { |
54 | Stat.NumFiles++; | 88 | Stat.NumFiles++; |
@@ -148,9 +182,13 @@ CDirItems::CDirItems(): | |||
148 | ScanAltStreams(false) | 182 | ScanAltStreams(false) |
149 | , ExcludeDirItems(false) | 183 | , ExcludeDirItems(false) |
150 | , ExcludeFileItems(false) | 184 | , ExcludeFileItems(false) |
151 | #ifdef _USE_SECURITY_CODE | 185 | , ShareForWrite(false) |
186 | #ifdef _USE_SECURITY_CODE | ||
152 | , ReadSecure(false) | 187 | , ReadSecure(false) |
153 | #endif | 188 | #endif |
189 | #ifndef _WIN32 | ||
190 | , StoreOwnerName(true) | ||
191 | #endif | ||
154 | , Callback(NULL) | 192 | , Callback(NULL) |
155 | { | 193 | { |
156 | #ifdef _USE_SECURITY_CODE | 194 | #ifdef _USE_SECURITY_CODE |
@@ -379,7 +417,7 @@ HRESULT CDirItems::EnumerateItems2( | |||
379 | const FString &filePath = filePaths[i]; | 417 | const FString &filePath = filePaths[i]; |
380 | NFind::CFileInfo fi; | 418 | NFind::CFileInfo fi; |
381 | const FString phyPath = phyPrefix + filePath; | 419 | const FString phyPath = phyPrefix + filePath; |
382 | if (!fi.Find(phyPath FOLLOW_LINK_PARAM)) | 420 | if (!FindFile_KeepDots(fi, phyPath FOLLOW_LINK_PARAM)) |
383 | { | 421 | { |
384 | RINOK(AddError(phyPath)); | 422 | RINOK(AddError(phyPath)); |
385 | continue; | 423 | continue; |
@@ -658,15 +696,14 @@ static HRESULT EnumerateForItem( | |||
658 | if (!enterToSubFolders) | 696 | if (!enterToSubFolders) |
659 | return S_OK; | 697 | return S_OK; |
660 | 698 | ||
661 | #ifndef _WIN32 | 699 | #ifndef _WIN32 |
662 | if (fi.IsPosixLink()) | 700 | if (fi.IsPosixLink()) |
663 | { | 701 | { |
664 | // here we can try to resolve posix link | 702 | // here we can try to resolve posix link |
665 | // if the link to dir, then can we follow it | 703 | // if the link to dir, then can we follow it |
666 | return S_OK; // we don't follow posix link | 704 | return S_OK; // we don't follow posix link |
667 | } | 705 | } |
668 | #endif | 706 | #else |
669 | |||
670 | if (dirItems.SymLinks && fi.HasReparsePoint()) | 707 | if (dirItems.SymLinks && fi.HasReparsePoint()) |
671 | { | 708 | { |
672 | /* 20.03: in SymLinks mode: we don't enter to directory that | 709 | /* 20.03: in SymLinks mode: we don't enter to directory that |
@@ -677,6 +714,7 @@ static HRESULT EnumerateForItem( | |||
677 | */ | 714 | */ |
678 | return S_OK; | 715 | return S_OK; |
679 | } | 716 | } |
717 | #endif | ||
680 | nextNode = &curNode; | 718 | nextNode = &curNode; |
681 | } | 719 | } |
682 | 720 | ||
@@ -826,7 +864,7 @@ static HRESULT EnumerateDirItems( | |||
826 | } | 864 | } |
827 | else | 865 | else |
828 | #endif | 866 | #endif |
829 | if (!fi.Find(fullPath FOLLOW_LINK_PARAM2)) | 867 | if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) |
830 | { | 868 | { |
831 | RINOK(dirItems.AddError(fullPath)); | 869 | RINOK(dirItems.AddError(fullPath)); |
832 | continue; | 870 | continue; |
@@ -914,15 +952,14 @@ static HRESULT EnumerateDirItems( | |||
914 | } | 952 | } |
915 | else | 953 | else |
916 | { | 954 | { |
917 | #ifndef _WIN32 | 955 | #ifndef _WIN32 |
918 | if (fi.IsPosixLink()) | 956 | if (fi.IsPosixLink()) |
919 | { | 957 | { |
920 | // here we can try to resolve posix link | 958 | // here we can try to resolve posix link |
921 | // if the link to dir, then can we follow it | 959 | // if the link to dir, then can we follow it |
922 | continue; // we don't follow posix link | 960 | continue; // we don't follow posix link |
923 | } | 961 | } |
924 | #endif | 962 | #else |
925 | |||
926 | if (dirItems.SymLinks) | 963 | if (dirItems.SymLinks) |
927 | { | 964 | { |
928 | if (fi.HasReparsePoint()) | 965 | if (fi.HasReparsePoint()) |
@@ -932,6 +969,7 @@ static HRESULT EnumerateDirItems( | |||
932 | continue; | 969 | continue; |
933 | } | 970 | } |
934 | } | 971 | } |
972 | #endif | ||
935 | nextNode = &curNode; | 973 | nextNode = &curNode; |
936 | newParts.Add(name); // don't change it to fi.Name. It's for shortnames support | 974 | newParts.Add(name); // don't change it to fi.Name. It's for shortnames support |
937 | } | 975 | } |
@@ -973,7 +1011,7 @@ static HRESULT EnumerateDirItems( | |||
973 | } | 1011 | } |
974 | else | 1012 | else |
975 | { | 1013 | { |
976 | if (!fi.Find(fullPath FOLLOW_LINK_PARAM2)) | 1014 | if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) |
977 | { | 1015 | { |
978 | if (!nextNode.AreThereIncludeItems()) | 1016 | if (!nextNode.AreThereIncludeItems()) |
979 | continue; | 1017 | continue; |
@@ -1136,15 +1174,18 @@ HRESULT EnumerateItems( | |||
1136 | } | 1174 | } |
1137 | dirItems.ReserveDown(); | 1175 | dirItems.ReserveDown(); |
1138 | 1176 | ||
1139 | #if defined(_WIN32) && !defined(UNDER_CE) | 1177 | #if defined(_WIN32) && !defined(UNDER_CE) |
1140 | RINOK(dirItems.FillFixedReparse()); | 1178 | RINOK(dirItems.FillFixedReparse()); |
1141 | #endif | 1179 | #endif |
1180 | |||
1181 | #ifndef _WIN32 | ||
1182 | RINOK(dirItems.FillDeviceSizes()); | ||
1183 | #endif | ||
1142 | 1184 | ||
1143 | return S_OK; | 1185 | return S_OK; |
1144 | } | 1186 | } |
1145 | 1187 | ||
1146 | 1188 | ||
1147 | |||
1148 | #if defined(_WIN32) && !defined(UNDER_CE) | 1189 | #if defined(_WIN32) && !defined(UNDER_CE) |
1149 | 1190 | ||
1150 | HRESULT CDirItems::FillFixedReparse() | 1191 | HRESULT CDirItems::FillFixedReparse() |
@@ -1281,6 +1322,148 @@ HRESULT CDirItems::FillFixedReparse() | |||
1281 | #endif | 1322 | #endif |
1282 | 1323 | ||
1283 | 1324 | ||
1325 | #ifndef _WIN32 | ||
1326 | |||
1327 | HRESULT CDirItems::FillDeviceSizes() | ||
1328 | { | ||
1329 | { | ||
1330 | FOR_VECTOR (i, Items) | ||
1331 | { | ||
1332 | CDirItem &item = Items[i]; | ||
1333 | |||
1334 | if (S_ISBLK(item.mode) && item.Size == 0) | ||
1335 | { | ||
1336 | const FString phyPath = GetPhyPath(i); | ||
1337 | NIO::CInFile inFile; | ||
1338 | inFile.PreserveATime = true; | ||
1339 | if (inFile.OpenShared(phyPath, ShareForWrite)) // fixme: OpenShared ?? | ||
1340 | { | ||
1341 | UInt64 size = 0; | ||
1342 | if (inFile.GetLength(size)) | ||
1343 | item.Size = size; | ||
1344 | } | ||
1345 | } | ||
1346 | if (StoreOwnerName) | ||
1347 | { | ||
1348 | OwnerNameMap.Add_UInt32(item.uid); | ||
1349 | OwnerGroupMap.Add_UInt32(item.gid); | ||
1350 | } | ||
1351 | } | ||
1352 | } | ||
1353 | |||
1354 | if (StoreOwnerName) | ||
1355 | { | ||
1356 | UString u; | ||
1357 | AString a; | ||
1358 | { | ||
1359 | FOR_VECTOR (i, OwnerNameMap.Numbers) | ||
1360 | { | ||
1361 | // 200K/sec speed | ||
1362 | u.Empty(); | ||
1363 | const passwd *pw = getpwuid(OwnerNameMap.Numbers[i]); | ||
1364 | if (pw) | ||
1365 | { | ||
1366 | a = pw->pw_name; | ||
1367 | ConvertUTF8ToUnicode(a, u); | ||
1368 | } | ||
1369 | OwnerNameMap.Strings.Add(u); | ||
1370 | } | ||
1371 | } | ||
1372 | { | ||
1373 | FOR_VECTOR (i, OwnerGroupMap.Numbers) | ||
1374 | { | ||
1375 | u.Empty(); | ||
1376 | const group *gr = getgrgid(OwnerGroupMap.Numbers[i]); | ||
1377 | if (gr) | ||
1378 | { | ||
1379 | // printf("\ngetgrgid %d %s\n", OwnerGroupMap.Numbers[i], gr->gr_name); | ||
1380 | a = gr->gr_name; | ||
1381 | ConvertUTF8ToUnicode(a, u); | ||
1382 | } | ||
1383 | OwnerGroupMap.Strings.Add(u); | ||
1384 | } | ||
1385 | } | ||
1386 | |||
1387 | FOR_VECTOR (i, Items) | ||
1388 | { | ||
1389 | CDirItem &item = Items[i]; | ||
1390 | { | ||
1391 | const int index = OwnerNameMap.Find(item.uid); | ||
1392 | if (index < 0) throw 1; | ||
1393 | item.OwnerNameIndex = index; | ||
1394 | } | ||
1395 | { | ||
1396 | const int index = OwnerGroupMap.Find(item.gid); | ||
1397 | if (index < 0) throw 1; | ||
1398 | item.OwnerGroupIndex = index; | ||
1399 | } | ||
1400 | } | ||
1401 | } | ||
1402 | |||
1403 | |||
1404 | // if (NeedOwnerNames) | ||
1405 | { | ||
1406 | /* | ||
1407 | { | ||
1408 | for (unsigned i = 0 ; i < 10000; i++) | ||
1409 | { | ||
1410 | const passwd *pw = getpwuid(i); | ||
1411 | if (pw) | ||
1412 | { | ||
1413 | UString u; | ||
1414 | ConvertUTF8ToUnicode(AString(pw->pw_name), u); | ||
1415 | OwnerNameMap.Add(i, u); | ||
1416 | OwnerNameMap.Add(i, u); | ||
1417 | OwnerNameMap.Add(i, u); | ||
1418 | } | ||
1419 | const group *gr = getgrgid(i); | ||
1420 | if (gr) | ||
1421 | { | ||
1422 | // we can use utf-8 here. | ||
1423 | UString u; | ||
1424 | ConvertUTF8ToUnicode(AString(gr->gr_name), u); | ||
1425 | OwnerGroupMap.Add(i, u); | ||
1426 | } | ||
1427 | } | ||
1428 | } | ||
1429 | */ | ||
1430 | /* | ||
1431 | { | ||
1432 | FOR_VECTOR (i, OwnerNameMap.Strings) | ||
1433 | { | ||
1434 | AString s; | ||
1435 | ConvertUnicodeToUTF8(OwnerNameMap.Strings[i], s); | ||
1436 | printf("\n%5d %s", (unsigned)OwnerNameMap.Numbers[i], s.Ptr()); | ||
1437 | } | ||
1438 | } | ||
1439 | { | ||
1440 | printf("\n\n=========Groups\n"); | ||
1441 | FOR_VECTOR (i, OwnerGroupMap.Strings) | ||
1442 | { | ||
1443 | AString s; | ||
1444 | ConvertUnicodeToUTF8(OwnerGroupMap.Strings[i], s); | ||
1445 | printf("\n%5d %s", (unsigned)OwnerGroupMap.Numbers[i], s.Ptr()); | ||
1446 | } | ||
1447 | } | ||
1448 | */ | ||
1449 | } | ||
1450 | /* | ||
1451 | for (unsigned i = 0 ; i < 100000000; i++) | ||
1452 | { | ||
1453 | // const passwd *pw = getpwuid(1000); | ||
1454 | // pw = pw; | ||
1455 | int pos = OwnerNameMap.Find(1000); | ||
1456 | if (pos < 0 - (int)i) | ||
1457 | throw 1; | ||
1458 | } | ||
1459 | */ | ||
1460 | |||
1461 | return S_OK; | ||
1462 | } | ||
1463 | |||
1464 | #endif | ||
1465 | |||
1466 | |||
1284 | 1467 | ||
1285 | static const char * const kCannotFindArchive = "Cannot find archive"; | 1468 | static const char * const kCannotFindArchive = "Cannot find archive"; |
1286 | 1469 | ||
@@ -1351,11 +1534,18 @@ HRESULT EnumerateDirItemsAndSort( | |||
1351 | 1534 | ||
1352 | #ifdef _WIN32 | 1535 | #ifdef _WIN32 |
1353 | 1536 | ||
1537 | static bool IsDotsName(const wchar_t *s) | ||
1538 | { | ||
1539 | return s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)); | ||
1540 | } | ||
1541 | |||
1354 | // This code converts all short file names to long file names. | 1542 | // This code converts all short file names to long file names. |
1355 | 1543 | ||
1356 | static void ConvertToLongName(const UString &prefix, UString &name) | 1544 | static void ConvertToLongName(const UString &prefix, UString &name) |
1357 | { | 1545 | { |
1358 | if (name.IsEmpty() || DoesNameContainWildcard(name)) | 1546 | if (name.IsEmpty() |
1547 | || DoesNameContainWildcard(name) | ||
1548 | || IsDotsName(name)) | ||
1359 | return; | 1549 | return; |
1360 | NFind::CFileInfo fi; | 1550 | NFind::CFileInfo fi; |
1361 | const FString path (us2fs(prefix + name)); | 1551 | const FString path (us2fs(prefix + name)); |
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp index de2aeb2..58f5218 100644 --- a/CPP/7zip/UI/Common/Extract.cpp +++ b/CPP/7zip/UI/Common/Extract.cpp | |||
@@ -239,18 +239,18 @@ static HRESULT DecompressArchive( | |||
239 | Sorted list for file paths was sorted with case insensitive compare function. | 239 | Sorted list for file paths was sorted with case insensitive compare function. |
240 | But FindInSorted function did binary search via case sensitive compare function */ | 240 | But FindInSorted function did binary search via case sensitive compare function */ |
241 | 241 | ||
242 | int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name); | 242 | int Find_FileName_InSortedVector(const UStringVector &fileNames, const UString &name); |
243 | int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name) | 243 | int Find_FileName_InSortedVector(const UStringVector &fileNames, const UString &name) |
244 | { | 244 | { |
245 | unsigned left = 0, right = fileName.Size(); | 245 | unsigned left = 0, right = fileNames.Size(); |
246 | while (left != right) | 246 | while (left != right) |
247 | { | 247 | { |
248 | unsigned mid = (left + right) / 2; | 248 | const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
249 | const UString &midValue = fileName[mid]; | 249 | const UString &midVal = fileNames[mid]; |
250 | int compare = CompareFileNames(name, midValue); | 250 | const int comp = CompareFileNames(name, midVal); |
251 | if (compare == 0) | 251 | if (comp == 0) |
252 | return (int)mid; | 252 | return (int)mid; |
253 | if (compare < 0) | 253 | if (comp < 0) |
254 | right = mid; | 254 | right = mid; |
255 | else | 255 | else |
256 | left = mid + 1; | 256 | left = mid + 1; |
@@ -314,8 +314,13 @@ HRESULT Extract( | |||
314 | 314 | ||
315 | CArchiveExtractCallback *ecs = new CArchiveExtractCallback; | 315 | CArchiveExtractCallback *ecs = new CArchiveExtractCallback; |
316 | CMyComPtr<IArchiveExtractCallback> ec(ecs); | 316 | CMyComPtr<IArchiveExtractCallback> ec(ecs); |
317 | bool multi = (numArcs > 1); | 317 | |
318 | ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode, | 318 | const bool multi = (numArcs > 1); |
319 | |||
320 | ecs->InitForMulti(multi, | ||
321 | options.PathMode, | ||
322 | options.OverwriteMode, | ||
323 | options.ZoneMode, | ||
319 | false // keepEmptyDirParts | 324 | false // keepEmptyDirParts |
320 | ); | 325 | ); |
321 | #ifndef _SFX | 326 | #ifndef _SFX |
@@ -335,12 +340,18 @@ HRESULT Extract( | |||
335 | if (skipArcs[i]) | 340 | if (skipArcs[i]) |
336 | continue; | 341 | continue; |
337 | 342 | ||
343 | ecs->InitBeforeNewArchive(); | ||
344 | |||
338 | const UString &arcPath = arcPaths[i]; | 345 | const UString &arcPath = arcPaths[i]; |
339 | NFind::CFileInfo fi; | 346 | NFind::CFileInfo fi; |
340 | if (options.StdInMode) | 347 | if (options.StdInMode) |
341 | { | 348 | { |
342 | fi.Size = 0; | 349 | // do we need ctime and mtime? |
343 | fi.Attrib = 0; | 350 | fi.ClearBase(); |
351 | fi.Size = 0; // (UInt64)(Int64)-1; | ||
352 | fi.SetAsFile(); | ||
353 | // NTime::GetCurUtc_FiTime(fi.MTime); | ||
354 | // fi.CTime = fi.ATime = fi.MTime; | ||
344 | } | 355 | } |
345 | else | 356 | else |
346 | { | 357 | { |
@@ -417,6 +428,15 @@ HRESULT Extract( | |||
417 | continue; | 428 | continue; |
418 | } | 429 | } |
419 | 430 | ||
431 | #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) | ||
432 | if (options.ZoneMode != NExtract::NZoneIdMode::kNone | ||
433 | && !options.StdInMode) | ||
434 | { | ||
435 | ReadZoneFile_Of_BaseFile(us2fs(arcPath), ecs->ZoneBuf); | ||
436 | } | ||
437 | #endif | ||
438 | |||
439 | |||
420 | if (arcLink.Arcs.Size() != 0) | 440 | if (arcLink.Arcs.Size() != 0) |
421 | { | 441 | { |
422 | if (arcLink.GetArc()->IsHashHandler(op)) | 442 | if (arcLink.GetArc()->IsHashHandler(op)) |
@@ -490,11 +510,16 @@ HRESULT Extract( | |||
490 | */ | 510 | */ |
491 | 511 | ||
492 | CArc &arc = arcLink.Arcs.Back(); | 512 | CArc &arc = arcLink.Arcs.Back(); |
493 | arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice); | 513 | arc.MTime.Def = !options.StdInMode |
494 | arc.MTime = fi.MTime; | 514 | #ifdef _WIN32 |
515 | && !fi.IsDevice | ||
516 | #endif | ||
517 | ; | ||
518 | if (arc.MTime.Def) | ||
519 | arc.MTime.Set_From_FiTime(fi.MTime); | ||
495 | 520 | ||
496 | UInt64 packProcessed; | 521 | UInt64 packProcessed; |
497 | bool calcCrc = | 522 | const bool calcCrc = |
498 | #ifndef _SFX | 523 | #ifndef _SFX |
499 | (hash != NULL); | 524 | (hash != NULL); |
500 | #else | 525 | #else |
diff --git a/CPP/7zip/UI/Common/Extract.h b/CPP/7zip/UI/Common/Extract.h index 10e06da..f3d1126 100644 --- a/CPP/7zip/UI/Common/Extract.h +++ b/CPP/7zip/UI/Common/Extract.h | |||
@@ -25,6 +25,7 @@ struct CExtractOptionsBase | |||
25 | bool OverwriteMode_Force; | 25 | bool OverwriteMode_Force; |
26 | NExtract::NPathMode::EEnum PathMode; | 26 | NExtract::NPathMode::EEnum PathMode; |
27 | NExtract::NOverwriteMode::EEnum OverwriteMode; | 27 | NExtract::NOverwriteMode::EEnum OverwriteMode; |
28 | NExtract::NZoneIdMode::EEnum ZoneMode; | ||
28 | 29 | ||
29 | FString OutputDir; | 30 | FString OutputDir; |
30 | CExtractNtOptions NtOptions; | 31 | CExtractNtOptions NtOptions; |
@@ -36,7 +37,8 @@ struct CExtractOptionsBase | |||
36 | PathMode_Force(false), | 37 | PathMode_Force(false), |
37 | OverwriteMode_Force(false), | 38 | OverwriteMode_Force(false), |
38 | PathMode(NExtract::NPathMode::kFullPaths), | 39 | PathMode(NExtract::NPathMode::kFullPaths), |
39 | OverwriteMode(NExtract::NOverwriteMode::kAsk) | 40 | OverwriteMode(NExtract::NOverwriteMode::kAsk), |
41 | ZoneMode(NExtract::NZoneIdMode::kNone) | ||
40 | {} | 42 | {} |
41 | }; | 43 | }; |
42 | 44 | ||
diff --git a/CPP/7zip/UI/Common/ExtractMode.h b/CPP/7zip/UI/Common/ExtractMode.h index 3b2b9a0..9ad831e 100644 --- a/CPP/7zip/UI/Common/ExtractMode.h +++ b/CPP/7zip/UI/Common/ExtractMode.h | |||
@@ -29,6 +29,16 @@ namespace NOverwriteMode | |||
29 | }; | 29 | }; |
30 | } | 30 | } |
31 | 31 | ||
32 | namespace NZoneIdMode | ||
33 | { | ||
34 | enum EEnum | ||
35 | { | ||
36 | kNone, | ||
37 | kAll, | ||
38 | kOffice | ||
39 | }; | ||
40 | } | ||
41 | |||
32 | } | 42 | } |
33 | 43 | ||
34 | #endif | 44 | #endif |
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp index 21a306d..a1282b7 100644 --- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp +++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp | |||
@@ -34,10 +34,19 @@ static void ReplaceIncorrectChars(UString &s) | |||
34 | || | 34 | || |
35 | #endif | 35 | #endif |
36 | c == WCHAR_PATH_SEPARATOR) | 36 | c == WCHAR_PATH_SEPARATOR) |
37 | { | ||
38 | #if WCHAR_PATH_SEPARATOR != L'/' | ||
39 | // 22.00 : WSL replacement for backslash | ||
40 | if (c == WCHAR_PATH_SEPARATOR) | ||
41 | c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; | ||
42 | else | ||
43 | #endif | ||
44 | c = '_'; | ||
37 | s.ReplaceOneCharAtPos(i, | 45 | s.ReplaceOneCharAtPos(i, |
38 | '_' // default | 46 | c |
39 | // (wchar_t)(0xf000 + c) // 21.02 debug: WSL encoding for unsupported characters | 47 | // (wchar_t)(0xf000 + c) // 21.02 debug: WSL encoding for unsupported characters |
40 | ); | 48 | ); |
49 | } | ||
41 | } | 50 | } |
42 | } | 51 | } |
43 | 52 | ||
diff --git a/CPP/7zip/UI/Common/HashCalc.cpp b/CPP/7zip/UI/Common/HashCalc.cpp index 2417708..f0aa4bd 100644 --- a/CPP/7zip/UI/Common/HashCalc.cpp +++ b/CPP/7zip/UI/Common/HashCalc.cpp | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "../../Common/StreamUtils.h" | 15 | #include "../../Common/StreamUtils.h" |
16 | 16 | ||
17 | #include "../../Archive/Common/ItemNameUtils.h" | 17 | #include "../../Archive/Common/ItemNameUtils.h" |
18 | #include "../../Archive/IArchive.h" | ||
18 | 19 | ||
19 | #include "EnumDirItems.h" | 20 | #include "EnumDirItems.h" |
20 | #include "HashCalc.h" | 21 | #include "HashCalc.h" |
@@ -309,8 +310,6 @@ static unsigned GetColumnWidth(unsigned digestSize) | |||
309 | } | 310 | } |
310 | 311 | ||
311 | 312 | ||
312 | void HashHexToString(char *dest, const Byte *data, UInt32 size); | ||
313 | |||
314 | static void AddHashResultLine( | 313 | static void AddHashResultLine( |
315 | AString &_s, | 314 | AString &_s, |
316 | // bool showHash, | 315 | // bool showHash, |
@@ -463,10 +462,7 @@ HRESULT HashCalc( | |||
463 | { | 462 | { |
464 | CDirItem di; | 463 | CDirItem di; |
465 | di.Size = (UInt64)(Int64)-1; | 464 | di.Size = (UInt64)(Int64)-1; |
466 | di.Attrib = 0; | 465 | di.SetAsFile(); |
467 | di.MTime.dwLowDateTime = 0; | ||
468 | di.MTime.dwHighDateTime = 0; | ||
469 | di.CTime = di.ATime = di.MTime; | ||
470 | dirItems.Items.Add(di); | 466 | dirItems.Items.Add(di); |
471 | } | 467 | } |
472 | else | 468 | else |
@@ -478,6 +474,8 @@ HRESULT HashCalc( | |||
478 | dirItems.ExcludeDirItems = censor.ExcludeDirItems; | 474 | dirItems.ExcludeDirItems = censor.ExcludeDirItems; |
479 | dirItems.ExcludeFileItems = censor.ExcludeFileItems; | 475 | dirItems.ExcludeFileItems = censor.ExcludeFileItems; |
480 | 476 | ||
477 | dirItems.ShareForWrite = options.OpenShareForWrite; | ||
478 | |||
481 | HRESULT res = EnumerateItems(censor, | 479 | HRESULT res = EnumerateItems(censor, |
482 | options.PathMode, | 480 | options.PathMode, |
483 | UString(), | 481 | UString(), |
@@ -498,14 +496,16 @@ HRESULT HashCalc( | |||
498 | // hb.Init(); | 496 | // hb.Init(); |
499 | 497 | ||
500 | hb.NumErrors = dirItems.Stat.NumErrors; | 498 | hb.NumErrors = dirItems.Stat.NumErrors; |
501 | 499 | ||
500 | UInt64 totalSize = 0; | ||
502 | if (options.StdInMode) | 501 | if (options.StdInMode) |
503 | { | 502 | { |
504 | RINOK(callback->SetNumFiles(1)); | 503 | RINOK(callback->SetNumFiles(1)); |
505 | } | 504 | } |
506 | else | 505 | else |
507 | { | 506 | { |
508 | RINOK(callback->SetTotal(dirItems.Stat.GetTotalBytes())); | 507 | totalSize = dirItems.Stat.GetTotalBytes(); |
508 | RINOK(callback->SetTotal(totalSize)); | ||
509 | } | 509 | } |
510 | 510 | ||
511 | const UInt32 kBufSize = 1 << 15; | 511 | const UInt32 kBufSize = 1 << 15; |
@@ -537,7 +537,9 @@ HRESULT HashCalc( | |||
537 | { | 537 | { |
538 | path = dirItems.GetLogPath(i); | 538 | path = dirItems.GetLogPath(i); |
539 | const CDirItem &di = dirItems.Items[i]; | 539 | const CDirItem &di = dirItems.Items[i]; |
540 | #ifdef _WIN32 | ||
540 | isAltStream = di.IsAltStream; | 541 | isAltStream = di.IsAltStream; |
542 | #endif | ||
541 | 543 | ||
542 | #ifndef UNDER_CE | 544 | #ifndef UNDER_CE |
543 | // if (di.AreReparseData()) | 545 | // if (di.AreReparseData()) |
@@ -551,7 +553,7 @@ HRESULT HashCalc( | |||
551 | #endif | 553 | #endif |
552 | { | 554 | { |
553 | CInFileStream *inStreamSpec = new CInFileStream; | 555 | CInFileStream *inStreamSpec = new CInFileStream; |
554 | inStreamSpec->File.PreserveATime = options.PreserveATime; | 556 | inStreamSpec->Set_PreserveATime(options.PreserveATime); |
555 | inStream = inStreamSpec; | 557 | inStream = inStreamSpec; |
556 | isDir = di.IsDir(); | 558 | isDir = di.IsDir(); |
557 | if (!isDir) | 559 | if (!isDir) |
@@ -565,6 +567,20 @@ HRESULT HashCalc( | |||
565 | return res; | 567 | return res; |
566 | continue; | 568 | continue; |
567 | } | 569 | } |
570 | if (!options.StdInMode) | ||
571 | { | ||
572 | UInt64 curSize = 0; | ||
573 | if (inStreamSpec->GetSize(&curSize) == S_OK) | ||
574 | { | ||
575 | if (curSize > di.Size) | ||
576 | { | ||
577 | totalSize += curSize - di.Size; | ||
578 | RINOK(callback->SetTotal(totalSize)); | ||
579 | // printf("\ntotal = %d MiB\n", (unsigned)(totalSize >> 20)); | ||
580 | } | ||
581 | } | ||
582 | } | ||
583 | // inStreamSpec->ReloadProps(); | ||
568 | } | 584 | } |
569 | } | 585 | } |
570 | } | 586 | } |
@@ -580,6 +596,7 @@ HRESULT HashCalc( | |||
580 | { | 596 | { |
581 | if ((step & 0xFF) == 0) | 597 | if ((step & 0xFF) == 0) |
582 | { | 598 | { |
599 | // printf("\ncompl = %d\n", (unsigned)(completeValue >> 20)); | ||
583 | RINOK(callback->SetCompleted(&completeValue)); | 600 | RINOK(callback->SetCompleted(&completeValue)); |
584 | } | 601 | } |
585 | UInt32 size; | 602 | UInt32 size; |
@@ -1679,8 +1696,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt | |||
1679 | if (_isArc && !CanUpdate()) | 1696 | if (_isArc && !CanUpdate()) |
1680 | return E_NOTIMPL; | 1697 | return E_NOTIMPL; |
1681 | 1698 | ||
1682 | // const UINT codePage = CP_UTF8; // // (_forceCodePage ? _specifiedCodePage : _openCodePage); | 1699 | /* |
1683 | // const unsigned utfFlags = g_Unicode_To_UTF8_Flags; | 1700 | CMyComPtr<IArchiveUpdateCallbackArcProp> reportArcProp; |
1701 | callback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp); | ||
1702 | */ | ||
1703 | |||
1684 | CObjectVector<CUpdateItem> updateItems; | 1704 | CObjectVector<CUpdateItem> updateItems; |
1685 | 1705 | ||
1686 | UInt64 complexity = 0; | 1706 | UInt64 complexity = 0; |
@@ -1827,6 +1847,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt | |||
1827 | if (ui.NewData) | 1847 | if (ui.NewData) |
1828 | { | 1848 | { |
1829 | UInt64 currentComplexity = ui.Size; | 1849 | UInt64 currentComplexity = ui.Size; |
1850 | UInt64 fileSize = 0; | ||
1851 | |||
1830 | CMyComPtr<ISequentialInStream> fileInStream; | 1852 | CMyComPtr<ISequentialInStream> fileInStream; |
1831 | bool needWrite = true; | 1853 | bool needWrite = true; |
1832 | { | 1854 | { |
@@ -1840,6 +1862,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt | |||
1840 | 1862 | ||
1841 | if (fileInStream) | 1863 | if (fileInStream) |
1842 | { | 1864 | { |
1865 | CMyComPtr<IStreamGetSize> streamGetSize; | ||
1866 | fileInStream->QueryInterface(IID_IStreamGetSize, (void **)&streamGetSize); | ||
1867 | if (streamGetSize) | ||
1868 | { | ||
1869 | UInt64 size; | ||
1870 | if (streamGetSize->GetSize(&size) == S_OK) | ||
1871 | currentComplexity = size; | ||
1872 | } | ||
1873 | /* | ||
1843 | CMyComPtr<IStreamGetProps> getProps; | 1874 | CMyComPtr<IStreamGetProps> getProps; |
1844 | fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); | 1875 | fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); |
1845 | if (getProps) | 1876 | if (getProps) |
@@ -1852,6 +1883,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt | |||
1852 | // item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);; | 1883 | // item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);; |
1853 | } | 1884 | } |
1854 | } | 1885 | } |
1886 | */ | ||
1855 | } | 1887 | } |
1856 | else | 1888 | else |
1857 | { | 1889 | { |
@@ -1865,7 +1897,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt | |||
1865 | 1897 | ||
1866 | if (needWrite && fileInStream && !isDir) | 1898 | if (needWrite && fileInStream && !isDir) |
1867 | { | 1899 | { |
1868 | UInt64 fileSize = 0; | ||
1869 | for (UInt32 step = 0;; step++) | 1900 | for (UInt32 step = 0;; step++) |
1870 | { | 1901 | { |
1871 | if ((step & 0xFF) == 0) | 1902 | if ((step & 0xFF) == 0) |
@@ -1901,6 +1932,36 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt | |||
1901 | } | 1932 | } |
1902 | 1933 | ||
1903 | complexity += currentComplexity; | 1934 | complexity += currentComplexity; |
1935 | |||
1936 | /* | ||
1937 | if (reportArcProp) | ||
1938 | { | ||
1939 | PROPVARIANT prop; | ||
1940 | prop.vt = VT_EMPTY; | ||
1941 | prop.wReserved1 = 0; | ||
1942 | |||
1943 | NCOM::PropVarEm_Set_UInt64(&prop, fileSize); | ||
1944 | RINOK(reportArcProp->ReportProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, kpidSize, &prop)); | ||
1945 | |||
1946 | for (unsigned k = 0; k < hb.Hashers.Size(); k++) | ||
1947 | { | ||
1948 | const CHasherState &hs = hb.Hashers[k]; | ||
1949 | |||
1950 | if (hs.DigestSize == 4 && hs.Name.IsEqualTo_Ascii_NoCase("crc32")) | ||
1951 | { | ||
1952 | NCOM::PropVarEm_Set_UInt32(&prop, GetUi32(hs.Digests[k_HashCalc_Index_Current])); | ||
1953 | RINOK(reportArcProp->ReportProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, kpidCRC, &prop)); | ||
1954 | } | ||
1955 | else | ||
1956 | { | ||
1957 | RINOK(reportArcProp->ReportRawProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, | ||
1958 | kpidChecksum, hs.Digests[k_HashCalc_Index_Current], | ||
1959 | hs.DigestSize, NPropDataType::kRaw)); | ||
1960 | } | ||
1961 | RINOK(reportArcProp->ReportFinished(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, NArchive::NUpdate::NOperationResult::kOK)); | ||
1962 | } | ||
1963 | } | ||
1964 | */ | ||
1904 | RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); | 1965 | RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); |
1905 | } | 1966 | } |
1906 | else | 1967 | else |
diff --git a/CPP/7zip/UI/Common/HashCalc.h b/CPP/7zip/UI/Common/HashCalc.h index 80a5565..c566caa 100644 --- a/CPP/7zip/UI/Common/HashCalc.h +++ b/CPP/7zip/UI/Common/HashCalc.h | |||
@@ -16,6 +16,12 @@ const unsigned k_HashCalc_DigestSize_Max = 64; | |||
16 | const unsigned k_HashCalc_ExtraSize = 8; | 16 | const unsigned k_HashCalc_ExtraSize = 8; |
17 | const unsigned k_HashCalc_NumGroups = 4; | 17 | const unsigned k_HashCalc_NumGroups = 4; |
18 | 18 | ||
19 | /* | ||
20 | if (size <= 8) : upper case : reversed byte order : it shows 32-bit/64-bit number, if data contains little-endian number | ||
21 | if (size > 8) : lower case : original byte order (as big-endian byte sequence) | ||
22 | */ | ||
23 | void HashHexToString(char *dest, const Byte *data, UInt32 size); | ||
24 | |||
19 | enum | 25 | enum |
20 | { | 26 | { |
21 | k_HashCalc_Index_Current, | 27 | k_HashCalc_Index_Current, |
diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp index 377963a..b6a2073 100644 --- a/CPP/7zip/UI/Common/LoadCodecs.cpp +++ b/CPP/7zip/UI/Common/LoadCodecs.cpp | |||
@@ -33,8 +33,6 @@ EXPORT_CODECS | |||
33 | 33 | ||
34 | #include "StdAfx.h" | 34 | #include "StdAfx.h" |
35 | 35 | ||
36 | #include "../../../../C/7zVersion.h" | ||
37 | |||
38 | #include "../../../Common/MyCom.h" | 36 | #include "../../../Common/MyCom.h" |
39 | #include "../../../Common/StringToInt.h" | 37 | #include "../../../Common/StringToInt.h" |
40 | #include "../../../Common/StringConvert.h" | 38 | #include "../../../Common/StringConvert.h" |
@@ -275,6 +273,9 @@ static HRESULT GetMethodBoolProp(Func_GetMethodProperty getMethodProperty, UInt3 | |||
275 | #define MY_GET_FUNC(dest, type, func) *(void **)(&dest) = (func); | 273 | #define MY_GET_FUNC(dest, type, func) *(void **)(&dest) = (func); |
276 | // #define MY_GET_FUNC(dest, type, func) dest = (type)(func); | 274 | // #define MY_GET_FUNC(dest, type, func) dest = (type)(func); |
277 | 275 | ||
276 | #define MY_GET_FUNC_LOC(dest, type, func) \ | ||
277 | type dest; MY_GET_FUNC(dest, type, func) | ||
278 | |||
278 | HRESULT CCodecs::LoadCodecs() | 279 | HRESULT CCodecs::LoadCodecs() |
279 | { | 280 | { |
280 | CCodecLib &lib = Libs.Back(); | 281 | CCodecLib &lib = Libs.Back(); |
@@ -286,8 +287,7 @@ HRESULT CCodecs::LoadCodecs() | |||
286 | if (lib.GetMethodProperty) | 287 | if (lib.GetMethodProperty) |
287 | { | 288 | { |
288 | UInt32 numMethods = 1; | 289 | UInt32 numMethods = 1; |
289 | Func_GetNumberOfMethods getNumberOfMethods; | 290 | MY_GET_FUNC_LOC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib.GetProc("GetNumberOfMethods")); |
290 | MY_GET_FUNC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib.GetProc("GetNumberOfMethods")); | ||
291 | if (getNumberOfMethods) | 291 | if (getNumberOfMethods) |
292 | { | 292 | { |
293 | RINOK(getNumberOfMethods(&numMethods)); | 293 | RINOK(getNumberOfMethods(&numMethods)); |
@@ -304,8 +304,7 @@ HRESULT CCodecs::LoadCodecs() | |||
304 | } | 304 | } |
305 | } | 305 | } |
306 | 306 | ||
307 | Func_GetHashers getHashers; | 307 | MY_GET_FUNC_LOC (getHashers, Func_GetHashers, lib.Lib.GetProc("GetHashers")); |
308 | MY_GET_FUNC (getHashers, Func_GetHashers, lib.Lib.GetProc("GetHashers")); | ||
309 | if (getHashers) | 308 | if (getHashers) |
310 | { | 309 | { |
311 | RINOK(getHashers(&lib.ComHashers)); | 310 | RINOK(getHashers(&lib.ComHashers)); |
@@ -414,17 +413,14 @@ HRESULT CCodecs::LoadFormats() | |||
414 | const NDLL::CLibrary &lib = Libs.Back().Lib; | 413 | const NDLL::CLibrary &lib = Libs.Back().Lib; |
415 | 414 | ||
416 | Func_GetHandlerProperty getProp = NULL; | 415 | Func_GetHandlerProperty getProp = NULL; |
417 | Func_GetHandlerProperty2 getProp2; | 416 | MY_GET_FUNC_LOC (getProp2, Func_GetHandlerProperty2, lib.GetProc("GetHandlerProperty2")); |
418 | MY_GET_FUNC (getProp2, Func_GetHandlerProperty2, lib.GetProc("GetHandlerProperty2")); | 417 | MY_GET_FUNC_LOC (getIsArc, Func_GetIsArc, lib.GetProc("GetIsArc")); |
419 | Func_GetIsArc getIsArc; | ||
420 | MY_GET_FUNC (getIsArc, Func_GetIsArc, lib.GetProc("GetIsArc")); | ||
421 | 418 | ||
422 | UInt32 numFormats = 1; | 419 | UInt32 numFormats = 1; |
423 | 420 | ||
424 | if (getProp2) | 421 | if (getProp2) |
425 | { | 422 | { |
426 | Func_GetNumberOfFormats getNumberOfFormats; | 423 | MY_GET_FUNC_LOC (getNumberOfFormats, Func_GetNumberOfFormats, lib.GetProc("GetNumberOfFormats")); |
427 | MY_GET_FUNC (getNumberOfFormats, Func_GetNumberOfFormats, lib.GetProc("GetNumberOfFormats")); | ||
428 | if (getNumberOfFormats) | 424 | if (getNumberOfFormats) |
429 | { | 425 | { |
430 | RINOK(getNumberOfFormats(&numFormats)); | 426 | RINOK(getNumberOfFormats(&numFormats)); |
@@ -477,6 +473,11 @@ HRESULT CCodecs::LoadFormats() | |||
477 | item.Flags |= kArcFlagsPars[j + 1]; | 473 | item.Flags |= kArcFlagsPars[j + 1]; |
478 | } | 474 | } |
479 | } | 475 | } |
476 | |||
477 | { | ||
478 | bool defined = false; | ||
479 | RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kTimeFlags, item.TimeFlags, defined)); | ||
480 | } | ||
480 | 481 | ||
481 | CByteBuffer sig; | 482 | CByteBuffer sig; |
482 | RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig)); | 483 | RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig)); |
@@ -567,8 +568,7 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded | |||
567 | 568 | ||
568 | /* | 569 | /* |
569 | { | 570 | { |
570 | Func_LibStartup _LibStartup; | 571 | MY_GET_FUNC_LOC (_LibStartup, Func_LibStartup, lib.Lib.GetProc("LibStartup")); |
571 | MY_GET_FUNC (_LibStartup, Func_LibStartup, lib.Lib.GetProc("LibStartup")); | ||
572 | if (_LibStartup) | 572 | if (_LibStartup) |
573 | { | 573 | { |
574 | HRESULT res = _LibStartup(); | 574 | HRESULT res = _LibStartup(); |
@@ -585,21 +585,31 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded | |||
585 | #ifdef _7ZIP_LARGE_PAGES | 585 | #ifdef _7ZIP_LARGE_PAGES |
586 | if (g_LargePageSize != 0) | 586 | if (g_LargePageSize != 0) |
587 | { | 587 | { |
588 | Func_SetLargePageMode setLargePageMode; | 588 | MY_GET_FUNC_LOC (setLargePageMode, Func_SetLargePageMode, lib.Lib.GetProc("SetLargePageMode")); |
589 | MY_GET_FUNC (setLargePageMode, Func_SetLargePageMode, lib.Lib.GetProc("SetLargePageMode")); | ||
590 | if (setLargePageMode) | 589 | if (setLargePageMode) |
591 | setLargePageMode(); | 590 | setLargePageMode(); |
592 | } | 591 | } |
593 | #endif | 592 | #endif |
594 | 593 | ||
595 | if (CaseSensitiveChange) | 594 | if (CaseSensitive_Change) |
596 | { | 595 | { |
597 | Func_SetCaseSensitive setCaseSensitive; | 596 | MY_GET_FUNC_LOC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib.GetProc("SetCaseSensitive")); |
598 | MY_GET_FUNC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib.GetProc("SetCaseSensitive")); | ||
599 | if (setCaseSensitive) | 597 | if (setCaseSensitive) |
600 | setCaseSensitive(CaseSensitive ? 1 : 0); | 598 | setCaseSensitive(CaseSensitive ? 1 : 0); |
601 | } | 599 | } |
602 | 600 | ||
601 | /* | ||
602 | { | ||
603 | MY_GET_FUNC_LOC (setClientVersion, Func_SetClientVersion, lib.Lib.GetProc("SetClientVersion")); | ||
604 | if (setClientVersion) | ||
605 | { | ||
606 | // const UInt32 kVersion = (MY_VER_MAJOR << 16) | MY_VER_MINOR; | ||
607 | setClientVersion(g_ClientVersion); | ||
608 | } | ||
609 | } | ||
610 | */ | ||
611 | |||
612 | |||
603 | MY_GET_FUNC (lib.CreateObject, Func_CreateObject, lib.Lib.GetProc("CreateObject")); | 613 | MY_GET_FUNC (lib.CreateObject, Func_CreateObject, lib.Lib.GetProc("CreateObject")); |
604 | { | 614 | { |
605 | unsigned startSize = Codecs.Size() + Hashers.Size(); | 615 | unsigned startSize = Codecs.Size() + Hashers.Size(); |
diff --git a/CPP/7zip/UI/Common/LoadCodecs.h b/CPP/7zip/UI/Common/LoadCodecs.h index 829472d..50fb9f8 100644 --- a/CPP/7zip/UI/Common/LoadCodecs.h +++ b/CPP/7zip/UI/Common/LoadCodecs.h | |||
@@ -96,6 +96,7 @@ struct CArcExtInfo | |||
96 | struct CArcInfoEx | 96 | struct CArcInfoEx |
97 | { | 97 | { |
98 | UInt32 Flags; | 98 | UInt32 Flags; |
99 | UInt32 TimeFlags; | ||
99 | 100 | ||
100 | Func_CreateInArchive CreateInArchive; | 101 | Func_CreateInArchive CreateInArchive; |
101 | Func_IsArc IsArcFunc; | 102 | Func_IsArc IsArcFunc; |
@@ -142,7 +143,7 @@ struct CArcInfoEx | |||
142 | bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; } | 143 | bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; } |
143 | 144 | ||
144 | bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; } | 145 | bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; } |
145 | bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; } | 146 | bool Flags_NtSecurity() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; } |
146 | bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; } | 147 | bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; } |
147 | bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; } | 148 | bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; } |
148 | 149 | ||
@@ -154,6 +155,27 @@ struct CArcInfoEx | |||
154 | bool Flags_ByExtOnlyOpen() const { return (Flags & NArcInfoFlags::kByExtOnlyOpen) != 0; } | 155 | bool Flags_ByExtOnlyOpen() const { return (Flags & NArcInfoFlags::kByExtOnlyOpen) != 0; } |
155 | bool Flags_HashHandler() const { return (Flags & NArcInfoFlags::kHashHandler) != 0; } | 156 | bool Flags_HashHandler() const { return (Flags & NArcInfoFlags::kHashHandler) != 0; } |
156 | 157 | ||
158 | bool Flags_CTime() const { return (Flags & NArcInfoFlags::kCTime) != 0; } | ||
159 | bool Flags_ATime() const { return (Flags & NArcInfoFlags::kATime) != 0; } | ||
160 | bool Flags_MTime() const { return (Flags & NArcInfoFlags::kMTime) != 0; } | ||
161 | |||
162 | bool Flags_CTime_Default() const { return (Flags & NArcInfoFlags::kCTime_Default) != 0; } | ||
163 | bool Flags_ATime_Default() const { return (Flags & NArcInfoFlags::kATime_Default) != 0; } | ||
164 | bool Flags_MTime_Default() const { return (Flags & NArcInfoFlags::kMTime_Default) != 0; } | ||
165 | |||
166 | UInt32 Get_TimePrecFlags() const | ||
167 | { | ||
168 | return (TimeFlags >> NArcInfoTimeFlags::kTime_Prec_Mask_bit_index) & | ||
169 | (((UInt32)1 << NArcInfoTimeFlags::kTime_Prec_Mask_num_bits) - 1); | ||
170 | } | ||
171 | |||
172 | UInt32 Get_DefaultTimePrec() const | ||
173 | { | ||
174 | return (TimeFlags >> NArcInfoTimeFlags::kTime_Prec_Default_bit_index) & | ||
175 | (((UInt32)1 << NArcInfoTimeFlags::kTime_Prec_Default_num_bits) - 1); | ||
176 | } | ||
177 | |||
178 | |||
157 | UString GetMainExt() const | 179 | UString GetMainExt() const |
158 | { | 180 | { |
159 | if (Exts.IsEmpty()) | 181 | if (Exts.IsEmpty()) |
@@ -162,6 +184,15 @@ struct CArcInfoEx | |||
162 | } | 184 | } |
163 | int FindExtension(const UString &ext) const; | 185 | int FindExtension(const UString &ext) const; |
164 | 186 | ||
187 | bool Is_7z() const { return Name.IsEqualTo_Ascii_NoCase("7z"); } | ||
188 | bool Is_Split() const { return Name.IsEqualTo_Ascii_NoCase("Split"); } | ||
189 | bool Is_Xz() const { return Name.IsEqualTo_Ascii_NoCase("xz"); } | ||
190 | bool Is_BZip2() const { return Name.IsEqualTo_Ascii_NoCase("bzip2"); } | ||
191 | bool Is_GZip() const { return Name.IsEqualTo_Ascii_NoCase("gzip"); } | ||
192 | bool Is_Tar() const { return Name.IsEqualTo_Ascii_NoCase("tar"); } | ||
193 | bool Is_Zip() const { return Name.IsEqualTo_Ascii_NoCase("zip"); } | ||
194 | bool Is_Rar() const { return Name.IsEqualTo_Ascii_NoCase("rar"); } | ||
195 | |||
165 | /* | 196 | /* |
166 | UString GetAllExtensions() const | 197 | UString GetAllExtensions() const |
167 | { | 198 | { |
@@ -178,11 +209,10 @@ struct CArcInfoEx | |||
178 | 209 | ||
179 | void AddExts(const UString &ext, const UString &addExt); | 210 | void AddExts(const UString &ext, const UString &addExt); |
180 | 211 | ||
181 | bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); } | ||
182 | // bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); } | ||
183 | 212 | ||
184 | CArcInfoEx(): | 213 | CArcInfoEx(): |
185 | Flags(0), | 214 | Flags(0), |
215 | TimeFlags(0), | ||
186 | CreateInArchive(NULL), | 216 | CreateInArchive(NULL), |
187 | IsArcFunc(NULL) | 217 | IsArcFunc(NULL) |
188 | #ifndef _SFX | 218 | #ifndef _SFX |
@@ -333,14 +363,14 @@ public: | |||
333 | CRecordVector<CDllHasherInfo> Hashers; | 363 | CRecordVector<CDllHasherInfo> Hashers; |
334 | #endif | 364 | #endif |
335 | 365 | ||
336 | bool CaseSensitiveChange; | 366 | bool CaseSensitive_Change; |
337 | bool CaseSensitive; | 367 | bool CaseSensitive; |
338 | 368 | ||
339 | CCodecs(): | 369 | CCodecs(): |
340 | #ifdef EXTERNAL_CODECS | 370 | #ifdef EXTERNAL_CODECS |
341 | NeedSetLibCodecs(true), | 371 | NeedSetLibCodecs(true), |
342 | #endif | 372 | #endif |
343 | CaseSensitiveChange(false), | 373 | CaseSensitive_Change(false), |
344 | CaseSensitive(false) | 374 | CaseSensitive(false) |
345 | {} | 375 | {} |
346 | 376 | ||
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp index 331793f..4a91a26 100644 --- a/CPP/7zip/UI/Common/OpenArchive.cpp +++ b/CPP/7zip/UI/Common/OpenArchive.cpp | |||
@@ -209,8 +209,8 @@ int CHandler::FindInsertPos(const CParseItem &item) const | |||
209 | unsigned left = 0, right = _items.Size(); | 209 | unsigned left = 0, right = _items.Size(); |
210 | while (left != right) | 210 | while (left != right) |
211 | { | 211 | { |
212 | unsigned mid = (left + right) / 2; | 212 | const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
213 | const CParseItem & midItem = _items[mid]; | 213 | const CParseItem &midItem = _items[mid]; |
214 | if (item.Offset < midItem.Offset) | 214 | if (item.Offset < midItem.Offset) |
215 | right = mid; | 215 | right = mid; |
216 | else if (item.Offset > midItem.Offset) | 216 | else if (item.Offset > midItem.Offset) |
@@ -262,8 +262,8 @@ void CHandler::AddUnknownItem(UInt64 next) | |||
262 | void CHandler::AddItem(const CParseItem &item) | 262 | void CHandler::AddItem(const CParseItem &item) |
263 | { | 263 | { |
264 | AddUnknownItem(item.Offset); | 264 | AddUnknownItem(item.Offset); |
265 | int pos = FindInsertPos(item); | 265 | const int pos = FindInsertPos(item); |
266 | if (pos >= 0) | 266 | if (pos != -1) |
267 | { | 267 | { |
268 | _items.Insert((unsigned)pos, item); | 268 | _items.Insert((unsigned)pos, item); |
269 | UInt64 next = item.Offset + item.Size; | 269 | UInt64 next = item.Offset + item.Size; |
@@ -482,7 +482,7 @@ HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) thro | |||
482 | return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result); | 482 | return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result); |
483 | } | 483 | } |
484 | 484 | ||
485 | static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result) throw() | 485 | static HRESULT Archive_GetArcProp_Bool(IInArchive *arc, PROPID propid, bool &result) throw() |
486 | { | 486 | { |
487 | NCOM::CPropVariant prop; | 487 | NCOM::CPropVariant prop; |
488 | result = false; | 488 | result = false; |
@@ -532,7 +532,7 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res | |||
532 | 532 | ||
533 | #ifndef _SFX | 533 | #ifndef _SFX |
534 | 534 | ||
535 | HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const | 535 | HRESULT CArc::GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const |
536 | { | 536 | { |
537 | if (!GetRawProps) | 537 | if (!GetRawProps) |
538 | return E_FAIL; | 538 | return E_FAIL; |
@@ -616,7 +616,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa | |||
616 | 616 | ||
617 | 617 | ||
618 | 618 | ||
619 | HRESULT CArc::GetItemPath(UInt32 index, UString &result) const | 619 | HRESULT CArc::GetItem_Path(UInt32 index, UString &result) const |
620 | { | 620 | { |
621 | #ifdef MY_CPU_LE | 621 | #ifdef MY_CPU_LE |
622 | if (GetRawProps) | 622 | if (GetRawProps) |
@@ -752,13 +752,13 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const | |||
752 | } | 752 | } |
753 | 753 | ||
754 | if (result.IsEmpty()) | 754 | if (result.IsEmpty()) |
755 | return GetDefaultItemPath(index, result); | 755 | return GetItem_DefaultPath(index, result); |
756 | 756 | ||
757 | Convert_UnicodeEsc16_To_UnicodeEscHigh(result); | 757 | Convert_UnicodeEsc16_To_UnicodeEscHigh(result); |
758 | return S_OK; | 758 | return S_OK; |
759 | } | 759 | } |
760 | 760 | ||
761 | HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const | 761 | HRESULT CArc::GetItem_DefaultPath(UInt32 index, UString &result) const |
762 | { | 762 | { |
763 | result.Empty(); | 763 | result.Empty(); |
764 | bool isDir; | 764 | bool isDir; |
@@ -779,9 +779,9 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const | |||
779 | return S_OK; | 779 | return S_OK; |
780 | } | 780 | } |
781 | 781 | ||
782 | HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const | 782 | HRESULT CArc::GetItem_Path2(UInt32 index, UString &result) const |
783 | { | 783 | { |
784 | RINOK(GetItemPath(index, result)); | 784 | RINOK(GetItem_Path(index, result)); |
785 | if (Ask_Deleted) | 785 | if (Ask_Deleted) |
786 | { | 786 | { |
787 | bool isDeleted = false; | 787 | bool isDeleted = false; |
@@ -833,7 +833,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const | |||
833 | RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)); | 833 | RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)); |
834 | item.MainIsDir = item.IsDir; | 834 | item.MainIsDir = item.IsDir; |
835 | 835 | ||
836 | RINOK(GetItemPath2(index, item.Path)); | 836 | RINOK(GetItem_Path2(index, item.Path)); |
837 | 837 | ||
838 | #ifndef _SFX | 838 | #ifndef _SFX |
839 | UInt32 mainIndex = index; | 839 | UInt32 mainIndex = index; |
@@ -885,7 +885,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const | |||
885 | } | 885 | } |
886 | else | 886 | else |
887 | { | 887 | { |
888 | RINOK(GetItemPath2(parentIndex, item.MainPath)); | 888 | RINOK(GetItem_Path2(parentIndex, item.MainPath)); |
889 | RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)); | 889 | RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)); |
890 | } | 890 | } |
891 | } | 891 | } |
@@ -911,7 +911,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const | |||
911 | #ifndef _SFX | 911 | #ifndef _SFX |
912 | if (item._use_baseParentFolder_mode) | 912 | if (item._use_baseParentFolder_mode) |
913 | { | 913 | { |
914 | RINOK(GetItemPathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts)); | 914 | RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts)); |
915 | 915 | ||
916 | #ifdef SUPPORT_ALT_STREAMS | 916 | #ifdef SUPPORT_ALT_STREAMS |
917 | if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty()) | 917 | if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty()) |
@@ -970,7 +970,7 @@ static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &s | |||
970 | 970 | ||
971 | #endif | 971 | #endif |
972 | 972 | ||
973 | HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const | 973 | HRESULT CArc::GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const |
974 | { | 974 | { |
975 | NCOM::CPropVariant prop; | 975 | NCOM::CPropVariant prop; |
976 | defined = false; | 976 | defined = false; |
@@ -989,24 +989,52 @@ HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const | |||
989 | return S_OK; | 989 | return S_OK; |
990 | } | 990 | } |
991 | 991 | ||
992 | HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const | 992 | HRESULT CArc::GetItem_MTime(UInt32 index, CArcTime &at) const |
993 | { | 993 | { |
994 | at.Clear(); | ||
994 | NCOM::CPropVariant prop; | 995 | NCOM::CPropVariant prop; |
995 | defined = false; | ||
996 | ft.dwHighDateTime = ft.dwLowDateTime = 0; | ||
997 | RINOK(Archive->GetProperty(index, kpidMTime, &prop)); | 996 | RINOK(Archive->GetProperty(index, kpidMTime, &prop)); |
997 | |||
998 | if (prop.vt == VT_FILETIME) | 998 | if (prop.vt == VT_FILETIME) |
999 | { | 999 | { |
1000 | ft = prop.filetime; | 1000 | /* |
1001 | defined = true; | 1001 | // for debug |
1002 | if (FILETIME_IsZero(prop.at) && MTime.Def) | ||
1003 | { | ||
1004 | at = MTime; | ||
1005 | return S_OK; | ||
1006 | } | ||
1007 | */ | ||
1008 | at.Set_From_Prop(prop); | ||
1009 | if (at.Prec == 0) | ||
1010 | { | ||
1011 | // (at.Prec == 0) before version 22. | ||
1012 | // so kpidTimeType is required for that code | ||
1013 | prop.Clear(); | ||
1014 | RINOK(Archive->GetProperty(index, kpidTimeType, &prop)); | ||
1015 | if (prop.vt == VT_UI4) | ||
1016 | { | ||
1017 | UInt32 val = prop.ulVal; | ||
1018 | if (val == NFileTimeType::kWindows) | ||
1019 | val = k_PropVar_TimePrec_100ns; | ||
1020 | /* | ||
1021 | else if (val > k_PropVar_TimePrec_1ns) | ||
1022 | { | ||
1023 | val = k_PropVar_TimePrec_100ns; | ||
1024 | // val = k_PropVar_TimePrec_1ns; | ||
1025 | // return E_FAIL; // for debug | ||
1026 | } | ||
1027 | */ | ||
1028 | at.Prec = (UInt16)val; | ||
1029 | } | ||
1030 | } | ||
1031 | return S_OK; | ||
1002 | } | 1032 | } |
1003 | else if (prop.vt != VT_EMPTY) | 1033 | |
1034 | if (prop.vt != VT_EMPTY) | ||
1004 | return E_FAIL; | 1035 | return E_FAIL; |
1005 | else if (MTimeDefined) | 1036 | if (MTime.Def) |
1006 | { | 1037 | at = MTime; |
1007 | ft = MTime; | ||
1008 | defined = true; | ||
1009 | } | ||
1010 | return S_OK; | 1038 | return S_OK; |
1011 | } | 1039 | } |
1012 | 1040 | ||
@@ -1020,6 +1048,7 @@ static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) | |||
1020 | return true; | 1048 | return true; |
1021 | } | 1049 | } |
1022 | 1050 | ||
1051 | |||
1023 | static void MakeCheckOrder(CCodecs *codecs, | 1052 | static void MakeCheckOrder(CCodecs *codecs, |
1024 | CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2, | 1053 | CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2, |
1025 | const Byte *data, size_t dataSize) | 1054 | const Byte *data, size_t dataSize) |
@@ -1034,7 +1063,7 @@ static void MakeCheckOrder(CCodecs *codecs, | |||
1034 | { | 1063 | { |
1035 | if (ai.Signatures.IsEmpty()) | 1064 | if (ai.Signatures.IsEmpty()) |
1036 | { | 1065 | { |
1037 | if (dataSize != 0) // 21.04: no Sinature means Empty Signature | 1066 | if (dataSize != 0) // 21.04: no Signature means Empty Signature |
1038 | continue; | 1067 | continue; |
1039 | } | 1068 | } |
1040 | else | 1069 | else |
@@ -1229,7 +1258,7 @@ void CArcErrorInfo::ClearErrors() | |||
1229 | HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes) | 1258 | HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes) |
1230 | { | 1259 | { |
1231 | // OkPhySize_Defined = false; | 1260 | // OkPhySize_Defined = false; |
1232 | PhySizeDefined = false; | 1261 | PhySize_Defined = false; |
1233 | PhySize = 0; | 1262 | PhySize = 0; |
1234 | Offset = 0; | 1263 | Offset = 0; |
1235 | AvailPhySize = FileSize - startPos; | 1264 | AvailPhySize = FileSize - startPos; |
@@ -1262,12 +1291,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR | |||
1262 | 1291 | ||
1263 | if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen()) | 1292 | if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen()) |
1264 | { | 1293 | { |
1265 | RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined)); | 1294 | RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined)); |
1266 | /* | 1295 | /* |
1267 | RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined)); | 1296 | RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined)); |
1268 | if (!OkPhySize_Defined) | 1297 | if (!OkPhySize_Defined) |
1269 | { | 1298 | { |
1270 | OkPhySize_Defined = PhySizeDefined; | 1299 | OkPhySize_Defined = PhySize_Defined; |
1271 | OkPhySize = PhySize; | 1300 | OkPhySize = PhySize; |
1272 | } | 1301 | } |
1273 | */ | 1302 | */ |
@@ -1277,7 +1306,7 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR | |||
1277 | 1306 | ||
1278 | Int64 globalOffset = (Int64)startPos + Offset; | 1307 | Int64 globalOffset = (Int64)startPos + Offset; |
1279 | AvailPhySize = (UInt64)((Int64)FileSize - globalOffset); | 1308 | AvailPhySize = (UInt64)((Int64)FileSize - globalOffset); |
1280 | if (PhySizeDefined) | 1309 | if (PhySize_Defined) |
1281 | { | 1310 | { |
1282 | UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize); | 1311 | UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize); |
1283 | if (endPos < FileSize) | 1312 | if (endPos < FileSize) |
@@ -1378,9 +1407,9 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr | |||
1378 | pi.FileTime_Defined = false; | 1407 | pi.FileTime_Defined = false; |
1379 | pi.ArcType = ai.Name; | 1408 | pi.ArcType = ai.Name; |
1380 | 1409 | ||
1381 | RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType)); | 1410 | RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType)); |
1382 | 1411 | ||
1383 | // RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe)); | 1412 | // RINOK(Archive_GetArcProp_Bool(archive, kpidIsSelfExe, pi.IsSelfExe)); |
1384 | pi.IsSelfExe = ai.Flags_PreArc(); | 1413 | pi.IsSelfExe = ai.Flags_PreArc(); |
1385 | 1414 | ||
1386 | { | 1415 | { |
@@ -1584,7 +1613,7 @@ static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize, | |||
1584 | return S_OK; | 1613 | return S_OK; |
1585 | 1614 | ||
1586 | bool phySizeCantBeDetected = false; | 1615 | bool phySizeCantBeDetected = false; |
1587 | RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)); | 1616 | RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)); |
1588 | 1617 | ||
1589 | if (!phySizeCantBeDetected) | 1618 | if (!phySizeCantBeDetected) |
1590 | { | 1619 | { |
@@ -1724,7 +1753,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
1724 | const CArcInfoEx &ai = op.codecs->Formats[i]; | 1753 | const CArcInfoEx &ai = op.codecs->Formats[i]; |
1725 | 1754 | ||
1726 | if (IgnoreSplit || !op.openType.CanReturnArc) | 1755 | if (IgnoreSplit || !op.openType.CanReturnArc) |
1727 | if (ai.IsSplit()) | 1756 | if (ai.Is_Split()) |
1728 | continue; | 1757 | continue; |
1729 | if (op.excludedFormats->FindInSorted((int)i) >= 0) | 1758 | if (op.excludedFormats->FindInSorted((int)i) >= 0) |
1730 | continue; | 1759 | continue; |
@@ -1736,8 +1765,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
1736 | 1765 | ||
1737 | if (ai.FindExtension(extension) >= 0 | 1766 | if (ai.FindExtension(extension) >= 0 |
1738 | #ifndef _SFX | 1767 | #ifndef _SFX |
1739 | || (isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip")) | 1768 | || (isZip && ai.Is_Zip()) |
1740 | || (isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar")) | 1769 | || (isRar && ai.Is_Rar()) |
1741 | #endif | 1770 | #endif |
1742 | ) | 1771 | ) |
1743 | { | 1772 | { |
@@ -1811,11 +1840,27 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
1811 | 1840 | ||
1812 | /* | 1841 | /* |
1813 | check type order: | 1842 | check type order: |
1814 | 1) matched extension, no signuature | 1843 | 0) matched_extension && Backward |
1815 | 2) matched extension, matched signuature | 1844 | 1) matched_extension && (no_signuature || SignatureOffset != 0) |
1845 | 2) matched_extension && (matched_signature) | ||
1816 | // 3) no signuature | 1846 | // 3) no signuature |
1817 | // 4) matched signuature | 1847 | // 4) matched signuature |
1818 | */ | 1848 | */ |
1849 | // we move index from orderIndices to orderIndices2 for priority handlers. | ||
1850 | |||
1851 | for (unsigned i = 0; i < numFinded; i++) | ||
1852 | { | ||
1853 | const int index = orderIndices[i]; | ||
1854 | if (index < 0) | ||
1855 | continue; | ||
1856 | const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; | ||
1857 | if (ai.Flags_BackwardOpen()) | ||
1858 | { | ||
1859 | // backward doesn't need start signatures | ||
1860 | orderIndices2.Add(index); | ||
1861 | orderIndices[i] = -1; | ||
1862 | } | ||
1863 | } | ||
1819 | 1864 | ||
1820 | MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0); | 1865 | MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0); |
1821 | MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize); | 1866 | MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize); |
@@ -1906,6 +1951,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
1906 | // OutputDebugStringW(ai.Name); | 1951 | // OutputDebugStringW(ai.Name); |
1907 | if (i >= numMainTypes) | 1952 | if (i >= numMainTypes) |
1908 | { | 1953 | { |
1954 | // here we allow mismatched extension only for backward handlers | ||
1909 | if (!ai.Flags_BackwardOpen() | 1955 | if (!ai.Flags_BackwardOpen() |
1910 | // && !ai.Flags_PureStartOpen() | 1956 | // && !ai.Flags_PureStartOpen() |
1911 | ) | 1957 | ) |
@@ -2125,7 +2171,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
2125 | 2171 | ||
2126 | const CArcInfoEx &ai = op.codecs->Formats[form]; | 2172 | const CArcInfoEx &ai = op.codecs->Formats[form]; |
2127 | 2173 | ||
2128 | if (ai.IsSplit()) | 2174 | if (ai.Is_Split()) |
2129 | { | 2175 | { |
2130 | splitIndex = (int)form; | 2176 | splitIndex = (int)form; |
2131 | continue; | 2177 | continue; |
@@ -2234,7 +2280,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
2234 | 2280 | ||
2235 | // bool needScan = false; | 2281 | // bool needScan = false; |
2236 | 2282 | ||
2237 | if (!PhySizeDefined) | 2283 | if (!PhySize_Defined) |
2238 | { | 2284 | { |
2239 | // it's for Z format | 2285 | // it's for Z format |
2240 | pi.LenIsUnknown = true; | 2286 | pi.LenIsUnknown = true; |
@@ -2726,14 +2772,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
2726 | } | 2772 | } |
2727 | continue; | 2773 | continue; |
2728 | } | 2774 | } |
2729 | if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0) | 2775 | if (!ErrorInfo.IsArc_After_NonOpen() || !PhySize_Defined || PhySize == 0) |
2730 | continue; | 2776 | continue; |
2731 | } | 2777 | } |
2732 | else | 2778 | else |
2733 | { | 2779 | { |
2734 | if (PhySizeDefined && PhySize == 0) | 2780 | if (PhySize_Defined && PhySize == 0) |
2735 | { | 2781 | { |
2736 | PRF(printf(" phySizeDefined && PhySize == 0 ")); | 2782 | PRF(printf(" phySize_Defined && PhySize == 0 ")); |
2737 | // we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function. | 2783 | // we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function. |
2738 | continue; | 2784 | continue; |
2739 | } | 2785 | } |
@@ -2754,10 +2800,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
2754 | else if (Offset != 0) | 2800 | else if (Offset != 0) |
2755 | return E_FAIL; | 2801 | return E_FAIL; |
2756 | 2802 | ||
2757 | UInt64 arcRem = FileSize - pi.Offset; | 2803 | const UInt64 arcRem = FileSize - pi.Offset; |
2758 | UInt64 phySize = arcRem; | 2804 | UInt64 phySize = arcRem; |
2759 | bool phySizeDefined = PhySizeDefined; | 2805 | const bool phySize_Defined = PhySize_Defined; |
2760 | if (phySizeDefined) | 2806 | if (phySize_Defined) |
2761 | { | 2807 | { |
2762 | if (pi.Offset + PhySize > FileSize) | 2808 | if (pi.Offset + PhySize > FileSize) |
2763 | { | 2809 | { |
@@ -2783,7 +2829,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
2783 | bool needScan = false; | 2829 | bool needScan = false; |
2784 | 2830 | ||
2785 | 2831 | ||
2786 | if (isOpen && !phySizeDefined) | 2832 | if (isOpen && !phySize_Defined) |
2787 | { | 2833 | { |
2788 | // it's for Z format, or bzip2,gz,xz with phySize that was not detected | 2834 | // it's for Z format, or bzip2,gz,xz with phySize that was not detected |
2789 | pi.LenIsUnknown = true; | 2835 | pi.LenIsUnknown = true; |
@@ -2802,7 +2848,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
2802 | 2848 | ||
2803 | /* | 2849 | /* |
2804 | if (needSkipFullArc) | 2850 | if (needSkipFullArc) |
2805 | if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize) | 2851 | if (pi.Offset == 0 && phySize_Defined && pi.Size >= fileSize) |
2806 | continue; | 2852 | continue; |
2807 | */ | 2853 | */ |
2808 | if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) | 2854 | if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) |
@@ -2830,7 +2876,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
2830 | 2876 | ||
2831 | RINOK(ReadParseItemProps(archive, ai, pi)); | 2877 | RINOK(ReadParseItemProps(archive, ai, pi)); |
2832 | 2878 | ||
2833 | if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */) | 2879 | if (pi.Offset < startArcPos && !mode.EachPos /* && phySize_Defined */) |
2834 | { | 2880 | { |
2835 | /* It's for DMG format. | 2881 | /* It's for DMG format. |
2836 | This code deletes all previous items that are included to current item */ | 2882 | This code deletes all previous items that are included to current item */ |
@@ -2849,7 +2895,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) | |||
2849 | } | 2895 | } |
2850 | 2896 | ||
2851 | 2897 | ||
2852 | if (isOpen && mode.CanReturnArc && phySizeDefined) | 2898 | if (isOpen && mode.CanReturnArc && phySize_Defined) |
2853 | { | 2899 | { |
2854 | // if (pi.Offset + pi.Size >= fileSize) | 2900 | // if (pi.Offset + pi.Size >= fileSize) |
2855 | bool openCur = false; | 2901 | bool openCur = false; |
@@ -2993,12 +3039,12 @@ HRESULT CArc::OpenStream(const COpenOptions &op) | |||
2993 | Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps); | 3039 | Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps); |
2994 | Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps); | 3040 | Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps); |
2995 | 3041 | ||
2996 | RINOK(Archive_GetArcBoolProp(Archive, kpidIsTree, IsTree)); | 3042 | RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree)); |
2997 | RINOK(Archive_GetArcBoolProp(Archive, kpidIsDeleted, Ask_Deleted)); | 3043 | RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted)); |
2998 | RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream)); | 3044 | RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream)); |
2999 | RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux)); | 3045 | RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux)); |
3000 | RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode)); | 3046 | RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode)); |
3001 | RINOK(Archive_GetArcBoolProp(Archive, kpidReadOnly, IsReadOnly)); | 3047 | RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly)); |
3002 | 3048 | ||
3003 | const UString fileName = ExtractFileNameFromPath(Path); | 3049 | const UString fileName = ExtractFileNameFromPath(Path); |
3004 | UString extension; | 3050 | UString extension; |
@@ -3092,7 +3138,7 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op) | |||
3092 | FOR_VECTOR (i, op.codecs->Formats) | 3138 | FOR_VECTOR (i, op.codecs->Formats) |
3093 | { | 3139 | { |
3094 | const CArcInfoEx &ai = op.codecs->Formats[i]; | 3140 | const CArcInfoEx &ai = op.codecs->Formats[i]; |
3095 | if (ai.IsSplit()) | 3141 | if (ai.Is_Split()) |
3096 | continue; | 3142 | continue; |
3097 | UString path3 = path2; | 3143 | UString path3 = path2; |
3098 | path3 += '.'; | 3144 | path3 += '.'; |
@@ -3299,7 +3345,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op) | |||
3299 | break; | 3345 | break; |
3300 | 3346 | ||
3301 | CArc arc2; | 3347 | CArc arc2; |
3302 | RINOK(arc.GetItemPath(mainSubfile, arc2.Path)); | 3348 | RINOK(arc.GetItem_Path(mainSubfile, arc2.Path)); |
3303 | 3349 | ||
3304 | bool zerosTailIsAllowed; | 3350 | bool zerosTailIsAllowed; |
3305 | RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)); | 3351 | RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)); |
@@ -3343,7 +3389,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op) | |||
3343 | break; | 3389 | break; |
3344 | } | 3390 | } |
3345 | RINOK(result); | 3391 | RINOK(result); |
3346 | RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined)); | 3392 | RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime)); |
3347 | Arcs.Add(arc2); | 3393 | Arcs.Add(arc2); |
3348 | } | 3394 | } |
3349 | IsOpen = !Arcs.IsEmpty(); | 3395 | IsOpen = !Arcs.IsEmpty(); |
diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h index 4e1192c..e3220b9 100644 --- a/CPP/7zip/UI/Common/OpenArchive.h +++ b/CPP/7zip/UI/Common/OpenArchive.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #include "ArchiveOpenCallback.h" | 8 | #include "ArchiveOpenCallback.h" |
9 | #include "LoadCodecs.h" | 9 | #include "LoadCodecs.h" |
10 | #include "Property.h" | 10 | #include "Property.h" |
11 | #include "DirItem.h" | ||
11 | 12 | ||
12 | #ifndef _SFX | 13 | #ifndef _SFX |
13 | 14 | ||
@@ -260,6 +261,9 @@ struct CReadArcItem | |||
260 | } | 261 | } |
261 | }; | 262 | }; |
262 | 263 | ||
264 | |||
265 | |||
266 | |||
263 | class CArc | 267 | class CArc |
264 | { | 268 | { |
265 | HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive); | 269 | HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive); |
@@ -268,7 +272,7 @@ class CArc | |||
268 | 272 | ||
269 | #ifndef _SFX | 273 | #ifndef _SFX |
270 | // parts.Back() can contain alt stream name "nams:AltName" | 274 | // parts.Back() can contain alt stream name "nams:AltName" |
271 | HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const; | 275 | HRESULT GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const; |
272 | #endif | 276 | #endif |
273 | 277 | ||
274 | public: | 278 | public: |
@@ -289,19 +293,21 @@ public: | |||
289 | UString DefaultName; | 293 | UString DefaultName; |
290 | int FormatIndex; // -1 means Parser | 294 | int FormatIndex; // -1 means Parser |
291 | UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile | 295 | UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile |
292 | FILETIME MTime; | 296 | |
293 | bool MTimeDefined; | 297 | // CFiTime MTime; |
298 | // bool MTime_Defined; | ||
299 | CArcTime MTime; | ||
294 | 300 | ||
295 | Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler | 301 | Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler |
296 | UInt64 PhySize; | 302 | UInt64 PhySize; |
297 | // UInt64 OkPhySize; | 303 | // UInt64 OkPhySize; |
298 | bool PhySizeDefined; | 304 | bool PhySize_Defined; |
299 | // bool OkPhySize_Defined; | 305 | // bool OkPhySize_Defined; |
300 | UInt64 FileSize; | 306 | UInt64 FileSize; |
301 | UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file | 307 | UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file |
302 | // bool offsetDefined; | 308 | // bool offsetDefined; |
303 | 309 | ||
304 | UInt64 GetEstmatedPhySize() const { return PhySizeDefined ? PhySize : FileSize; } | 310 | UInt64 GetEstmatedPhySize() const { return PhySize_Defined ? PhySize : FileSize; } |
305 | 311 | ||
306 | UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler | 312 | UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler |
307 | Int64 GetGlobalOffset() const { return (Int64)ArcStreamOffset + Offset; } // it's global offset of archive | 313 | Int64 GetGlobalOffset() const { return (Int64)ArcStreamOffset + Offset; } // it's global offset of archive |
@@ -323,7 +329,7 @@ public: | |||
323 | // void Set_ErrorFlagsText(); | 329 | // void Set_ErrorFlagsText(); |
324 | 330 | ||
325 | CArc(): | 331 | CArc(): |
326 | MTimeDefined(false), | 332 | // MTime_Defined(false), |
327 | IsTree(false), | 333 | IsTree(false), |
328 | IsReadOnly(false), | 334 | IsReadOnly(false), |
329 | Ask_Deleted(false), | 335 | Ask_Deleted(false), |
@@ -343,17 +349,29 @@ public: | |||
343 | return Archive->Close(); | 349 | return Archive->Close(); |
344 | } | 350 | } |
345 | 351 | ||
346 | HRESULT GetItemPath(UInt32 index, UString &result) const; | 352 | HRESULT GetItem_Path(UInt32 index, UString &result) const; |
347 | HRESULT GetDefaultItemPath(UInt32 index, UString &result) const; | 353 | HRESULT GetItem_DefaultPath(UInt32 index, UString &result) const; |
348 | 354 | ||
349 | // GetItemPath2 adds [DELETED] dir prefix for deleted items. | 355 | // GetItemPath2 adds [DELETED] dir prefix for deleted items. |
350 | HRESULT GetItemPath2(UInt32 index, UString &result) const; | 356 | HRESULT GetItem_Path2(UInt32 index, UString &result) const; |
351 | 357 | ||
352 | HRESULT GetItem(UInt32 index, CReadArcItem &item) const; | 358 | HRESULT GetItem(UInt32 index, CReadArcItem &item) const; |
353 | 359 | ||
354 | HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const; | 360 | HRESULT GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const; |
355 | HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const; | 361 | |
356 | HRESULT IsItemAnti(UInt32 index, bool &result) const | 362 | /* if (GetProperty() returns vt==VT_EMPTY), this function sets |
363 | timestamp from archive file timestamp (MTime). | ||
364 | So (at) will be set in most cases (at.Def == true) | ||
365 | if (at.Prec == 0) | ||
366 | { | ||
367 | it means that (Prec == 0) was returned for (kpidMTime), | ||
368 | and no value was returned for (kpidTimeType). | ||
369 | it can mean Windows precision or unknown precision. | ||
370 | } | ||
371 | */ | ||
372 | HRESULT GetItem_MTime(UInt32 index, CArcTime &at) const; | ||
373 | |||
374 | HRESULT IsItem_Anti(UInt32 index, bool &result) const | ||
357 | { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); } | 375 | { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); } |
358 | 376 | ||
359 | 377 | ||
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp index 30efd53..72384b3 100644 --- a/CPP/7zip/UI/Common/PropIDUtils.cpp +++ b/CPP/7zip/UI/Common/PropIDUtils.cpp | |||
@@ -136,10 +136,37 @@ void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID p | |||
136 | if (prop.vt == VT_FILETIME) | 136 | if (prop.vt == VT_FILETIME) |
137 | { | 137 | { |
138 | const FILETIME &ft = prop.filetime; | 138 | const FILETIME &ft = prop.filetime; |
139 | if ((ft.dwHighDateTime == 0 && | 139 | unsigned ns100 = 0; |
140 | ft.dwLowDateTime == 0)) | 140 | int numDigits = kTimestampPrintLevel_NTFS; |
141 | const unsigned prec = prop.wReserved1; | ||
142 | const unsigned ns100_Temp = prop.wReserved2; | ||
143 | if (prec != 0 | ||
144 | && prec <= k_PropVar_TimePrec_1ns | ||
145 | && ns100_Temp < 100 | ||
146 | && prop.wReserved3 == 0) | ||
147 | { | ||
148 | ns100 = ns100_Temp; | ||
149 | if (prec == k_PropVar_TimePrec_Unix || | ||
150 | prec == k_PropVar_TimePrec_DOS) | ||
151 | numDigits = 0; | ||
152 | else if (prec == k_PropVar_TimePrec_HighPrec) | ||
153 | numDigits = 9; | ||
154 | else | ||
155 | { | ||
156 | numDigits = (int)prec - (int)k_PropVar_TimePrec_Base; | ||
157 | if ( | ||
158 | // numDigits < kTimestampPrintLevel_DAY // for debuf | ||
159 | numDigits < kTimestampPrintLevel_SEC | ||
160 | ) | ||
161 | |||
162 | numDigits = kTimestampPrintLevel_NTFS; | ||
163 | } | ||
164 | } | ||
165 | if (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0 && ns100 == 0) | ||
141 | return; | 166 | return; |
142 | ConvertUtcFileTimeToString(prop.filetime, dest, level); | 167 | if (level > numDigits) |
168 | level = numDigits; | ||
169 | ConvertUtcFileTimeToString2(ft, ns100, dest, level); | ||
143 | return; | 170 | return; |
144 | } | 171 | } |
145 | 172 | ||
@@ -198,6 +225,24 @@ void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID p | |||
198 | ConvertUInt64ToHex(v, dest + 2); | 225 | ConvertUInt64ToHex(v, dest + 2); |
199 | return; | 226 | return; |
200 | } | 227 | } |
228 | |||
229 | /* | ||
230 | case kpidDevice: | ||
231 | { | ||
232 | UInt64 v = 0; | ||
233 | if (prop.vt == VT_UI4) | ||
234 | v = prop.ulVal; | ||
235 | else if (prop.vt == VT_UI8) | ||
236 | v = (UInt64)prop.uhVal.QuadPart; | ||
237 | else | ||
238 | break; | ||
239 | ConvertUInt32ToString(MY_dev_major(v), dest); | ||
240 | dest += strlen(dest); | ||
241 | *dest++ = ','; | ||
242 | ConvertUInt32ToString(MY_dev_minor(v), dest); | ||
243 | return; | ||
244 | } | ||
245 | */ | ||
201 | } | 246 | } |
202 | 247 | ||
203 | ConvertPropVariantToShortString(prop, dest); | 248 | ConvertPropVariantToShortString(prop, dest); |
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp index 032a876..042991d 100644 --- a/CPP/7zip/UI/Common/Update.cpp +++ b/CPP/7zip/UI/Common/Update.cpp | |||
@@ -2,6 +2,8 @@ | |||
2 | 2 | ||
3 | #include "StdAfx.h" | 3 | #include "StdAfx.h" |
4 | 4 | ||
5 | // #include <stdio.h> | ||
6 | |||
5 | #include "Update.h" | 7 | #include "Update.h" |
6 | 8 | ||
7 | #include "../../../Common/StringConvert.h" | 9 | #include "../../../Common/StringConvert.h" |
@@ -101,7 +103,7 @@ public: | |||
101 | _length = 0; | 103 | _length = 0; |
102 | } | 104 | } |
103 | 105 | ||
104 | bool SetMTime(const FILETIME *mTime); | 106 | bool SetMTime(const CFiTime *mTime); |
105 | HRESULT Close(); | 107 | HRESULT Close(); |
106 | 108 | ||
107 | UInt64 GetSize() const { return _length; } | 109 | UInt64 GetSize() const { return _length; } |
@@ -131,7 +133,7 @@ HRESULT COutMultiVolStream::Close() | |||
131 | return res; | 133 | return res; |
132 | } | 134 | } |
133 | 135 | ||
134 | bool COutMultiVolStream::SetMTime(const FILETIME *mTime) | 136 | bool COutMultiVolStream::SetMTime(const CFiTime *mTime) |
135 | { | 137 | { |
136 | bool res = true; | 138 | bool res = true; |
137 | FOR_VECTOR (i, Streams) | 139 | FOR_VECTOR (i, Streams) |
@@ -545,11 +547,46 @@ static HRESULT Compress( | |||
545 | if (!outArchive) | 547 | if (!outArchive) |
546 | throw kUpdateIsNotSupoorted; | 548 | throw kUpdateIsNotSupoorted; |
547 | 549 | ||
550 | // we need to set properties to get fileTimeType. | ||
551 | RINOK(SetProperties(outArchive, options.MethodMode.Properties)); | ||
552 | |||
548 | NFileTimeType::EEnum fileTimeType; | 553 | NFileTimeType::EEnum fileTimeType; |
549 | { | 554 | { |
555 | /* | ||
556 | how we compare file_in_archive::MTime with dirItem.MTime | ||
557 | for GetUpdatePairInfoList(): | ||
558 | |||
559 | if (kpidMTime is not defined), external MTime of archive is used. | ||
560 | |||
561 | before 22.00: | ||
562 | if (kpidTimeType is defined) | ||
563 | { | ||
564 | kpidTimeType is used as precision. | ||
565 | (kpidTimeType > kDOS) is not allowed. | ||
566 | } | ||
567 | else GetFileTimeType() value is used as precision. | ||
568 | |||
569 | 22.00: | ||
570 | if (kpidMTime is defined) | ||
571 | { | ||
572 | if (kpidMTime::precision != 0), then kpidMTime::precision is used as precision. | ||
573 | else | ||
574 | { | ||
575 | if (kpidTimeType is defined), kpidTimeType is used as precision. | ||
576 | else GetFileTimeType() value is used as precision. | ||
577 | } | ||
578 | } | ||
579 | else external MTime of archive is used as precision. | ||
580 | */ | ||
581 | |||
550 | UInt32 value; | 582 | UInt32 value; |
551 | RINOK(outArchive->GetFileTimeType(&value)); | 583 | RINOK(outArchive->GetFileTimeType(&value)); |
584 | |||
585 | // we support any future fileType here. | ||
586 | fileTimeType = (NFileTimeType::EEnum)value; | ||
552 | 587 | ||
588 | /* | ||
589 | old 21.07 code: | ||
553 | switch (value) | 590 | switch (value) |
554 | { | 591 | { |
555 | case NFileTimeType::kWindows: | 592 | case NFileTimeType::kWindows: |
@@ -560,13 +597,26 @@ static HRESULT Compress( | |||
560 | default: | 597 | default: |
561 | return E_FAIL; | 598 | return E_FAIL; |
562 | } | 599 | } |
600 | */ | ||
563 | } | 601 | } |
564 | 602 | ||
603 | // bool noTimestampExpected = false; | ||
565 | { | 604 | { |
566 | const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex]; | 605 | const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex]; |
606 | |||
607 | // if (arcInfo.Flags_KeepName()) noTimestampExpected = true; | ||
608 | if (arcInfo.Is_Xz() || | ||
609 | arcInfo.Is_BZip2()) | ||
610 | { | ||
611 | /* 7-zip before 22.00 returns NFileTimeType::kUnix for xz and bzip2, | ||
612 | but we want to set timestamp without reduction to unix. */ | ||
613 | // noTimestampExpected = true; | ||
614 | fileTimeType = NFileTimeType::kNotDefined; // it means not defined | ||
615 | } | ||
616 | |||
567 | if (options.AltStreams.Val && !arcInfo.Flags_AltStreams()) | 617 | if (options.AltStreams.Val && !arcInfo.Flags_AltStreams()) |
568 | return E_NOTIMPL; | 618 | return E_NOTIMPL; |
569 | if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure()) | 619 | if (options.NtSecurity.Val && !arcInfo.Flags_NtSecurity()) |
570 | return E_NOTIMPL; | 620 | return E_NOTIMPL; |
571 | if (options.DeleteAfterCompressing && arcInfo.Flags_HashHandler()) | 621 | if (options.DeleteAfterCompressing && arcInfo.Flags_HashHandler()) |
572 | return E_NOTIMPL; | 622 | return E_NOTIMPL; |
@@ -626,7 +676,7 @@ static HRESULT Compress( | |||
626 | if (needRename) | 676 | if (needRename) |
627 | { | 677 | { |
628 | up2.NewProps = true; | 678 | up2.NewProps = true; |
629 | RINOK(arc->IsItemAnti(i, up2.IsAnti)); | 679 | RINOK(arc->IsItem_Anti(i, up2.IsAnti)); |
630 | up2.NewNameIndex = (int)newNames.Add(dest); | 680 | up2.NewNameIndex = (int)newNames.Add(dest); |
631 | } | 681 | } |
632 | updatePairs2.Add(up2); | 682 | updatePairs2.Add(up2); |
@@ -661,6 +711,7 @@ static HRESULT Compress( | |||
661 | else | 711 | else |
662 | stat.NumDirs++; | 712 | stat.NumDirs++; |
663 | } | 713 | } |
714 | #ifdef _WIN32 | ||
664 | else if (di.IsAltStream) | 715 | else if (di.IsAltStream) |
665 | { | 716 | { |
666 | if (up.IsAnti) | 717 | if (up.IsAnti) |
@@ -671,6 +722,7 @@ static HRESULT Compress( | |||
671 | stat.AltStreamsSize += di.Size; | 722 | stat.AltStreamsSize += di.Size; |
672 | } | 723 | } |
673 | } | 724 | } |
725 | #endif | ||
674 | else | 726 | else |
675 | { | 727 | { |
676 | if (up.IsAnti) | 728 | if (up.IsAnti) |
@@ -740,6 +792,8 @@ static HRESULT Compress( | |||
740 | updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val; | 792 | updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val; |
741 | updateCallbackSpec->StoreHardLinks = options.HardLinks.Val; | 793 | updateCallbackSpec->StoreHardLinks = options.HardLinks.Val; |
742 | updateCallbackSpec->StoreSymLinks = options.SymLinks.Val; | 794 | updateCallbackSpec->StoreSymLinks = options.SymLinks.Val; |
795 | updateCallbackSpec->StoreOwnerName = options.StoreOwnerName.Val; | ||
796 | updateCallbackSpec->StoreOwnerId = options.StoreOwnerId.Val; | ||
743 | 797 | ||
744 | updateCallbackSpec->Arc = arc; | 798 | updateCallbackSpec->Arc = arc; |
745 | updateCallbackSpec->ArcItems = &arcItems; | 799 | updateCallbackSpec->ArcItems = &arcItems; |
@@ -755,6 +809,12 @@ static HRESULT Compress( | |||
755 | if (options.RenamePairs.Size() != 0) | 809 | if (options.RenamePairs.Size() != 0) |
756 | updateCallbackSpec->NewNames = &newNames; | 810 | updateCallbackSpec->NewNames = &newNames; |
757 | 811 | ||
812 | if (options.SetArcMTime) | ||
813 | { | ||
814 | // updateCallbackSpec->Need_ArcMTime_Report = true; | ||
815 | updateCallbackSpec->Need_LatestMTime = true; | ||
816 | } | ||
817 | |||
758 | CMyComPtr<IOutStream> outSeekStream; | 818 | CMyComPtr<IOutStream> outSeekStream; |
759 | CMyComPtr<ISequentialOutStream> outStream; | 819 | CMyComPtr<ISequentialOutStream> outStream; |
760 | 820 | ||
@@ -838,8 +898,6 @@ static HRESULT Compress( | |||
838 | */ | 898 | */ |
839 | } | 899 | } |
840 | 900 | ||
841 | RINOK(SetProperties(outArchive, options.MethodMode.Properties)); | ||
842 | |||
843 | if (options.SfxMode) | 901 | if (options.SfxMode) |
844 | { | 902 | { |
845 | CInFileStream *sfxStreamSpec = new CInFileStream; | 903 | CInFileStream *sfxStreamSpec = new CInFileStream; |
@@ -909,24 +967,71 @@ static HRESULT Compress( | |||
909 | 967 | ||
910 | if (options.SetArcMTime) | 968 | if (options.SetArcMTime) |
911 | { | 969 | { |
912 | FILETIME ft; | 970 | CFiTime ft; |
913 | ft.dwLowDateTime = 0; | 971 | FiTime_Clear(ft); |
914 | ft.dwHighDateTime = 0; | 972 | bool isDefined = false; |
915 | FOR_VECTOR (i, updatePairs2) | 973 | |
974 | // bool needNormalizeAfterStream; | ||
975 | // needParse; | ||
976 | /* | ||
977 | if (updateCallbackSpec->ArcMTime_WasReported) | ||
916 | { | 978 | { |
917 | const CUpdatePair2 &pair2 = updatePairs2[i]; | 979 | isDefined = updateCallbackSpec->Reported_ArcMTime.Def; |
918 | const FILETIME *ft2 = NULL; | 980 | if (isDefined) |
919 | if (pair2.NewProps && pair2.DirIndex >= 0) | 981 | updateCallbackSpec->Reported_ArcMTime.Write_To_FiTime(ft); |
920 | ft2 = &dirItems.Items[(unsigned)pair2.DirIndex].MTime; | 982 | else |
921 | else if (pair2.UseArcProps && pair2.ArcIndex >= 0) | 983 | fileTimeType = NFileTimeType::kNotDefined; |
922 | ft2 = &arcItems[(unsigned)pair2.ArcIndex].MTime; | 984 | } |
923 | if (ft2) | 985 | if (!isDefined) |
986 | */ | ||
987 | { | ||
988 | if (updateCallbackSpec->LatestMTime_Defined) | ||
924 | { | 989 | { |
925 | if (::CompareFileTime(&ft, ft2) < 0) | 990 | // CArcTime at = StreamCallback_ArcMTime; |
926 | ft = *ft2; | 991 | // updateCallbackSpec->StreamCallback_ArcMTime.Write_To_FiTime(ft); |
992 | // we must normalize with precision from archive; | ||
993 | ft = updateCallbackSpec->LatestMTime; | ||
994 | isDefined = true; | ||
927 | } | 995 | } |
996 | |||
997 | FOR_VECTOR (i, updatePairs2) | ||
998 | { | ||
999 | const CUpdatePair2 &pair2 = updatePairs2[i]; | ||
1000 | CFiTime ft2; | ||
1001 | bool ft2_Defined = false; | ||
1002 | /* we use full precision of dirItem, if dirItem is defined | ||
1003 | and (dirItem will be used or dirItem is sameTime in dir and arc */ | ||
1004 | if (pair2.DirIndex >= 0 && | ||
1005 | (pair2.NewProps || pair2.IsSameTime)) | ||
1006 | { | ||
1007 | ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime; | ||
1008 | ft2_Defined = true; | ||
1009 | } | ||
1010 | else if (pair2.UseArcProps && pair2.ArcIndex >= 0) | ||
1011 | { | ||
1012 | const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex]; | ||
1013 | if (arcItem.MTime.Def) | ||
1014 | { | ||
1015 | arcItem.MTime.Write_To_FiTime(ft2); | ||
1016 | ft2_Defined = true; | ||
1017 | } | ||
1018 | } | ||
1019 | if (ft2_Defined) | ||
1020 | { | ||
1021 | if (Compare_FiTime(&ft, &ft2) < 0) | ||
1022 | { | ||
1023 | ft = ft2; | ||
1024 | isDefined = true; | ||
1025 | } | ||
1026 | } | ||
1027 | } | ||
1028 | /* | ||
1029 | if (fileTimeType != NFileTimeType::kNotDefined) | ||
1030 | FiTime_Normalize_With_Prec(ft, fileTimeType); | ||
1031 | */ | ||
928 | } | 1032 | } |
929 | if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) | 1033 | // if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) |
1034 | if (isDefined) | ||
930 | { | 1035 | { |
931 | if (outStreamSpec) | 1036 | if (outStreamSpec) |
932 | outStreamSpec->SetMTime(&ft); | 1037 | outStreamSpec->SetMTime(&ft); |
@@ -1046,26 +1151,9 @@ static HRESULT EnumerateInArchiveItems( | |||
1046 | else | 1151 | else |
1047 | ai.Censored = Censor_CheckPath(censor, item); | 1152 | ai.Censored = Censor_CheckPath(censor, item); |
1048 | 1153 | ||
1049 | RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined)); | 1154 | // ai.MTime will be set to archive MTime, if not present in archive item |
1050 | RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined)); | 1155 | RINOK(arc.GetItem_MTime(i, ai.MTime)); |
1051 | 1156 | RINOK(arc.GetItem_Size(i, ai.Size, ai.Size_Defined)); | |
1052 | { | ||
1053 | CPropVariant prop; | ||
1054 | RINOK(archive->GetProperty(i, kpidTimeType, &prop)); | ||
1055 | if (prop.vt == VT_UI4) | ||
1056 | { | ||
1057 | ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal; | ||
1058 | switch (ai.TimeType) | ||
1059 | { | ||
1060 | case NFileTimeType::kWindows: | ||
1061 | case NFileTimeType::kUnix: | ||
1062 | case NFileTimeType::kDOS: | ||
1063 | break; | ||
1064 | default: | ||
1065 | return E_FAIL; | ||
1066 | } | ||
1067 | } | ||
1068 | } | ||
1069 | 1157 | ||
1070 | ai.IndexInServer = i; | 1158 | ai.IndexInServer = i; |
1071 | arcItems.AddInReserved(ai); | 1159 | arcItems.AddInReserved(ai); |
@@ -1198,8 +1286,10 @@ HRESULT UpdateArchive( | |||
1198 | EISDIR | 1286 | EISDIR |
1199 | #endif | 1287 | #endif |
1200 | ); | 1288 | ); |
1289 | #ifdef _WIN32 | ||
1201 | if (fi.IsDevice) | 1290 | if (fi.IsDevice) |
1202 | return E_NOTIMPL; | 1291 | return E_NOTIMPL; |
1292 | #endif | ||
1203 | 1293 | ||
1204 | if (!options.StdOutMode && options.UpdateArchiveItself) | 1294 | if (!options.StdOutMode && options.UpdateArchiveItself) |
1205 | if (fi.IsReadOnly()) | 1295 | if (fi.IsReadOnly()) |
@@ -1262,8 +1352,14 @@ HRESULT UpdateArchive( | |||
1262 | } | 1352 | } |
1263 | 1353 | ||
1264 | CArc &arc = arcLink.Arcs.Back(); | 1354 | CArc &arc = arcLink.Arcs.Back(); |
1265 | arc.MTimeDefined = !fi.IsDevice; | 1355 | arc.MTime.Def = |
1266 | arc.MTime = fi.MTime; | 1356 | #ifdef _WIN32 |
1357 | !fi.IsDevice; | ||
1358 | #else | ||
1359 | true; | ||
1360 | #endif | ||
1361 | if (arc.MTime.Def) | ||
1362 | arc.MTime.Set_From_FiTime(fi.MTime); | ||
1267 | 1363 | ||
1268 | if (arc.ErrorInfo.ThereIsTail) | 1364 | if (arc.ErrorInfo.ThereIsTail) |
1269 | { | 1365 | { |
@@ -1307,10 +1403,11 @@ HRESULT UpdateArchive( | |||
1307 | if (options.StdInMode) | 1403 | if (options.StdInMode) |
1308 | { | 1404 | { |
1309 | CDirItem di; | 1405 | CDirItem di; |
1406 | di.ClearBase(); | ||
1310 | di.Name = options.StdInFileName; | 1407 | di.Name = options.StdInFileName; |
1311 | di.Size = (UInt64)(Int64)-1; | 1408 | di.Size = (UInt64)(Int64)-1; |
1312 | di.Attrib = 0; | 1409 | di.SetAsFile(); |
1313 | NTime::GetCurUtcFileTime(di.MTime); | 1410 | NTime::GetCurUtc_FiTime(di.MTime); |
1314 | di.CTime = di.ATime = di.MTime; | 1411 | di.CTime = di.ATime = di.MTime; |
1315 | dirItems.Items.Add(di); | 1412 | dirItems.Items.Add(di); |
1316 | } | 1413 | } |
@@ -1336,8 +1433,14 @@ HRESULT UpdateArchive( | |||
1336 | dirItems.ScanAltStreams = options.AltStreams.Val; | 1433 | dirItems.ScanAltStreams = options.AltStreams.Val; |
1337 | dirItems.ExcludeDirItems = censor.ExcludeDirItems; | 1434 | dirItems.ExcludeDirItems = censor.ExcludeDirItems; |
1338 | dirItems.ExcludeFileItems = censor.ExcludeFileItems; | 1435 | dirItems.ExcludeFileItems = censor.ExcludeFileItems; |
1436 | |||
1437 | dirItems.ShareForWrite = options.OpenShareForWrite; | ||
1438 | |||
1439 | #ifndef _WIN32 | ||
1440 | dirItems.StoreOwnerName = options.StoreOwnerName.Val; | ||
1441 | #endif | ||
1339 | 1442 | ||
1340 | HRESULT res = EnumerateItems(censor, | 1443 | const HRESULT res = EnumerateItems(censor, |
1341 | options.PathMode, | 1444 | options.PathMode, |
1342 | UString(), // options.AddPathPrefix, | 1445 | UString(), // options.AddPathPrefix, |
1343 | dirItems); | 1446 | dirItems); |
@@ -1351,6 +1454,8 @@ HRESULT UpdateArchive( | |||
1351 | 1454 | ||
1352 | RINOK(callback->FinishScanning(dirItems.Stat)); | 1455 | RINOK(callback->FinishScanning(dirItems.Stat)); |
1353 | 1456 | ||
1457 | // 22.00: we don't need parent folder, if absolute path mode | ||
1458 | if (options.PathMode != NWildcard::k_AbsPath) | ||
1354 | if (censor.Pairs.Size() == 1) | 1459 | if (censor.Pairs.Size() == 1) |
1355 | { | 1460 | { |
1356 | NFind::CFileInfo fi; | 1461 | NFind::CFileInfo fi; |
@@ -1366,11 +1471,7 @@ HRESULT UpdateArchive( | |||
1366 | if (fi.Find(prefix)) | 1471 | if (fi.Find(prefix)) |
1367 | if (fi.IsDir()) | 1472 | if (fi.IsDir()) |
1368 | { | 1473 | { |
1369 | parentDirItem.Size = fi.Size; | 1474 | parentDirItem.Copy_From_FileInfoBase(fi); |
1370 | parentDirItem.CTime = fi.CTime; | ||
1371 | parentDirItem.ATime = fi.ATime; | ||
1372 | parentDirItem.MTime = fi.MTime; | ||
1373 | parentDirItem.Attrib = fi.Attrib; | ||
1374 | parentDirItem_Ptr = &parentDirItem; | 1475 | parentDirItem_Ptr = &parentDirItem; |
1375 | 1476 | ||
1376 | int secureIndex = -1; | 1477 | int secureIndex = -1; |
@@ -1723,8 +1824,8 @@ HRESULT UpdateArchive( | |||
1723 | is_SameSize = (fileInfo.Size == dirItem.Size); | 1824 | is_SameSize = (fileInfo.Size == dirItem.Size); |
1724 | 1825 | ||
1725 | if (is_SameSize | 1826 | if (is_SameSize |
1726 | && CompareFileTime(&fileInfo.MTime, &dirItem.MTime) == 0 | 1827 | && Compare_FiTime(&fileInfo.MTime, &dirItem.MTime) == 0 |
1727 | && CompareFileTime(&fileInfo.CTime, &dirItem.CTime) == 0) | 1828 | && Compare_FiTime(&fileInfo.CTime, &dirItem.CTime) == 0) |
1728 | { | 1829 | { |
1729 | RINOK(callback->DeletingAfterArchiving(phyPath, false)); | 1830 | RINOK(callback->DeletingAfterArchiving(phyPath, false)); |
1730 | DeleteFileAlways(phyPath); | 1831 | DeleteFileAlways(phyPath); |
diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h index 06d1387..01fc43e 100644 --- a/CPP/7zip/UI/Common/Update.h +++ b/CPP/7zip/UI/Common/Update.h | |||
@@ -112,6 +112,9 @@ struct CUpdateOptions | |||
112 | CBoolPair HardLinks; | 112 | CBoolPair HardLinks; |
113 | CBoolPair SymLinks; | 113 | CBoolPair SymLinks; |
114 | 114 | ||
115 | CBoolPair StoreOwnerId; | ||
116 | CBoolPair StoreOwnerName; | ||
117 | |||
115 | bool DeleteAfterCompressing; | 118 | bool DeleteAfterCompressing; |
116 | 119 | ||
117 | bool SetArcMTime; | 120 | bool SetArcMTime; |
diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp index 7b705ba..926a275 100644 --- a/CPP/7zip/UI/Common/UpdateCallback.cpp +++ b/CPP/7zip/UI/Common/UpdateCallback.cpp | |||
@@ -4,6 +4,15 @@ | |||
4 | 4 | ||
5 | // #include <stdio.h> | 5 | // #include <stdio.h> |
6 | 6 | ||
7 | #ifndef _WIN32 | ||
8 | // #include <grp.h> | ||
9 | // #include <pwd.h> | ||
10 | |||
11 | // for major minor: | ||
12 | // BSD: <sys/types.h> | ||
13 | #include <sys/sysmacros.h> | ||
14 | #endif | ||
15 | |||
7 | #ifndef _7ZIP_ST | 16 | #ifndef _7ZIP_ST |
8 | #include "../../../Windows/Synchronization.h" | 17 | #include "../../../Windows/Synchronization.h" |
9 | #endif | 18 | #endif |
@@ -66,6 +75,18 @@ CArchiveUpdateCallback::CArchiveUpdateCallback(): | |||
66 | StoreNtSecurity(false), | 75 | StoreNtSecurity(false), |
67 | StoreHardLinks(false), | 76 | StoreHardLinks(false), |
68 | StoreSymLinks(false), | 77 | StoreSymLinks(false), |
78 | |||
79 | #ifndef _WIN32 | ||
80 | StoreOwnerId(false), | ||
81 | StoreOwnerName(false), | ||
82 | #endif | ||
83 | |||
84 | /* | ||
85 | , Need_ArcMTime_Report(false), | ||
86 | , ArcMTime_WasReported(false), | ||
87 | */ | ||
88 | Need_LatestMTime(false), | ||
89 | LatestMTime_Defined(false), | ||
69 | 90 | ||
70 | ProcessedItemsStatuses(NULL) | 91 | ProcessedItemsStatuses(NULL) |
71 | { | 92 | { |
@@ -134,16 +155,17 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, | |||
134 | COM_TRY_END | 155 | COM_TRY_END |
135 | } | 156 | } |
136 | 157 | ||
158 | |||
137 | STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value) | 159 | STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value) |
138 | { | 160 | { |
139 | NCOM::CPropVariant prop; | 161 | NCOM::CPropVariant prop; |
140 | switch (propID) | 162 | switch (propID) |
141 | { | 163 | { |
142 | case kpidIsDir: prop = true; break; | 164 | case kpidIsDir: prop = true; break; |
143 | case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->Attrib; break; | 165 | case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->GetWinAttrib(); break; |
144 | case kpidCTime: if (ParentDirItem) prop = ParentDirItem->CTime; break; | 166 | case kpidCTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->CTime); break; |
145 | case kpidATime: if (ParentDirItem) prop = ParentDirItem->ATime; break; | 167 | case kpidATime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->ATime); break; |
146 | case kpidMTime: if (ParentDirItem) prop = ParentDirItem->MTime; break; | 168 | case kpidMTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->MTime); break; |
147 | case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break; | 169 | case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break; |
148 | } | 170 | } |
149 | prop.Detach(value); | 171 | prop.Detach(value); |
@@ -446,25 +468,46 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR | |||
446 | { | 468 | { |
447 | case kpidPath: prop = DirItems->GetLogPath((unsigned)up.DirIndex); break; | 469 | case kpidPath: prop = DirItems->GetLogPath((unsigned)up.DirIndex); break; |
448 | case kpidIsDir: prop = di.IsDir(); break; | 470 | case kpidIsDir: prop = di.IsDir(); break; |
449 | case kpidSize: prop = di.IsDir() ? (UInt64)0 : di.Size; break; | 471 | case kpidSize: prop = (UInt64)(di.IsDir() ? (UInt64)0 : di.Size); break; |
450 | case kpidAttrib: prop = di.Attrib; break; | 472 | case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break; |
451 | case kpidCTime: prop = di.CTime; break; | 473 | case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break; |
452 | case kpidATime: prop = di.ATime; break; | 474 | case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break; |
453 | case kpidMTime: prop = di.MTime; break; | 475 | case kpidAttrib: prop = (UInt32)di.GetWinAttrib(); break; |
476 | case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break; | ||
477 | |||
478 | #if defined(_WIN32) | ||
454 | case kpidIsAltStream: prop = di.IsAltStream; break; | 479 | case kpidIsAltStream: prop = di.IsAltStream; break; |
455 | #if defined(_WIN32) && !defined(UNDER_CE) | ||
456 | // case kpidShortName: prop = di.ShortName; break; | 480 | // case kpidShortName: prop = di.ShortName; break; |
457 | #endif | 481 | #else |
458 | case kpidPosixAttrib: | 482 | |
459 | { | 483 | case kpidDeviceMajor: |
460 | #ifdef _WIN32 | 484 | /* |
461 | prop = di.GetPosixAttrib(); | 485 | printf("\ndi.mode = %o\n", di.mode); |
462 | #else | 486 | printf("\nst.st_rdev major = %d\n", (unsigned)major(di.rdev)); |
463 | if (di.Attrib & FILE_ATTRIBUTE_UNIX_EXTENSION) | 487 | printf("\nst.st_rdev minor = %d\n", (unsigned)minor(di.rdev)); |
464 | prop = (UInt32)(di.Attrib >> 16); | 488 | */ |
465 | #endif | 489 | if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) |
490 | prop = (UInt32)major(di.rdev); | ||
466 | break; | 491 | break; |
467 | } | 492 | |
493 | case kpidDeviceMinor: | ||
494 | if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) | ||
495 | prop = (UInt32)minor(di.rdev); | ||
496 | break; | ||
497 | |||
498 | // case kpidDevice: if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) prop = (UInt64)(di.rdev); break; | ||
499 | |||
500 | case kpidUserId: if (StoreOwnerId) prop = (UInt32)di.uid; break; | ||
501 | case kpidGroupId: if (StoreOwnerId) prop = (UInt32)di.gid; break; | ||
502 | case kpidUser: | ||
503 | if (di.OwnerNameIndex >= 0) | ||
504 | prop = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex]; | ||
505 | break; | ||
506 | case kpidGroup: | ||
507 | if (di.OwnerGroupIndex >= 0) | ||
508 | prop = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex]; | ||
509 | break; | ||
510 | #endif | ||
468 | } | 511 | } |
469 | } | 512 | } |
470 | prop.Detach(value); | 513 | prop.Detach(value); |
@@ -565,12 +608,41 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea | |||
565 | CInFileStream *inStreamSpec = new CInFileStream; | 608 | CInFileStream *inStreamSpec = new CInFileStream; |
566 | CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); | 609 | CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); |
567 | 610 | ||
611 | /* | ||
612 | // for debug: | ||
613 | #ifdef _WIN32 | ||
614 | inStreamSpec->StoreOwnerName = true; | ||
615 | inStreamSpec->OwnerName = "user_name"; | ||
616 | inStreamSpec->OwnerName += di.Name; | ||
617 | inStreamSpec->OwnerName += "11111111112222222222222333333333333"; | ||
618 | inStreamSpec->OwnerGroup = "gname_"; | ||
619 | inStreamSpec->OwnerGroup += inStreamSpec->OwnerName; | ||
620 | #endif | ||
621 | */ | ||
622 | |||
623 | #ifndef _WIN32 | ||
624 | inStreamSpec->StoreOwnerId = StoreOwnerId; | ||
625 | inStreamSpec->StoreOwnerName = StoreOwnerName; | ||
626 | |||
627 | // if (StoreOwner) | ||
628 | { | ||
629 | inStreamSpec->_uid = di.uid; | ||
630 | inStreamSpec->_gid = di.gid; | ||
631 | if (di.OwnerNameIndex >= 0) | ||
632 | inStreamSpec->OwnerName = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex]; | ||
633 | if (di.OwnerGroupIndex >= 0) | ||
634 | inStreamSpec->OwnerGroup = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex]; | ||
635 | } | ||
636 | #endif | ||
637 | |||
568 | inStreamSpec->SupportHardLinks = StoreHardLinks; | 638 | inStreamSpec->SupportHardLinks = StoreHardLinks; |
569 | inStreamSpec->File.PreserveATime = PreserveATime; | 639 | inStreamSpec->Set_PreserveATime(PreserveATime |
640 | || mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass. | ||
570 | 641 | ||
571 | const FString path = DirItems->GetPhyPath((unsigned)up.DirIndex); | 642 | const FString path = DirItems->GetPhyPath((unsigned)up.DirIndex); |
572 | _openFiles_Indexes.Add(index); | 643 | _openFiles_Indexes.Add(index); |
573 | _openFiles_Paths.Add(path); | 644 | _openFiles_Paths.Add(path); |
645 | // _openFiles_Streams.Add(inStreamSpec); | ||
574 | 646 | ||
575 | /* 21.02 : we set Callback/CallbackRef after _openFiles_Indexes adding | 647 | /* 21.02 : we set Callback/CallbackRef after _openFiles_Indexes adding |
576 | for correct working if exception was raised in GetPhyPath */ | 648 | for correct working if exception was raised in GetPhyPath */ |
@@ -579,14 +651,30 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea | |||
579 | 651 | ||
580 | if (!inStreamSpec->OpenShared(path, ShareForWrite)) | 652 | if (!inStreamSpec->OpenShared(path, ShareForWrite)) |
581 | { | 653 | { |
582 | DWORD error = ::GetLastError(); | 654 | const DWORD error = ::GetLastError(); |
583 | HRESULT hres = Callback->OpenFileError(path, error); | 655 | const HRESULT hres = Callback->OpenFileError(path, error); |
584 | if (StopAfterOpenError) | 656 | if (StopAfterOpenError) |
585 | if (hres == S_OK || hres == S_FALSE) | 657 | if (hres == S_OK || hres == S_FALSE) |
586 | return HRESULT_FROM_WIN32(error); | 658 | return HRESULT_FROM_WIN32(error); |
587 | return hres; | 659 | return hres; |
588 | } | 660 | } |
589 | 661 | ||
662 | /* | ||
663 | { | ||
664 | // for debug: | ||
665 | Byte b = 0; | ||
666 | UInt32 processedSize = 0; | ||
667 | if (inStreamSpec->Read(&b, 1, &processedSize) != S_OK || | ||
668 | processedSize != 1) | ||
669 | return E_FAIL; | ||
670 | } | ||
671 | */ | ||
672 | |||
673 | if (Need_LatestMTime) | ||
674 | { | ||
675 | inStreamSpec->ReloadProps(); | ||
676 | } | ||
677 | |||
590 | // #if defined(USE_WIN_FILE) || !defined(_WIN32) | 678 | // #if defined(USE_WIN_FILE) || !defined(_WIN32) |
591 | if (StoreHardLinks) | 679 | if (StoreHardLinks) |
592 | { | 680 | { |
@@ -643,6 +731,8 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in | |||
643 | { | 731 | { |
644 | COM_TRY_BEGIN | 732 | COM_TRY_BEGIN |
645 | 733 | ||
734 | // if (op == NUpdateNotifyOp::kOpFinished) return Callback->ReportFinished(indexType, index); | ||
735 | |||
646 | bool isDir = false; | 736 | bool isDir = false; |
647 | 737 | ||
648 | if (indexType == NArchive::NEventIndexType::kOutArcIndex) | 738 | if (indexType == NArchive::NEventIndexType::kOutArcIndex) |
@@ -676,7 +766,7 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in | |||
676 | } | 766 | } |
677 | else if (Arc) | 767 | else if (Arc) |
678 | { | 768 | { |
679 | RINOK(Arc->GetItemPath(index, s2)); | 769 | RINOK(Arc->GetItem_Path(index, s2)); |
680 | s = s2; | 770 | s = s2; |
681 | RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir)); | 771 | RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir)); |
682 | } | 772 | } |
@@ -731,7 +821,7 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3 | |||
731 | s = (*ArcItems)[index].Name; | 821 | s = (*ArcItems)[index].Name; |
732 | else if (Arc) | 822 | else if (Arc) |
733 | { | 823 | { |
734 | RINOK(Arc->GetItemPath(index, s2)); | 824 | RINOK(Arc->GetItem_Path(index, s2)); |
735 | s = s2; | 825 | s = s2; |
736 | } | 826 | } |
737 | if (Archive) | 827 | if (Archive) |
@@ -752,6 +842,51 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3 | |||
752 | COM_TRY_END | 842 | COM_TRY_END |
753 | } | 843 | } |
754 | 844 | ||
845 | |||
846 | /* | ||
847 | STDMETHODIMP CArchiveUpdateCallback::DoNeedArcProp(PROPID propID, Int32 *answer) | ||
848 | { | ||
849 | *answer = 0; | ||
850 | if (Need_ArcMTime_Report && propID == kpidComboMTime) | ||
851 | *answer = 1; | ||
852 | return S_OK; | ||
853 | } | ||
854 | |||
855 | STDMETHODIMP CArchiveUpdateCallback::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) | ||
856 | { | ||
857 | if (indexType == NArchive::NEventIndexType::kArcProp) | ||
858 | { | ||
859 | if (propID == kpidComboMTime) | ||
860 | { | ||
861 | ArcMTime_WasReported = true; | ||
862 | if (value->vt == VT_FILETIME) | ||
863 | { | ||
864 | Reported_ArcMTime.Set_From_Prop(*value); | ||
865 | Reported_ArcMTime.Def = true; | ||
866 | } | ||
867 | else | ||
868 | { | ||
869 | Reported_ArcMTime.Clear(); | ||
870 | if (value->vt != VT_EMPTY) | ||
871 | return E_FAIL; // for debug | ||
872 | } | ||
873 | } | ||
874 | } | ||
875 | return Callback->ReportProp(indexType, index, propID, value); | ||
876 | } | ||
877 | |||
878 | STDMETHODIMP CArchiveUpdateCallback::ReportRawProp(UInt32 indexType, UInt32 index, | ||
879 | PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) | ||
880 | { | ||
881 | return Callback->ReportRawProp(indexType, index, propID, data, dataSize, propType); | ||
882 | } | ||
883 | |||
884 | STDMETHODIMP CArchiveUpdateCallback::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) | ||
885 | { | ||
886 | return Callback->ReportFinished(indexType, index, opRes); | ||
887 | } | ||
888 | */ | ||
889 | |||
755 | STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) | 890 | STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) |
756 | { | 891 | { |
757 | if (VolumesSizes.Size() == 0) | 892 | if (VolumesSizes.Size() == 0) |
@@ -805,7 +940,7 @@ HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error) | |||
805 | #endif | 940 | #endif |
806 | { | 941 | { |
807 | MT_LOCK | 942 | MT_LOCK |
808 | UInt32 index = (UInt32)val; | 943 | const UInt32 index = (UInt32)val; |
809 | FOR_VECTOR(i, _openFiles_Indexes) | 944 | FOR_VECTOR(i, _openFiles_Indexes) |
810 | { | 945 | { |
811 | if (_openFiles_Indexes[i] == index) | 946 | if (_openFiles_Indexes[i] == index) |
@@ -818,21 +953,31 @@ HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error) | |||
818 | return HRESULT_FROM_WIN32(error); | 953 | return HRESULT_FROM_WIN32(error); |
819 | } | 954 | } |
820 | 955 | ||
821 | void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val) | 956 | void CArchiveUpdateCallback::InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) |
822 | { | 957 | { |
823 | { | ||
824 | MT_LOCK | 958 | MT_LOCK |
825 | UInt32 index = (UInt32)val; | 959 | if (Need_LatestMTime) |
960 | { | ||
961 | if (stream->_info_WasLoaded) | ||
962 | { | ||
963 | const CFiTime &ft = ST_MTIME(stream->_info); | ||
964 | if (!LatestMTime_Defined | ||
965 | || Compare_FiTime(&LatestMTime, &ft) < 0) | ||
966 | LatestMTime = ft; | ||
967 | LatestMTime_Defined = true; | ||
968 | } | ||
969 | } | ||
970 | const UInt32 index = (UInt32)val; | ||
826 | FOR_VECTOR(i, _openFiles_Indexes) | 971 | FOR_VECTOR(i, _openFiles_Indexes) |
827 | { | 972 | { |
828 | if (_openFiles_Indexes[i] == index) | 973 | if (_openFiles_Indexes[i] == index) |
829 | { | 974 | { |
830 | _openFiles_Indexes.Delete(i); | 975 | _openFiles_Indexes.Delete(i); |
831 | _openFiles_Paths.Delete(i); | 976 | _openFiles_Paths.Delete(i); |
977 | // _openFiles_Streams.Delete(i); | ||
832 | return; | 978 | return; |
833 | } | 979 | } |
834 | } | 980 | } |
835 | } | ||
836 | /* 21.02 : this function can be called in destructor. | 981 | /* 21.02 : this function can be called in destructor. |
837 | And destructor can be called after some exception. | 982 | And destructor can be called after some exception. |
838 | If we don't want to throw exception in desctructors or after another exceptions, | 983 | If we don't want to throw exception in desctructors or after another exceptions, |
diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h index d27776e..3719c1e 100644 --- a/CPP/7zip/UI/Common/UpdateCallback.h +++ b/CPP/7zip/UI/Common/UpdateCallback.h | |||
@@ -45,6 +45,13 @@ struct CArcToDoStat | |||
45 | virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \ | 45 | virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \ |
46 | virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \ | 46 | virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \ |
47 | virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x; \ | 47 | virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x; \ |
48 | |||
49 | /* | ||
50 | virtual HRESULT ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) x; \ | ||
51 | virtual HRESULT ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) x; \ | ||
52 | virtual HRESULT ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) x; \ | ||
53 | */ | ||
54 | |||
48 | /* virtual HRESULT CloseProgress() { return S_OK; } */ | 55 | /* virtual HRESULT CloseProgress() { return S_OK; } */ |
49 | 56 | ||
50 | struct IUpdateCallbackUI | 57 | struct IUpdateCallbackUI |
@@ -70,6 +77,7 @@ struct CKeyKeyValPair | |||
70 | class CArchiveUpdateCallback: | 77 | class CArchiveUpdateCallback: |
71 | public IArchiveUpdateCallback2, | 78 | public IArchiveUpdateCallback2, |
72 | public IArchiveUpdateCallbackFile, | 79 | public IArchiveUpdateCallbackFile, |
80 | // public IArchiveUpdateCallbackArcProp, | ||
73 | public IArchiveExtractCallbackMessage, | 81 | public IArchiveExtractCallbackMessage, |
74 | public IArchiveGetRawProps, | 82 | public IArchiveGetRawProps, |
75 | public IArchiveGetRootProps, | 83 | public IArchiveGetRootProps, |
@@ -92,6 +100,7 @@ class CArchiveUpdateCallback: | |||
92 | public: | 100 | public: |
93 | MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2) | 101 | MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2) |
94 | MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile) | 102 | MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile) |
103 | // MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackArcProp) | ||
95 | MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) | 104 | MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) |
96 | MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) | 105 | MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) |
97 | MY_QUERYINTERFACE_ENTRY(IArchiveGetRootProps) | 106 | MY_QUERYINTERFACE_ENTRY(IArchiveGetRootProps) |
@@ -106,6 +115,7 @@ public: | |||
106 | 115 | ||
107 | INTERFACE_IArchiveUpdateCallback2(;) | 116 | INTERFACE_IArchiveUpdateCallback2(;) |
108 | INTERFACE_IArchiveUpdateCallbackFile(;) | 117 | INTERFACE_IArchiveUpdateCallbackFile(;) |
118 | // INTERFACE_IArchiveUpdateCallbackArcProp(;) | ||
109 | INTERFACE_IArchiveExtractCallbackMessage(;) | 119 | INTERFACE_IArchiveExtractCallbackMessage(;) |
110 | INTERFACE_IArchiveGetRawProps(;) | 120 | INTERFACE_IArchiveGetRawProps(;) |
111 | INTERFACE_IArchiveGetRootProps(;) | 121 | INTERFACE_IArchiveGetRootProps(;) |
@@ -115,10 +125,11 @@ public: | |||
115 | 125 | ||
116 | CRecordVector<UInt32> _openFiles_Indexes; | 126 | CRecordVector<UInt32> _openFiles_Indexes; |
117 | FStringVector _openFiles_Paths; | 127 | FStringVector _openFiles_Paths; |
128 | // CRecordVector< CInFileStream* > _openFiles_Streams; | ||
118 | 129 | ||
119 | bool AreAllFilesClosed() const { return _openFiles_Indexes.IsEmpty(); } | 130 | bool AreAllFilesClosed() const { return _openFiles_Indexes.IsEmpty(); } |
120 | virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error); | 131 | virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error); |
121 | virtual void InFileStream_On_Destroy(UINT_PTR val); | 132 | virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val); |
122 | 133 | ||
123 | CRecordVector<UInt64> VolumesSizes; | 134 | CRecordVector<UInt64> VolumesSizes; |
124 | FString VolName; | 135 | FString VolName; |
@@ -148,8 +159,22 @@ public: | |||
148 | bool StoreHardLinks; | 159 | bool StoreHardLinks; |
149 | bool StoreSymLinks; | 160 | bool StoreSymLinks; |
150 | 161 | ||
162 | bool StoreOwnerId; | ||
163 | bool StoreOwnerName; | ||
164 | |||
165 | /* | ||
166 | bool Need_ArcMTime_Report; | ||
167 | bool ArcMTime_WasReported; | ||
168 | CArcTime Reported_ArcMTime; | ||
169 | */ | ||
170 | bool Need_LatestMTime; | ||
171 | bool LatestMTime_Defined; | ||
172 | CFiTime LatestMTime; | ||
173 | |||
151 | Byte *ProcessedItemsStatuses; | 174 | Byte *ProcessedItemsStatuses; |
152 | 175 | ||
176 | |||
177 | |||
153 | CArchiveUpdateCallback(); | 178 | CArchiveUpdateCallback(); |
154 | 179 | ||
155 | bool IsDir(const CUpdatePair2 &up) const | 180 | bool IsDir(const CUpdatePair2 &up) const |
diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp index 31d73f9..e9a1644 100644 --- a/CPP/7zip/UI/Common/UpdatePair.cpp +++ b/CPP/7zip/UI/Common/UpdatePair.cpp | |||
@@ -3,6 +3,7 @@ | |||
3 | #include "StdAfx.h" | 3 | #include "StdAfx.h" |
4 | 4 | ||
5 | #include <time.h> | 5 | #include <time.h> |
6 | // #include <stdio.h> | ||
6 | 7 | ||
7 | #include "../../../Common/Wildcard.h" | 8 | #include "../../../Common/Wildcard.h" |
8 | 9 | ||
@@ -14,30 +15,90 @@ | |||
14 | using namespace NWindows; | 15 | using namespace NWindows; |
15 | using namespace NTime; | 16 | using namespace NTime; |
16 | 17 | ||
17 | static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2) | 18 | |
19 | /* | ||
20 | a2.Prec = | ||
21 | { | ||
22 | 0 (k_PropVar_TimePrec_0): | ||
23 | if GetProperty(kpidMTime) returned 0 and | ||
24 | GetProperty(kpidTimeType) did not returned VT_UI4. | ||
25 | 7z, wim, tar in 7-Zip before v21) | ||
26 | in that case we use | ||
27 | (prec) that is set by IOutArchive::GetFileTimeType() | ||
28 | } | ||
29 | */ | ||
30 | |||
31 | static int MyCompareTime(unsigned prec, const CFiTime &f1, const CArcTime &a2) | ||
18 | { | 32 | { |
19 | switch (fileTimeType) | 33 | // except of precision, we also have limitation, when timestamp is out of range |
34 | |||
35 | /* if (Prec) in archive item is defined, then use global (prec) */ | ||
36 | if (a2.Prec != k_PropVar_TimePrec_0) | ||
37 | prec = a2.Prec; | ||
38 | |||
39 | CArcTime a1; | ||
40 | a1.Set_From_FiTime(f1); | ||
41 | /* Set_From_FiTime() must set full form precision: | ||
42 | k_PropVar_TimePrec_Base + numDigits | ||
43 | windows: 7 digits, non-windows: 9 digits */ | ||
44 | |||
45 | if (prec == k_PropVar_TimePrec_DOS) | ||
20 | { | 46 | { |
21 | case NFileTimeType::kWindows: | 47 | const UInt32 dosTime1 = a1.Get_DosTime(); |
22 | return ::CompareFileTime(&time1, &time2); | 48 | const UInt32 dosTime2 = a2.Get_DosTime(); |
23 | case NFileTimeType::kUnix: | 49 | return MyCompare(dosTime1, dosTime2); |
24 | { | ||
25 | UInt32 unixTime1, unixTime2; | ||
26 | FileTimeToUnixTime(time1, unixTime1); | ||
27 | FileTimeToUnixTime(time2, unixTime2); | ||
28 | return MyCompare(unixTime1, unixTime2); | ||
29 | } | ||
30 | case NFileTimeType::kDOS: | ||
31 | { | ||
32 | UInt32 dosTime1, dosTime2; | ||
33 | FileTimeToDosTime(time1, dosTime1); | ||
34 | FileTimeToDosTime(time2, dosTime2); | ||
35 | return MyCompare(dosTime1, dosTime2); | ||
36 | } | ||
37 | } | 50 | } |
38 | throw 4191618; | 51 | |
52 | if (prec == k_PropVar_TimePrec_Unix) | ||
53 | { | ||
54 | const Int64 u2 = FileTime_To_UnixTime64(a2.FT); | ||
55 | if (u2 == 0 || u2 == (UInt32)0xFFFFFFFF) | ||
56 | { | ||
57 | // timestamp probably was saturated in archive to 32-bit | ||
58 | // so we use saturated 32-bit value for disk file too. | ||
59 | UInt32 u1; | ||
60 | FileTime_To_UnixTime(a1.FT, u1); | ||
61 | const UInt32 u2_32 = (UInt32)u2; | ||
62 | return MyCompare(u1, u2_32); | ||
63 | } | ||
64 | |||
65 | const Int64 u1 = FileTime_To_UnixTime64(a1.FT); | ||
66 | return MyCompare(u1, u2); | ||
67 | // prec = k_PropVar_TimePrec_Base; // for debug | ||
68 | } | ||
69 | |||
70 | if (prec == k_PropVar_TimePrec_0) | ||
71 | prec = k_PropVar_TimePrec_Base + 7; | ||
72 | else if (prec == k_PropVar_TimePrec_HighPrec) | ||
73 | prec = k_PropVar_TimePrec_Base + 9; | ||
74 | else if (prec < k_PropVar_TimePrec_Base) | ||
75 | prec = k_PropVar_TimePrec_Base; | ||
76 | else if (prec > k_PropVar_TimePrec_Base + 9) | ||
77 | prec = k_PropVar_TimePrec_Base + 7; | ||
78 | |||
79 | // prec now is full form: k_PropVar_TimePrec_Base + numDigits; | ||
80 | if (prec > a1.Prec && a1.Prec >= k_PropVar_TimePrec_Base) | ||
81 | prec = a1.Prec; | ||
82 | |||
83 | const unsigned numDigits = prec - k_PropVar_TimePrec_Base; | ||
84 | if (numDigits >= 7) | ||
85 | { | ||
86 | const int comp = CompareFileTime(&a1.FT, &a2.FT); | ||
87 | if (comp != 0 || numDigits == 7) | ||
88 | return comp; | ||
89 | return MyCompare(a1.Ns100, a2.Ns100); | ||
90 | } | ||
91 | UInt32 d = 1; | ||
92 | for (unsigned k = numDigits; k < 7; k++) | ||
93 | d *= 10; | ||
94 | const UInt64 v1 = a1.Get_FILETIME_as_UInt64() / d * d; | ||
95 | const UInt64 v2 = a2.Get_FILETIME_as_UInt64() / d * d; | ||
96 | // printf("\ndelta=%d numDigits=%d\n", (unsigned)(v1- v2), numDigits); | ||
97 | return MyCompare(v1, v2); | ||
39 | } | 98 | } |
40 | 99 | ||
100 | |||
101 | |||
41 | static const char * const k_Duplicate_inArc_Message = "Duplicate filename in archive:"; | 102 | static const char * const k_Duplicate_inArc_Message = "Duplicate filename in archive:"; |
42 | static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:"; | 103 | static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:"; |
43 | static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):"; | 104 | static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):"; |
@@ -64,8 +125,8 @@ static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2) | |||
64 | 125 | ||
65 | static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param) | 126 | static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param) |
66 | { | 127 | { |
67 | unsigned i1 = *p1; | 128 | const unsigned i1 = *p1; |
68 | unsigned i2 = *p2; | 129 | const unsigned i2 = *p2; |
69 | const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param; | 130 | const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param; |
70 | int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]); | 131 | int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]); |
71 | if (res != 0) | 132 | if (res != 0) |
@@ -81,8 +142,8 @@ void GetUpdatePairInfoList( | |||
81 | { | 142 | { |
82 | CUIntVector dirIndices, arcIndices; | 143 | CUIntVector dirIndices, arcIndices; |
83 | 144 | ||
84 | unsigned numDirItems = dirItems.Items.Size(); | 145 | const unsigned numDirItems = dirItems.Items.Size(); |
85 | unsigned numArcItems = arcItems.Size(); | 146 | const unsigned numArcItems = arcItems.Size(); |
86 | 147 | ||
87 | CIntArr duplicatedArcItem(numArcItems); | 148 | CIntArr duplicatedArcItem(numArcItems); |
88 | { | 149 | { |
@@ -184,7 +245,7 @@ void GetUpdatePairInfoList( | |||
184 | } | 245 | } |
185 | else | 246 | else |
186 | { | 247 | { |
187 | int dupl = duplicatedArcItem[arcIndex]; | 248 | const int dupl = duplicatedArcItem[arcIndex]; |
188 | if (dupl != 0) | 249 | if (dupl != 0) |
189 | ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[(unsigned)((int)arcIndex + dupl)]].Name); | 250 | ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[(unsigned)((int)arcIndex + dupl)]].Name); |
190 | 251 | ||
@@ -195,14 +256,17 @@ void GetUpdatePairInfoList( | |||
195 | pair.DirIndex = dirIndex2; | 256 | pair.DirIndex = dirIndex2; |
196 | pair.ArcIndex = arcIndex2; | 257 | pair.ArcIndex = arcIndex2; |
197 | 258 | ||
198 | switch (ai->MTimeDefined ? MyCompareTime( | 259 | int compResult = 0; |
199 | ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType, | 260 | if (ai->MTime.Def) |
200 | di->MTime, ai->MTime): 0) | 261 | { |
262 | compResult = MyCompareTime(fileTimeType, di->MTime, ai->MTime); | ||
263 | } | ||
264 | switch (compResult) | ||
201 | { | 265 | { |
202 | case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break; | 266 | case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break; |
203 | case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break; | 267 | case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break; |
204 | default: | 268 | default: |
205 | pair.State = (ai->SizeDefined && di->Size == ai->Size) ? | 269 | pair.State = (ai->Size_Defined && di->Size == ai->Size) ? |
206 | NUpdateArchive::NPairState::kSameFiles : | 270 | NUpdateArchive::NPairState::kSameFiles : |
207 | NUpdateArchive::NPairState::kUnknowNewerFiles; | 271 | NUpdateArchive::NPairState::kUnknowNewerFiles; |
208 | } | 272 | } |
@@ -211,7 +275,10 @@ void GetUpdatePairInfoList( | |||
211 | arcIndex++; | 275 | arcIndex++; |
212 | } | 276 | } |
213 | 277 | ||
214 | if ((di && di->IsAltStream) || | 278 | if ( |
279 | #ifdef _WIN32 | ||
280 | (di && di->IsAltStream) || | ||
281 | #endif | ||
215 | (ai && ai->IsAltStream)) | 282 | (ai && ai->IsAltStream)) |
216 | { | 283 | { |
217 | if (prevHostName) | 284 | if (prevHostName) |
diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp index fa4bd69..e921dc3 100644 --- a/CPP/7zip/UI/Common/UpdateProduce.cpp +++ b/CPP/7zip/UI/Common/UpdateProduce.cpp | |||
@@ -63,6 +63,8 @@ void UpdateProduce( | |||
63 | break; | 63 | break; |
64 | } | 64 | } |
65 | 65 | ||
66 | up2.IsSameTime = ((unsigned)pair.State == NUpdateArchive::NPairState::kSameFiles); | ||
67 | |||
66 | operationChain.Add(up2); | 68 | operationChain.Add(up2); |
67 | } | 69 | } |
68 | 70 | ||
diff --git a/CPP/7zip/UI/Common/UpdateProduce.h b/CPP/7zip/UI/Common/UpdateProduce.h index 595370f..24bb32e 100644 --- a/CPP/7zip/UI/Common/UpdateProduce.h +++ b/CPP/7zip/UI/Common/UpdateProduce.h | |||
@@ -17,6 +17,7 @@ struct CUpdatePair2 | |||
17 | int NewNameIndex; | 17 | int NewNameIndex; |
18 | 18 | ||
19 | bool IsMainRenameItem; | 19 | bool IsMainRenameItem; |
20 | bool IsSameTime; | ||
20 | 21 | ||
21 | void SetAs_NoChangeArcItem(unsigned arcIndex) // int | 22 | void SetAs_NoChangeArcItem(unsigned arcIndex) // int |
22 | { | 23 | { |
@@ -37,7 +38,8 @@ struct CUpdatePair2 | |||
37 | DirIndex(-1), | 38 | DirIndex(-1), |
38 | ArcIndex(-1), | 39 | ArcIndex(-1), |
39 | NewNameIndex(-1), | 40 | NewNameIndex(-1), |
40 | IsMainRenameItem(false) | 41 | IsMainRenameItem(false), |
42 | IsSameTime(false) | ||
41 | {} | 43 | {} |
42 | }; | 44 | }; |
43 | 45 | ||
diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp index ab4871f..a67a99b 100644 --- a/CPP/7zip/UI/Common/ZipRegistry.cpp +++ b/CPP/7zip/UI/Common/ZipRegistry.cpp | |||
@@ -33,12 +33,45 @@ static LONG CreateMainKey(CKey &key, LPCTSTR keyName) | |||
33 | return key.Create(HKEY_CURRENT_USER, GetKeyPath(keyName)); | 33 | return key.Create(HKEY_CURRENT_USER, GetKeyPath(keyName)); |
34 | } | 34 | } |
35 | 35 | ||
36 | static void Key_Set_UInt32(CKey &key, LPCTSTR name, UInt32 value) | ||
37 | { | ||
38 | if (value == (UInt32)(Int32)-1) | ||
39 | key.DeleteValue(name); | ||
40 | else | ||
41 | key.SetValue(name, value); | ||
42 | } | ||
43 | |||
44 | |||
45 | static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value) | ||
46 | { | ||
47 | if (key.QueryValue(name, value) != ERROR_SUCCESS) | ||
48 | value = (UInt32)(Int32)-1; | ||
49 | } | ||
50 | |||
51 | |||
36 | static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b) | 52 | static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b) |
37 | { | 53 | { |
38 | if (b.Def) | 54 | if (b.Def) |
39 | key.SetValue(name, b.Val); | 55 | key.SetValue(name, b.Val); |
40 | } | 56 | } |
41 | 57 | ||
58 | static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val) | ||
59 | { | ||
60 | bool oldVal = false; | ||
61 | if (key.GetValue_IfOk(name, oldVal) == ERROR_SUCCESS) | ||
62 | if (val == oldVal) | ||
63 | return; | ||
64 | key.SetValue(name, val); | ||
65 | } | ||
66 | |||
67 | static void Key_Set_BoolPair_Delete_IfNotDef(CKey &key, LPCTSTR name, const CBoolPair &b) | ||
68 | { | ||
69 | if (b.Def) | ||
70 | Key_Set_bool_if_Changed(key, name, b.Val); | ||
71 | else | ||
72 | key.DeleteValue(name); | ||
73 | } | ||
74 | |||
42 | static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b) | 75 | static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b) |
43 | { | 76 | { |
44 | b.Val = false; | 77 | b.Val = false; |
@@ -169,6 +202,13 @@ static LPCTSTR const kNtSecur = TEXT("Security"); | |||
169 | static LPCTSTR const kAltStreams = TEXT("AltStreams"); | 202 | static LPCTSTR const kAltStreams = TEXT("AltStreams"); |
170 | static LPCTSTR const kHardLinks = TEXT("HardLinks"); | 203 | static LPCTSTR const kHardLinks = TEXT("HardLinks"); |
171 | static LPCTSTR const kSymLinks = TEXT("SymLinks"); | 204 | static LPCTSTR const kSymLinks = TEXT("SymLinks"); |
205 | static LPCTSTR const kPreserveATime = TEXT("PreserveATime"); | ||
206 | |||
207 | static LPCTSTR const kTimePrec = TEXT("TimePrec"); | ||
208 | static LPCTSTR const kMTime = TEXT("MTime"); | ||
209 | static LPCTSTR const kATime = TEXT("ATime"); | ||
210 | static LPCTSTR const kCTime = TEXT("CTime"); | ||
211 | static LPCTSTR const kSetArcMTime = TEXT("SetArcMTime"); | ||
172 | 212 | ||
173 | static void SetRegString(CKey &key, LPCWSTR name, const UString &value) | 213 | static void SetRegString(CKey &key, LPCWSTR name, const UString &value) |
174 | { | 214 | { |
@@ -178,26 +218,12 @@ static void SetRegString(CKey &key, LPCWSTR name, const UString &value) | |||
178 | key.SetValue(name, value); | 218 | key.SetValue(name, value); |
179 | } | 219 | } |
180 | 220 | ||
181 | static void SetRegUInt32(CKey &key, LPCTSTR name, UInt32 value) | ||
182 | { | ||
183 | if (value == (UInt32)(Int32)-1) | ||
184 | key.DeleteValue(name); | ||
185 | else | ||
186 | key.SetValue(name, value); | ||
187 | } | ||
188 | |||
189 | static void GetRegString(CKey &key, LPCWSTR name, UString &value) | 221 | static void GetRegString(CKey &key, LPCWSTR name, UString &value) |
190 | { | 222 | { |
191 | if (key.QueryValue(name, value) != ERROR_SUCCESS) | 223 | if (key.QueryValue(name, value) != ERROR_SUCCESS) |
192 | value.Empty(); | 224 | value.Empty(); |
193 | } | 225 | } |
194 | 226 | ||
195 | static void GetRegUInt32(CKey &key, LPCTSTR name, UInt32 &value) | ||
196 | { | ||
197 | if (key.QueryValue(name, value) != ERROR_SUCCESS) | ||
198 | value = (UInt32)(Int32)-1; | ||
199 | } | ||
200 | |||
201 | static LPCWSTR const kMemUse = L"MemUse" | 227 | static LPCWSTR const kMemUse = L"MemUse" |
202 | #if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4) | 228 | #if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4) |
203 | L"32"; | 229 | L"32"; |
@@ -212,10 +238,11 @@ void CInfo::Save() const | |||
212 | CKey key; | 238 | CKey key; |
213 | CreateMainKey(key, kKeyName); | 239 | CreateMainKey(key, kKeyName); |
214 | 240 | ||
215 | Key_Set_BoolPair(key, kNtSecur, NtSecurity); | 241 | Key_Set_BoolPair_Delete_IfNotDef (key, kNtSecur, NtSecurity); |
216 | Key_Set_BoolPair(key, kAltStreams, AltStreams); | 242 | Key_Set_BoolPair_Delete_IfNotDef (key, kAltStreams, AltStreams); |
217 | Key_Set_BoolPair(key, kHardLinks, HardLinks); | 243 | Key_Set_BoolPair_Delete_IfNotDef (key, kHardLinks, HardLinks); |
218 | Key_Set_BoolPair(key, kSymLinks, SymLinks); | 244 | Key_Set_BoolPair_Delete_IfNotDef (key, kSymLinks, SymLinks); |
245 | Key_Set_BoolPair_Delete_IfNotDef (key, kPreserveATime, PreserveATime); | ||
219 | 246 | ||
220 | key.SetValue(kShowPassword, ShowPassword); | 247 | key.SetValue(kShowPassword, ShowPassword); |
221 | key.SetValue(kLevel, (UInt32)Level); | 248 | key.SetValue(kLevel, (UInt32)Level); |
@@ -235,16 +262,22 @@ void CInfo::Save() const | |||
235 | CKey fk; | 262 | CKey fk; |
236 | fk.Create(optionsKey, fo.FormatID); | 263 | fk.Create(optionsKey, fo.FormatID); |
237 | 264 | ||
238 | SetRegUInt32(fk, kLevel, fo.Level); | ||
239 | SetRegUInt32(fk, kDictionary, fo.Dictionary); | ||
240 | SetRegUInt32(fk, kOrder, fo.Order); | ||
241 | SetRegUInt32(fk, kBlockSize, fo.BlockLogSize); | ||
242 | SetRegUInt32(fk, kNumThreads, fo.NumThreads); | ||
243 | |||
244 | SetRegString(fk, kMethod, fo.Method); | 265 | SetRegString(fk, kMethod, fo.Method); |
245 | SetRegString(fk, kOptions, fo.Options); | 266 | SetRegString(fk, kOptions, fo.Options); |
246 | SetRegString(fk, kEncryptionMethod, fo.EncryptionMethod); | 267 | SetRegString(fk, kEncryptionMethod, fo.EncryptionMethod); |
247 | SetRegString(fk, kMemUse, fo.MemUse); | 268 | SetRegString(fk, kMemUse, fo.MemUse); |
269 | |||
270 | Key_Set_UInt32(fk, kLevel, fo.Level); | ||
271 | Key_Set_UInt32(fk, kDictionary, fo.Dictionary); | ||
272 | Key_Set_UInt32(fk, kOrder, fo.Order); | ||
273 | Key_Set_UInt32(fk, kBlockSize, fo.BlockLogSize); | ||
274 | Key_Set_UInt32(fk, kNumThreads, fo.NumThreads); | ||
275 | |||
276 | Key_Set_UInt32(fk, kTimePrec, fo.TimePrec); | ||
277 | Key_Set_BoolPair_Delete_IfNotDef (fk, kMTime, fo.MTime); | ||
278 | Key_Set_BoolPair_Delete_IfNotDef (fk, kATime, fo.ATime); | ||
279 | Key_Set_BoolPair_Delete_IfNotDef (fk, kCTime, fo.CTime); | ||
280 | Key_Set_BoolPair_Delete_IfNotDef (fk, kSetArcMTime, fo.SetArcMTime); | ||
248 | } | 281 | } |
249 | } | 282 | } |
250 | } | 283 | } |
@@ -269,6 +302,7 @@ void CInfo::Load() | |||
269 | Key_Get_BoolPair(key, kAltStreams, AltStreams); | 302 | Key_Get_BoolPair(key, kAltStreams, AltStreams); |
270 | Key_Get_BoolPair(key, kHardLinks, HardLinks); | 303 | Key_Get_BoolPair(key, kHardLinks, HardLinks); |
271 | Key_Get_BoolPair(key, kSymLinks, SymLinks); | 304 | Key_Get_BoolPair(key, kSymLinks, SymLinks); |
305 | Key_Get_BoolPair(key, kPreserveATime, PreserveATime); | ||
272 | 306 | ||
273 | key.GetValue_Strings(kArcHistory, ArcPaths); | 307 | key.GetValue_Strings(kArcHistory, ArcPaths); |
274 | 308 | ||
@@ -290,11 +324,17 @@ void CInfo::Load() | |||
290 | GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod); | 324 | GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod); |
291 | GetRegString(fk, kMemUse, fo.MemUse); | 325 | GetRegString(fk, kMemUse, fo.MemUse); |
292 | 326 | ||
293 | GetRegUInt32(fk, kLevel, fo.Level); | 327 | Key_Get_UInt32(fk, kLevel, fo.Level); |
294 | GetRegUInt32(fk, kDictionary, fo.Dictionary); | 328 | Key_Get_UInt32(fk, kDictionary, fo.Dictionary); |
295 | GetRegUInt32(fk, kOrder, fo.Order); | 329 | Key_Get_UInt32(fk, kOrder, fo.Order); |
296 | GetRegUInt32(fk, kBlockSize, fo.BlockLogSize); | 330 | Key_Get_UInt32(fk, kBlockSize, fo.BlockLogSize); |
297 | GetRegUInt32(fk, kNumThreads, fo.NumThreads); | 331 | Key_Get_UInt32(fk, kNumThreads, fo.NumThreads); |
332 | |||
333 | Key_Get_UInt32(fk, kTimePrec, fo.TimePrec); | ||
334 | Key_Get_BoolPair(fk, kMTime, fo.MTime); | ||
335 | Key_Get_BoolPair(fk, kATime, fo.ATime); | ||
336 | Key_Get_BoolPair(fk, kCTime, fo.CTime); | ||
337 | Key_Get_BoolPair(fk, kSetArcMTime, fo.SetArcMTime); | ||
298 | 338 | ||
299 | Formats.Add(fo); | 339 | Formats.Add(fo); |
300 | } | 340 | } |
@@ -478,6 +518,7 @@ static LPCTSTR const kCascadedMenu = TEXT("CascadedMenu"); | |||
478 | static LPCTSTR const kContextMenu = TEXT("ContextMenu"); | 518 | static LPCTSTR const kContextMenu = TEXT("ContextMenu"); |
479 | static LPCTSTR const kMenuIcons = TEXT("MenuIcons"); | 519 | static LPCTSTR const kMenuIcons = TEXT("MenuIcons"); |
480 | static LPCTSTR const kElimDup = TEXT("ElimDupExtract"); | 520 | static LPCTSTR const kElimDup = TEXT("ElimDupExtract"); |
521 | static LPCTSTR const kWriteZoneId = TEXT("WriteZoneIdExtract"); | ||
481 | 522 | ||
482 | void CContextMenuInfo::Save() const | 523 | void CContextMenuInfo::Save() const |
483 | { | 524 | { |
@@ -488,6 +529,8 @@ void CContextMenuInfo::Save() const | |||
488 | Key_Set_BoolPair(key, kCascadedMenu, Cascaded); | 529 | Key_Set_BoolPair(key, kCascadedMenu, Cascaded); |
489 | Key_Set_BoolPair(key, kMenuIcons, MenuIcons); | 530 | Key_Set_BoolPair(key, kMenuIcons, MenuIcons); |
490 | Key_Set_BoolPair(key, kElimDup, ElimDup); | 531 | Key_Set_BoolPair(key, kElimDup, ElimDup); |
532 | |||
533 | Key_Set_UInt32(key, kWriteZoneId, WriteZone); | ||
491 | 534 | ||
492 | if (Flags_Def) | 535 | if (Flags_Def) |
493 | key.SetValue(kContextMenu, Flags); | 536 | key.SetValue(kContextMenu, Flags); |
@@ -504,6 +547,8 @@ void CContextMenuInfo::Load() | |||
504 | ElimDup.Val = true; | 547 | ElimDup.Val = true; |
505 | ElimDup.Def = false; | 548 | ElimDup.Def = false; |
506 | 549 | ||
550 | WriteZone = (UInt32)(Int32)-1; | ||
551 | |||
507 | Flags = (UInt32)(Int32)-1; | 552 | Flags = (UInt32)(Int32)-1; |
508 | Flags_Def = false; | 553 | Flags_Def = false; |
509 | 554 | ||
@@ -517,5 +562,7 @@ void CContextMenuInfo::Load() | |||
517 | Key_Get_BoolPair_true(key, kElimDup, ElimDup); | 562 | Key_Get_BoolPair_true(key, kElimDup, ElimDup); |
518 | Key_Get_BoolPair(key, kMenuIcons, MenuIcons); | 563 | Key_Get_BoolPair(key, kMenuIcons, MenuIcons); |
519 | 564 | ||
565 | Key_Get_UInt32(key, kWriteZoneId, WriteZone); | ||
566 | |||
520 | Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); | 567 | Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); |
521 | } | 568 | } |
diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h index 3d2e4b9..b7075e6 100644 --- a/CPP/7zip/UI/Common/ZipRegistry.h +++ b/CPP/7zip/UI/Common/ZipRegistry.h | |||
@@ -10,6 +10,16 @@ | |||
10 | 10 | ||
11 | #include "ExtractMode.h" | 11 | #include "ExtractMode.h" |
12 | 12 | ||
13 | /* | ||
14 | CBoolPair::Def in writing functions means: | ||
15 | if ( CBoolPair::Def ), we write CBoolPair::Val | ||
16 | if ( !CBoolPair::Def ) | ||
17 | { | ||
18 | in NCompression functions we delete registry value | ||
19 | in another functions we do nothing | ||
20 | } | ||
21 | */ | ||
22 | |||
13 | namespace NExtract | 23 | namespace NExtract |
14 | { | 24 | { |
15 | struct CInfo | 25 | struct CInfo |
@@ -75,12 +85,29 @@ namespace NCompression | |||
75 | UInt32 BlockLogSize; | 85 | UInt32 BlockLogSize; |
76 | UInt32 NumThreads; | 86 | UInt32 NumThreads; |
77 | 87 | ||
88 | UInt32 TimePrec; | ||
89 | CBoolPair MTime; | ||
90 | CBoolPair ATime; | ||
91 | CBoolPair CTime; | ||
92 | CBoolPair SetArcMTime; | ||
93 | |||
78 | CSysString FormatID; | 94 | CSysString FormatID; |
79 | UString Method; | 95 | UString Method; |
80 | UString Options; | 96 | UString Options; |
81 | UString EncryptionMethod; | 97 | UString EncryptionMethod; |
82 | UString MemUse; | 98 | UString MemUse; |
83 | 99 | ||
100 | void Reset_TimePrec() | ||
101 | { | ||
102 | TimePrec = (UInt32)(Int32)-1; | ||
103 | } | ||
104 | |||
105 | bool IsSet_TimePrec() const | ||
106 | { | ||
107 | return TimePrec != (UInt32)(Int32)-1; | ||
108 | } | ||
109 | |||
110 | |||
84 | void Reset_BlockLogSize() | 111 | void Reset_BlockLogSize() |
85 | { | 112 | { |
86 | BlockLogSize = (UInt32)(Int32)-1; | 113 | BlockLogSize = (UInt32)(Int32)-1; |
@@ -93,7 +120,12 @@ namespace NCompression | |||
93 | // Options.Empty(); | 120 | // Options.Empty(); |
94 | // EncryptionMethod.Empty(); | 121 | // EncryptionMethod.Empty(); |
95 | } | 122 | } |
96 | CFormatOptions() { ResetForLevelChange(); } | 123 | CFormatOptions() |
124 | { | ||
125 | // TimePrec = 0; | ||
126 | Reset_TimePrec(); | ||
127 | ResetForLevelChange(); | ||
128 | } | ||
97 | }; | 129 | }; |
98 | 130 | ||
99 | struct CInfo | 131 | struct CInfo |
@@ -111,6 +143,8 @@ namespace NCompression | |||
111 | CBoolPair HardLinks; | 143 | CBoolPair HardLinks; |
112 | CBoolPair SymLinks; | 144 | CBoolPair SymLinks; |
113 | 145 | ||
146 | CBoolPair PreserveATime; | ||
147 | |||
114 | void Save() const; | 148 | void Save() const; |
115 | void Load(); | 149 | void Load(); |
116 | }; | 150 | }; |
@@ -152,9 +186,18 @@ struct CContextMenuInfo | |||
152 | CBoolPair Cascaded; | 186 | CBoolPair Cascaded; |
153 | CBoolPair MenuIcons; | 187 | CBoolPair MenuIcons; |
154 | CBoolPair ElimDup; | 188 | CBoolPair ElimDup; |
155 | 189 | ||
156 | bool Flags_Def; | 190 | bool Flags_Def; |
157 | UInt32 Flags; | 191 | UInt32 Flags; |
192 | UInt32 WriteZone; | ||
193 | |||
194 | /* | ||
195 | CContextMenuInfo(): | ||
196 | Flags_Def(0), | ||
197 | WriteZone((UInt32)(Int32)-1), | ||
198 | Flags((UInt32)(Int32)-1) | ||
199 | {} | ||
200 | */ | ||
158 | 201 | ||
159 | void Save() const; | 202 | void Save() const; |
160 | void Load(); | 203 | void Load(); |