1370b324cSopenharmony_ci// Update.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci// #include <stdio.h> 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "Update.h" 8370b324cSopenharmony_ci 9370b324cSopenharmony_ci#include "../../../Common/StringConvert.h" 10370b324cSopenharmony_ci 11370b324cSopenharmony_ci#include "../../../Windows/DLL.h" 12370b324cSopenharmony_ci#include "../../../Windows/FileDir.h" 13370b324cSopenharmony_ci#include "../../../Windows/FileFind.h" 14370b324cSopenharmony_ci#include "../../../Windows/FileName.h" 15370b324cSopenharmony_ci#include "../../../Windows/PropVariant.h" 16370b324cSopenharmony_ci#include "../../../Windows/PropVariantConv.h" 17370b324cSopenharmony_ci#include "../../../Windows/TimeUtils.h" 18370b324cSopenharmony_ci 19370b324cSopenharmony_ci#include "../../Common/FileStreams.h" 20370b324cSopenharmony_ci#include "../../Common/LimitedStreams.h" 21370b324cSopenharmony_ci#include "../../Common/MultiOutStream.h" 22370b324cSopenharmony_ci#include "../../Common/StreamUtils.h" 23370b324cSopenharmony_ci 24370b324cSopenharmony_ci#include "../../Compress/CopyCoder.h" 25370b324cSopenharmony_ci 26370b324cSopenharmony_ci#include "../Common/DirItem.h" 27370b324cSopenharmony_ci#include "../Common/EnumDirItems.h" 28370b324cSopenharmony_ci#include "../Common/OpenArchive.h" 29370b324cSopenharmony_ci#include "../Common/UpdateProduce.h" 30370b324cSopenharmony_ci 31370b324cSopenharmony_ci#include "EnumDirItems.h" 32370b324cSopenharmony_ci#include "SetProperties.h" 33370b324cSopenharmony_ci#include "TempFiles.h" 34370b324cSopenharmony_ci#include "UpdateCallback.h" 35370b324cSopenharmony_ci 36370b324cSopenharmony_cistatic const char * const kUpdateIsNotSupoorted = 37370b324cSopenharmony_ci "update operations are not supported for this archive"; 38370b324cSopenharmony_ci 39370b324cSopenharmony_cistatic const char * const kUpdateIsNotSupported_MultiVol = 40370b324cSopenharmony_ci "Updating for multivolume archives is not implemented"; 41370b324cSopenharmony_ci 42370b324cSopenharmony_ciusing namespace NWindows; 43370b324cSopenharmony_ciusing namespace NCOM; 44370b324cSopenharmony_ciusing namespace NFile; 45370b324cSopenharmony_ciusing namespace NDir; 46370b324cSopenharmony_ciusing namespace NName; 47370b324cSopenharmony_ci 48370b324cSopenharmony_ci#ifdef _WIN32 49370b324cSopenharmony_cistatic CFSTR const kTempFolderPrefix = FTEXT("7zE"); 50370b324cSopenharmony_ci#endif 51370b324cSopenharmony_ci 52370b324cSopenharmony_civoid CUpdateErrorInfo::SetFromLastError(const char *message) 53370b324cSopenharmony_ci{ 54370b324cSopenharmony_ci SystemError = ::GetLastError(); 55370b324cSopenharmony_ci Message = message; 56370b324cSopenharmony_ci} 57370b324cSopenharmony_ci 58370b324cSopenharmony_ciHRESULT CUpdateErrorInfo::SetFromLastError(const char *message, const FString &fileName) 59370b324cSopenharmony_ci{ 60370b324cSopenharmony_ci SetFromLastError(message); 61370b324cSopenharmony_ci FileNames.Add(fileName); 62370b324cSopenharmony_ci return Get_HRESULT_Error(); 63370b324cSopenharmony_ci} 64370b324cSopenharmony_ci 65370b324cSopenharmony_ciHRESULT CUpdateErrorInfo::SetFromError_DWORD(const char *message, const FString &fileName, DWORD error) 66370b324cSopenharmony_ci{ 67370b324cSopenharmony_ci Message = message; 68370b324cSopenharmony_ci FileNames.Add(fileName); 69370b324cSopenharmony_ci SystemError = error; 70370b324cSopenharmony_ci return Get_HRESULT_Error(); 71370b324cSopenharmony_ci} 72370b324cSopenharmony_ci 73370b324cSopenharmony_ci 74370b324cSopenharmony_ciusing namespace NUpdateArchive; 75370b324cSopenharmony_ci 76370b324cSopenharmony_cistruct CMultiOutStream_Rec 77370b324cSopenharmony_ci{ 78370b324cSopenharmony_ci CMultiOutStream *Spec; 79370b324cSopenharmony_ci CMyComPtr<IOutStream> Ref; 80370b324cSopenharmony_ci}; 81370b324cSopenharmony_ci 82370b324cSopenharmony_cistruct CMultiOutStream_Bunch 83370b324cSopenharmony_ci{ 84370b324cSopenharmony_ci CObjectVector<CMultiOutStream_Rec> Items; 85370b324cSopenharmony_ci 86370b324cSopenharmony_ci HRESULT Destruct() 87370b324cSopenharmony_ci { 88370b324cSopenharmony_ci HRESULT hres = S_OK; 89370b324cSopenharmony_ci FOR_VECTOR (i, Items) 90370b324cSopenharmony_ci { 91370b324cSopenharmony_ci CMultiOutStream_Rec &rec = Items[i]; 92370b324cSopenharmony_ci if (rec.Ref) 93370b324cSopenharmony_ci { 94370b324cSopenharmony_ci const HRESULT hres2 = rec.Spec->Destruct(); 95370b324cSopenharmony_ci if (hres == S_OK) 96370b324cSopenharmony_ci hres = hres2; 97370b324cSopenharmony_ci } 98370b324cSopenharmony_ci } 99370b324cSopenharmony_ci Items.Clear(); 100370b324cSopenharmony_ci return hres; 101370b324cSopenharmony_ci } 102370b324cSopenharmony_ci 103370b324cSopenharmony_ci void DisableDeletion() 104370b324cSopenharmony_ci { 105370b324cSopenharmony_ci FOR_VECTOR (i, Items) 106370b324cSopenharmony_ci { 107370b324cSopenharmony_ci CMultiOutStream_Rec &rec = Items[i]; 108370b324cSopenharmony_ci if (rec.Ref) 109370b324cSopenharmony_ci rec.Spec->NeedDelete = false; 110370b324cSopenharmony_ci } 111370b324cSopenharmony_ci } 112370b324cSopenharmony_ci}; 113370b324cSopenharmony_ci 114370b324cSopenharmony_ci 115370b324cSopenharmony_civoid CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode) 116370b324cSopenharmony_ci{ 117370b324cSopenharmony_ci OriginalPath = path; 118370b324cSopenharmony_ci 119370b324cSopenharmony_ci SplitPathToParts_2(path, Prefix, Name); 120370b324cSopenharmony_ci 121370b324cSopenharmony_ci if (mode == k_ArcNameMode_Add) 122370b324cSopenharmony_ci return; 123370b324cSopenharmony_ci 124370b324cSopenharmony_ci if (mode != k_ArcNameMode_Exact) 125370b324cSopenharmony_ci { 126370b324cSopenharmony_ci int dotPos = Name.ReverseFind_Dot(); 127370b324cSopenharmony_ci if (dotPos < 0) 128370b324cSopenharmony_ci return; 129370b324cSopenharmony_ci if ((unsigned)dotPos == Name.Len() - 1) 130370b324cSopenharmony_ci Name.DeleteBack(); 131370b324cSopenharmony_ci else 132370b324cSopenharmony_ci { 133370b324cSopenharmony_ci const UString ext = Name.Ptr((unsigned)(dotPos + 1)); 134370b324cSopenharmony_ci if (BaseExtension.IsEqualTo_NoCase(ext)) 135370b324cSopenharmony_ci { 136370b324cSopenharmony_ci BaseExtension = ext; 137370b324cSopenharmony_ci Name.DeleteFrom((unsigned)dotPos); 138370b324cSopenharmony_ci return; 139370b324cSopenharmony_ci } 140370b324cSopenharmony_ci } 141370b324cSopenharmony_ci } 142370b324cSopenharmony_ci 143370b324cSopenharmony_ci BaseExtension.Empty(); 144370b324cSopenharmony_ci} 145370b324cSopenharmony_ci 146370b324cSopenharmony_ciUString CArchivePath::GetFinalPath() const 147370b324cSopenharmony_ci{ 148370b324cSopenharmony_ci UString path = GetPathWithoutExt(); 149370b324cSopenharmony_ci if (!BaseExtension.IsEmpty()) 150370b324cSopenharmony_ci { 151370b324cSopenharmony_ci path.Add_Dot(); 152370b324cSopenharmony_ci path += BaseExtension; 153370b324cSopenharmony_ci } 154370b324cSopenharmony_ci return path; 155370b324cSopenharmony_ci} 156370b324cSopenharmony_ci 157370b324cSopenharmony_ciUString CArchivePath::GetFinalVolPath() const 158370b324cSopenharmony_ci{ 159370b324cSopenharmony_ci UString path = GetPathWithoutExt(); 160370b324cSopenharmony_ci // if BaseExtension is empty, we must ignore VolExtension also. 161370b324cSopenharmony_ci if (!BaseExtension.IsEmpty()) 162370b324cSopenharmony_ci { 163370b324cSopenharmony_ci path.Add_Dot(); 164370b324cSopenharmony_ci path += VolExtension; 165370b324cSopenharmony_ci } 166370b324cSopenharmony_ci return path; 167370b324cSopenharmony_ci} 168370b324cSopenharmony_ci 169370b324cSopenharmony_ciFString CArchivePath::GetTempPath() const 170370b324cSopenharmony_ci{ 171370b324cSopenharmony_ci FString path = TempPrefix; 172370b324cSopenharmony_ci path += us2fs(Name); 173370b324cSopenharmony_ci if (!BaseExtension.IsEmpty()) 174370b324cSopenharmony_ci { 175370b324cSopenharmony_ci path.Add_Dot(); 176370b324cSopenharmony_ci path += us2fs(BaseExtension); 177370b324cSopenharmony_ci } 178370b324cSopenharmony_ci path += ".tmp"; 179370b324cSopenharmony_ci path += TempPostfix; 180370b324cSopenharmony_ci return path; 181370b324cSopenharmony_ci} 182370b324cSopenharmony_ci 183370b324cSopenharmony_cistatic const char * const kDefaultArcType = "7z"; 184370b324cSopenharmony_cistatic const char * const kDefaultArcExt = "7z"; 185370b324cSopenharmony_cistatic const char * const kSFXExtension = 186370b324cSopenharmony_ci #ifdef _WIN32 187370b324cSopenharmony_ci "exe"; 188370b324cSopenharmony_ci #else 189370b324cSopenharmony_ci ""; 190370b324cSopenharmony_ci #endif 191370b324cSopenharmony_ci 192370b324cSopenharmony_cibool CUpdateOptions::InitFormatIndex(const CCodecs *codecs, 193370b324cSopenharmony_ci const CObjectVector<COpenType> &types, const UString &arcPath) 194370b324cSopenharmony_ci{ 195370b324cSopenharmony_ci if (types.Size() > 1) 196370b324cSopenharmony_ci return false; 197370b324cSopenharmony_ci // int arcTypeIndex = -1; 198370b324cSopenharmony_ci if (types.Size() != 0) 199370b324cSopenharmony_ci { 200370b324cSopenharmony_ci MethodMode.Type = types[0]; 201370b324cSopenharmony_ci MethodMode.Type_Defined = true; 202370b324cSopenharmony_ci } 203370b324cSopenharmony_ci if (MethodMode.Type.FormatIndex < 0) 204370b324cSopenharmony_ci { 205370b324cSopenharmony_ci // MethodMode.Type = -1; 206370b324cSopenharmony_ci MethodMode.Type = COpenType(); 207370b324cSopenharmony_ci if (ArcNameMode != k_ArcNameMode_Add) 208370b324cSopenharmony_ci { 209370b324cSopenharmony_ci MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveName(arcPath); 210370b324cSopenharmony_ci if (MethodMode.Type.FormatIndex >= 0) 211370b324cSopenharmony_ci MethodMode.Type_Defined = true; 212370b324cSopenharmony_ci } 213370b324cSopenharmony_ci } 214370b324cSopenharmony_ci return true; 215370b324cSopenharmony_ci} 216370b324cSopenharmony_ci 217370b324cSopenharmony_cibool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath) 218370b324cSopenharmony_ci{ 219370b324cSopenharmony_ci UString typeExt; 220370b324cSopenharmony_ci int formatIndex = MethodMode.Type.FormatIndex; 221370b324cSopenharmony_ci if (formatIndex < 0) 222370b324cSopenharmony_ci { 223370b324cSopenharmony_ci typeExt = kDefaultArcExt; 224370b324cSopenharmony_ci } 225370b324cSopenharmony_ci else 226370b324cSopenharmony_ci { 227370b324cSopenharmony_ci const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex]; 228370b324cSopenharmony_ci if (!arcInfo.UpdateEnabled) 229370b324cSopenharmony_ci return false; 230370b324cSopenharmony_ci typeExt = arcInfo.GetMainExt(); 231370b324cSopenharmony_ci } 232370b324cSopenharmony_ci UString ext = typeExt; 233370b324cSopenharmony_ci if (SfxMode) 234370b324cSopenharmony_ci ext = kSFXExtension; 235370b324cSopenharmony_ci ArchivePath.BaseExtension = ext; 236370b324cSopenharmony_ci ArchivePath.VolExtension = typeExt; 237370b324cSopenharmony_ci ArchivePath.ParseFromPath(arcPath, ArcNameMode); 238370b324cSopenharmony_ci FOR_VECTOR (i, Commands) 239370b324cSopenharmony_ci { 240370b324cSopenharmony_ci CUpdateArchiveCommand &uc = Commands[i]; 241370b324cSopenharmony_ci uc.ArchivePath.BaseExtension = ext; 242370b324cSopenharmony_ci uc.ArchivePath.VolExtension = typeExt; 243370b324cSopenharmony_ci uc.ArchivePath.ParseFromPath(uc.UserArchivePath, ArcNameMode); 244370b324cSopenharmony_ci } 245370b324cSopenharmony_ci return true; 246370b324cSopenharmony_ci} 247370b324cSopenharmony_ci 248370b324cSopenharmony_ci 249370b324cSopenharmony_cistruct CUpdateProduceCallbackImp Z7_final: public IUpdateProduceCallback 250370b324cSopenharmony_ci{ 251370b324cSopenharmony_ci const CObjectVector<CArcItem> *_arcItems; 252370b324cSopenharmony_ci CDirItemsStat *_stat; 253370b324cSopenharmony_ci IUpdateCallbackUI *_callback; 254370b324cSopenharmony_ci 255370b324cSopenharmony_ci CUpdateProduceCallbackImp( 256370b324cSopenharmony_ci const CObjectVector<CArcItem> *a, 257370b324cSopenharmony_ci CDirItemsStat *stat, 258370b324cSopenharmony_ci IUpdateCallbackUI *callback): 259370b324cSopenharmony_ci _arcItems(a), 260370b324cSopenharmony_ci _stat(stat), 261370b324cSopenharmony_ci _callback(callback) {} 262370b324cSopenharmony_ci 263370b324cSopenharmony_ci virtual HRESULT ShowDeleteFile(unsigned arcIndex) Z7_override; 264370b324cSopenharmony_ci}; 265370b324cSopenharmony_ci 266370b324cSopenharmony_ci 267370b324cSopenharmony_ciHRESULT CUpdateProduceCallbackImp::ShowDeleteFile(unsigned arcIndex) 268370b324cSopenharmony_ci{ 269370b324cSopenharmony_ci const CArcItem &ai = (*_arcItems)[arcIndex]; 270370b324cSopenharmony_ci { 271370b324cSopenharmony_ci CDirItemsStat &stat = *_stat; 272370b324cSopenharmony_ci if (ai.IsDir) 273370b324cSopenharmony_ci stat.NumDirs++; 274370b324cSopenharmony_ci else if (ai.IsAltStream) 275370b324cSopenharmony_ci { 276370b324cSopenharmony_ci stat.NumAltStreams++; 277370b324cSopenharmony_ci stat.AltStreamsSize += ai.Size; 278370b324cSopenharmony_ci } 279370b324cSopenharmony_ci else 280370b324cSopenharmony_ci { 281370b324cSopenharmony_ci stat.NumFiles++; 282370b324cSopenharmony_ci stat.FilesSize += ai.Size; 283370b324cSopenharmony_ci } 284370b324cSopenharmony_ci } 285370b324cSopenharmony_ci return _callback->ShowDeleteFile(ai.Name, ai.IsDir); 286370b324cSopenharmony_ci} 287370b324cSopenharmony_ci 288370b324cSopenharmony_cibool CRenamePair::Prepare() 289370b324cSopenharmony_ci{ 290370b324cSopenharmony_ci if (RecursedType != NRecursedType::kNonRecursed) 291370b324cSopenharmony_ci return false; 292370b324cSopenharmony_ci if (!WildcardParsing) 293370b324cSopenharmony_ci return true; 294370b324cSopenharmony_ci return !DoesNameContainWildcard(OldName); 295370b324cSopenharmony_ci} 296370b324cSopenharmony_ci 297370b324cSopenharmony_ciextern bool g_CaseSensitive; 298370b324cSopenharmony_ci 299370b324cSopenharmony_cistatic unsigned CompareTwoNames(const wchar_t *s1, const wchar_t *s2) 300370b324cSopenharmony_ci{ 301370b324cSopenharmony_ci for (unsigned i = 0;; i++) 302370b324cSopenharmony_ci { 303370b324cSopenharmony_ci wchar_t c1 = s1[i]; 304370b324cSopenharmony_ci wchar_t c2 = s2[i]; 305370b324cSopenharmony_ci if (c1 == 0 || c2 == 0) 306370b324cSopenharmony_ci return i; 307370b324cSopenharmony_ci if (c1 == c2) 308370b324cSopenharmony_ci continue; 309370b324cSopenharmony_ci if (!g_CaseSensitive && (MyCharUpper(c1) == MyCharUpper(c2))) 310370b324cSopenharmony_ci continue; 311370b324cSopenharmony_ci if (IsPathSepar(c1) && IsPathSepar(c2)) 312370b324cSopenharmony_ci continue; 313370b324cSopenharmony_ci return i; 314370b324cSopenharmony_ci } 315370b324cSopenharmony_ci} 316370b324cSopenharmony_ci 317370b324cSopenharmony_cibool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) const 318370b324cSopenharmony_ci{ 319370b324cSopenharmony_ci unsigned num = CompareTwoNames(OldName, src); 320370b324cSopenharmony_ci if (OldName[num] == 0) 321370b324cSopenharmony_ci { 322370b324cSopenharmony_ci if (src[num] != 0 && !IsPathSepar(src[num]) && num != 0 && !IsPathSepar(src[num - 1])) 323370b324cSopenharmony_ci return false; 324370b324cSopenharmony_ci } 325370b324cSopenharmony_ci else 326370b324cSopenharmony_ci { 327370b324cSopenharmony_ci // OldName[num] != 0 328370b324cSopenharmony_ci // OldName = "1\1a.txt" 329370b324cSopenharmony_ci // src = "1" 330370b324cSopenharmony_ci 331370b324cSopenharmony_ci if (!isFolder 332370b324cSopenharmony_ci || src[num] != 0 333370b324cSopenharmony_ci || !IsPathSepar(OldName[num]) 334370b324cSopenharmony_ci || OldName[num + 1] != 0) 335370b324cSopenharmony_ci return false; 336370b324cSopenharmony_ci } 337370b324cSopenharmony_ci dest = NewName + src.Ptr(num); 338370b324cSopenharmony_ci return true; 339370b324cSopenharmony_ci} 340370b324cSopenharmony_ci 341370b324cSopenharmony_ci#ifdef SUPPORT_ALT_STREAMS 342370b324cSopenharmony_ciint FindAltStreamColon_in_Path(const wchar_t *path); 343370b324cSopenharmony_ci#endif 344370b324cSopenharmony_ci 345370b324cSopenharmony_ci 346370b324cSopenharmony_ci 347370b324cSopenharmony_cistatic HRESULT Compress( 348370b324cSopenharmony_ci const CUpdateOptions &options, 349370b324cSopenharmony_ci bool isUpdatingItself, 350370b324cSopenharmony_ci CCodecs *codecs, 351370b324cSopenharmony_ci const CActionSet &actionSet, 352370b324cSopenharmony_ci const CArc *arc, 353370b324cSopenharmony_ci CArchivePath &archivePath, 354370b324cSopenharmony_ci const CObjectVector<CArcItem> &arcItems, 355370b324cSopenharmony_ci Byte *processedItemsStatuses, 356370b324cSopenharmony_ci const CDirItems &dirItems, 357370b324cSopenharmony_ci const CDirItem *parentDirItem, 358370b324cSopenharmony_ci CTempFiles &tempFiles, 359370b324cSopenharmony_ci CMultiOutStream_Bunch &multiStreams, 360370b324cSopenharmony_ci CUpdateErrorInfo &errorInfo, 361370b324cSopenharmony_ci IUpdateCallbackUI *callback, 362370b324cSopenharmony_ci CFinishArchiveStat &st) 363370b324cSopenharmony_ci{ 364370b324cSopenharmony_ci CMyComPtr<IOutArchive> outArchive; 365370b324cSopenharmony_ci int formatIndex = options.MethodMode.Type.FormatIndex; 366370b324cSopenharmony_ci 367370b324cSopenharmony_ci if (arc) 368370b324cSopenharmony_ci { 369370b324cSopenharmony_ci formatIndex = arc->FormatIndex; 370370b324cSopenharmony_ci if (formatIndex < 0) 371370b324cSopenharmony_ci return E_NOTIMPL; 372370b324cSopenharmony_ci CMyComPtr<IInArchive> archive2 = arc->Archive; 373370b324cSopenharmony_ci HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); 374370b324cSopenharmony_ci if (result != S_OK) 375370b324cSopenharmony_ci throw kUpdateIsNotSupoorted; 376370b324cSopenharmony_ci } 377370b324cSopenharmony_ci else 378370b324cSopenharmony_ci { 379370b324cSopenharmony_ci RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)) 380370b324cSopenharmony_ci 381370b324cSopenharmony_ci #ifdef Z7_EXTERNAL_CODECS 382370b324cSopenharmony_ci { 383370b324cSopenharmony_ci CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; 384370b324cSopenharmony_ci outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); 385370b324cSopenharmony_ci if (setCompressCodecsInfo) 386370b324cSopenharmony_ci { 387370b324cSopenharmony_ci RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)) 388370b324cSopenharmony_ci } 389370b324cSopenharmony_ci } 390370b324cSopenharmony_ci #endif 391370b324cSopenharmony_ci } 392370b324cSopenharmony_ci 393370b324cSopenharmony_ci if (!outArchive) 394370b324cSopenharmony_ci throw kUpdateIsNotSupoorted; 395370b324cSopenharmony_ci 396370b324cSopenharmony_ci // we need to set properties to get fileTimeType. 397370b324cSopenharmony_ci RINOK(SetProperties(outArchive, options.MethodMode.Properties)) 398370b324cSopenharmony_ci 399370b324cSopenharmony_ci NFileTimeType::EEnum fileTimeType; 400370b324cSopenharmony_ci { 401370b324cSopenharmony_ci /* 402370b324cSopenharmony_ci how we compare file_in_archive::MTime with dirItem.MTime 403370b324cSopenharmony_ci for GetUpdatePairInfoList(): 404370b324cSopenharmony_ci 405370b324cSopenharmony_ci if (kpidMTime is not defined), external MTime of archive is used. 406370b324cSopenharmony_ci 407370b324cSopenharmony_ci before 22.00: 408370b324cSopenharmony_ci if (kpidTimeType is defined) 409370b324cSopenharmony_ci { 410370b324cSopenharmony_ci kpidTimeType is used as precision. 411370b324cSopenharmony_ci (kpidTimeType > kDOS) is not allowed. 412370b324cSopenharmony_ci } 413370b324cSopenharmony_ci else GetFileTimeType() value is used as precision. 414370b324cSopenharmony_ci 415370b324cSopenharmony_ci 22.00: 416370b324cSopenharmony_ci if (kpidMTime is defined) 417370b324cSopenharmony_ci { 418370b324cSopenharmony_ci if (kpidMTime::precision != 0), then kpidMTime::precision is used as precision. 419370b324cSopenharmony_ci else 420370b324cSopenharmony_ci { 421370b324cSopenharmony_ci if (kpidTimeType is defined), kpidTimeType is used as precision. 422370b324cSopenharmony_ci else GetFileTimeType() value is used as precision. 423370b324cSopenharmony_ci } 424370b324cSopenharmony_ci } 425370b324cSopenharmony_ci else external MTime of archive is used as precision. 426370b324cSopenharmony_ci */ 427370b324cSopenharmony_ci 428370b324cSopenharmony_ci UInt32 value; 429370b324cSopenharmony_ci RINOK(outArchive->GetFileTimeType(&value)) 430370b324cSopenharmony_ci 431370b324cSopenharmony_ci // we support any future fileType here. 432370b324cSopenharmony_ci fileTimeType = (NFileTimeType::EEnum)value; 433370b324cSopenharmony_ci 434370b324cSopenharmony_ci /* 435370b324cSopenharmony_ci old 21.07 code: 436370b324cSopenharmony_ci switch (value) 437370b324cSopenharmony_ci { 438370b324cSopenharmony_ci case NFileTimeType::kWindows: 439370b324cSopenharmony_ci case NFileTimeType::kUnix: 440370b324cSopenharmony_ci case NFileTimeType::kDOS: 441370b324cSopenharmony_ci fileTimeType = (NFileTimeType::EEnum)value; 442370b324cSopenharmony_ci break; 443370b324cSopenharmony_ci default: 444370b324cSopenharmony_ci return E_FAIL; 445370b324cSopenharmony_ci } 446370b324cSopenharmony_ci */ 447370b324cSopenharmony_ci } 448370b324cSopenharmony_ci 449370b324cSopenharmony_ci // bool noTimestampExpected = false; 450370b324cSopenharmony_ci { 451370b324cSopenharmony_ci const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex]; 452370b324cSopenharmony_ci 453370b324cSopenharmony_ci // if (arcInfo.Flags_KeepName()) noTimestampExpected = true; 454370b324cSopenharmony_ci if (arcInfo.Is_Xz() || 455370b324cSopenharmony_ci arcInfo.Is_BZip2()) 456370b324cSopenharmony_ci { 457370b324cSopenharmony_ci /* 7-zip before 22.00 returns NFileTimeType::kUnix for xz and bzip2, 458370b324cSopenharmony_ci but we want to set timestamp without reduction to unix. */ 459370b324cSopenharmony_ci // noTimestampExpected = true; 460370b324cSopenharmony_ci fileTimeType = NFileTimeType::kNotDefined; // it means not defined 461370b324cSopenharmony_ci } 462370b324cSopenharmony_ci 463370b324cSopenharmony_ci if (options.AltStreams.Val && !arcInfo.Flags_AltStreams()) 464370b324cSopenharmony_ci return E_NOTIMPL; 465370b324cSopenharmony_ci if (options.NtSecurity.Val && !arcInfo.Flags_NtSecurity()) 466370b324cSopenharmony_ci return E_NOTIMPL; 467370b324cSopenharmony_ci if (options.DeleteAfterCompressing && arcInfo.Flags_HashHandler()) 468370b324cSopenharmony_ci return E_NOTIMPL; 469370b324cSopenharmony_ci } 470370b324cSopenharmony_ci 471370b324cSopenharmony_ci CRecordVector<CUpdatePair2> updatePairs2; 472370b324cSopenharmony_ci 473370b324cSopenharmony_ci UStringVector newNames; 474370b324cSopenharmony_ci 475370b324cSopenharmony_ci CArcToDoStat stat2; 476370b324cSopenharmony_ci 477370b324cSopenharmony_ci if (options.RenamePairs.Size() != 0) 478370b324cSopenharmony_ci { 479370b324cSopenharmony_ci FOR_VECTOR (i, arcItems) 480370b324cSopenharmony_ci { 481370b324cSopenharmony_ci const CArcItem &ai = arcItems[i]; 482370b324cSopenharmony_ci bool needRename = false; 483370b324cSopenharmony_ci UString dest; 484370b324cSopenharmony_ci 485370b324cSopenharmony_ci if (ai.Censored) 486370b324cSopenharmony_ci { 487370b324cSopenharmony_ci FOR_VECTOR (j, options.RenamePairs) 488370b324cSopenharmony_ci { 489370b324cSopenharmony_ci const CRenamePair &rp = options.RenamePairs[j]; 490370b324cSopenharmony_ci if (rp.GetNewPath(ai.IsDir, ai.Name, dest)) 491370b324cSopenharmony_ci { 492370b324cSopenharmony_ci needRename = true; 493370b324cSopenharmony_ci break; 494370b324cSopenharmony_ci } 495370b324cSopenharmony_ci 496370b324cSopenharmony_ci #ifdef SUPPORT_ALT_STREAMS 497370b324cSopenharmony_ci if (ai.IsAltStream) 498370b324cSopenharmony_ci { 499370b324cSopenharmony_ci int colonPos = FindAltStreamColon_in_Path(ai.Name); 500370b324cSopenharmony_ci if (colonPos >= 0) 501370b324cSopenharmony_ci { 502370b324cSopenharmony_ci UString mainName = ai.Name.Left((unsigned)colonPos); 503370b324cSopenharmony_ci /* 504370b324cSopenharmony_ci actually we must improve that code to support cases 505370b324cSopenharmony_ci with folder renaming like: rn arc dir1\ dir2\ 506370b324cSopenharmony_ci */ 507370b324cSopenharmony_ci if (rp.GetNewPath(false, mainName, dest)) 508370b324cSopenharmony_ci { 509370b324cSopenharmony_ci needRename = true; 510370b324cSopenharmony_ci dest += ':'; 511370b324cSopenharmony_ci dest += ai.Name.Ptr((unsigned)(colonPos + 1)); 512370b324cSopenharmony_ci break; 513370b324cSopenharmony_ci } 514370b324cSopenharmony_ci } 515370b324cSopenharmony_ci } 516370b324cSopenharmony_ci #endif 517370b324cSopenharmony_ci } 518370b324cSopenharmony_ci } 519370b324cSopenharmony_ci 520370b324cSopenharmony_ci CUpdatePair2 up2; 521370b324cSopenharmony_ci up2.SetAs_NoChangeArcItem(ai.IndexInServer); 522370b324cSopenharmony_ci if (needRename) 523370b324cSopenharmony_ci { 524370b324cSopenharmony_ci up2.NewProps = true; 525370b324cSopenharmony_ci RINOK(arc->IsItem_Anti(i, up2.IsAnti)) 526370b324cSopenharmony_ci up2.NewNameIndex = (int)newNames.Add(dest); 527370b324cSopenharmony_ci } 528370b324cSopenharmony_ci updatePairs2.Add(up2); 529370b324cSopenharmony_ci } 530370b324cSopenharmony_ci } 531370b324cSopenharmony_ci else 532370b324cSopenharmony_ci { 533370b324cSopenharmony_ci CRecordVector<CUpdatePair> updatePairs; 534370b324cSopenharmony_ci GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!! 535370b324cSopenharmony_ci CUpdateProduceCallbackImp upCallback(&arcItems, &stat2.DeleteData, callback); 536370b324cSopenharmony_ci 537370b324cSopenharmony_ci UpdateProduce(updatePairs, actionSet, updatePairs2, isUpdatingItself ? &upCallback : NULL); 538370b324cSopenharmony_ci } 539370b324cSopenharmony_ci 540370b324cSopenharmony_ci { 541370b324cSopenharmony_ci FOR_VECTOR (i, updatePairs2) 542370b324cSopenharmony_ci { 543370b324cSopenharmony_ci const CUpdatePair2 &up = updatePairs2[i]; 544370b324cSopenharmony_ci 545370b324cSopenharmony_ci // 17.01: anti-item is (up.NewData && (p.UseArcProps in most cases)) 546370b324cSopenharmony_ci 547370b324cSopenharmony_ci if (up.NewData && !up.UseArcProps) 548370b324cSopenharmony_ci { 549370b324cSopenharmony_ci if (up.ExistOnDisk()) 550370b324cSopenharmony_ci { 551370b324cSopenharmony_ci CDirItemsStat2 &stat = stat2.NewData; 552370b324cSopenharmony_ci const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex]; 553370b324cSopenharmony_ci if (di.IsDir()) 554370b324cSopenharmony_ci { 555370b324cSopenharmony_ci if (up.IsAnti) 556370b324cSopenharmony_ci stat.Anti_NumDirs++; 557370b324cSopenharmony_ci else 558370b324cSopenharmony_ci stat.NumDirs++; 559370b324cSopenharmony_ci } 560370b324cSopenharmony_ci #ifdef _WIN32 561370b324cSopenharmony_ci else if (di.IsAltStream) 562370b324cSopenharmony_ci { 563370b324cSopenharmony_ci if (up.IsAnti) 564370b324cSopenharmony_ci stat.Anti_NumAltStreams++; 565370b324cSopenharmony_ci else 566370b324cSopenharmony_ci { 567370b324cSopenharmony_ci stat.NumAltStreams++; 568370b324cSopenharmony_ci stat.AltStreamsSize += di.Size; 569370b324cSopenharmony_ci } 570370b324cSopenharmony_ci } 571370b324cSopenharmony_ci #endif 572370b324cSopenharmony_ci else 573370b324cSopenharmony_ci { 574370b324cSopenharmony_ci if (up.IsAnti) 575370b324cSopenharmony_ci stat.Anti_NumFiles++; 576370b324cSopenharmony_ci else 577370b324cSopenharmony_ci { 578370b324cSopenharmony_ci stat.NumFiles++; 579370b324cSopenharmony_ci stat.FilesSize += di.Size; 580370b324cSopenharmony_ci } 581370b324cSopenharmony_ci } 582370b324cSopenharmony_ci } 583370b324cSopenharmony_ci } 584370b324cSopenharmony_ci else if (up.ArcIndex >= 0) 585370b324cSopenharmony_ci { 586370b324cSopenharmony_ci CDirItemsStat2 &stat = *(up.NewData ? &stat2.NewData : &stat2.OldData); 587370b324cSopenharmony_ci const CArcItem &ai = arcItems[(unsigned)up.ArcIndex]; 588370b324cSopenharmony_ci if (ai.IsDir) 589370b324cSopenharmony_ci { 590370b324cSopenharmony_ci if (up.IsAnti) 591370b324cSopenharmony_ci stat.Anti_NumDirs++; 592370b324cSopenharmony_ci else 593370b324cSopenharmony_ci stat.NumDirs++; 594370b324cSopenharmony_ci } 595370b324cSopenharmony_ci else if (ai.IsAltStream) 596370b324cSopenharmony_ci { 597370b324cSopenharmony_ci if (up.IsAnti) 598370b324cSopenharmony_ci stat.Anti_NumAltStreams++; 599370b324cSopenharmony_ci else 600370b324cSopenharmony_ci { 601370b324cSopenharmony_ci stat.NumAltStreams++; 602370b324cSopenharmony_ci stat.AltStreamsSize += ai.Size; 603370b324cSopenharmony_ci } 604370b324cSopenharmony_ci } 605370b324cSopenharmony_ci else 606370b324cSopenharmony_ci { 607370b324cSopenharmony_ci if (up.IsAnti) 608370b324cSopenharmony_ci stat.Anti_NumFiles++; 609370b324cSopenharmony_ci else 610370b324cSopenharmony_ci { 611370b324cSopenharmony_ci stat.NumFiles++; 612370b324cSopenharmony_ci stat.FilesSize += ai.Size; 613370b324cSopenharmony_ci } 614370b324cSopenharmony_ci } 615370b324cSopenharmony_ci } 616370b324cSopenharmony_ci } 617370b324cSopenharmony_ci RINOK(callback->SetNumItems(stat2)) 618370b324cSopenharmony_ci } 619370b324cSopenharmony_ci 620370b324cSopenharmony_ci CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; 621370b324cSopenharmony_ci CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); 622370b324cSopenharmony_ci 623370b324cSopenharmony_ci updateCallbackSpec->PreserveATime = options.PreserveATime; 624370b324cSopenharmony_ci updateCallbackSpec->ShareForWrite = options.OpenShareForWrite; 625370b324cSopenharmony_ci updateCallbackSpec->StopAfterOpenError = options.StopAfterOpenError; 626370b324cSopenharmony_ci updateCallbackSpec->StdInMode = options.StdInMode; 627370b324cSopenharmony_ci updateCallbackSpec->Callback = callback; 628370b324cSopenharmony_ci 629370b324cSopenharmony_ci if (arc) 630370b324cSopenharmony_ci { 631370b324cSopenharmony_ci // we set Archive to allow to transfer GetProperty requests back to DLL. 632370b324cSopenharmony_ci updateCallbackSpec->Archive = arc->Archive; 633370b324cSopenharmony_ci } 634370b324cSopenharmony_ci 635370b324cSopenharmony_ci updateCallbackSpec->DirItems = &dirItems; 636370b324cSopenharmony_ci updateCallbackSpec->ParentDirItem = parentDirItem; 637370b324cSopenharmony_ci 638370b324cSopenharmony_ci updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val; 639370b324cSopenharmony_ci updateCallbackSpec->StoreHardLinks = options.HardLinks.Val; 640370b324cSopenharmony_ci updateCallbackSpec->StoreSymLinks = options.SymLinks.Val; 641370b324cSopenharmony_ci updateCallbackSpec->StoreOwnerName = options.StoreOwnerName.Val; 642370b324cSopenharmony_ci updateCallbackSpec->StoreOwnerId = options.StoreOwnerId.Val; 643370b324cSopenharmony_ci 644370b324cSopenharmony_ci updateCallbackSpec->Arc = arc; 645370b324cSopenharmony_ci updateCallbackSpec->ArcItems = &arcItems; 646370b324cSopenharmony_ci updateCallbackSpec->UpdatePairs = &updatePairs2; 647370b324cSopenharmony_ci 648370b324cSopenharmony_ci updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses; 649370b324cSopenharmony_ci 650370b324cSopenharmony_ci { 651370b324cSopenharmony_ci const UString arcPath = archivePath.GetFinalPath(); 652370b324cSopenharmony_ci updateCallbackSpec->ArcFileName = ExtractFileNameFromPath(arcPath); 653370b324cSopenharmony_ci } 654370b324cSopenharmony_ci 655370b324cSopenharmony_ci if (options.RenamePairs.Size() != 0) 656370b324cSopenharmony_ci updateCallbackSpec->NewNames = &newNames; 657370b324cSopenharmony_ci 658370b324cSopenharmony_ci if (options.SetArcMTime) 659370b324cSopenharmony_ci { 660370b324cSopenharmony_ci // updateCallbackSpec->Need_ArcMTime_Report = true; 661370b324cSopenharmony_ci updateCallbackSpec->Need_LatestMTime = true; 662370b324cSopenharmony_ci } 663370b324cSopenharmony_ci 664370b324cSopenharmony_ci CMyComPtr<IOutStream> outSeekStream; 665370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> outStream; 666370b324cSopenharmony_ci 667370b324cSopenharmony_ci if (!options.StdOutMode) 668370b324cSopenharmony_ci { 669370b324cSopenharmony_ci FString dirPrefix; 670370b324cSopenharmony_ci if (!GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix)) 671370b324cSopenharmony_ci throw 1417161; 672370b324cSopenharmony_ci CreateComplexDir(dirPrefix); 673370b324cSopenharmony_ci } 674370b324cSopenharmony_ci 675370b324cSopenharmony_ci COutFileStream *outStreamSpec = NULL; 676370b324cSopenharmony_ci CStdOutFileStream *stdOutFileStreamSpec = NULL; 677370b324cSopenharmony_ci CMultiOutStream *volStreamSpec = NULL; 678370b324cSopenharmony_ci 679370b324cSopenharmony_ci if (options.VolumesSizes.Size() == 0) 680370b324cSopenharmony_ci { 681370b324cSopenharmony_ci if (options.StdOutMode) 682370b324cSopenharmony_ci { 683370b324cSopenharmony_ci stdOutFileStreamSpec = new CStdOutFileStream; 684370b324cSopenharmony_ci outStream = stdOutFileStreamSpec; 685370b324cSopenharmony_ci } 686370b324cSopenharmony_ci else 687370b324cSopenharmony_ci { 688370b324cSopenharmony_ci outStreamSpec = new COutFileStream; 689370b324cSopenharmony_ci outSeekStream = outStreamSpec; 690370b324cSopenharmony_ci outStream = outSeekStream; 691370b324cSopenharmony_ci bool isOK = false; 692370b324cSopenharmony_ci FString realPath; 693370b324cSopenharmony_ci 694370b324cSopenharmony_ci for (unsigned i = 0; i < (1 << 16); i++) 695370b324cSopenharmony_ci { 696370b324cSopenharmony_ci if (archivePath.Temp) 697370b324cSopenharmony_ci { 698370b324cSopenharmony_ci if (i > 0) 699370b324cSopenharmony_ci { 700370b324cSopenharmony_ci archivePath.TempPostfix.Empty(); 701370b324cSopenharmony_ci archivePath.TempPostfix.Add_UInt32(i); 702370b324cSopenharmony_ci } 703370b324cSopenharmony_ci realPath = archivePath.GetTempPath(); 704370b324cSopenharmony_ci } 705370b324cSopenharmony_ci else 706370b324cSopenharmony_ci realPath = us2fs(archivePath.GetFinalPath()); 707370b324cSopenharmony_ci if (outStreamSpec->Create(realPath, false)) 708370b324cSopenharmony_ci { 709370b324cSopenharmony_ci tempFiles.Paths.Add(realPath); 710370b324cSopenharmony_ci isOK = true; 711370b324cSopenharmony_ci break; 712370b324cSopenharmony_ci } 713370b324cSopenharmony_ci if (::GetLastError() != ERROR_FILE_EXISTS) 714370b324cSopenharmony_ci break; 715370b324cSopenharmony_ci if (!archivePath.Temp) 716370b324cSopenharmony_ci break; 717370b324cSopenharmony_ci } 718370b324cSopenharmony_ci 719370b324cSopenharmony_ci if (!isOK) 720370b324cSopenharmony_ci return errorInfo.SetFromLastError("cannot open file", realPath); 721370b324cSopenharmony_ci } 722370b324cSopenharmony_ci } 723370b324cSopenharmony_ci else 724370b324cSopenharmony_ci { 725370b324cSopenharmony_ci if (options.StdOutMode) 726370b324cSopenharmony_ci return E_FAIL; 727370b324cSopenharmony_ci if (arc && arc->GetGlobalOffset() > 0) 728370b324cSopenharmony_ci return E_NOTIMPL; 729370b324cSopenharmony_ci 730370b324cSopenharmony_ci volStreamSpec = new CMultiOutStream(); 731370b324cSopenharmony_ci outSeekStream = volStreamSpec; 732370b324cSopenharmony_ci outStream = outSeekStream; 733370b324cSopenharmony_ci volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath()); 734370b324cSopenharmony_ci volStreamSpec->Prefix.Add_Dot(); 735370b324cSopenharmony_ci volStreamSpec->Init(options.VolumesSizes); 736370b324cSopenharmony_ci { 737370b324cSopenharmony_ci CMultiOutStream_Rec &rec = multiStreams.Items.AddNew(); 738370b324cSopenharmony_ci rec.Spec = volStreamSpec; 739370b324cSopenharmony_ci rec.Ref = rec.Spec; 740370b324cSopenharmony_ci } 741370b324cSopenharmony_ci 742370b324cSopenharmony_ci /* 743370b324cSopenharmony_ci updateCallbackSpec->VolumesSizes = volumesSizes; 744370b324cSopenharmony_ci updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; 745370b324cSopenharmony_ci if (!archivePath.VolExtension.IsEmpty()) 746370b324cSopenharmony_ci updateCallbackSpec->VolExt = UString('.') + archivePath.VolExtension; 747370b324cSopenharmony_ci */ 748370b324cSopenharmony_ci } 749370b324cSopenharmony_ci 750370b324cSopenharmony_ci if (options.SfxMode) 751370b324cSopenharmony_ci { 752370b324cSopenharmony_ci CInFileStream *sfxStreamSpec = new CInFileStream; 753370b324cSopenharmony_ci CMyComPtr<IInStream> sfxStream(sfxStreamSpec); 754370b324cSopenharmony_ci if (!sfxStreamSpec->Open(options.SfxModule)) 755370b324cSopenharmony_ci return errorInfo.SetFromLastError("cannot open SFX module", options.SfxModule); 756370b324cSopenharmony_ci 757370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> sfxOutStream; 758370b324cSopenharmony_ci COutFileStream *outStreamSpec2 = NULL; 759370b324cSopenharmony_ci if (options.VolumesSizes.Size() == 0) 760370b324cSopenharmony_ci sfxOutStream = outStream; 761370b324cSopenharmony_ci else 762370b324cSopenharmony_ci { 763370b324cSopenharmony_ci outStreamSpec2 = new COutFileStream; 764370b324cSopenharmony_ci sfxOutStream = outStreamSpec2; 765370b324cSopenharmony_ci const FString realPath = us2fs(archivePath.GetFinalPath()); 766370b324cSopenharmony_ci if (!outStreamSpec2->Create(realPath, false)) 767370b324cSopenharmony_ci return errorInfo.SetFromLastError("cannot open file", realPath); 768370b324cSopenharmony_ci } 769370b324cSopenharmony_ci 770370b324cSopenharmony_ci { 771370b324cSopenharmony_ci UInt64 sfxSize; 772370b324cSopenharmony_ci RINOK(sfxStreamSpec->GetSize(&sfxSize)) 773370b324cSopenharmony_ci RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)) 774370b324cSopenharmony_ci } 775370b324cSopenharmony_ci 776370b324cSopenharmony_ci RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)) 777370b324cSopenharmony_ci 778370b324cSopenharmony_ci if (outStreamSpec2) 779370b324cSopenharmony_ci { 780370b324cSopenharmony_ci RINOK(outStreamSpec2->Close()) 781370b324cSopenharmony_ci } 782370b324cSopenharmony_ci } 783370b324cSopenharmony_ci 784370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> tailStream; 785370b324cSopenharmony_ci 786370b324cSopenharmony_ci if (options.SfxMode || !arc || arc->ArcStreamOffset == 0) 787370b324cSopenharmony_ci tailStream = outStream; 788370b324cSopenharmony_ci else 789370b324cSopenharmony_ci { 790370b324cSopenharmony_ci // Int64 globalOffset = arc->GetGlobalOffset(); 791370b324cSopenharmony_ci RINOK(InStream_SeekToBegin(arc->InStream)) 792370b324cSopenharmony_ci RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)) 793370b324cSopenharmony_ci if (options.StdOutMode) 794370b324cSopenharmony_ci tailStream = outStream; 795370b324cSopenharmony_ci else 796370b324cSopenharmony_ci { 797370b324cSopenharmony_ci CTailOutStream *tailStreamSpec = new CTailOutStream; 798370b324cSopenharmony_ci tailStream = tailStreamSpec; 799370b324cSopenharmony_ci tailStreamSpec->Stream = outSeekStream; 800370b324cSopenharmony_ci tailStreamSpec->Offset = arc->ArcStreamOffset; 801370b324cSopenharmony_ci tailStreamSpec->Init(); 802370b324cSopenharmony_ci } 803370b324cSopenharmony_ci } 804370b324cSopenharmony_ci 805370b324cSopenharmony_ci CFiTime ft; 806370b324cSopenharmony_ci FiTime_Clear(ft); 807370b324cSopenharmony_ci bool ft_Defined = false; 808370b324cSopenharmony_ci { 809370b324cSopenharmony_ci FOR_VECTOR (i, updatePairs2) 810370b324cSopenharmony_ci { 811370b324cSopenharmony_ci const CUpdatePair2 &pair2 = updatePairs2[i]; 812370b324cSopenharmony_ci CFiTime ft2; 813370b324cSopenharmony_ci FiTime_Clear(ft2); 814370b324cSopenharmony_ci bool ft2_Defined = false; 815370b324cSopenharmony_ci /* we use full precision of dirItem, if dirItem is defined 816370b324cSopenharmony_ci and (dirItem will be used or dirItem is sameTime in dir and arc */ 817370b324cSopenharmony_ci if (pair2.DirIndex >= 0 && 818370b324cSopenharmony_ci (pair2.NewProps || pair2.IsSameTime)) 819370b324cSopenharmony_ci { 820370b324cSopenharmony_ci ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime; 821370b324cSopenharmony_ci ft2_Defined = true; 822370b324cSopenharmony_ci } 823370b324cSopenharmony_ci else if (pair2.UseArcProps && pair2.ArcIndex >= 0) 824370b324cSopenharmony_ci { 825370b324cSopenharmony_ci const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex]; 826370b324cSopenharmony_ci if (arcItem.MTime.Def) 827370b324cSopenharmony_ci { 828370b324cSopenharmony_ci arcItem.MTime.Write_To_FiTime(ft2); 829370b324cSopenharmony_ci ft2_Defined = true; 830370b324cSopenharmony_ci } 831370b324cSopenharmony_ci } 832370b324cSopenharmony_ci if (ft2_Defined) 833370b324cSopenharmony_ci { 834370b324cSopenharmony_ci if (!ft_Defined || Compare_FiTime(&ft, &ft2) < 0) 835370b324cSopenharmony_ci { 836370b324cSopenharmony_ci ft = ft2; 837370b324cSopenharmony_ci ft_Defined = true; 838370b324cSopenharmony_ci } 839370b324cSopenharmony_ci } 840370b324cSopenharmony_ci } 841370b324cSopenharmony_ci /* 842370b324cSopenharmony_ci if (fileTimeType != NFileTimeType::kNotDefined) 843370b324cSopenharmony_ci FiTime_Normalize_With_Prec(ft, fileTimeType); 844370b324cSopenharmony_ci */ 845370b324cSopenharmony_ci } 846370b324cSopenharmony_ci 847370b324cSopenharmony_ci if (volStreamSpec && options.SetArcMTime && ft_Defined) 848370b324cSopenharmony_ci { 849370b324cSopenharmony_ci volStreamSpec->MTime = ft; 850370b324cSopenharmony_ci volStreamSpec->MTime_Defined = true; 851370b324cSopenharmony_ci } 852370b324cSopenharmony_ci 853370b324cSopenharmony_ci HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback); 854370b324cSopenharmony_ci // callback->Finalize(); 855370b324cSopenharmony_ci RINOK(result) 856370b324cSopenharmony_ci 857370b324cSopenharmony_ci if (!updateCallbackSpec->AreAllFilesClosed()) 858370b324cSopenharmony_ci { 859370b324cSopenharmony_ci errorInfo.Message = "There are unclosed input file:"; 860370b324cSopenharmony_ci errorInfo.FileNames = updateCallbackSpec->_openFiles_Paths; 861370b324cSopenharmony_ci return E_FAIL; 862370b324cSopenharmony_ci } 863370b324cSopenharmony_ci 864370b324cSopenharmony_ci if (options.SetArcMTime) 865370b324cSopenharmony_ci { 866370b324cSopenharmony_ci // bool needNormalizeAfterStream; 867370b324cSopenharmony_ci // needParse; 868370b324cSopenharmony_ci /* 869370b324cSopenharmony_ci if (updateCallbackSpec->ArcMTime_WasReported) 870370b324cSopenharmony_ci { 871370b324cSopenharmony_ci isDefined = updateCallbackSpec->Reported_ArcMTime.Def; 872370b324cSopenharmony_ci if (isDefined) 873370b324cSopenharmony_ci updateCallbackSpec->Reported_ArcMTime.Write_To_FiTime(ft); 874370b324cSopenharmony_ci else 875370b324cSopenharmony_ci fileTimeType = NFileTimeType::kNotDefined; 876370b324cSopenharmony_ci } 877370b324cSopenharmony_ci if (!isDefined) 878370b324cSopenharmony_ci */ 879370b324cSopenharmony_ci { 880370b324cSopenharmony_ci if (updateCallbackSpec->LatestMTime_Defined) 881370b324cSopenharmony_ci { 882370b324cSopenharmony_ci // CArcTime at = StreamCallback_ArcMTime; 883370b324cSopenharmony_ci // updateCallbackSpec->StreamCallback_ArcMTime.Write_To_FiTime(ft); 884370b324cSopenharmony_ci // we must normalize with precision from archive; 885370b324cSopenharmony_ci if (!ft_Defined || Compare_FiTime(&ft, &updateCallbackSpec->LatestMTime) < 0) 886370b324cSopenharmony_ci ft = updateCallbackSpec->LatestMTime; 887370b324cSopenharmony_ci ft_Defined = true; 888370b324cSopenharmony_ci } 889370b324cSopenharmony_ci /* 890370b324cSopenharmony_ci if (fileTimeType != NFileTimeType::kNotDefined) 891370b324cSopenharmony_ci FiTime_Normalize_With_Prec(ft, fileTimeType); 892370b324cSopenharmony_ci */ 893370b324cSopenharmony_ci } 894370b324cSopenharmony_ci // if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) 895370b324cSopenharmony_ci if (ft_Defined) 896370b324cSopenharmony_ci { 897370b324cSopenharmony_ci // we ignore set time errors here. 898370b324cSopenharmony_ci // note that user could move some finished volumes to another folder. 899370b324cSopenharmony_ci if (outStreamSpec) 900370b324cSopenharmony_ci outStreamSpec->SetMTime(&ft); 901370b324cSopenharmony_ci else if (volStreamSpec) 902370b324cSopenharmony_ci volStreamSpec->SetMTime_Final(ft); 903370b324cSopenharmony_ci } 904370b324cSopenharmony_ci } 905370b324cSopenharmony_ci 906370b324cSopenharmony_ci if (callback) 907370b324cSopenharmony_ci { 908370b324cSopenharmony_ci UInt64 size = 0; 909370b324cSopenharmony_ci if (outStreamSpec) 910370b324cSopenharmony_ci outStreamSpec->GetSize(&size); 911370b324cSopenharmony_ci else if (stdOutFileStreamSpec) 912370b324cSopenharmony_ci size = stdOutFileStreamSpec->GetSize(); 913370b324cSopenharmony_ci else 914370b324cSopenharmony_ci size = volStreamSpec->GetSize(); 915370b324cSopenharmony_ci 916370b324cSopenharmony_ci st.OutArcFileSize = size; 917370b324cSopenharmony_ci } 918370b324cSopenharmony_ci 919370b324cSopenharmony_ci if (outStreamSpec) 920370b324cSopenharmony_ci result = outStreamSpec->Close(); 921370b324cSopenharmony_ci else if (volStreamSpec) 922370b324cSopenharmony_ci { 923370b324cSopenharmony_ci result = volStreamSpec->FinalFlush_and_CloseFiles(st.NumVolumes); 924370b324cSopenharmony_ci st.IsMultiVolMode = true; 925370b324cSopenharmony_ci } 926370b324cSopenharmony_ci 927370b324cSopenharmony_ci RINOK(result) 928370b324cSopenharmony_ci 929370b324cSopenharmony_ci if (processedItemsStatuses) 930370b324cSopenharmony_ci { 931370b324cSopenharmony_ci FOR_VECTOR (i, updatePairs2) 932370b324cSopenharmony_ci { 933370b324cSopenharmony_ci const CUpdatePair2 &up = updatePairs2[i]; 934370b324cSopenharmony_ci if (up.NewData && up.DirIndex >= 0) 935370b324cSopenharmony_ci { 936370b324cSopenharmony_ci const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex]; 937370b324cSopenharmony_ci if (di.AreReparseData() || (!di.IsDir() && di.Size == 0)) 938370b324cSopenharmony_ci processedItemsStatuses[(unsigned)up.DirIndex] = 1; 939370b324cSopenharmony_ci } 940370b324cSopenharmony_ci } 941370b324cSopenharmony_ci } 942370b324cSopenharmony_ci 943370b324cSopenharmony_ci return result; 944370b324cSopenharmony_ci} 945370b324cSopenharmony_ci 946370b324cSopenharmony_ci 947370b324cSopenharmony_ci 948370b324cSopenharmony_cistatic bool Censor_AreAllAllowed(const NWildcard::CCensor &censor) 949370b324cSopenharmony_ci{ 950370b324cSopenharmony_ci if (censor.Pairs.Size() != 1) 951370b324cSopenharmony_ci return false; 952370b324cSopenharmony_ci const NWildcard::CPair &pair = censor.Pairs[0]; 953370b324cSopenharmony_ci /* Censor_CheckPath() ignores (CPair::Prefix). 954370b324cSopenharmony_ci So we also ignore (CPair::Prefix) here */ 955370b324cSopenharmony_ci // if (!pair.Prefix.IsEmpty()) return false; 956370b324cSopenharmony_ci return pair.Head.AreAllAllowed(); 957370b324cSopenharmony_ci} 958370b324cSopenharmony_ci 959370b324cSopenharmony_cibool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include); 960370b324cSopenharmony_ci 961370b324cSopenharmony_cistatic bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item) 962370b324cSopenharmony_ci{ 963370b324cSopenharmony_ci bool finded = false; 964370b324cSopenharmony_ci FOR_VECTOR (i, censor.Pairs) 965370b324cSopenharmony_ci { 966370b324cSopenharmony_ci /* (CPair::Prefix) in not used for matching items in archive. 967370b324cSopenharmony_ci So we ignore (CPair::Prefix) here */ 968370b324cSopenharmony_ci bool include; 969370b324cSopenharmony_ci if (CensorNode_CheckPath2(censor.Pairs[i].Head, item, include)) 970370b324cSopenharmony_ci { 971370b324cSopenharmony_ci // Check it and FIXME !!!! 972370b324cSopenharmony_ci // here we can exclude item via some Pair, that is still allowed by another Pair 973370b324cSopenharmony_ci if (!include) 974370b324cSopenharmony_ci return false; 975370b324cSopenharmony_ci finded = true; 976370b324cSopenharmony_ci } 977370b324cSopenharmony_ci } 978370b324cSopenharmony_ci return finded; 979370b324cSopenharmony_ci} 980370b324cSopenharmony_ci 981370b324cSopenharmony_cistatic HRESULT EnumerateInArchiveItems( 982370b324cSopenharmony_ci // bool storeStreamsMode, 983370b324cSopenharmony_ci const NWildcard::CCensor &censor, 984370b324cSopenharmony_ci const CArc &arc, 985370b324cSopenharmony_ci CObjectVector<CArcItem> &arcItems) 986370b324cSopenharmony_ci{ 987370b324cSopenharmony_ci arcItems.Clear(); 988370b324cSopenharmony_ci UInt32 numItems; 989370b324cSopenharmony_ci IInArchive *archive = arc.Archive; 990370b324cSopenharmony_ci RINOK(archive->GetNumberOfItems(&numItems)) 991370b324cSopenharmony_ci arcItems.ClearAndReserve(numItems); 992370b324cSopenharmony_ci 993370b324cSopenharmony_ci CReadArcItem item; 994370b324cSopenharmony_ci 995370b324cSopenharmony_ci const bool allFilesAreAllowed = Censor_AreAllAllowed(censor); 996370b324cSopenharmony_ci 997370b324cSopenharmony_ci for (UInt32 i = 0; i < numItems; i++) 998370b324cSopenharmony_ci { 999370b324cSopenharmony_ci CArcItem ai; 1000370b324cSopenharmony_ci 1001370b324cSopenharmony_ci RINOK(arc.GetItem(i, item)) 1002370b324cSopenharmony_ci ai.Name = item.Path; 1003370b324cSopenharmony_ci ai.IsDir = item.IsDir; 1004370b324cSopenharmony_ci ai.IsAltStream = 1005370b324cSopenharmony_ci #ifdef SUPPORT_ALT_STREAMS 1006370b324cSopenharmony_ci item.IsAltStream; 1007370b324cSopenharmony_ci #else 1008370b324cSopenharmony_ci false; 1009370b324cSopenharmony_ci #endif 1010370b324cSopenharmony_ci 1011370b324cSopenharmony_ci /* 1012370b324cSopenharmony_ci if (!storeStreamsMode && ai.IsAltStream) 1013370b324cSopenharmony_ci continue; 1014370b324cSopenharmony_ci */ 1015370b324cSopenharmony_ci if (allFilesAreAllowed) 1016370b324cSopenharmony_ci ai.Censored = true; 1017370b324cSopenharmony_ci else 1018370b324cSopenharmony_ci ai.Censored = Censor_CheckPath(censor, item); 1019370b324cSopenharmony_ci 1020370b324cSopenharmony_ci // ai.MTime will be set to archive MTime, if not present in archive item 1021370b324cSopenharmony_ci RINOK(arc.GetItem_MTime(i, ai.MTime)) 1022370b324cSopenharmony_ci RINOK(arc.GetItem_Size(i, ai.Size, ai.Size_Defined)) 1023370b324cSopenharmony_ci 1024370b324cSopenharmony_ci ai.IndexInServer = i; 1025370b324cSopenharmony_ci arcItems.AddInReserved(ai); 1026370b324cSopenharmony_ci } 1027370b324cSopenharmony_ci return S_OK; 1028370b324cSopenharmony_ci} 1029370b324cSopenharmony_ci 1030370b324cSopenharmony_ci#if defined(_WIN32) && !defined(UNDER_CE) 1031370b324cSopenharmony_ci 1032370b324cSopenharmony_ci#if defined(__MINGW32__) || defined(__MINGW64__) 1033370b324cSopenharmony_ci#include <mapi.h> 1034370b324cSopenharmony_ci#else 1035370b324cSopenharmony_ci#include <MAPI.h> 1036370b324cSopenharmony_ci#endif 1037370b324cSopenharmony_ci 1038370b324cSopenharmony_ciextern "C" { 1039370b324cSopenharmony_ci 1040370b324cSopenharmony_ci#ifdef MAPI_FORCE_UNICODE 1041370b324cSopenharmony_ci 1042370b324cSopenharmony_ci#define Z7_WIN_LPMAPISENDMAILW LPMAPISENDMAILW 1043370b324cSopenharmony_ci#define Z7_WIN_MapiFileDescW MapiFileDescW 1044370b324cSopenharmony_ci#define Z7_WIN_MapiMessageW MapiMessageW 1045370b324cSopenharmony_ci#define Z7_WIN_MapiRecipDescW MapiRecipDescW 1046370b324cSopenharmony_ci 1047370b324cSopenharmony_ci#else 1048370b324cSopenharmony_ci 1049370b324cSopenharmony_citypedef struct 1050370b324cSopenharmony_ci{ 1051370b324cSopenharmony_ci ULONG ulReserved; 1052370b324cSopenharmony_ci ULONG ulRecipClass; 1053370b324cSopenharmony_ci PWSTR lpszName; 1054370b324cSopenharmony_ci PWSTR lpszAddress; 1055370b324cSopenharmony_ci ULONG ulEIDSize; 1056370b324cSopenharmony_ci PVOID lpEntryID; 1057370b324cSopenharmony_ci} Z7_WIN_MapiRecipDescW, *Z7_WIN_lpMapiRecipDescW; 1058370b324cSopenharmony_ci 1059370b324cSopenharmony_citypedef struct 1060370b324cSopenharmony_ci{ 1061370b324cSopenharmony_ci ULONG ulReserved; 1062370b324cSopenharmony_ci ULONG flFlags; 1063370b324cSopenharmony_ci ULONG nPosition; 1064370b324cSopenharmony_ci PWSTR lpszPathName; 1065370b324cSopenharmony_ci PWSTR lpszFileName; 1066370b324cSopenharmony_ci PVOID lpFileType; 1067370b324cSopenharmony_ci} Z7_WIN_MapiFileDescW, *Z7_WIN_lpMapiFileDescW; 1068370b324cSopenharmony_ci 1069370b324cSopenharmony_citypedef struct 1070370b324cSopenharmony_ci{ 1071370b324cSopenharmony_ci ULONG ulReserved; 1072370b324cSopenharmony_ci PWSTR lpszSubject; 1073370b324cSopenharmony_ci PWSTR lpszNoteText; 1074370b324cSopenharmony_ci PWSTR lpszMessageType; 1075370b324cSopenharmony_ci PWSTR lpszDateReceived; 1076370b324cSopenharmony_ci PWSTR lpszConversationID; 1077370b324cSopenharmony_ci FLAGS flFlags; 1078370b324cSopenharmony_ci Z7_WIN_lpMapiRecipDescW lpOriginator; 1079370b324cSopenharmony_ci ULONG nRecipCount; 1080370b324cSopenharmony_ci Z7_WIN_lpMapiRecipDescW lpRecips; 1081370b324cSopenharmony_ci ULONG nFileCount; 1082370b324cSopenharmony_ci Z7_WIN_lpMapiFileDescW lpFiles; 1083370b324cSopenharmony_ci} Z7_WIN_MapiMessageW, *Z7_WIN_lpMapiMessageW; 1084370b324cSopenharmony_ci 1085370b324cSopenharmony_citypedef ULONG (FAR PASCAL Z7_WIN_MAPISENDMAILW)( 1086370b324cSopenharmony_ci LHANDLE lhSession, 1087370b324cSopenharmony_ci ULONG_PTR ulUIParam, 1088370b324cSopenharmony_ci Z7_WIN_lpMapiMessageW lpMessage, 1089370b324cSopenharmony_ci FLAGS flFlags, 1090370b324cSopenharmony_ci ULONG ulReserved 1091370b324cSopenharmony_ci); 1092370b324cSopenharmony_citypedef Z7_WIN_MAPISENDMAILW FAR *Z7_WIN_LPMAPISENDMAILW; 1093370b324cSopenharmony_ci 1094370b324cSopenharmony_ci#endif // MAPI_FORCE_UNICODE 1095370b324cSopenharmony_ci} 1096370b324cSopenharmony_ci#endif // _WIN32 1097370b324cSopenharmony_ci 1098370b324cSopenharmony_ci 1099370b324cSopenharmony_ciHRESULT UpdateArchive( 1100370b324cSopenharmony_ci CCodecs *codecs, 1101370b324cSopenharmony_ci const CObjectVector<COpenType> &types, 1102370b324cSopenharmony_ci const UString &cmdArcPath2, 1103370b324cSopenharmony_ci NWildcard::CCensor &censor, 1104370b324cSopenharmony_ci CUpdateOptions &options, 1105370b324cSopenharmony_ci CUpdateErrorInfo &errorInfo, 1106370b324cSopenharmony_ci IOpenCallbackUI *openCallback, 1107370b324cSopenharmony_ci IUpdateCallbackUI2 *callback, 1108370b324cSopenharmony_ci bool needSetPath) 1109370b324cSopenharmony_ci{ 1110370b324cSopenharmony_ci if (options.StdOutMode && options.EMailMode) 1111370b324cSopenharmony_ci return E_FAIL; 1112370b324cSopenharmony_ci 1113370b324cSopenharmony_ci if (types.Size() > 1) 1114370b324cSopenharmony_ci return E_NOTIMPL; 1115370b324cSopenharmony_ci 1116370b324cSopenharmony_ci bool renameMode = !options.RenamePairs.IsEmpty(); 1117370b324cSopenharmony_ci if (renameMode) 1118370b324cSopenharmony_ci { 1119370b324cSopenharmony_ci if (options.Commands.Size() != 1) 1120370b324cSopenharmony_ci return E_FAIL; 1121370b324cSopenharmony_ci } 1122370b324cSopenharmony_ci 1123370b324cSopenharmony_ci if (options.DeleteAfterCompressing) 1124370b324cSopenharmony_ci { 1125370b324cSopenharmony_ci if (options.Commands.Size() != 1) 1126370b324cSopenharmony_ci return E_NOTIMPL; 1127370b324cSopenharmony_ci const CActionSet &as = options.Commands[0].ActionSet; 1128370b324cSopenharmony_ci for (unsigned i = 2; i < NPairState::kNumValues; i++) 1129370b324cSopenharmony_ci if (as.StateActions[i] != NPairAction::kCompress) 1130370b324cSopenharmony_ci return E_NOTIMPL; 1131370b324cSopenharmony_ci } 1132370b324cSopenharmony_ci 1133370b324cSopenharmony_ci censor.AddPathsToCensor(options.PathMode); 1134370b324cSopenharmony_ci #ifdef _WIN32 1135370b324cSopenharmony_ci ConvertToLongNames(censor); 1136370b324cSopenharmony_ci #endif 1137370b324cSopenharmony_ci censor.ExtendExclude(); 1138370b324cSopenharmony_ci 1139370b324cSopenharmony_ci 1140370b324cSopenharmony_ci if (options.VolumesSizes.Size() > 0 && (options.EMailMode /* || options.SfxMode */)) 1141370b324cSopenharmony_ci return E_NOTIMPL; 1142370b324cSopenharmony_ci 1143370b324cSopenharmony_ci if (options.SfxMode) 1144370b324cSopenharmony_ci { 1145370b324cSopenharmony_ci CProperty property; 1146370b324cSopenharmony_ci property.Name = "rsfx"; 1147370b324cSopenharmony_ci options.MethodMode.Properties.Add(property); 1148370b324cSopenharmony_ci if (options.SfxModule.IsEmpty()) 1149370b324cSopenharmony_ci { 1150370b324cSopenharmony_ci errorInfo.Message = "SFX file is not specified"; 1151370b324cSopenharmony_ci return E_FAIL; 1152370b324cSopenharmony_ci } 1153370b324cSopenharmony_ci bool found = false; 1154370b324cSopenharmony_ci if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0) 1155370b324cSopenharmony_ci { 1156370b324cSopenharmony_ci const FString fullName = NDLL::GetModuleDirPrefix() + options.SfxModule; 1157370b324cSopenharmony_ci if (NFind::DoesFileExist_FollowLink(fullName)) 1158370b324cSopenharmony_ci { 1159370b324cSopenharmony_ci options.SfxModule = fullName; 1160370b324cSopenharmony_ci found = true; 1161370b324cSopenharmony_ci } 1162370b324cSopenharmony_ci } 1163370b324cSopenharmony_ci if (!found) 1164370b324cSopenharmony_ci { 1165370b324cSopenharmony_ci if (!NFind::DoesFileExist_FollowLink(options.SfxModule)) 1166370b324cSopenharmony_ci return errorInfo.SetFromLastError("cannot find specified SFX module", options.SfxModule); 1167370b324cSopenharmony_ci } 1168370b324cSopenharmony_ci } 1169370b324cSopenharmony_ci 1170370b324cSopenharmony_ci CArchiveLink arcLink; 1171370b324cSopenharmony_ci 1172370b324cSopenharmony_ci 1173370b324cSopenharmony_ci if (needSetPath) 1174370b324cSopenharmony_ci { 1175370b324cSopenharmony_ci if (!options.InitFormatIndex(codecs, types, cmdArcPath2) || 1176370b324cSopenharmony_ci !options.SetArcPath(codecs, cmdArcPath2)) 1177370b324cSopenharmony_ci return E_NOTIMPL; 1178370b324cSopenharmony_ci } 1179370b324cSopenharmony_ci 1180370b324cSopenharmony_ci UString arcPath = options.ArchivePath.GetFinalPath(); 1181370b324cSopenharmony_ci 1182370b324cSopenharmony_ci if (!options.VolumesSizes.IsEmpty()) 1183370b324cSopenharmony_ci { 1184370b324cSopenharmony_ci arcPath = options.ArchivePath.GetFinalVolPath(); 1185370b324cSopenharmony_ci arcPath += ".001"; 1186370b324cSopenharmony_ci } 1187370b324cSopenharmony_ci 1188370b324cSopenharmony_ci if (cmdArcPath2.IsEmpty()) 1189370b324cSopenharmony_ci { 1190370b324cSopenharmony_ci if (options.MethodMode.Type.FormatIndex < 0) 1191370b324cSopenharmony_ci throw "type of archive is not specified"; 1192370b324cSopenharmony_ci } 1193370b324cSopenharmony_ci else 1194370b324cSopenharmony_ci { 1195370b324cSopenharmony_ci NFind::CFileInfo fi; 1196370b324cSopenharmony_ci if (!fi.Find_FollowLink(us2fs(arcPath))) 1197370b324cSopenharmony_ci { 1198370b324cSopenharmony_ci if (renameMode) 1199370b324cSopenharmony_ci throw "can't find archive"; 1200370b324cSopenharmony_ci if (options.MethodMode.Type.FormatIndex < 0) 1201370b324cSopenharmony_ci { 1202370b324cSopenharmony_ci if (!options.SetArcPath(codecs, cmdArcPath2)) 1203370b324cSopenharmony_ci return E_NOTIMPL; 1204370b324cSopenharmony_ci } 1205370b324cSopenharmony_ci } 1206370b324cSopenharmony_ci else 1207370b324cSopenharmony_ci { 1208370b324cSopenharmony_ci if (fi.IsDir()) 1209370b324cSopenharmony_ci return errorInfo.SetFromError_DWORD("There is a folder with the name of archive", 1210370b324cSopenharmony_ci us2fs(arcPath), 1211370b324cSopenharmony_ci #ifdef _WIN32 1212370b324cSopenharmony_ci ERROR_ACCESS_DENIED 1213370b324cSopenharmony_ci #else 1214370b324cSopenharmony_ci EISDIR 1215370b324cSopenharmony_ci #endif 1216370b324cSopenharmony_ci ); 1217370b324cSopenharmony_ci #ifdef _WIN32 1218370b324cSopenharmony_ci if (fi.IsDevice) 1219370b324cSopenharmony_ci return E_NOTIMPL; 1220370b324cSopenharmony_ci #endif 1221370b324cSopenharmony_ci 1222370b324cSopenharmony_ci if (!options.StdOutMode && options.UpdateArchiveItself) 1223370b324cSopenharmony_ci if (fi.IsReadOnly()) 1224370b324cSopenharmony_ci { 1225370b324cSopenharmony_ci return errorInfo.SetFromError_DWORD("The file is read-only", 1226370b324cSopenharmony_ci us2fs(arcPath), 1227370b324cSopenharmony_ci #ifdef _WIN32 1228370b324cSopenharmony_ci ERROR_ACCESS_DENIED 1229370b324cSopenharmony_ci #else 1230370b324cSopenharmony_ci EACCES 1231370b324cSopenharmony_ci #endif 1232370b324cSopenharmony_ci ); 1233370b324cSopenharmony_ci } 1234370b324cSopenharmony_ci 1235370b324cSopenharmony_ci if (options.VolumesSizes.Size() > 0) 1236370b324cSopenharmony_ci { 1237370b324cSopenharmony_ci errorInfo.FileNames.Add(us2fs(arcPath)); 1238370b324cSopenharmony_ci // errorInfo.SystemError = (DWORD)E_NOTIMPL; 1239370b324cSopenharmony_ci errorInfo.Message = kUpdateIsNotSupported_MultiVol; 1240370b324cSopenharmony_ci return E_NOTIMPL; 1241370b324cSopenharmony_ci } 1242370b324cSopenharmony_ci CObjectVector<COpenType> types2; 1243370b324cSopenharmony_ci // change it. 1244370b324cSopenharmony_ci if (options.MethodMode.Type_Defined) 1245370b324cSopenharmony_ci types2.Add(options.MethodMode.Type); 1246370b324cSopenharmony_ci // We need to set Properties to open archive only in some cases (WIM archives). 1247370b324cSopenharmony_ci 1248370b324cSopenharmony_ci CIntVector excl; 1249370b324cSopenharmony_ci COpenOptions op; 1250370b324cSopenharmony_ci #ifndef Z7_SFX 1251370b324cSopenharmony_ci op.props = &options.MethodMode.Properties; 1252370b324cSopenharmony_ci #endif 1253370b324cSopenharmony_ci op.codecs = codecs; 1254370b324cSopenharmony_ci op.types = &types2; 1255370b324cSopenharmony_ci op.excludedFormats = ! 1256370b324cSopenharmony_ci op.stdInMode = false; 1257370b324cSopenharmony_ci op.stream = NULL; 1258370b324cSopenharmony_ci op.filePath = arcPath; 1259370b324cSopenharmony_ci 1260370b324cSopenharmony_ci RINOK(callback->StartOpenArchive(arcPath)) 1261370b324cSopenharmony_ci 1262370b324cSopenharmony_ci HRESULT result = arcLink.Open_Strict(op, openCallback); 1263370b324cSopenharmony_ci 1264370b324cSopenharmony_ci if (result == E_ABORT) 1265370b324cSopenharmony_ci return result; 1266370b324cSopenharmony_ci 1267370b324cSopenharmony_ci HRESULT res2 = callback->OpenResult(codecs, arcLink, arcPath, result); 1268370b324cSopenharmony_ci /* 1269370b324cSopenharmony_ci if (result == S_FALSE) 1270370b324cSopenharmony_ci return E_FAIL; 1271370b324cSopenharmony_ci */ 1272370b324cSopenharmony_ci RINOK(res2) 1273370b324cSopenharmony_ci RINOK(result) 1274370b324cSopenharmony_ci 1275370b324cSopenharmony_ci if (arcLink.VolumePaths.Size() > 1) 1276370b324cSopenharmony_ci { 1277370b324cSopenharmony_ci // errorInfo.SystemError = (DWORD)E_NOTIMPL; 1278370b324cSopenharmony_ci errorInfo.Message = kUpdateIsNotSupported_MultiVol; 1279370b324cSopenharmony_ci return E_NOTIMPL; 1280370b324cSopenharmony_ci } 1281370b324cSopenharmony_ci 1282370b324cSopenharmony_ci CArc &arc = arcLink.Arcs.Back(); 1283370b324cSopenharmony_ci arc.MTime.Def = 1284370b324cSopenharmony_ci #ifdef _WIN32 1285370b324cSopenharmony_ci !fi.IsDevice; 1286370b324cSopenharmony_ci #else 1287370b324cSopenharmony_ci true; 1288370b324cSopenharmony_ci #endif 1289370b324cSopenharmony_ci if (arc.MTime.Def) 1290370b324cSopenharmony_ci arc.MTime.Set_From_FiTime(fi.MTime); 1291370b324cSopenharmony_ci 1292370b324cSopenharmony_ci if (arc.ErrorInfo.ThereIsTail) 1293370b324cSopenharmony_ci { 1294370b324cSopenharmony_ci // errorInfo.SystemError = (DWORD)E_NOTIMPL; 1295370b324cSopenharmony_ci errorInfo.Message = "There is some data block after the end of the archive"; 1296370b324cSopenharmony_ci return E_NOTIMPL; 1297370b324cSopenharmony_ci } 1298370b324cSopenharmony_ci if (options.MethodMode.Type.FormatIndex < 0) 1299370b324cSopenharmony_ci { 1300370b324cSopenharmony_ci options.MethodMode.Type.FormatIndex = arcLink.GetArc()->FormatIndex; 1301370b324cSopenharmony_ci if (!options.SetArcPath(codecs, cmdArcPath2)) 1302370b324cSopenharmony_ci return E_NOTIMPL; 1303370b324cSopenharmony_ci } 1304370b324cSopenharmony_ci } 1305370b324cSopenharmony_ci } 1306370b324cSopenharmony_ci 1307370b324cSopenharmony_ci if (options.MethodMode.Type.FormatIndex < 0) 1308370b324cSopenharmony_ci { 1309370b324cSopenharmony_ci options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType((UString)kDefaultArcType); 1310370b324cSopenharmony_ci if (options.MethodMode.Type.FormatIndex < 0) 1311370b324cSopenharmony_ci return E_NOTIMPL; 1312370b324cSopenharmony_ci } 1313370b324cSopenharmony_ci 1314370b324cSopenharmony_ci bool thereIsInArchive = arcLink.IsOpen; 1315370b324cSopenharmony_ci if (!thereIsInArchive && renameMode) 1316370b324cSopenharmony_ci return E_FAIL; 1317370b324cSopenharmony_ci 1318370b324cSopenharmony_ci CDirItems dirItems; 1319370b324cSopenharmony_ci dirItems.Callback = callback; 1320370b324cSopenharmony_ci 1321370b324cSopenharmony_ci CDirItem parentDirItem; 1322370b324cSopenharmony_ci CDirItem *parentDirItem_Ptr = NULL; 1323370b324cSopenharmony_ci 1324370b324cSopenharmony_ci /* 1325370b324cSopenharmony_ci FStringVector requestedPaths; 1326370b324cSopenharmony_ci FStringVector *requestedPaths_Ptr = NULL; 1327370b324cSopenharmony_ci if (options.DeleteAfterCompressing) 1328370b324cSopenharmony_ci requestedPaths_Ptr = &requestedPaths; 1329370b324cSopenharmony_ci */ 1330370b324cSopenharmony_ci 1331370b324cSopenharmony_ci if (options.StdInMode) 1332370b324cSopenharmony_ci { 1333370b324cSopenharmony_ci CDirItem di; 1334370b324cSopenharmony_ci di.ClearBase(); 1335370b324cSopenharmony_ci di.Name = options.StdInFileName; 1336370b324cSopenharmony_ci di.Size = (UInt64)(Int64)-1; 1337370b324cSopenharmony_ci di.SetAsFile(); 1338370b324cSopenharmony_ci NTime::GetCurUtc_FiTime(di.MTime); 1339370b324cSopenharmony_ci di.CTime = di.ATime = di.MTime; 1340370b324cSopenharmony_ci dirItems.Items.Add(di); 1341370b324cSopenharmony_ci } 1342370b324cSopenharmony_ci else 1343370b324cSopenharmony_ci { 1344370b324cSopenharmony_ci bool needScanning = false; 1345370b324cSopenharmony_ci 1346370b324cSopenharmony_ci if (!renameMode) 1347370b324cSopenharmony_ci FOR_VECTOR (i, options.Commands) 1348370b324cSopenharmony_ci if (options.Commands[i].ActionSet.NeedScanning()) 1349370b324cSopenharmony_ci needScanning = true; 1350370b324cSopenharmony_ci 1351370b324cSopenharmony_ci if (needScanning) 1352370b324cSopenharmony_ci { 1353370b324cSopenharmony_ci RINOK(callback->StartScanning()) 1354370b324cSopenharmony_ci 1355370b324cSopenharmony_ci dirItems.SymLinks = options.SymLinks.Val; 1356370b324cSopenharmony_ci 1357370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 1358370b324cSopenharmony_ci dirItems.ReadSecure = options.NtSecurity.Val; 1359370b324cSopenharmony_ci #endif 1360370b324cSopenharmony_ci 1361370b324cSopenharmony_ci dirItems.ScanAltStreams = options.AltStreams.Val; 1362370b324cSopenharmony_ci dirItems.ExcludeDirItems = censor.ExcludeDirItems; 1363370b324cSopenharmony_ci dirItems.ExcludeFileItems = censor.ExcludeFileItems; 1364370b324cSopenharmony_ci 1365370b324cSopenharmony_ci dirItems.ShareForWrite = options.OpenShareForWrite; 1366370b324cSopenharmony_ci 1367370b324cSopenharmony_ci #ifndef _WIN32 1368370b324cSopenharmony_ci dirItems.StoreOwnerName = options.StoreOwnerName.Val; 1369370b324cSopenharmony_ci #endif 1370370b324cSopenharmony_ci 1371370b324cSopenharmony_ci const HRESULT res = EnumerateItems(censor, 1372370b324cSopenharmony_ci options.PathMode, 1373370b324cSopenharmony_ci UString(), // options.AddPathPrefix, 1374370b324cSopenharmony_ci dirItems); 1375370b324cSopenharmony_ci 1376370b324cSopenharmony_ci if (res != S_OK) 1377370b324cSopenharmony_ci { 1378370b324cSopenharmony_ci if (res != E_ABORT) 1379370b324cSopenharmony_ci errorInfo.Message = "Scanning error"; 1380370b324cSopenharmony_ci return res; 1381370b324cSopenharmony_ci } 1382370b324cSopenharmony_ci 1383370b324cSopenharmony_ci RINOK(callback->FinishScanning(dirItems.Stat)) 1384370b324cSopenharmony_ci 1385370b324cSopenharmony_ci // 22.00: we don't need parent folder, if absolute path mode 1386370b324cSopenharmony_ci if (options.PathMode != NWildcard::k_AbsPath) 1387370b324cSopenharmony_ci if (censor.Pairs.Size() == 1) 1388370b324cSopenharmony_ci { 1389370b324cSopenharmony_ci NFind::CFileInfo fi; 1390370b324cSopenharmony_ci FString prefix = us2fs(censor.Pairs[0].Prefix); 1391370b324cSopenharmony_ci prefix.Add_Dot(); 1392370b324cSopenharmony_ci // UString prefix = censor.Pairs[0].Prefix; 1393370b324cSopenharmony_ci /* 1394370b324cSopenharmony_ci if (prefix.Back() == WCHAR_PATH_SEPARATOR) 1395370b324cSopenharmony_ci { 1396370b324cSopenharmony_ci prefix.DeleteBack(); 1397370b324cSopenharmony_ci } 1398370b324cSopenharmony_ci */ 1399370b324cSopenharmony_ci if (fi.Find(prefix)) 1400370b324cSopenharmony_ci if (fi.IsDir()) 1401370b324cSopenharmony_ci { 1402370b324cSopenharmony_ci parentDirItem.Copy_From_FileInfoBase(fi); 1403370b324cSopenharmony_ci parentDirItem_Ptr = &parentDirItem; 1404370b324cSopenharmony_ci 1405370b324cSopenharmony_ci int secureIndex = -1; 1406370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 1407370b324cSopenharmony_ci if (options.NtSecurity.Val) 1408370b324cSopenharmony_ci dirItems.AddSecurityItem(prefix, secureIndex); 1409370b324cSopenharmony_ci #endif 1410370b324cSopenharmony_ci parentDirItem.SecureIndex = secureIndex; 1411370b324cSopenharmony_ci } 1412370b324cSopenharmony_ci } 1413370b324cSopenharmony_ci } 1414370b324cSopenharmony_ci } 1415370b324cSopenharmony_ci 1416370b324cSopenharmony_ci FString tempDirPrefix; 1417370b324cSopenharmony_ci bool usesTempDir = false; 1418370b324cSopenharmony_ci 1419370b324cSopenharmony_ci #ifdef _WIN32 1420370b324cSopenharmony_ci CTempDir tempDirectory; 1421370b324cSopenharmony_ci if (options.EMailMode && options.EMailRemoveAfter) 1422370b324cSopenharmony_ci { 1423370b324cSopenharmony_ci tempDirectory.Create(kTempFolderPrefix); 1424370b324cSopenharmony_ci tempDirPrefix = tempDirectory.GetPath(); 1425370b324cSopenharmony_ci NormalizeDirPathPrefix(tempDirPrefix); 1426370b324cSopenharmony_ci usesTempDir = true; 1427370b324cSopenharmony_ci } 1428370b324cSopenharmony_ci #endif 1429370b324cSopenharmony_ci 1430370b324cSopenharmony_ci CTempFiles tempFiles; 1431370b324cSopenharmony_ci 1432370b324cSopenharmony_ci bool createTempFile = false; 1433370b324cSopenharmony_ci 1434370b324cSopenharmony_ci if (!options.StdOutMode && options.UpdateArchiveItself) 1435370b324cSopenharmony_ci { 1436370b324cSopenharmony_ci CArchivePath &ap = options.Commands[0].ArchivePath; 1437370b324cSopenharmony_ci ap = options.ArchivePath; 1438370b324cSopenharmony_ci // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty()) 1439370b324cSopenharmony_ci if ((thereIsInArchive || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0) 1440370b324cSopenharmony_ci { 1441370b324cSopenharmony_ci createTempFile = true; 1442370b324cSopenharmony_ci ap.Temp = true; 1443370b324cSopenharmony_ci if (!options.WorkingDir.IsEmpty()) 1444370b324cSopenharmony_ci ap.TempPrefix = options.WorkingDir; 1445370b324cSopenharmony_ci else 1446370b324cSopenharmony_ci ap.TempPrefix = us2fs(ap.Prefix); 1447370b324cSopenharmony_ci NormalizeDirPathPrefix(ap.TempPrefix); 1448370b324cSopenharmony_ci } 1449370b324cSopenharmony_ci } 1450370b324cSopenharmony_ci 1451370b324cSopenharmony_ci unsigned ci; 1452370b324cSopenharmony_ci 1453370b324cSopenharmony_ci 1454370b324cSopenharmony_ci // self including protection 1455370b324cSopenharmony_ci if (options.DeleteAfterCompressing) 1456370b324cSopenharmony_ci { 1457370b324cSopenharmony_ci for (ci = 0; ci < options.Commands.Size(); ci++) 1458370b324cSopenharmony_ci { 1459370b324cSopenharmony_ci CArchivePath &ap = options.Commands[ci].ArchivePath; 1460370b324cSopenharmony_ci const FString path = us2fs(ap.GetFinalPath()); 1461370b324cSopenharmony_ci // maybe we must compare absolute paths path here 1462370b324cSopenharmony_ci FOR_VECTOR (i, dirItems.Items) 1463370b324cSopenharmony_ci { 1464370b324cSopenharmony_ci const FString phyPath = dirItems.GetPhyPath(i); 1465370b324cSopenharmony_ci if (phyPath == path) 1466370b324cSopenharmony_ci { 1467370b324cSopenharmony_ci UString s; 1468370b324cSopenharmony_ci s = "It is not allowed to include archive to itself"; 1469370b324cSopenharmony_ci s.Add_LF(); 1470370b324cSopenharmony_ci s += fs2us(path); 1471370b324cSopenharmony_ci throw s; 1472370b324cSopenharmony_ci } 1473370b324cSopenharmony_ci } 1474370b324cSopenharmony_ci } 1475370b324cSopenharmony_ci } 1476370b324cSopenharmony_ci 1477370b324cSopenharmony_ci 1478370b324cSopenharmony_ci for (ci = 0; ci < options.Commands.Size(); ci++) 1479370b324cSopenharmony_ci { 1480370b324cSopenharmony_ci CArchivePath &ap = options.Commands[ci].ArchivePath; 1481370b324cSopenharmony_ci if (usesTempDir) 1482370b324cSopenharmony_ci { 1483370b324cSopenharmony_ci // Check it 1484370b324cSopenharmony_ci ap.Prefix = fs2us(tempDirPrefix); 1485370b324cSopenharmony_ci // ap.Temp = true; 1486370b324cSopenharmony_ci // ap.TempPrefix = tempDirPrefix; 1487370b324cSopenharmony_ci } 1488370b324cSopenharmony_ci if (!options.StdOutMode && 1489370b324cSopenharmony_ci (ci > 0 || !createTempFile)) 1490370b324cSopenharmony_ci { 1491370b324cSopenharmony_ci const FString path = us2fs(ap.GetFinalPath()); 1492370b324cSopenharmony_ci if (NFind::DoesFileOrDirExist(path)) 1493370b324cSopenharmony_ci { 1494370b324cSopenharmony_ci errorInfo.SystemError = ERROR_FILE_EXISTS; 1495370b324cSopenharmony_ci errorInfo.Message = "The file already exists"; 1496370b324cSopenharmony_ci errorInfo.FileNames.Add(path); 1497370b324cSopenharmony_ci return errorInfo.Get_HRESULT_Error(); 1498370b324cSopenharmony_ci } 1499370b324cSopenharmony_ci } 1500370b324cSopenharmony_ci } 1501370b324cSopenharmony_ci 1502370b324cSopenharmony_ci CObjectVector<CArcItem> arcItems; 1503370b324cSopenharmony_ci if (thereIsInArchive) 1504370b324cSopenharmony_ci { 1505370b324cSopenharmony_ci RINOK(EnumerateInArchiveItems( 1506370b324cSopenharmony_ci // options.StoreAltStreams, 1507370b324cSopenharmony_ci censor, arcLink.Arcs.Back(), arcItems)) 1508370b324cSopenharmony_ci } 1509370b324cSopenharmony_ci 1510370b324cSopenharmony_ci /* 1511370b324cSopenharmony_ci FStringVector processedFilePaths; 1512370b324cSopenharmony_ci FStringVector *processedFilePaths_Ptr = NULL; 1513370b324cSopenharmony_ci if (options.DeleteAfterCompressing) 1514370b324cSopenharmony_ci processedFilePaths_Ptr = &processedFilePaths; 1515370b324cSopenharmony_ci */ 1516370b324cSopenharmony_ci 1517370b324cSopenharmony_ci CByteBuffer processedItems; 1518370b324cSopenharmony_ci if (options.DeleteAfterCompressing) 1519370b324cSopenharmony_ci { 1520370b324cSopenharmony_ci const unsigned num = dirItems.Items.Size(); 1521370b324cSopenharmony_ci processedItems.Alloc(num); 1522370b324cSopenharmony_ci for (unsigned i = 0; i < num; i++) 1523370b324cSopenharmony_ci processedItems[i] = 0; 1524370b324cSopenharmony_ci } 1525370b324cSopenharmony_ci 1526370b324cSopenharmony_ci CMultiOutStream_Bunch multiStreams; 1527370b324cSopenharmony_ci 1528370b324cSopenharmony_ci /* 1529370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 1530370b324cSopenharmony_ci if (arcLink.PasswordWasAsked) 1531370b324cSopenharmony_ci { 1532370b324cSopenharmony_ci // We set password, if open have requested password 1533370b324cSopenharmony_ci RINOK(callback->SetPassword(arcLink.Password)); 1534370b324cSopenharmony_ci } 1535370b324cSopenharmony_ci #endif 1536370b324cSopenharmony_ci */ 1537370b324cSopenharmony_ci 1538370b324cSopenharmony_ci for (ci = 0; ci < options.Commands.Size(); ci++) 1539370b324cSopenharmony_ci { 1540370b324cSopenharmony_ci const CArc *arc = thereIsInArchive ? arcLink.GetArc() : NULL; 1541370b324cSopenharmony_ci CUpdateArchiveCommand &command = options.Commands[ci]; 1542370b324cSopenharmony_ci UString name; 1543370b324cSopenharmony_ci bool isUpdating; 1544370b324cSopenharmony_ci 1545370b324cSopenharmony_ci if (options.StdOutMode) 1546370b324cSopenharmony_ci { 1547370b324cSopenharmony_ci name = "stdout"; 1548370b324cSopenharmony_ci isUpdating = thereIsInArchive; 1549370b324cSopenharmony_ci } 1550370b324cSopenharmony_ci else 1551370b324cSopenharmony_ci { 1552370b324cSopenharmony_ci name = command.ArchivePath.GetFinalPath(); 1553370b324cSopenharmony_ci isUpdating = (ci == 0 && options.UpdateArchiveItself && thereIsInArchive); 1554370b324cSopenharmony_ci } 1555370b324cSopenharmony_ci 1556370b324cSopenharmony_ci RINOK(callback->StartArchive(name, isUpdating)) 1557370b324cSopenharmony_ci 1558370b324cSopenharmony_ci CFinishArchiveStat st; 1559370b324cSopenharmony_ci 1560370b324cSopenharmony_ci RINOK(Compress(options, 1561370b324cSopenharmony_ci isUpdating, 1562370b324cSopenharmony_ci codecs, 1563370b324cSopenharmony_ci command.ActionSet, 1564370b324cSopenharmony_ci arc, 1565370b324cSopenharmony_ci command.ArchivePath, 1566370b324cSopenharmony_ci arcItems, 1567370b324cSopenharmony_ci options.DeleteAfterCompressing ? (Byte *)processedItems : NULL, 1568370b324cSopenharmony_ci 1569370b324cSopenharmony_ci dirItems, 1570370b324cSopenharmony_ci parentDirItem_Ptr, 1571370b324cSopenharmony_ci 1572370b324cSopenharmony_ci tempFiles, 1573370b324cSopenharmony_ci multiStreams, 1574370b324cSopenharmony_ci errorInfo, callback, st)) 1575370b324cSopenharmony_ci 1576370b324cSopenharmony_ci RINOK(callback->FinishArchive(st)) 1577370b324cSopenharmony_ci } 1578370b324cSopenharmony_ci 1579370b324cSopenharmony_ci 1580370b324cSopenharmony_ci if (thereIsInArchive) 1581370b324cSopenharmony_ci { 1582370b324cSopenharmony_ci RINOK(arcLink.Close()) 1583370b324cSopenharmony_ci arcLink.Release(); 1584370b324cSopenharmony_ci } 1585370b324cSopenharmony_ci 1586370b324cSopenharmony_ci multiStreams.DisableDeletion(); 1587370b324cSopenharmony_ci RINOK(multiStreams.Destruct()) 1588370b324cSopenharmony_ci 1589370b324cSopenharmony_ci tempFiles.Paths.Clear(); 1590370b324cSopenharmony_ci if (createTempFile) 1591370b324cSopenharmony_ci { 1592370b324cSopenharmony_ci try 1593370b324cSopenharmony_ci { 1594370b324cSopenharmony_ci CArchivePath &ap = options.Commands[0].ArchivePath; 1595370b324cSopenharmony_ci const FString &tempPath = ap.GetTempPath(); 1596370b324cSopenharmony_ci 1597370b324cSopenharmony_ci // DWORD attrib = 0; 1598370b324cSopenharmony_ci if (thereIsInArchive) 1599370b324cSopenharmony_ci { 1600370b324cSopenharmony_ci // attrib = NFind::GetFileAttrib(us2fs(arcPath)); 1601370b324cSopenharmony_ci if (!DeleteFileAlways(us2fs(arcPath))) 1602370b324cSopenharmony_ci return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath)); 1603370b324cSopenharmony_ci } 1604370b324cSopenharmony_ci 1605370b324cSopenharmony_ci if (!MyMoveFile(tempPath, us2fs(arcPath))) 1606370b324cSopenharmony_ci { 1607370b324cSopenharmony_ci errorInfo.SetFromLastError("cannot move the file", tempPath); 1608370b324cSopenharmony_ci errorInfo.FileNames.Add(us2fs(arcPath)); 1609370b324cSopenharmony_ci return errorInfo.Get_HRESULT_Error(); 1610370b324cSopenharmony_ci } 1611370b324cSopenharmony_ci 1612370b324cSopenharmony_ci /* 1613370b324cSopenharmony_ci if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) 1614370b324cSopenharmony_ci { 1615370b324cSopenharmony_ci DWORD attrib2 = NFind::GetFileAttrib(us2fs(arcPath)); 1616370b324cSopenharmony_ci if (attrib2 != INVALID_FILE_ATTRIBUTES) 1617370b324cSopenharmony_ci NDir::SetFileAttrib(us2fs(arcPath), attrib2 | FILE_ATTRIBUTE_READONLY); 1618370b324cSopenharmony_ci } 1619370b324cSopenharmony_ci */ 1620370b324cSopenharmony_ci } 1621370b324cSopenharmony_ci catch(...) 1622370b324cSopenharmony_ci { 1623370b324cSopenharmony_ci throw; 1624370b324cSopenharmony_ci } 1625370b324cSopenharmony_ci } 1626370b324cSopenharmony_ci 1627370b324cSopenharmony_ci 1628370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 1629370b324cSopenharmony_ci 1630370b324cSopenharmony_ci if (options.EMailMode) 1631370b324cSopenharmony_ci { 1632370b324cSopenharmony_ci NDLL::CLibrary mapiLib; 1633370b324cSopenharmony_ci if (!mapiLib.Load(FTEXT("Mapi32.dll"))) 1634370b324cSopenharmony_ci { 1635370b324cSopenharmony_ci errorInfo.SetFromLastError("cannot load Mapi32.dll"); 1636370b324cSopenharmony_ci return errorInfo.Get_HRESULT_Error(); 1637370b324cSopenharmony_ci } 1638370b324cSopenharmony_ci 1639370b324cSopenharmony_ci FStringVector fullPaths; 1640370b324cSopenharmony_ci unsigned i; 1641370b324cSopenharmony_ci 1642370b324cSopenharmony_ci for (i = 0; i < options.Commands.Size(); i++) 1643370b324cSopenharmony_ci { 1644370b324cSopenharmony_ci CArchivePath &ap = options.Commands[i].ArchivePath; 1645370b324cSopenharmony_ci const FString finalPath = us2fs(ap.GetFinalPath()); 1646370b324cSopenharmony_ci FString arcPath2; 1647370b324cSopenharmony_ci if (!MyGetFullPathName(finalPath, arcPath2)) 1648370b324cSopenharmony_ci return errorInfo.SetFromLastError("GetFullPathName error", finalPath); 1649370b324cSopenharmony_ci fullPaths.Add(arcPath2); 1650370b324cSopenharmony_ci } 1651370b324cSopenharmony_ci 1652370b324cSopenharmony_ci /* 1653370b324cSopenharmony_ci LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments"); 1654370b324cSopenharmony_ci if (fnSend == 0) 1655370b324cSopenharmony_ci { 1656370b324cSopenharmony_ci errorInfo.SetFromLastError)("7-Zip cannot find MAPISendDocuments function"); 1657370b324cSopenharmony_ci return errorInfo.Get_HRESULT_Error(); 1658370b324cSopenharmony_ci } 1659370b324cSopenharmony_ci */ 1660370b324cSopenharmony_ci const 1661370b324cSopenharmony_ci Z7_WIN_LPMAPISENDMAILW sendMailW = Z7_GET_PROC_ADDRESS( 1662370b324cSopenharmony_ci Z7_WIN_LPMAPISENDMAILW, mapiLib.Get_HMODULE(), 1663370b324cSopenharmony_ci "MAPISendMailW"); 1664370b324cSopenharmony_ci if (sendMailW) 1665370b324cSopenharmony_ci { 1666370b324cSopenharmony_ci 1667370b324cSopenharmony_ci CCurrentDirRestorer curDirRestorer; 1668370b324cSopenharmony_ci 1669370b324cSopenharmony_ci UStringVector paths; 1670370b324cSopenharmony_ci UStringVector names; 1671370b324cSopenharmony_ci 1672370b324cSopenharmony_ci for (i = 0; i < fullPaths.Size(); i++) 1673370b324cSopenharmony_ci { 1674370b324cSopenharmony_ci const UString arcPath2 = fs2us(fullPaths[i]); 1675370b324cSopenharmony_ci const UString fileName = ExtractFileNameFromPath(arcPath2); 1676370b324cSopenharmony_ci paths.Add(arcPath2); 1677370b324cSopenharmony_ci names.Add(fileName); 1678370b324cSopenharmony_ci // Warning!!! MAPISendDocuments function changes Current directory 1679370b324cSopenharmony_ci // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); 1680370b324cSopenharmony_ci } 1681370b324cSopenharmony_ci 1682370b324cSopenharmony_ci CRecordVector<Z7_WIN_MapiFileDescW> files; 1683370b324cSopenharmony_ci files.ClearAndSetSize(paths.Size()); 1684370b324cSopenharmony_ci 1685370b324cSopenharmony_ci for (i = 0; i < paths.Size(); i++) 1686370b324cSopenharmony_ci { 1687370b324cSopenharmony_ci Z7_WIN_MapiFileDescW &f = files[i]; 1688370b324cSopenharmony_ci memset(&f, 0, sizeof(f)); 1689370b324cSopenharmony_ci f.nPosition = 0xFFFFFFFF; 1690370b324cSopenharmony_ci f.lpszPathName = paths[i].Ptr_non_const(); 1691370b324cSopenharmony_ci f.lpszFileName = names[i].Ptr_non_const(); 1692370b324cSopenharmony_ci } 1693370b324cSopenharmony_ci 1694370b324cSopenharmony_ci { 1695370b324cSopenharmony_ci Z7_WIN_MapiMessageW m; 1696370b324cSopenharmony_ci memset(&m, 0, sizeof(m)); 1697370b324cSopenharmony_ci m.nFileCount = files.Size(); 1698370b324cSopenharmony_ci m.lpFiles = &files.Front(); 1699370b324cSopenharmony_ci 1700370b324cSopenharmony_ci const UString addr (options.EMailAddress); 1701370b324cSopenharmony_ci Z7_WIN_MapiRecipDescW rec; 1702370b324cSopenharmony_ci if (!addr.IsEmpty()) 1703370b324cSopenharmony_ci { 1704370b324cSopenharmony_ci memset(&rec, 0, sizeof(rec)); 1705370b324cSopenharmony_ci rec.ulRecipClass = MAPI_TO; 1706370b324cSopenharmony_ci rec.lpszAddress = addr.Ptr_non_const(); 1707370b324cSopenharmony_ci m.nRecipCount = 1; 1708370b324cSopenharmony_ci m.lpRecips = &rec; 1709370b324cSopenharmony_ci } 1710370b324cSopenharmony_ci 1711370b324cSopenharmony_ci sendMailW((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); 1712370b324cSopenharmony_ci } 1713370b324cSopenharmony_ci } 1714370b324cSopenharmony_ci else 1715370b324cSopenharmony_ci { 1716370b324cSopenharmony_ci const 1717370b324cSopenharmony_ci LPMAPISENDMAIL sendMail = Z7_GET_PROC_ADDRESS( 1718370b324cSopenharmony_ci LPMAPISENDMAIL, mapiLib.Get_HMODULE(), 1719370b324cSopenharmony_ci "MAPISendMail"); 1720370b324cSopenharmony_ci if (!sendMail) 1721370b324cSopenharmony_ci { 1722370b324cSopenharmony_ci errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); 1723370b324cSopenharmony_ci return errorInfo.Get_HRESULT_Error(); 1724370b324cSopenharmony_ci } 1725370b324cSopenharmony_ci 1726370b324cSopenharmony_ci CCurrentDirRestorer curDirRestorer; 1727370b324cSopenharmony_ci 1728370b324cSopenharmony_ci AStringVector paths; 1729370b324cSopenharmony_ci AStringVector names; 1730370b324cSopenharmony_ci 1731370b324cSopenharmony_ci for (i = 0; i < fullPaths.Size(); i++) 1732370b324cSopenharmony_ci { 1733370b324cSopenharmony_ci const UString arcPath2 = fs2us(fullPaths[i]); 1734370b324cSopenharmony_ci const UString fileName = ExtractFileNameFromPath(arcPath2); 1735370b324cSopenharmony_ci paths.Add(GetAnsiString(arcPath2)); 1736370b324cSopenharmony_ci names.Add(GetAnsiString(fileName)); 1737370b324cSopenharmony_ci // const AString path (GetAnsiString(arcPath2)); 1738370b324cSopenharmony_ci // const AString name (GetAnsiString(fileName)); 1739370b324cSopenharmony_ci // Warning!!! MAPISendDocuments function changes Current directory 1740370b324cSopenharmony_ci // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); 1741370b324cSopenharmony_ci } 1742370b324cSopenharmony_ci 1743370b324cSopenharmony_ci CRecordVector<MapiFileDesc> files; 1744370b324cSopenharmony_ci files.ClearAndSetSize(paths.Size()); 1745370b324cSopenharmony_ci 1746370b324cSopenharmony_ci for (i = 0; i < paths.Size(); i++) 1747370b324cSopenharmony_ci { 1748370b324cSopenharmony_ci MapiFileDesc &f = files[i]; 1749370b324cSopenharmony_ci memset(&f, 0, sizeof(f)); 1750370b324cSopenharmony_ci f.nPosition = 0xFFFFFFFF; 1751370b324cSopenharmony_ci f.lpszPathName = paths[i].Ptr_non_const(); 1752370b324cSopenharmony_ci f.lpszFileName = names[i].Ptr_non_const(); 1753370b324cSopenharmony_ci } 1754370b324cSopenharmony_ci 1755370b324cSopenharmony_ci { 1756370b324cSopenharmony_ci MapiMessage m; 1757370b324cSopenharmony_ci memset(&m, 0, sizeof(m)); 1758370b324cSopenharmony_ci m.nFileCount = files.Size(); 1759370b324cSopenharmony_ci m.lpFiles = &files.Front(); 1760370b324cSopenharmony_ci 1761370b324cSopenharmony_ci const AString addr (GetAnsiString(options.EMailAddress)); 1762370b324cSopenharmony_ci MapiRecipDesc rec; 1763370b324cSopenharmony_ci if (!addr.IsEmpty()) 1764370b324cSopenharmony_ci { 1765370b324cSopenharmony_ci memset(&rec, 0, sizeof(rec)); 1766370b324cSopenharmony_ci rec.ulRecipClass = MAPI_TO; 1767370b324cSopenharmony_ci rec.lpszAddress = addr.Ptr_non_const(); 1768370b324cSopenharmony_ci m.nRecipCount = 1; 1769370b324cSopenharmony_ci m.lpRecips = &rec; 1770370b324cSopenharmony_ci } 1771370b324cSopenharmony_ci 1772370b324cSopenharmony_ci sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); 1773370b324cSopenharmony_ci } 1774370b324cSopenharmony_ci } 1775370b324cSopenharmony_ci } 1776370b324cSopenharmony_ci 1777370b324cSopenharmony_ci #endif 1778370b324cSopenharmony_ci 1779370b324cSopenharmony_ci if (options.DeleteAfterCompressing) 1780370b324cSopenharmony_ci { 1781370b324cSopenharmony_ci CRecordVector<CDirPathSortPair> pairs; 1782370b324cSopenharmony_ci FStringVector foldersNames; 1783370b324cSopenharmony_ci 1784370b324cSopenharmony_ci unsigned i; 1785370b324cSopenharmony_ci 1786370b324cSopenharmony_ci for (i = 0; i < dirItems.Items.Size(); i++) 1787370b324cSopenharmony_ci { 1788370b324cSopenharmony_ci const CDirItem &dirItem = dirItems.Items[i]; 1789370b324cSopenharmony_ci const FString phyPath = dirItems.GetPhyPath(i); 1790370b324cSopenharmony_ci if (dirItem.IsDir()) 1791370b324cSopenharmony_ci { 1792370b324cSopenharmony_ci CDirPathSortPair pair; 1793370b324cSopenharmony_ci pair.Index = i; 1794370b324cSopenharmony_ci pair.SetNumSlashes(phyPath); 1795370b324cSopenharmony_ci pairs.Add(pair); 1796370b324cSopenharmony_ci } 1797370b324cSopenharmony_ci else 1798370b324cSopenharmony_ci { 1799370b324cSopenharmony_ci // 21.04: we have set processedItems[*] before for all required items 1800370b324cSopenharmony_ci if (processedItems[i] != 0 1801370b324cSopenharmony_ci // || dirItem.Size == 0 1802370b324cSopenharmony_ci // || dirItem.AreReparseData() 1803370b324cSopenharmony_ci ) 1804370b324cSopenharmony_ci { 1805370b324cSopenharmony_ci NFind::CFileInfo fileInfo; 1806370b324cSopenharmony_ci /* if (!SymLinks), we follow link here, similar to (dirItem) filling */ 1807370b324cSopenharmony_ci if (fileInfo.Find(phyPath, !options.SymLinks.Val)) 1808370b324cSopenharmony_ci { 1809370b324cSopenharmony_ci bool is_SameSize = false; 1810370b324cSopenharmony_ci if (options.SymLinks.Val && dirItem.AreReparseData()) 1811370b324cSopenharmony_ci { 1812370b324cSopenharmony_ci /* (dirItem.Size = dirItem.ReparseData.Size()) was set before. 1813370b324cSopenharmony_ci So we don't compare sizes for that case here */ 1814370b324cSopenharmony_ci is_SameSize = fileInfo.IsOsSymLink(); 1815370b324cSopenharmony_ci } 1816370b324cSopenharmony_ci else 1817370b324cSopenharmony_ci is_SameSize = (fileInfo.Size == dirItem.Size); 1818370b324cSopenharmony_ci 1819370b324cSopenharmony_ci if (is_SameSize 1820370b324cSopenharmony_ci && Compare_FiTime(&fileInfo.MTime, &dirItem.MTime) == 0 1821370b324cSopenharmony_ci && Compare_FiTime(&fileInfo.CTime, &dirItem.CTime) == 0) 1822370b324cSopenharmony_ci { 1823370b324cSopenharmony_ci RINOK(callback->DeletingAfterArchiving(phyPath, false)) 1824370b324cSopenharmony_ci DeleteFileAlways(phyPath); 1825370b324cSopenharmony_ci } 1826370b324cSopenharmony_ci } 1827370b324cSopenharmony_ci } 1828370b324cSopenharmony_ci else 1829370b324cSopenharmony_ci { 1830370b324cSopenharmony_ci // file was skipped by some reason. We can throw error for debug: 1831370b324cSopenharmony_ci /* 1832370b324cSopenharmony_ci errorInfo.SystemError = 0; 1833370b324cSopenharmony_ci errorInfo.Message = "file was not processed"; 1834370b324cSopenharmony_ci errorInfo.FileNames.Add(phyPath); 1835370b324cSopenharmony_ci return E_FAIL; 1836370b324cSopenharmony_ci */ 1837370b324cSopenharmony_ci } 1838370b324cSopenharmony_ci } 1839370b324cSopenharmony_ci } 1840370b324cSopenharmony_ci 1841370b324cSopenharmony_ci pairs.Sort2(); 1842370b324cSopenharmony_ci 1843370b324cSopenharmony_ci for (i = 0; i < pairs.Size(); i++) 1844370b324cSopenharmony_ci { 1845370b324cSopenharmony_ci const FString phyPath = dirItems.GetPhyPath(pairs[i].Index); 1846370b324cSopenharmony_ci if (NFind::DoesDirExist(phyPath)) 1847370b324cSopenharmony_ci { 1848370b324cSopenharmony_ci RINOK(callback->DeletingAfterArchiving(phyPath, true)) 1849370b324cSopenharmony_ci RemoveDir(phyPath); 1850370b324cSopenharmony_ci } 1851370b324cSopenharmony_ci } 1852370b324cSopenharmony_ci 1853370b324cSopenharmony_ci RINOK(callback->FinishDeletingAfterArchiving()) 1854370b324cSopenharmony_ci } 1855370b324cSopenharmony_ci 1856370b324cSopenharmony_ci return S_OK; 1857370b324cSopenharmony_ci} 1858