1370b324cSopenharmony_ci// EnumDirItems.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include <wchar.h> 6370b324cSopenharmony_ci// #include <stdio.h> 7370b324cSopenharmony_ci 8370b324cSopenharmony_ci#ifndef _WIN32 9370b324cSopenharmony_ci#include <grp.h> 10370b324cSopenharmony_ci#include <pwd.h> 11370b324cSopenharmony_ci#include "../../../Common/UTFConvert.h" 12370b324cSopenharmony_ci#endif 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci#include "../../../Common/Wildcard.h" 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci#include "../../../Windows/FileDir.h" 17370b324cSopenharmony_ci#include "../../../Windows/FileIO.h" 18370b324cSopenharmony_ci#include "../../../Windows/FileName.h" 19370b324cSopenharmony_ci 20370b324cSopenharmony_ci#if defined(_WIN32) && !defined(UNDER_CE) 21370b324cSopenharmony_ci#define Z7_USE_SECURITY_CODE 22370b324cSopenharmony_ci#include "../../../Windows/SecurityUtils.h" 23370b324cSopenharmony_ci#endif 24370b324cSopenharmony_ci 25370b324cSopenharmony_ci#include "EnumDirItems.h" 26370b324cSopenharmony_ci#include "SortUtils.h" 27370b324cSopenharmony_ci 28370b324cSopenharmony_ciusing namespace NWindows; 29370b324cSopenharmony_ciusing namespace NFile; 30370b324cSopenharmony_ciusing namespace NName; 31370b324cSopenharmony_ci 32370b324cSopenharmony_ci 33370b324cSopenharmony_cistatic bool FindFile_KeepDots(NFile::NFind::CFileInfo &fi, const FString &path, bool followLink) 34370b324cSopenharmony_ci{ 35370b324cSopenharmony_ci const bool res = fi.Find(path, followLink); 36370b324cSopenharmony_ci if (!res) 37370b324cSopenharmony_ci return res; 38370b324cSopenharmony_ci if (path.IsEmpty()) 39370b324cSopenharmony_ci return res; 40370b324cSopenharmony_ci // we keep name "." and "..", if it's without tail slash 41370b324cSopenharmony_ci const FChar *p = path.RightPtr(1); 42370b324cSopenharmony_ci if (*p != '.') 43370b324cSopenharmony_ci return res; 44370b324cSopenharmony_ci if (p != path.Ptr()) 45370b324cSopenharmony_ci { 46370b324cSopenharmony_ci FChar c = p[-1]; 47370b324cSopenharmony_ci if (!IS_PATH_SEPAR(c)) 48370b324cSopenharmony_ci { 49370b324cSopenharmony_ci if (c != '.') 50370b324cSopenharmony_ci return res; 51370b324cSopenharmony_ci p--; 52370b324cSopenharmony_ci if (p != path.Ptr()) 53370b324cSopenharmony_ci { 54370b324cSopenharmony_ci c = p[-1]; 55370b324cSopenharmony_ci if (!IS_PATH_SEPAR(c)) 56370b324cSopenharmony_ci return res; 57370b324cSopenharmony_ci } 58370b324cSopenharmony_ci } 59370b324cSopenharmony_ci } 60370b324cSopenharmony_ci fi.Name = p; 61370b324cSopenharmony_ci return res; 62370b324cSopenharmony_ci} 63370b324cSopenharmony_ci 64370b324cSopenharmony_ci 65370b324cSopenharmony_civoid CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex, 66370b324cSopenharmony_ci const NFind::CFileInfo &fi) 67370b324cSopenharmony_ci{ 68370b324cSopenharmony_ci /* 69370b324cSopenharmony_ci CDirItem di(fi); 70370b324cSopenharmony_ci di.PhyParent = phyParent; 71370b324cSopenharmony_ci di.LogParent = logParent; 72370b324cSopenharmony_ci di.SecureIndex = secureIndex; 73370b324cSopenharmony_ci Items.Add(di); 74370b324cSopenharmony_ci */ 75370b324cSopenharmony_ci VECTOR_ADD_NEW_OBJECT (Items, CDirItem(fi, phyParent, logParent, secureIndex)) 76370b324cSopenharmony_ci 77370b324cSopenharmony_ci if (fi.IsDir()) 78370b324cSopenharmony_ci Stat.NumDirs++; 79370b324cSopenharmony_ci #ifdef _WIN32 80370b324cSopenharmony_ci else if (fi.IsAltStream) 81370b324cSopenharmony_ci { 82370b324cSopenharmony_ci Stat.NumAltStreams++; 83370b324cSopenharmony_ci Stat.AltStreamsSize += fi.Size; 84370b324cSopenharmony_ci } 85370b324cSopenharmony_ci #endif 86370b324cSopenharmony_ci else 87370b324cSopenharmony_ci { 88370b324cSopenharmony_ci Stat.NumFiles++; 89370b324cSopenharmony_ci Stat.FilesSize += fi.Size; 90370b324cSopenharmony_ci } 91370b324cSopenharmony_ci} 92370b324cSopenharmony_ci 93370b324cSopenharmony_ci// (DWORD)E_FAIL 94370b324cSopenharmony_ci#define DI_DEFAULT_ERROR ERROR_INVALID_FUNCTION 95370b324cSopenharmony_ci 96370b324cSopenharmony_ciHRESULT CDirItems::AddError(const FString &path, DWORD errorCode) 97370b324cSopenharmony_ci{ 98370b324cSopenharmony_ci if (errorCode == 0) 99370b324cSopenharmony_ci errorCode = DI_DEFAULT_ERROR; 100370b324cSopenharmony_ci Stat.NumErrors++; 101370b324cSopenharmony_ci if (Callback) 102370b324cSopenharmony_ci return Callback->ScanError(path, errorCode); 103370b324cSopenharmony_ci return S_OK; 104370b324cSopenharmony_ci} 105370b324cSopenharmony_ci 106370b324cSopenharmony_ciHRESULT CDirItems::AddError(const FString &path) 107370b324cSopenharmony_ci{ 108370b324cSopenharmony_ci return AddError(path, ::GetLastError()); 109370b324cSopenharmony_ci} 110370b324cSopenharmony_ci 111370b324cSopenharmony_cistatic const unsigned kScanProgressStepMask = (1 << 12) - 1; 112370b324cSopenharmony_ci 113370b324cSopenharmony_ciHRESULT CDirItems::ScanProgress(const FString &dirPath) 114370b324cSopenharmony_ci{ 115370b324cSopenharmony_ci if (Callback) 116370b324cSopenharmony_ci return Callback->ScanProgress(Stat, dirPath, true); 117370b324cSopenharmony_ci return S_OK; 118370b324cSopenharmony_ci} 119370b324cSopenharmony_ci 120370b324cSopenharmony_ciUString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const 121370b324cSopenharmony_ci{ 122370b324cSopenharmony_ci UString path; 123370b324cSopenharmony_ci unsigned len = name.Len(); 124370b324cSopenharmony_ci 125370b324cSopenharmony_ci int i; 126370b324cSopenharmony_ci for (i = index; i >= 0; i = parents[(unsigned)i]) 127370b324cSopenharmony_ci len += Prefixes[(unsigned)i].Len(); 128370b324cSopenharmony_ci 129370b324cSopenharmony_ci wchar_t *p = path.GetBuf_SetEnd(len) + len; 130370b324cSopenharmony_ci 131370b324cSopenharmony_ci p -= name.Len(); 132370b324cSopenharmony_ci wmemcpy(p, (const wchar_t *)name, name.Len()); 133370b324cSopenharmony_ci 134370b324cSopenharmony_ci for (i = index; i >= 0; i = parents[(unsigned)i]) 135370b324cSopenharmony_ci { 136370b324cSopenharmony_ci const UString &s = Prefixes[(unsigned)i]; 137370b324cSopenharmony_ci p -= s.Len(); 138370b324cSopenharmony_ci wmemcpy(p, (const wchar_t *)s, s.Len()); 139370b324cSopenharmony_ci } 140370b324cSopenharmony_ci 141370b324cSopenharmony_ci return path; 142370b324cSopenharmony_ci} 143370b324cSopenharmony_ci 144370b324cSopenharmony_ciFString CDirItems::GetPhyPath(unsigned index) const 145370b324cSopenharmony_ci{ 146370b324cSopenharmony_ci const CDirItem &di = Items[index]; 147370b324cSopenharmony_ci return us2fs(GetPrefixesPath(PhyParents, di.PhyParent, di.Name)); 148370b324cSopenharmony_ci} 149370b324cSopenharmony_ci 150370b324cSopenharmony_ciUString CDirItems::GetLogPath(unsigned index) const 151370b324cSopenharmony_ci{ 152370b324cSopenharmony_ci const CDirItem &di = Items[index]; 153370b324cSopenharmony_ci return GetPrefixesPath(LogParents, di.LogParent, di.Name); 154370b324cSopenharmony_ci} 155370b324cSopenharmony_ci 156370b324cSopenharmony_civoid CDirItems::ReserveDown() 157370b324cSopenharmony_ci{ 158370b324cSopenharmony_ci Prefixes.ReserveDown(); 159370b324cSopenharmony_ci PhyParents.ReserveDown(); 160370b324cSopenharmony_ci LogParents.ReserveDown(); 161370b324cSopenharmony_ci Items.ReserveDown(); 162370b324cSopenharmony_ci} 163370b324cSopenharmony_ci 164370b324cSopenharmony_ciunsigned CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix) 165370b324cSopenharmony_ci{ 166370b324cSopenharmony_ci PhyParents.Add(phyParent); 167370b324cSopenharmony_ci LogParents.Add(logParent); 168370b324cSopenharmony_ci return Prefixes.Add(prefix); 169370b324cSopenharmony_ci} 170370b324cSopenharmony_ci 171370b324cSopenharmony_civoid CDirItems::DeleteLastPrefix() 172370b324cSopenharmony_ci{ 173370b324cSopenharmony_ci PhyParents.DeleteBack(); 174370b324cSopenharmony_ci LogParents.DeleteBack(); 175370b324cSopenharmony_ci Prefixes.DeleteBack(); 176370b324cSopenharmony_ci} 177370b324cSopenharmony_ci 178370b324cSopenharmony_cibool InitLocalPrivileges(); 179370b324cSopenharmony_ci 180370b324cSopenharmony_ciCDirItems::CDirItems(): 181370b324cSopenharmony_ci SymLinks(false), 182370b324cSopenharmony_ci ScanAltStreams(false) 183370b324cSopenharmony_ci , ExcludeDirItems(false) 184370b324cSopenharmony_ci , ExcludeFileItems(false) 185370b324cSopenharmony_ci , ShareForWrite(false) 186370b324cSopenharmony_ci #ifdef Z7_USE_SECURITY_CODE 187370b324cSopenharmony_ci , ReadSecure(false) 188370b324cSopenharmony_ci #endif 189370b324cSopenharmony_ci #ifndef _WIN32 190370b324cSopenharmony_ci , StoreOwnerName(false) 191370b324cSopenharmony_ci #endif 192370b324cSopenharmony_ci , Callback(NULL) 193370b324cSopenharmony_ci{ 194370b324cSopenharmony_ci #ifdef Z7_USE_SECURITY_CODE 195370b324cSopenharmony_ci _saclEnabled = InitLocalPrivileges(); 196370b324cSopenharmony_ci #endif 197370b324cSopenharmony_ci} 198370b324cSopenharmony_ci 199370b324cSopenharmony_ci 200370b324cSopenharmony_ci#ifdef Z7_USE_SECURITY_CODE 201370b324cSopenharmony_ci 202370b324cSopenharmony_ciHRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex) 203370b324cSopenharmony_ci{ 204370b324cSopenharmony_ci secureIndex = -1; 205370b324cSopenharmony_ci 206370b324cSopenharmony_ci SECURITY_INFORMATION securInfo = 207370b324cSopenharmony_ci DACL_SECURITY_INFORMATION | 208370b324cSopenharmony_ci GROUP_SECURITY_INFORMATION | 209370b324cSopenharmony_ci OWNER_SECURITY_INFORMATION; 210370b324cSopenharmony_ci if (_saclEnabled) 211370b324cSopenharmony_ci securInfo |= SACL_SECURITY_INFORMATION; 212370b324cSopenharmony_ci 213370b324cSopenharmony_ci DWORD errorCode = 0; 214370b324cSopenharmony_ci DWORD secureSize; 215370b324cSopenharmony_ci 216370b324cSopenharmony_ci BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); 217370b324cSopenharmony_ci 218370b324cSopenharmony_ci if (res) 219370b324cSopenharmony_ci { 220370b324cSopenharmony_ci if (secureSize == 0) 221370b324cSopenharmony_ci return S_OK; 222370b324cSopenharmony_ci if (secureSize > TempSecureBuf.Size()) 223370b324cSopenharmony_ci errorCode = ERROR_INVALID_FUNCTION; 224370b324cSopenharmony_ci } 225370b324cSopenharmony_ci else 226370b324cSopenharmony_ci { 227370b324cSopenharmony_ci errorCode = GetLastError(); 228370b324cSopenharmony_ci if (errorCode == ERROR_INSUFFICIENT_BUFFER) 229370b324cSopenharmony_ci { 230370b324cSopenharmony_ci if (secureSize <= TempSecureBuf.Size()) 231370b324cSopenharmony_ci errorCode = ERROR_INVALID_FUNCTION; 232370b324cSopenharmony_ci else 233370b324cSopenharmony_ci { 234370b324cSopenharmony_ci TempSecureBuf.Alloc(secureSize); 235370b324cSopenharmony_ci res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); 236370b324cSopenharmony_ci if (res) 237370b324cSopenharmony_ci { 238370b324cSopenharmony_ci if (secureSize != TempSecureBuf.Size()) 239370b324cSopenharmony_ci errorCode = ERROR_INVALID_FUNCTION; 240370b324cSopenharmony_ci } 241370b324cSopenharmony_ci else 242370b324cSopenharmony_ci errorCode = GetLastError(); 243370b324cSopenharmony_ci } 244370b324cSopenharmony_ci } 245370b324cSopenharmony_ci } 246370b324cSopenharmony_ci 247370b324cSopenharmony_ci if (res) 248370b324cSopenharmony_ci { 249370b324cSopenharmony_ci secureIndex = (int)SecureBlocks.AddUniq(TempSecureBuf, secureSize); 250370b324cSopenharmony_ci return S_OK; 251370b324cSopenharmony_ci } 252370b324cSopenharmony_ci 253370b324cSopenharmony_ci return AddError(path, errorCode); 254370b324cSopenharmony_ci} 255370b324cSopenharmony_ci 256370b324cSopenharmony_ci#endif // Z7_USE_SECURITY_CODE 257370b324cSopenharmony_ci 258370b324cSopenharmony_ci 259370b324cSopenharmony_ciHRESULT CDirItems::EnumerateOneDir(const FString &phyPrefix, CObjectVector<NFind::CFileInfo> &files) 260370b324cSopenharmony_ci{ 261370b324cSopenharmony_ci NFind::CEnumerator enumerator; 262370b324cSopenharmony_ci // printf("\n enumerator.SetDirPrefix(phyPrefix) \n"); 263370b324cSopenharmony_ci 264370b324cSopenharmony_ci enumerator.SetDirPrefix(phyPrefix); 265370b324cSopenharmony_ci 266370b324cSopenharmony_ci #ifdef _WIN32 267370b324cSopenharmony_ci 268370b324cSopenharmony_ci NFind::CFileInfo fi; 269370b324cSopenharmony_ci 270370b324cSopenharmony_ci for (unsigned ttt = 0; ; ttt++) 271370b324cSopenharmony_ci { 272370b324cSopenharmony_ci bool found; 273370b324cSopenharmony_ci if (!enumerator.Next(fi, found)) 274370b324cSopenharmony_ci return AddError(phyPrefix); 275370b324cSopenharmony_ci if (!found) 276370b324cSopenharmony_ci return S_OK; 277370b324cSopenharmony_ci files.Add(fi); 278370b324cSopenharmony_ci if (Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask) 279370b324cSopenharmony_ci { 280370b324cSopenharmony_ci RINOK(ScanProgress(phyPrefix)) 281370b324cSopenharmony_ci } 282370b324cSopenharmony_ci } 283370b324cSopenharmony_ci 284370b324cSopenharmony_ci #else // _WIN32 285370b324cSopenharmony_ci 286370b324cSopenharmony_ci // enumerator.SolveLinks = !SymLinks; 287370b324cSopenharmony_ci 288370b324cSopenharmony_ci CObjectVector<NFind::CDirEntry> entries; 289370b324cSopenharmony_ci 290370b324cSopenharmony_ci for (unsigned ttt = 0; ; ttt++) 291370b324cSopenharmony_ci { 292370b324cSopenharmony_ci bool found; 293370b324cSopenharmony_ci NFind::CDirEntry de; 294370b324cSopenharmony_ci if (!enumerator.Next(de, found)) 295370b324cSopenharmony_ci { 296370b324cSopenharmony_ci return AddError(phyPrefix); 297370b324cSopenharmony_ci } 298370b324cSopenharmony_ci if (!found) 299370b324cSopenharmony_ci break; 300370b324cSopenharmony_ci entries.Add(de); 301370b324cSopenharmony_ci } 302370b324cSopenharmony_ci 303370b324cSopenharmony_ci FOR_VECTOR(i, entries) 304370b324cSopenharmony_ci { 305370b324cSopenharmony_ci const NFind::CDirEntry &de = entries[i]; 306370b324cSopenharmony_ci NFind::CFileInfo fi; 307370b324cSopenharmony_ci if (!enumerator.Fill_FileInfo(de, fi, !SymLinks)) 308370b324cSopenharmony_ci // if (!fi.Find_AfterEnumerator(path)) 309370b324cSopenharmony_ci { 310370b324cSopenharmony_ci const FString path = phyPrefix + de.Name; 311370b324cSopenharmony_ci { 312370b324cSopenharmony_ci RINOK(AddError(path)) 313370b324cSopenharmony_ci continue; 314370b324cSopenharmony_ci } 315370b324cSopenharmony_ci } 316370b324cSopenharmony_ci 317370b324cSopenharmony_ci files.Add(fi); 318370b324cSopenharmony_ci 319370b324cSopenharmony_ci if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) 320370b324cSopenharmony_ci { 321370b324cSopenharmony_ci RINOK(ScanProgress(phyPrefix)) 322370b324cSopenharmony_ci } 323370b324cSopenharmony_ci } 324370b324cSopenharmony_ci 325370b324cSopenharmony_ci return S_OK; 326370b324cSopenharmony_ci 327370b324cSopenharmony_ci #endif // _WIN32 328370b324cSopenharmony_ci} 329370b324cSopenharmony_ci 330370b324cSopenharmony_ci 331370b324cSopenharmony_ci 332370b324cSopenharmony_ci 333370b324cSopenharmony_ciHRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix) 334370b324cSopenharmony_ci{ 335370b324cSopenharmony_ci RINOK(ScanProgress(phyPrefix)) 336370b324cSopenharmony_ci 337370b324cSopenharmony_ci CObjectVector<NFind::CFileInfo> files; 338370b324cSopenharmony_ci RINOK(EnumerateOneDir(phyPrefix, files)) 339370b324cSopenharmony_ci 340370b324cSopenharmony_ci FOR_VECTOR (i, files) 341370b324cSopenharmony_ci { 342370b324cSopenharmony_ci #ifdef _WIN32 343370b324cSopenharmony_ci const NFind::CFileInfo &fi = files[i]; 344370b324cSopenharmony_ci #else 345370b324cSopenharmony_ci const NFind::CFileInfo &fi = files[i]; 346370b324cSopenharmony_ci /* 347370b324cSopenharmony_ci NFind::CFileInfo fi; 348370b324cSopenharmony_ci { 349370b324cSopenharmony_ci const NFind::CDirEntry &di = files[i]; 350370b324cSopenharmony_ci const FString path = phyPrefix + di.Name; 351370b324cSopenharmony_ci if (!fi.Find_AfterEnumerator(path)) 352370b324cSopenharmony_ci { 353370b324cSopenharmony_ci RINOK(AddError(path)); 354370b324cSopenharmony_ci continue; 355370b324cSopenharmony_ci } 356370b324cSopenharmony_ci fi.Name = di.Name; 357370b324cSopenharmony_ci } 358370b324cSopenharmony_ci */ 359370b324cSopenharmony_ci #endif 360370b324cSopenharmony_ci 361370b324cSopenharmony_ci if (CanIncludeItem(fi.IsDir())) 362370b324cSopenharmony_ci { 363370b324cSopenharmony_ci int secureIndex = -1; 364370b324cSopenharmony_ci #ifdef Z7_USE_SECURITY_CODE 365370b324cSopenharmony_ci if (ReadSecure) 366370b324cSopenharmony_ci { 367370b324cSopenharmony_ci RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex)) 368370b324cSopenharmony_ci } 369370b324cSopenharmony_ci #endif 370370b324cSopenharmony_ci AddDirFileInfo(phyParent, logParent, secureIndex, fi); 371370b324cSopenharmony_ci } 372370b324cSopenharmony_ci 373370b324cSopenharmony_ci if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) 374370b324cSopenharmony_ci { 375370b324cSopenharmony_ci RINOK(ScanProgress(phyPrefix)) 376370b324cSopenharmony_ci } 377370b324cSopenharmony_ci 378370b324cSopenharmony_ci if (fi.IsDir()) 379370b324cSopenharmony_ci { 380370b324cSopenharmony_ci const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; 381370b324cSopenharmony_ci unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2)); 382370b324cSopenharmony_ci RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + name2)) 383370b324cSopenharmony_ci } 384370b324cSopenharmony_ci } 385370b324cSopenharmony_ci return S_OK; 386370b324cSopenharmony_ci} 387370b324cSopenharmony_ci 388370b324cSopenharmony_ci 389370b324cSopenharmony_ci/* 390370b324cSopenharmony_ciEnumerateItems2() 391370b324cSopenharmony_ci const FStringVector &filePaths - are path without tail slashes. 392370b324cSopenharmony_ci All dir prefixes of filePaths will be not stores in logical paths 393370b324cSopenharmony_cifix it: we can scan AltStream also. 394370b324cSopenharmony_ci*/ 395370b324cSopenharmony_ci 396370b324cSopenharmony_ci#ifdef _WIN32 397370b324cSopenharmony_ci// #define FOLLOW_LINK_PARAM 398370b324cSopenharmony_ci// #define FOLLOW_LINK_PARAM2 399370b324cSopenharmony_ci#define FOLLOW_LINK_PARAM , (!SymLinks) 400370b324cSopenharmony_ci#define FOLLOW_LINK_PARAM2 , (!dirItems.SymLinks) 401370b324cSopenharmony_ci#else 402370b324cSopenharmony_ci#define FOLLOW_LINK_PARAM , (!SymLinks) 403370b324cSopenharmony_ci#define FOLLOW_LINK_PARAM2 , (!dirItems.SymLinks) 404370b324cSopenharmony_ci#endif 405370b324cSopenharmony_ci 406370b324cSopenharmony_ciHRESULT CDirItems::EnumerateItems2( 407370b324cSopenharmony_ci const FString &phyPrefix, 408370b324cSopenharmony_ci const UString &logPrefix, 409370b324cSopenharmony_ci const FStringVector &filePaths, 410370b324cSopenharmony_ci FStringVector *requestedPaths) 411370b324cSopenharmony_ci{ 412370b324cSopenharmony_ci const int phyParent = phyPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, fs2us(phyPrefix)); 413370b324cSopenharmony_ci const int logParent = logPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, logPrefix); 414370b324cSopenharmony_ci 415370b324cSopenharmony_ci #ifdef _WIN32 416370b324cSopenharmony_ci const bool phyPrefix_isAltStreamPrefix = 417370b324cSopenharmony_ci NFile::NName::IsAltStreamPrefixWithColon(fs2us(phyPrefix)); 418370b324cSopenharmony_ci #endif 419370b324cSopenharmony_ci 420370b324cSopenharmony_ci FOR_VECTOR (i, filePaths) 421370b324cSopenharmony_ci { 422370b324cSopenharmony_ci const FString &filePath = filePaths[i]; 423370b324cSopenharmony_ci NFind::CFileInfo fi; 424370b324cSopenharmony_ci const FString phyPath = phyPrefix + filePath; 425370b324cSopenharmony_ci if (!FindFile_KeepDots(fi, phyPath FOLLOW_LINK_PARAM)) 426370b324cSopenharmony_ci { 427370b324cSopenharmony_ci RINOK(AddError(phyPath)) 428370b324cSopenharmony_ci continue; 429370b324cSopenharmony_ci } 430370b324cSopenharmony_ci if (requestedPaths) 431370b324cSopenharmony_ci requestedPaths->Add(phyPath); 432370b324cSopenharmony_ci 433370b324cSopenharmony_ci const int delimiter = filePath.ReverseFind_PathSepar(); 434370b324cSopenharmony_ci FString phyPrefixCur; 435370b324cSopenharmony_ci int phyParentCur = phyParent; 436370b324cSopenharmony_ci if (delimiter >= 0) 437370b324cSopenharmony_ci { 438370b324cSopenharmony_ci phyPrefixCur.SetFrom(filePath, (unsigned)(delimiter + 1)); 439370b324cSopenharmony_ci phyParentCur = (int)AddPrefix(phyParent, logParent, fs2us(phyPrefixCur)); 440370b324cSopenharmony_ci } 441370b324cSopenharmony_ci 442370b324cSopenharmony_ci if (CanIncludeItem(fi.IsDir())) 443370b324cSopenharmony_ci { 444370b324cSopenharmony_ci int secureIndex = -1; 445370b324cSopenharmony_ci #ifdef Z7_USE_SECURITY_CODE 446370b324cSopenharmony_ci if (ReadSecure) 447370b324cSopenharmony_ci { 448370b324cSopenharmony_ci RINOK(AddSecurityItem(phyPath, secureIndex)) 449370b324cSopenharmony_ci } 450370b324cSopenharmony_ci #endif 451370b324cSopenharmony_ci #ifdef _WIN32 452370b324cSopenharmony_ci if (phyPrefix_isAltStreamPrefix && fi.IsAltStream) 453370b324cSopenharmony_ci { 454370b324cSopenharmony_ci const int pos = fi.Name.Find(FChar(':')); 455370b324cSopenharmony_ci if (pos >= 0) 456370b324cSopenharmony_ci fi.Name.DeleteFrontal((unsigned)pos + 1); 457370b324cSopenharmony_ci } 458370b324cSopenharmony_ci #endif 459370b324cSopenharmony_ci AddDirFileInfo(phyParentCur, logParent, secureIndex, fi); 460370b324cSopenharmony_ci } 461370b324cSopenharmony_ci 462370b324cSopenharmony_ci if (fi.IsDir()) 463370b324cSopenharmony_ci { 464370b324cSopenharmony_ci const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; 465370b324cSopenharmony_ci const unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2)); 466370b324cSopenharmony_ci RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + phyPrefixCur + name2)) 467370b324cSopenharmony_ci } 468370b324cSopenharmony_ci } 469370b324cSopenharmony_ci 470370b324cSopenharmony_ci ReserveDown(); 471370b324cSopenharmony_ci return S_OK; 472370b324cSopenharmony_ci} 473370b324cSopenharmony_ci 474370b324cSopenharmony_ci 475370b324cSopenharmony_ci 476370b324cSopenharmony_ci 477370b324cSopenharmony_cistatic HRESULT EnumerateDirItems( 478370b324cSopenharmony_ci const NWildcard::CCensorNode &curNode, 479370b324cSopenharmony_ci const int phyParent, const int logParent, 480370b324cSopenharmony_ci const FString &phyPrefix, 481370b324cSopenharmony_ci const UStringVector &addParts, // additional parts from curNode 482370b324cSopenharmony_ci CDirItems &dirItems, 483370b324cSopenharmony_ci bool enterToSubFolders); 484370b324cSopenharmony_ci 485370b324cSopenharmony_ci 486370b324cSopenharmony_ci/* EnumerateDirItems_Spec() 487370b324cSopenharmony_ci adds new Dir item prefix, and enumerates dir items, 488370b324cSopenharmony_ci then it can remove that Dir item prefix, if there are no items in that dir. 489370b324cSopenharmony_ci*/ 490370b324cSopenharmony_ci 491370b324cSopenharmony_ci 492370b324cSopenharmony_ci/* 493370b324cSopenharmony_ci EnumerateDirItems_Spec() 494370b324cSopenharmony_ci it's similar to EnumerateDirItems, but phyPrefix doesn't include (curFolderName) 495370b324cSopenharmony_ci*/ 496370b324cSopenharmony_ci 497370b324cSopenharmony_cistatic HRESULT EnumerateDirItems_Spec( 498370b324cSopenharmony_ci const NWildcard::CCensorNode &curNode, 499370b324cSopenharmony_ci const int phyParent, const int logParent, const FString &curFolderName, 500370b324cSopenharmony_ci const FString &phyPrefix, // without (curFolderName) 501370b324cSopenharmony_ci const UStringVector &addParts, // (curNode + addParts) includes (curFolderName) 502370b324cSopenharmony_ci CDirItems &dirItems, 503370b324cSopenharmony_ci bool enterToSubFolders) 504370b324cSopenharmony_ci{ 505370b324cSopenharmony_ci const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR; 506370b324cSopenharmony_ci const unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2)); 507370b324cSopenharmony_ci const unsigned numItems = dirItems.Items.Size(); 508370b324cSopenharmony_ci HRESULT res = EnumerateDirItems( 509370b324cSopenharmony_ci curNode, (int)parent, (int)parent, phyPrefix + name2, 510370b324cSopenharmony_ci addParts, dirItems, enterToSubFolders); 511370b324cSopenharmony_ci if (numItems == dirItems.Items.Size()) 512370b324cSopenharmony_ci dirItems.DeleteLastPrefix(); 513370b324cSopenharmony_ci return res; 514370b324cSopenharmony_ci} 515370b324cSopenharmony_ci 516370b324cSopenharmony_ci 517370b324cSopenharmony_ci#ifndef UNDER_CE 518370b324cSopenharmony_ci 519370b324cSopenharmony_ci#ifdef _WIN32 520370b324cSopenharmony_ci 521370b324cSopenharmony_cistatic HRESULT EnumerateAltStreams( 522370b324cSopenharmony_ci const NFind::CFileInfo &fi, 523370b324cSopenharmony_ci const NWildcard::CCensorNode &curNode, 524370b324cSopenharmony_ci const int phyParent, const int logParent, 525370b324cSopenharmony_ci const FString &phyPath, // with (fi.Name), without tail slash for folders 526370b324cSopenharmony_ci const UStringVector &addParts, // with (fi.Name), prefix parts from curNode 527370b324cSopenharmony_ci bool addAllSubStreams, 528370b324cSopenharmony_ci CDirItems &dirItems) 529370b324cSopenharmony_ci{ 530370b324cSopenharmony_ci // we don't use (ExcludeFileItems) rules for AltStreams 531370b324cSopenharmony_ci // if (dirItems.ExcludeFileItems) return S_OK; 532370b324cSopenharmony_ci 533370b324cSopenharmony_ci NFind::CStreamEnumerator enumerator(phyPath); 534370b324cSopenharmony_ci for (;;) 535370b324cSopenharmony_ci { 536370b324cSopenharmony_ci NFind::CStreamInfo si; 537370b324cSopenharmony_ci bool found; 538370b324cSopenharmony_ci if (!enumerator.Next(si, found)) 539370b324cSopenharmony_ci { 540370b324cSopenharmony_ci return dirItems.AddError(phyPath + FTEXT(":*")); // , (DWORD)E_FAIL 541370b324cSopenharmony_ci } 542370b324cSopenharmony_ci if (!found) 543370b324cSopenharmony_ci return S_OK; 544370b324cSopenharmony_ci if (si.IsMainStream()) 545370b324cSopenharmony_ci continue; 546370b324cSopenharmony_ci UStringVector parts = addParts; 547370b324cSopenharmony_ci const UString reducedName = si.GetReducedName(); 548370b324cSopenharmony_ci parts.Back() += reducedName; 549370b324cSopenharmony_ci if (curNode.CheckPathToRoot(false, parts, true)) 550370b324cSopenharmony_ci continue; 551370b324cSopenharmony_ci if (!addAllSubStreams) 552370b324cSopenharmony_ci if (!curNode.CheckPathToRoot(true, parts, true)) 553370b324cSopenharmony_ci continue; 554370b324cSopenharmony_ci 555370b324cSopenharmony_ci NFind::CFileInfo fi2 = fi; 556370b324cSopenharmony_ci fi2.Name += us2fs(reducedName); 557370b324cSopenharmony_ci fi2.Size = si.Size; 558370b324cSopenharmony_ci fi2.Attrib &= ~(DWORD)(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); 559370b324cSopenharmony_ci fi2.IsAltStream = true; 560370b324cSopenharmony_ci dirItems.AddDirFileInfo(phyParent, logParent, -1, fi2); 561370b324cSopenharmony_ci } 562370b324cSopenharmony_ci} 563370b324cSopenharmony_ci 564370b324cSopenharmony_ci#endif // _WIN32 565370b324cSopenharmony_ci 566370b324cSopenharmony_ci 567370b324cSopenharmony_ci/* We get Reparse data and parse it. 568370b324cSopenharmony_ci If there is Reparse error, we free dirItem.Reparse data. 569370b324cSopenharmony_ci Do we need to work with empty reparse data? 570370b324cSopenharmony_ci*/ 571370b324cSopenharmony_ci 572370b324cSopenharmony_ciHRESULT CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi, 573370b324cSopenharmony_ci const FString &phyPrefix) 574370b324cSopenharmony_ci{ 575370b324cSopenharmony_ci if (!SymLinks) 576370b324cSopenharmony_ci return S_OK; 577370b324cSopenharmony_ci 578370b324cSopenharmony_ci #ifdef _WIN32 579370b324cSopenharmony_ci if (!fi.HasReparsePoint() || fi.IsAltStream) 580370b324cSopenharmony_ci #else // _WIN32 581370b324cSopenharmony_ci if (!fi.IsPosixLink()) 582370b324cSopenharmony_ci #endif // _WIN32 583370b324cSopenharmony_ci return S_OK; 584370b324cSopenharmony_ci 585370b324cSopenharmony_ci const FString path = phyPrefix + fi.Name; 586370b324cSopenharmony_ci CByteBuffer &buf = dirItem.ReparseData; 587370b324cSopenharmony_ci if (NIO::GetReparseData(path, buf)) 588370b324cSopenharmony_ci { 589370b324cSopenharmony_ci // if (dirItem.ReparseData.Size() != 0) 590370b324cSopenharmony_ci Stat.FilesSize -= fi.Size; 591370b324cSopenharmony_ci return S_OK; 592370b324cSopenharmony_ci } 593370b324cSopenharmony_ci 594370b324cSopenharmony_ci DWORD res = ::GetLastError(); 595370b324cSopenharmony_ci buf.Free(); 596370b324cSopenharmony_ci return AddError(path, res); 597370b324cSopenharmony_ci} 598370b324cSopenharmony_ci 599370b324cSopenharmony_ci#endif // UNDER_CE 600370b324cSopenharmony_ci 601370b324cSopenharmony_ci 602370b324cSopenharmony_ci 603370b324cSopenharmony_cistatic HRESULT EnumerateForItem( 604370b324cSopenharmony_ci const NFind::CFileInfo &fi, 605370b324cSopenharmony_ci const NWildcard::CCensorNode &curNode, 606370b324cSopenharmony_ci const int phyParent, const int logParent, const FString &phyPrefix, 607370b324cSopenharmony_ci const UStringVector &addParts, // additional parts from curNode, without (fi.Name) 608370b324cSopenharmony_ci CDirItems &dirItems, 609370b324cSopenharmony_ci bool enterToSubFolders) 610370b324cSopenharmony_ci{ 611370b324cSopenharmony_ci const UString name = fs2us(fi.Name); 612370b324cSopenharmony_ci UStringVector newParts = addParts; 613370b324cSopenharmony_ci newParts.Add(name); 614370b324cSopenharmony_ci 615370b324cSopenharmony_ci // check the path in exclude rules 616370b324cSopenharmony_ci if (curNode.CheckPathToRoot(false, newParts, !fi.IsDir())) 617370b324cSopenharmony_ci return S_OK; 618370b324cSopenharmony_ci 619370b324cSopenharmony_ci #if !defined(UNDER_CE) 620370b324cSopenharmony_ci int dirItemIndex = -1; 621370b324cSopenharmony_ci #if defined(_WIN32) 622370b324cSopenharmony_ci bool addAllSubStreams = false; 623370b324cSopenharmony_ci bool needAltStreams = true; 624370b324cSopenharmony_ci #endif // _WIN32 625370b324cSopenharmony_ci #endif // !defined(UNDER_CE) 626370b324cSopenharmony_ci 627370b324cSopenharmony_ci // check the path in inlcude rules 628370b324cSopenharmony_ci if (curNode.CheckPathToRoot(true, newParts, !fi.IsDir())) 629370b324cSopenharmony_ci { 630370b324cSopenharmony_ci #if !defined(UNDER_CE) 631370b324cSopenharmony_ci // dirItemIndex = (int)dirItems.Items.Size(); 632370b324cSopenharmony_ci #if defined(_WIN32) 633370b324cSopenharmony_ci // we will not check include rules for substreams. 634370b324cSopenharmony_ci addAllSubStreams = true; 635370b324cSopenharmony_ci #endif // _WIN32 636370b324cSopenharmony_ci #endif // !defined(UNDER_CE) 637370b324cSopenharmony_ci 638370b324cSopenharmony_ci if (dirItems.CanIncludeItem(fi.IsDir())) 639370b324cSopenharmony_ci { 640370b324cSopenharmony_ci int secureIndex = -1; 641370b324cSopenharmony_ci #ifdef Z7_USE_SECURITY_CODE 642370b324cSopenharmony_ci if (dirItems.ReadSecure) 643370b324cSopenharmony_ci { 644370b324cSopenharmony_ci RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex)) 645370b324cSopenharmony_ci } 646370b324cSopenharmony_ci #endif 647370b324cSopenharmony_ci #if !defined(UNDER_CE) 648370b324cSopenharmony_ci dirItemIndex = (int)dirItems.Items.Size(); 649370b324cSopenharmony_ci #endif // !defined(UNDER_CE) 650370b324cSopenharmony_ci dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); 651370b324cSopenharmony_ci } 652370b324cSopenharmony_ci else 653370b324cSopenharmony_ci { 654370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 655370b324cSopenharmony_ci needAltStreams = false; 656370b324cSopenharmony_ci #endif 657370b324cSopenharmony_ci } 658370b324cSopenharmony_ci 659370b324cSopenharmony_ci if (fi.IsDir()) 660370b324cSopenharmony_ci enterToSubFolders = true; 661370b324cSopenharmony_ci } 662370b324cSopenharmony_ci 663370b324cSopenharmony_ci #if !defined(UNDER_CE) 664370b324cSopenharmony_ci 665370b324cSopenharmony_ci // we don't scan AltStreams for link files 666370b324cSopenharmony_ci 667370b324cSopenharmony_ci if (dirItemIndex >= 0) 668370b324cSopenharmony_ci { 669370b324cSopenharmony_ci CDirItem &dirItem = dirItems.Items[(unsigned)dirItemIndex]; 670370b324cSopenharmony_ci RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)) 671370b324cSopenharmony_ci if (dirItem.ReparseData.Size() != 0) 672370b324cSopenharmony_ci return S_OK; 673370b324cSopenharmony_ci } 674370b324cSopenharmony_ci 675370b324cSopenharmony_ci #if defined(_WIN32) 676370b324cSopenharmony_ci if (needAltStreams && dirItems.ScanAltStreams) 677370b324cSopenharmony_ci { 678370b324cSopenharmony_ci RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, 679370b324cSopenharmony_ci phyPrefix + fi.Name, // with (fi.Name) 680370b324cSopenharmony_ci newParts, // with (fi.Name) 681370b324cSopenharmony_ci addAllSubStreams, 682370b324cSopenharmony_ci dirItems)) 683370b324cSopenharmony_ci } 684370b324cSopenharmony_ci #endif 685370b324cSopenharmony_ci 686370b324cSopenharmony_ci #endif // !defined(UNDER_CE) 687370b324cSopenharmony_ci 688370b324cSopenharmony_ci 689370b324cSopenharmony_ci #ifndef _WIN32 690370b324cSopenharmony_ci if (!fi.IsPosixLink()) // posix link can follow to dir 691370b324cSopenharmony_ci #endif 692370b324cSopenharmony_ci if (!fi.IsDir()) 693370b324cSopenharmony_ci return S_OK; 694370b324cSopenharmony_ci 695370b324cSopenharmony_ci const NWildcard::CCensorNode *nextNode = NULL; 696370b324cSopenharmony_ci 697370b324cSopenharmony_ci if (addParts.IsEmpty()) 698370b324cSopenharmony_ci { 699370b324cSopenharmony_ci int index = curNode.FindSubNode(name); 700370b324cSopenharmony_ci if (index >= 0) 701370b324cSopenharmony_ci { 702370b324cSopenharmony_ci nextNode = &curNode.SubNodes[(unsigned)index]; 703370b324cSopenharmony_ci newParts.Clear(); 704370b324cSopenharmony_ci } 705370b324cSopenharmony_ci } 706370b324cSopenharmony_ci 707370b324cSopenharmony_ci if (!nextNode) 708370b324cSopenharmony_ci { 709370b324cSopenharmony_ci if (!enterToSubFolders) 710370b324cSopenharmony_ci return S_OK; 711370b324cSopenharmony_ci 712370b324cSopenharmony_ci #ifndef _WIN32 713370b324cSopenharmony_ci if (fi.IsPosixLink()) 714370b324cSopenharmony_ci { 715370b324cSopenharmony_ci // here we can try to resolve posix link 716370b324cSopenharmony_ci // if the link to dir, then can we follow it 717370b324cSopenharmony_ci return S_OK; // we don't follow posix link 718370b324cSopenharmony_ci } 719370b324cSopenharmony_ci #else 720370b324cSopenharmony_ci if (dirItems.SymLinks && fi.HasReparsePoint()) 721370b324cSopenharmony_ci { 722370b324cSopenharmony_ci /* 20.03: in SymLinks mode: we don't enter to directory that 723370b324cSopenharmony_ci has reparse point and has no CCensorNode 724370b324cSopenharmony_ci NOTE: (curNode and parent nodes) still can have wildcard rules 725370b324cSopenharmony_ci to include some items of target directory (of reparse point), 726370b324cSopenharmony_ci but we ignore these rules here. 727370b324cSopenharmony_ci */ 728370b324cSopenharmony_ci return S_OK; 729370b324cSopenharmony_ci } 730370b324cSopenharmony_ci #endif 731370b324cSopenharmony_ci nextNode = &curNode; 732370b324cSopenharmony_ci } 733370b324cSopenharmony_ci 734370b324cSopenharmony_ci return EnumerateDirItems_Spec( 735370b324cSopenharmony_ci *nextNode, phyParent, logParent, fi.Name, 736370b324cSopenharmony_ci phyPrefix, // without (fi.Name) 737370b324cSopenharmony_ci newParts, // relative to (*nextNode). (*nextNode + newParts) includes (fi.Name) 738370b324cSopenharmony_ci dirItems, 739370b324cSopenharmony_ci enterToSubFolders); 740370b324cSopenharmony_ci} 741370b324cSopenharmony_ci 742370b324cSopenharmony_ci 743370b324cSopenharmony_cistatic bool CanUseFsDirect(const NWildcard::CCensorNode &curNode) 744370b324cSopenharmony_ci{ 745370b324cSopenharmony_ci FOR_VECTOR (i, curNode.IncludeItems) 746370b324cSopenharmony_ci { 747370b324cSopenharmony_ci const NWildcard::CItem &item = curNode.IncludeItems[i]; 748370b324cSopenharmony_ci if (item.Recursive || item.PathParts.Size() != 1) 749370b324cSopenharmony_ci return false; 750370b324cSopenharmony_ci const UString &name = item.PathParts.Front(); 751370b324cSopenharmony_ci /* 752370b324cSopenharmony_ci if (name.IsEmpty()) 753370b324cSopenharmony_ci return false; 754370b324cSopenharmony_ci */ 755370b324cSopenharmony_ci 756370b324cSopenharmony_ci /* Windows doesn't support file name with wildcard 757370b324cSopenharmony_ci But if another system supports file name with wildcard, 758370b324cSopenharmony_ci and wildcard mode is disabled, we can ignore wildcard in name 759370b324cSopenharmony_ci */ 760370b324cSopenharmony_ci /* 761370b324cSopenharmony_ci #ifndef _WIN32 762370b324cSopenharmony_ci if (!item.WildcardParsing) 763370b324cSopenharmony_ci continue; 764370b324cSopenharmony_ci #endif 765370b324cSopenharmony_ci */ 766370b324cSopenharmony_ci if (DoesNameContainWildcard(name)) 767370b324cSopenharmony_ci return false; 768370b324cSopenharmony_ci } 769370b324cSopenharmony_ci return true; 770370b324cSopenharmony_ci} 771370b324cSopenharmony_ci 772370b324cSopenharmony_ci 773370b324cSopenharmony_ci#if defined(_WIN32) && !defined(UNDER_CE) 774370b324cSopenharmony_ci 775370b324cSopenharmony_cistatic bool IsVirtualFsFolder(const FString &prefix, const UString &name) 776370b324cSopenharmony_ci{ 777370b324cSopenharmony_ci UString s = fs2us(prefix); 778370b324cSopenharmony_ci s += name; 779370b324cSopenharmony_ci s.Add_PathSepar(); 780370b324cSopenharmony_ci // it returns (true) for non real FS folder path like - "\\SERVER\" 781370b324cSopenharmony_ci return IsPathSepar(s[0]) && GetRootPrefixSize(s) == 0; 782370b324cSopenharmony_ci} 783370b324cSopenharmony_ci 784370b324cSopenharmony_ci#endif 785370b324cSopenharmony_ci 786370b324cSopenharmony_ci 787370b324cSopenharmony_ci 788370b324cSopenharmony_cistatic HRESULT EnumerateDirItems( 789370b324cSopenharmony_ci const NWildcard::CCensorNode &curNode, 790370b324cSopenharmony_ci const int phyParent, const int logParent, const FString &phyPrefix, 791370b324cSopenharmony_ci const UStringVector &addParts, // prefix from curNode including 792370b324cSopenharmony_ci CDirItems &dirItems, 793370b324cSopenharmony_ci bool enterToSubFolders) 794370b324cSopenharmony_ci{ 795370b324cSopenharmony_ci if (!enterToSubFolders) 796370b324cSopenharmony_ci { 797370b324cSopenharmony_ci /* if there are IncludeItems censor rules that affect items in subdirs, 798370b324cSopenharmony_ci then we will enter to all subfolders */ 799370b324cSopenharmony_ci if (curNode.NeedCheckSubDirs()) 800370b324cSopenharmony_ci enterToSubFolders = true; 801370b324cSopenharmony_ci } 802370b324cSopenharmony_ci 803370b324cSopenharmony_ci RINOK(dirItems.ScanProgress(phyPrefix)) 804370b324cSopenharmony_ci 805370b324cSopenharmony_ci // try direct_names case at first 806370b324cSopenharmony_ci if (addParts.IsEmpty() && !enterToSubFolders) 807370b324cSopenharmony_ci { 808370b324cSopenharmony_ci if (CanUseFsDirect(curNode)) 809370b324cSopenharmony_ci { 810370b324cSopenharmony_ci // all names are direct (no wildcards) 811370b324cSopenharmony_ci // so we don't need file_system's dir enumerator 812370b324cSopenharmony_ci CRecordVector<bool> needEnterVector; 813370b324cSopenharmony_ci unsigned i; 814370b324cSopenharmony_ci 815370b324cSopenharmony_ci for (i = 0; i < curNode.IncludeItems.Size(); i++) 816370b324cSopenharmony_ci { 817370b324cSopenharmony_ci const NWildcard::CItem &item = curNode.IncludeItems[i]; 818370b324cSopenharmony_ci const UString &name = item.PathParts.Front(); 819370b324cSopenharmony_ci FString fullPath = phyPrefix + us2fs(name); 820370b324cSopenharmony_ci 821370b324cSopenharmony_ci /* 822370b324cSopenharmony_ci // not possible now 823370b324cSopenharmony_ci if (!item.ForDir && !item.ForFile) 824370b324cSopenharmony_ci { 825370b324cSopenharmony_ci RINOK(dirItems.AddError(fullPath, ERROR_INVALID_PARAMETER)); 826370b324cSopenharmony_ci continue; 827370b324cSopenharmony_ci } 828370b324cSopenharmony_ci */ 829370b324cSopenharmony_ci 830370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 831370b324cSopenharmony_ci bool needAltStreams = true; 832370b324cSopenharmony_ci #endif 833370b324cSopenharmony_ci 834370b324cSopenharmony_ci #ifdef Z7_USE_SECURITY_CODE 835370b324cSopenharmony_ci bool needSecurity = true; 836370b324cSopenharmony_ci #endif 837370b324cSopenharmony_ci 838370b324cSopenharmony_ci if (phyPrefix.IsEmpty()) 839370b324cSopenharmony_ci { 840370b324cSopenharmony_ci if (!item.ForFile) 841370b324cSopenharmony_ci { 842370b324cSopenharmony_ci /* we don't like some names for alt streams inside archive: 843370b324cSopenharmony_ci ":sname" for "\" 844370b324cSopenharmony_ci "c:::sname" for "C:\" 845370b324cSopenharmony_ci So we ignore alt streams for these cases */ 846370b324cSopenharmony_ci if (name.IsEmpty()) 847370b324cSopenharmony_ci { 848370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 849370b324cSopenharmony_ci needAltStreams = false; 850370b324cSopenharmony_ci #endif 851370b324cSopenharmony_ci 852370b324cSopenharmony_ci /* 853370b324cSopenharmony_ci // do we need to ignore security info for "\\" folder ? 854370b324cSopenharmony_ci #ifdef Z7_USE_SECURITY_CODE 855370b324cSopenharmony_ci needSecurity = false; 856370b324cSopenharmony_ci #endif 857370b324cSopenharmony_ci */ 858370b324cSopenharmony_ci 859370b324cSopenharmony_ci fullPath = CHAR_PATH_SEPARATOR; 860370b324cSopenharmony_ci } 861370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 862370b324cSopenharmony_ci else if (item.IsDriveItem()) 863370b324cSopenharmony_ci { 864370b324cSopenharmony_ci needAltStreams = false; 865370b324cSopenharmony_ci fullPath.Add_PathSepar(); 866370b324cSopenharmony_ci } 867370b324cSopenharmony_ci #endif 868370b324cSopenharmony_ci } 869370b324cSopenharmony_ci } 870370b324cSopenharmony_ci 871370b324cSopenharmony_ci NFind::CFileInfo fi; 872370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 873370b324cSopenharmony_ci if (IsVirtualFsFolder(phyPrefix, name)) 874370b324cSopenharmony_ci { 875370b324cSopenharmony_ci fi.SetAsDir(); 876370b324cSopenharmony_ci fi.Name = us2fs(name); 877370b324cSopenharmony_ci } 878370b324cSopenharmony_ci else 879370b324cSopenharmony_ci #endif 880370b324cSopenharmony_ci if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) 881370b324cSopenharmony_ci { 882370b324cSopenharmony_ci RINOK(dirItems.AddError(fullPath)) 883370b324cSopenharmony_ci continue; 884370b324cSopenharmony_ci } 885370b324cSopenharmony_ci 886370b324cSopenharmony_ci /* 887370b324cSopenharmony_ci #ifdef _WIN32 888370b324cSopenharmony_ci #define MY_ERROR_IS_DIR ERROR_FILE_NOT_FOUND 889370b324cSopenharmony_ci #define MY_ERROR_NOT_DIR DI_DEFAULT_ERROR 890370b324cSopenharmony_ci #else 891370b324cSopenharmony_ci #define MY_ERROR_IS_DIR EISDIR 892370b324cSopenharmony_ci #define MY_ERROR_NOT_DIR ENOTDIR 893370b324cSopenharmony_ci #endif 894370b324cSopenharmony_ci */ 895370b324cSopenharmony_ci 896370b324cSopenharmony_ci const bool isDir = fi.IsDir(); 897370b324cSopenharmony_ci if (isDir ? !item.ForDir : !item.ForFile) 898370b324cSopenharmony_ci { 899370b324cSopenharmony_ci // RINOK(dirItems.AddError(fullPath, isDir ? MY_ERROR_IS_DIR: MY_ERROR_NOT_DIR)); 900370b324cSopenharmony_ci RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)) 901370b324cSopenharmony_ci continue; 902370b324cSopenharmony_ci } 903370b324cSopenharmony_ci { 904370b324cSopenharmony_ci UStringVector pathParts; 905370b324cSopenharmony_ci pathParts.Add(fs2us(fi.Name)); 906370b324cSopenharmony_ci if (curNode.CheckPathToRoot(false, pathParts, !isDir)) 907370b324cSopenharmony_ci continue; 908370b324cSopenharmony_ci } 909370b324cSopenharmony_ci 910370b324cSopenharmony_ci 911370b324cSopenharmony_ci if (dirItems.CanIncludeItem(fi.IsDir())) 912370b324cSopenharmony_ci { 913370b324cSopenharmony_ci int secureIndex = -1; 914370b324cSopenharmony_ci #ifdef Z7_USE_SECURITY_CODE 915370b324cSopenharmony_ci if (needSecurity && dirItems.ReadSecure) 916370b324cSopenharmony_ci { 917370b324cSopenharmony_ci RINOK(dirItems.AddSecurityItem(fullPath, secureIndex)) 918370b324cSopenharmony_ci } 919370b324cSopenharmony_ci #endif 920370b324cSopenharmony_ci 921370b324cSopenharmony_ci dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); 922370b324cSopenharmony_ci 923370b324cSopenharmony_ci // we don't scan AltStreams for link files 924370b324cSopenharmony_ci 925370b324cSopenharmony_ci #if !defined(UNDER_CE) 926370b324cSopenharmony_ci { 927370b324cSopenharmony_ci CDirItem &dirItem = dirItems.Items.Back(); 928370b324cSopenharmony_ci RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)) 929370b324cSopenharmony_ci if (dirItem.ReparseData.Size() != 0) 930370b324cSopenharmony_ci continue; 931370b324cSopenharmony_ci } 932370b324cSopenharmony_ci 933370b324cSopenharmony_ci #if defined(_WIN32) 934370b324cSopenharmony_ci if (needAltStreams && dirItems.ScanAltStreams) 935370b324cSopenharmony_ci { 936370b324cSopenharmony_ci UStringVector pathParts; 937370b324cSopenharmony_ci pathParts.Add(fs2us(fi.Name)); 938370b324cSopenharmony_ci RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, 939370b324cSopenharmony_ci fullPath, // including (name) 940370b324cSopenharmony_ci pathParts, // including (fi.Name) 941370b324cSopenharmony_ci true, /* addAllSubStreams */ 942370b324cSopenharmony_ci dirItems)) 943370b324cSopenharmony_ci } 944370b324cSopenharmony_ci #endif // defined(_WIN32) 945370b324cSopenharmony_ci 946370b324cSopenharmony_ci #endif // !defined(UNDER_CE) 947370b324cSopenharmony_ci } 948370b324cSopenharmony_ci 949370b324cSopenharmony_ci 950370b324cSopenharmony_ci #ifndef _WIN32 951370b324cSopenharmony_ci if (!fi.IsPosixLink()) // posix link can follow to dir 952370b324cSopenharmony_ci #endif 953370b324cSopenharmony_ci if (!isDir) 954370b324cSopenharmony_ci continue; 955370b324cSopenharmony_ci 956370b324cSopenharmony_ci UStringVector newParts; 957370b324cSopenharmony_ci const NWildcard::CCensorNode *nextNode = NULL; 958370b324cSopenharmony_ci int index = curNode.FindSubNode(name); 959370b324cSopenharmony_ci if (index >= 0) 960370b324cSopenharmony_ci { 961370b324cSopenharmony_ci for (int t = (int)needEnterVector.Size(); t <= index; t++) 962370b324cSopenharmony_ci needEnterVector.Add(true); 963370b324cSopenharmony_ci needEnterVector[(unsigned)index] = false; 964370b324cSopenharmony_ci nextNode = &curNode.SubNodes[(unsigned)index]; 965370b324cSopenharmony_ci } 966370b324cSopenharmony_ci else 967370b324cSopenharmony_ci { 968370b324cSopenharmony_ci #ifndef _WIN32 969370b324cSopenharmony_ci if (fi.IsPosixLink()) 970370b324cSopenharmony_ci { 971370b324cSopenharmony_ci // here we can try to resolve posix link 972370b324cSopenharmony_ci // if the link to dir, then can we follow it 973370b324cSopenharmony_ci continue; // we don't follow posix link 974370b324cSopenharmony_ci } 975370b324cSopenharmony_ci #else 976370b324cSopenharmony_ci if (dirItems.SymLinks) 977370b324cSopenharmony_ci { 978370b324cSopenharmony_ci if (fi.HasReparsePoint()) 979370b324cSopenharmony_ci { 980370b324cSopenharmony_ci /* 20.03: in SymLinks mode: we don't enter to directory that 981370b324cSopenharmony_ci has reparse point and has no CCensorNode */ 982370b324cSopenharmony_ci continue; 983370b324cSopenharmony_ci } 984370b324cSopenharmony_ci } 985370b324cSopenharmony_ci #endif 986370b324cSopenharmony_ci nextNode = &curNode; 987370b324cSopenharmony_ci newParts.Add(name); // don't change it to fi.Name. It's for shortnames support 988370b324cSopenharmony_ci } 989370b324cSopenharmony_ci 990370b324cSopenharmony_ci RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix, 991370b324cSopenharmony_ci newParts, dirItems, true)) 992370b324cSopenharmony_ci } 993370b324cSopenharmony_ci 994370b324cSopenharmony_ci for (i = 0; i < curNode.SubNodes.Size(); i++) 995370b324cSopenharmony_ci { 996370b324cSopenharmony_ci if (i < needEnterVector.Size()) 997370b324cSopenharmony_ci if (!needEnterVector[i]) 998370b324cSopenharmony_ci continue; 999370b324cSopenharmony_ci const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; 1000370b324cSopenharmony_ci FString fullPath = phyPrefix + us2fs(nextNode.Name); 1001370b324cSopenharmony_ci NFind::CFileInfo fi; 1002370b324cSopenharmony_ci 1003370b324cSopenharmony_ci if (nextNode.Name.IsEmpty()) 1004370b324cSopenharmony_ci { 1005370b324cSopenharmony_ci if (phyPrefix.IsEmpty()) 1006370b324cSopenharmony_ci fullPath = CHAR_PATH_SEPARATOR; 1007370b324cSopenharmony_ci } 1008370b324cSopenharmony_ci #ifdef _WIN32 1009370b324cSopenharmony_ci else if(phyPrefix.IsEmpty() 1010370b324cSopenharmony_ci || (phyPrefix.Len() == NName::kSuperPathPrefixSize 1011370b324cSopenharmony_ci && IsSuperPath(phyPrefix))) 1012370b324cSopenharmony_ci { 1013370b324cSopenharmony_ci if (NWildcard::IsDriveColonName(nextNode.Name)) 1014370b324cSopenharmony_ci fullPath.Add_PathSepar(); 1015370b324cSopenharmony_ci } 1016370b324cSopenharmony_ci #endif 1017370b324cSopenharmony_ci 1018370b324cSopenharmony_ci // we don't want to call fi.Find() for root folder or virtual folder 1019370b324cSopenharmony_ci if ((phyPrefix.IsEmpty() && nextNode.Name.IsEmpty()) 1020370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 1021370b324cSopenharmony_ci || IsVirtualFsFolder(phyPrefix, nextNode.Name) 1022370b324cSopenharmony_ci #endif 1023370b324cSopenharmony_ci ) 1024370b324cSopenharmony_ci { 1025370b324cSopenharmony_ci fi.SetAsDir(); 1026370b324cSopenharmony_ci fi.Name = us2fs(nextNode.Name); 1027370b324cSopenharmony_ci } 1028370b324cSopenharmony_ci else 1029370b324cSopenharmony_ci { 1030370b324cSopenharmony_ci if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) 1031370b324cSopenharmony_ci { 1032370b324cSopenharmony_ci if (!nextNode.AreThereIncludeItems()) 1033370b324cSopenharmony_ci continue; 1034370b324cSopenharmony_ci RINOK(dirItems.AddError(fullPath)) 1035370b324cSopenharmony_ci continue; 1036370b324cSopenharmony_ci } 1037370b324cSopenharmony_ci 1038370b324cSopenharmony_ci if (!fi.IsDir()) 1039370b324cSopenharmony_ci { 1040370b324cSopenharmony_ci RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)) 1041370b324cSopenharmony_ci continue; 1042370b324cSopenharmony_ci } 1043370b324cSopenharmony_ci } 1044370b324cSopenharmony_ci 1045370b324cSopenharmony_ci RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix, 1046370b324cSopenharmony_ci UStringVector(), dirItems, false)) 1047370b324cSopenharmony_ci } 1048370b324cSopenharmony_ci 1049370b324cSopenharmony_ci return S_OK; 1050370b324cSopenharmony_ci } 1051370b324cSopenharmony_ci } 1052370b324cSopenharmony_ci 1053370b324cSopenharmony_ci #ifdef _WIN32 1054370b324cSopenharmony_ci #ifndef UNDER_CE 1055370b324cSopenharmony_ci 1056370b324cSopenharmony_ci // scan drives, if wildcard is "*:\" 1057370b324cSopenharmony_ci 1058370b324cSopenharmony_ci if (phyPrefix.IsEmpty() && curNode.IncludeItems.Size() > 0) 1059370b324cSopenharmony_ci { 1060370b324cSopenharmony_ci unsigned i; 1061370b324cSopenharmony_ci for (i = 0; i < curNode.IncludeItems.Size(); i++) 1062370b324cSopenharmony_ci { 1063370b324cSopenharmony_ci const NWildcard::CItem &item = curNode.IncludeItems[i]; 1064370b324cSopenharmony_ci if (item.PathParts.Size() < 1) 1065370b324cSopenharmony_ci break; 1066370b324cSopenharmony_ci const UString &name = item.PathParts.Front(); 1067370b324cSopenharmony_ci if (name.Len() != 2 || name[1] != ':') 1068370b324cSopenharmony_ci break; 1069370b324cSopenharmony_ci if (item.PathParts.Size() == 1) 1070370b324cSopenharmony_ci if (item.ForFile || !item.ForDir) 1071370b324cSopenharmony_ci break; 1072370b324cSopenharmony_ci if (NWildcard::IsDriveColonName(name)) 1073370b324cSopenharmony_ci continue; 1074370b324cSopenharmony_ci if (name[0] != '*' && name[0] != '?') 1075370b324cSopenharmony_ci break; 1076370b324cSopenharmony_ci } 1077370b324cSopenharmony_ci if (i == curNode.IncludeItems.Size()) 1078370b324cSopenharmony_ci { 1079370b324cSopenharmony_ci FStringVector driveStrings; 1080370b324cSopenharmony_ci NFind::MyGetLogicalDriveStrings(driveStrings); 1081370b324cSopenharmony_ci for (i = 0; i < driveStrings.Size(); i++) 1082370b324cSopenharmony_ci { 1083370b324cSopenharmony_ci FString driveName = driveStrings[i]; 1084370b324cSopenharmony_ci if (driveName.Len() < 3 || driveName.Back() != '\\') 1085370b324cSopenharmony_ci return E_FAIL; 1086370b324cSopenharmony_ci driveName.DeleteBack(); 1087370b324cSopenharmony_ci NFind::CFileInfo fi; 1088370b324cSopenharmony_ci fi.SetAsDir(); 1089370b324cSopenharmony_ci fi.Name = driveName; 1090370b324cSopenharmony_ci 1091370b324cSopenharmony_ci RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, 1092370b324cSopenharmony_ci addParts, dirItems, enterToSubFolders)) 1093370b324cSopenharmony_ci } 1094370b324cSopenharmony_ci return S_OK; 1095370b324cSopenharmony_ci } 1096370b324cSopenharmony_ci } 1097370b324cSopenharmony_ci 1098370b324cSopenharmony_ci #endif 1099370b324cSopenharmony_ci #endif 1100370b324cSopenharmony_ci 1101370b324cSopenharmony_ci 1102370b324cSopenharmony_ci CObjectVector<NFind::CFileInfo> files; 1103370b324cSopenharmony_ci 1104370b324cSopenharmony_ci // for (int y = 0; y < 1; y++) 1105370b324cSopenharmony_ci { 1106370b324cSopenharmony_ci // files.Clear(); 1107370b324cSopenharmony_ci RINOK(dirItems.EnumerateOneDir(phyPrefix, files)) 1108370b324cSopenharmony_ci /* 1109370b324cSopenharmony_ci FOR_VECTOR (i, files) 1110370b324cSopenharmony_ci { 1111370b324cSopenharmony_ci #ifdef _WIN32 1112370b324cSopenharmony_ci // const NFind::CFileInfo &fi = files[i]; 1113370b324cSopenharmony_ci #else 1114370b324cSopenharmony_ci NFind::CFileInfo &fi = files[i]; 1115370b324cSopenharmony_ci { 1116370b324cSopenharmony_ci const NFind::CFileInfo &di = files[i]; 1117370b324cSopenharmony_ci const FString path = phyPrefix + di.Name; 1118370b324cSopenharmony_ci if (!fi.Find_AfterEnumerator(path)) 1119370b324cSopenharmony_ci { 1120370b324cSopenharmony_ci RINOK(dirItems.AddError(path)); 1121370b324cSopenharmony_ci continue; 1122370b324cSopenharmony_ci } 1123370b324cSopenharmony_ci fi.Name = di.Name; 1124370b324cSopenharmony_ci } 1125370b324cSopenharmony_ci #endif 1126370b324cSopenharmony_ci 1127370b324cSopenharmony_ci } 1128370b324cSopenharmony_ci */ 1129370b324cSopenharmony_ci } 1130370b324cSopenharmony_ci 1131370b324cSopenharmony_ci FOR_VECTOR (i, files) 1132370b324cSopenharmony_ci { 1133370b324cSopenharmony_ci #ifdef _WIN32 1134370b324cSopenharmony_ci const NFind::CFileInfo &fi = files[i]; 1135370b324cSopenharmony_ci #else 1136370b324cSopenharmony_ci const NFind::CFileInfo &fi = files[i]; 1137370b324cSopenharmony_ci /* 1138370b324cSopenharmony_ci NFind::CFileInfo fi; 1139370b324cSopenharmony_ci { 1140370b324cSopenharmony_ci const NFind::CDirEntry &di = files[i]; 1141370b324cSopenharmony_ci const FString path = phyPrefix + di.Name; 1142370b324cSopenharmony_ci if (!fi.Find_AfterEnumerator(path)) 1143370b324cSopenharmony_ci { 1144370b324cSopenharmony_ci RINOK(dirItems.AddError(path)); 1145370b324cSopenharmony_ci continue; 1146370b324cSopenharmony_ci } 1147370b324cSopenharmony_ci fi.Name = di.Name; 1148370b324cSopenharmony_ci } 1149370b324cSopenharmony_ci */ 1150370b324cSopenharmony_ci #endif 1151370b324cSopenharmony_ci 1152370b324cSopenharmony_ci RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, 1153370b324cSopenharmony_ci addParts, dirItems, enterToSubFolders)) 1154370b324cSopenharmony_ci if (dirItems.Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) 1155370b324cSopenharmony_ci { 1156370b324cSopenharmony_ci RINOK(dirItems.ScanProgress(phyPrefix)) 1157370b324cSopenharmony_ci } 1158370b324cSopenharmony_ci } 1159370b324cSopenharmony_ci 1160370b324cSopenharmony_ci return S_OK; 1161370b324cSopenharmony_ci} 1162370b324cSopenharmony_ci 1163370b324cSopenharmony_ci 1164370b324cSopenharmony_ci 1165370b324cSopenharmony_ci 1166370b324cSopenharmony_ciHRESULT EnumerateItems( 1167370b324cSopenharmony_ci const NWildcard::CCensor &censor, 1168370b324cSopenharmony_ci const NWildcard::ECensorPathMode pathMode, 1169370b324cSopenharmony_ci const UString &addPathPrefix, // prefix that will be added to Logical Path 1170370b324cSopenharmony_ci CDirItems &dirItems) 1171370b324cSopenharmony_ci{ 1172370b324cSopenharmony_ci FOR_VECTOR (i, censor.Pairs) 1173370b324cSopenharmony_ci { 1174370b324cSopenharmony_ci const NWildcard::CPair &pair = censor.Pairs[i]; 1175370b324cSopenharmony_ci const int phyParent = pair.Prefix.IsEmpty() ? -1 : (int)dirItems.AddPrefix(-1, -1, pair.Prefix); 1176370b324cSopenharmony_ci int logParent = -1; 1177370b324cSopenharmony_ci 1178370b324cSopenharmony_ci if (pathMode == NWildcard::k_AbsPath) 1179370b324cSopenharmony_ci logParent = phyParent; 1180370b324cSopenharmony_ci else 1181370b324cSopenharmony_ci { 1182370b324cSopenharmony_ci if (!addPathPrefix.IsEmpty()) 1183370b324cSopenharmony_ci logParent = (int)dirItems.AddPrefix(-1, -1, addPathPrefix); 1184370b324cSopenharmony_ci } 1185370b324cSopenharmony_ci 1186370b324cSopenharmony_ci RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(), 1187370b324cSopenharmony_ci dirItems, 1188370b324cSopenharmony_ci false // enterToSubFolders 1189370b324cSopenharmony_ci )) 1190370b324cSopenharmony_ci } 1191370b324cSopenharmony_ci dirItems.ReserveDown(); 1192370b324cSopenharmony_ci 1193370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 1194370b324cSopenharmony_ci RINOK(dirItems.FillFixedReparse()) 1195370b324cSopenharmony_ci #endif 1196370b324cSopenharmony_ci 1197370b324cSopenharmony_ci #ifndef _WIN32 1198370b324cSopenharmony_ci RINOK(dirItems.FillDeviceSizes()) 1199370b324cSopenharmony_ci #endif 1200370b324cSopenharmony_ci 1201370b324cSopenharmony_ci return S_OK; 1202370b324cSopenharmony_ci} 1203370b324cSopenharmony_ci 1204370b324cSopenharmony_ci 1205370b324cSopenharmony_ci#if defined(_WIN32) && !defined(UNDER_CE) 1206370b324cSopenharmony_ci 1207370b324cSopenharmony_ciHRESULT CDirItems::FillFixedReparse() 1208370b324cSopenharmony_ci{ 1209370b324cSopenharmony_ci FOR_VECTOR(i, Items) 1210370b324cSopenharmony_ci { 1211370b324cSopenharmony_ci CDirItem &item = Items[i]; 1212370b324cSopenharmony_ci 1213370b324cSopenharmony_ci if (!SymLinks) 1214370b324cSopenharmony_ci { 1215370b324cSopenharmony_ci // continue; // for debug 1216370b324cSopenharmony_ci if (!item.Has_Attrib_ReparsePoint()) 1217370b324cSopenharmony_ci continue; 1218370b324cSopenharmony_ci 1219370b324cSopenharmony_ci // if (item.IsDir()) continue; 1220370b324cSopenharmony_ci 1221370b324cSopenharmony_ci const FString phyPath = GetPhyPath(i); 1222370b324cSopenharmony_ci 1223370b324cSopenharmony_ci NFind::CFileInfo fi; 1224370b324cSopenharmony_ci if (fi.Fill_From_ByHandleFileInfo(phyPath)) // item.IsDir() 1225370b324cSopenharmony_ci { 1226370b324cSopenharmony_ci item.Size = fi.Size; 1227370b324cSopenharmony_ci item.CTime = fi.CTime; 1228370b324cSopenharmony_ci item.ATime = fi.ATime; 1229370b324cSopenharmony_ci item.MTime = fi.MTime; 1230370b324cSopenharmony_ci item.Attrib = fi.Attrib; 1231370b324cSopenharmony_ci continue; 1232370b324cSopenharmony_ci } 1233370b324cSopenharmony_ci 1234370b324cSopenharmony_ci /* 1235370b324cSopenharmony_ci // we request properties of target file instead of properies of symbolic link 1236370b324cSopenharmony_ci // here we also can manually parse unsupported links (like WSL links) 1237370b324cSopenharmony_ci NIO::CInFile inFile; 1238370b324cSopenharmony_ci if (inFile.Open(phyPath)) 1239370b324cSopenharmony_ci { 1240370b324cSopenharmony_ci BY_HANDLE_FILE_INFORMATION info; 1241370b324cSopenharmony_ci if (inFile.GetFileInformation(&info)) 1242370b324cSopenharmony_ci { 1243370b324cSopenharmony_ci // Stat.FilesSize doesn't contain item.Size already 1244370b324cSopenharmony_ci // Stat.FilesSize -= item.Size; 1245370b324cSopenharmony_ci item.Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; 1246370b324cSopenharmony_ci Stat.FilesSize += item.Size; 1247370b324cSopenharmony_ci item.CTime = info.ftCreationTime; 1248370b324cSopenharmony_ci item.ATime = info.ftLastAccessTime; 1249370b324cSopenharmony_ci item.MTime = info.ftLastWriteTime; 1250370b324cSopenharmony_ci item.Attrib = info.dwFileAttributes; 1251370b324cSopenharmony_ci continue; 1252370b324cSopenharmony_ci } 1253370b324cSopenharmony_ci } 1254370b324cSopenharmony_ci */ 1255370b324cSopenharmony_ci 1256370b324cSopenharmony_ci RINOK(AddError(phyPath)) 1257370b324cSopenharmony_ci continue; 1258370b324cSopenharmony_ci } 1259370b324cSopenharmony_ci 1260370b324cSopenharmony_ci // (SymLinks == true) here 1261370b324cSopenharmony_ci 1262370b324cSopenharmony_ci if (item.ReparseData.Size() == 0) 1263370b324cSopenharmony_ci continue; 1264370b324cSopenharmony_ci 1265370b324cSopenharmony_ci // if (item.Size == 0) 1266370b324cSopenharmony_ci { 1267370b324cSopenharmony_ci // 20.03: we use Reparse Data instead of real data 1268370b324cSopenharmony_ci item.Size = item.ReparseData.Size(); 1269370b324cSopenharmony_ci } 1270370b324cSopenharmony_ci 1271370b324cSopenharmony_ci CReparseAttr attr; 1272370b324cSopenharmony_ci if (!attr.Parse(item.ReparseData, item.ReparseData.Size())) 1273370b324cSopenharmony_ci { 1274370b324cSopenharmony_ci const FString phyPath = GetPhyPath(i); 1275370b324cSopenharmony_ci AddError(phyPath, attr.ErrorCode); 1276370b324cSopenharmony_ci continue; 1277370b324cSopenharmony_ci } 1278370b324cSopenharmony_ci 1279370b324cSopenharmony_ci /* imagex/WIM reduces absolute paths in links (raparse data), 1280370b324cSopenharmony_ci if we archive non root folder. We do same thing here */ 1281370b324cSopenharmony_ci 1282370b324cSopenharmony_ci bool isWSL = false; 1283370b324cSopenharmony_ci if (attr.IsSymLink_WSL()) 1284370b324cSopenharmony_ci { 1285370b324cSopenharmony_ci // isWSL = true; 1286370b324cSopenharmony_ci // we don't change WSL symlinks 1287370b324cSopenharmony_ci continue; 1288370b324cSopenharmony_ci } 1289370b324cSopenharmony_ci else 1290370b324cSopenharmony_ci { 1291370b324cSopenharmony_ci if (attr.IsRelative_Win()) 1292370b324cSopenharmony_ci continue; 1293370b324cSopenharmony_ci } 1294370b324cSopenharmony_ci 1295370b324cSopenharmony_ci const UString &link = attr.GetPath(); 1296370b324cSopenharmony_ci if (!IsDrivePath(link)) 1297370b324cSopenharmony_ci continue; 1298370b324cSopenharmony_ci // maybe we need to support networks paths also ? 1299370b324cSopenharmony_ci 1300370b324cSopenharmony_ci FString fullPathF; 1301370b324cSopenharmony_ci if (!NDir::MyGetFullPathName(GetPhyPath(i), fullPathF)) 1302370b324cSopenharmony_ci continue; 1303370b324cSopenharmony_ci const UString fullPath = fs2us(fullPathF); 1304370b324cSopenharmony_ci const UString logPath = GetLogPath(i); 1305370b324cSopenharmony_ci if (logPath.Len() >= fullPath.Len()) 1306370b324cSopenharmony_ci continue; 1307370b324cSopenharmony_ci if (CompareFileNames(logPath, fullPath.RightPtr(logPath.Len())) != 0) 1308370b324cSopenharmony_ci continue; 1309370b324cSopenharmony_ci 1310370b324cSopenharmony_ci const UString prefix = fullPath.Left(fullPath.Len() - logPath.Len()); 1311370b324cSopenharmony_ci if (!IsPathSepar(prefix.Back())) 1312370b324cSopenharmony_ci continue; 1313370b324cSopenharmony_ci 1314370b324cSopenharmony_ci const unsigned rootPrefixSize = GetRootPrefixSize(prefix); 1315370b324cSopenharmony_ci if (rootPrefixSize == 0) 1316370b324cSopenharmony_ci continue; 1317370b324cSopenharmony_ci if (rootPrefixSize == prefix.Len()) 1318370b324cSopenharmony_ci continue; // simple case: paths are from root 1319370b324cSopenharmony_ci 1320370b324cSopenharmony_ci if (link.Len() <= prefix.Len()) 1321370b324cSopenharmony_ci continue; 1322370b324cSopenharmony_ci 1323370b324cSopenharmony_ci if (CompareFileNames(link.Left(prefix.Len()), prefix) != 0) 1324370b324cSopenharmony_ci continue; 1325370b324cSopenharmony_ci 1326370b324cSopenharmony_ci UString newLink = prefix.Left(rootPrefixSize); 1327370b324cSopenharmony_ci newLink += link.Ptr(prefix.Len()); 1328370b324cSopenharmony_ci 1329370b324cSopenharmony_ci CByteBuffer data; 1330370b324cSopenharmony_ci bool isSymLink = !attr.IsMountPoint(); 1331370b324cSopenharmony_ci if (!FillLinkData(data, newLink, isSymLink, isWSL)) 1332370b324cSopenharmony_ci continue; 1333370b324cSopenharmony_ci item.ReparseData2 = data; 1334370b324cSopenharmony_ci } 1335370b324cSopenharmony_ci return S_OK; 1336370b324cSopenharmony_ci} 1337370b324cSopenharmony_ci 1338370b324cSopenharmony_ci#endif 1339370b324cSopenharmony_ci 1340370b324cSopenharmony_ci 1341370b324cSopenharmony_ci#ifndef _WIN32 1342370b324cSopenharmony_ci 1343370b324cSopenharmony_ciHRESULT CDirItems::FillDeviceSizes() 1344370b324cSopenharmony_ci{ 1345370b324cSopenharmony_ci { 1346370b324cSopenharmony_ci FOR_VECTOR (i, Items) 1347370b324cSopenharmony_ci { 1348370b324cSopenharmony_ci CDirItem &item = Items[i]; 1349370b324cSopenharmony_ci 1350370b324cSopenharmony_ci if (S_ISBLK(item.mode) && item.Size == 0) 1351370b324cSopenharmony_ci { 1352370b324cSopenharmony_ci const FString phyPath = GetPhyPath(i); 1353370b324cSopenharmony_ci NIO::CInFile inFile; 1354370b324cSopenharmony_ci inFile.PreserveATime = true; 1355370b324cSopenharmony_ci if (inFile.OpenShared(phyPath, ShareForWrite)) // fixme: OpenShared ?? 1356370b324cSopenharmony_ci { 1357370b324cSopenharmony_ci UInt64 size = 0; 1358370b324cSopenharmony_ci if (inFile.GetLength(size)) 1359370b324cSopenharmony_ci item.Size = size; 1360370b324cSopenharmony_ci } 1361370b324cSopenharmony_ci } 1362370b324cSopenharmony_ci if (StoreOwnerName) 1363370b324cSopenharmony_ci { 1364370b324cSopenharmony_ci OwnerNameMap.Add_UInt32(item.uid); 1365370b324cSopenharmony_ci OwnerGroupMap.Add_UInt32(item.gid); 1366370b324cSopenharmony_ci } 1367370b324cSopenharmony_ci } 1368370b324cSopenharmony_ci } 1369370b324cSopenharmony_ci 1370370b324cSopenharmony_ci if (StoreOwnerName) 1371370b324cSopenharmony_ci { 1372370b324cSopenharmony_ci UString u; 1373370b324cSopenharmony_ci AString a; 1374370b324cSopenharmony_ci { 1375370b324cSopenharmony_ci FOR_VECTOR (i, OwnerNameMap.Numbers) 1376370b324cSopenharmony_ci { 1377370b324cSopenharmony_ci // 200K/sec speed 1378370b324cSopenharmony_ci u.Empty(); 1379370b324cSopenharmony_ci const passwd *pw = getpwuid(OwnerNameMap.Numbers[i]); 1380370b324cSopenharmony_ci // printf("\ngetpwuid=%s\n", pw->pw_name); 1381370b324cSopenharmony_ci if (pw) 1382370b324cSopenharmony_ci { 1383370b324cSopenharmony_ci a = pw->pw_name; 1384370b324cSopenharmony_ci ConvertUTF8ToUnicode(a, u); 1385370b324cSopenharmony_ci } 1386370b324cSopenharmony_ci OwnerNameMap.Strings.Add(u); 1387370b324cSopenharmony_ci } 1388370b324cSopenharmony_ci } 1389370b324cSopenharmony_ci { 1390370b324cSopenharmony_ci FOR_VECTOR (i, OwnerGroupMap.Numbers) 1391370b324cSopenharmony_ci { 1392370b324cSopenharmony_ci u.Empty(); 1393370b324cSopenharmony_ci const group *gr = getgrgid(OwnerGroupMap.Numbers[i]); 1394370b324cSopenharmony_ci if (gr) 1395370b324cSopenharmony_ci { 1396370b324cSopenharmony_ci // printf("\ngetgrgid %d %s\n", OwnerGroupMap.Numbers[i], gr->gr_name); 1397370b324cSopenharmony_ci a = gr->gr_name; 1398370b324cSopenharmony_ci ConvertUTF8ToUnicode(a, u); 1399370b324cSopenharmony_ci } 1400370b324cSopenharmony_ci OwnerGroupMap.Strings.Add(u); 1401370b324cSopenharmony_ci } 1402370b324cSopenharmony_ci } 1403370b324cSopenharmony_ci 1404370b324cSopenharmony_ci FOR_VECTOR (i, Items) 1405370b324cSopenharmony_ci { 1406370b324cSopenharmony_ci CDirItem &item = Items[i]; 1407370b324cSopenharmony_ci { 1408370b324cSopenharmony_ci const int index = OwnerNameMap.Find(item.uid); 1409370b324cSopenharmony_ci if (index < 0) throw 1; 1410370b324cSopenharmony_ci item.OwnerNameIndex = index; 1411370b324cSopenharmony_ci } 1412370b324cSopenharmony_ci { 1413370b324cSopenharmony_ci const int index = OwnerGroupMap.Find(item.gid); 1414370b324cSopenharmony_ci if (index < 0) throw 1; 1415370b324cSopenharmony_ci item.OwnerGroupIndex = index; 1416370b324cSopenharmony_ci } 1417370b324cSopenharmony_ci } 1418370b324cSopenharmony_ci } 1419370b324cSopenharmony_ci 1420370b324cSopenharmony_ci 1421370b324cSopenharmony_ci // if (NeedOwnerNames) 1422370b324cSopenharmony_ci { 1423370b324cSopenharmony_ci /* 1424370b324cSopenharmony_ci { 1425370b324cSopenharmony_ci for (unsigned i = 0 ; i < 10000; i++) 1426370b324cSopenharmony_ci { 1427370b324cSopenharmony_ci const passwd *pw = getpwuid(i); 1428370b324cSopenharmony_ci if (pw) 1429370b324cSopenharmony_ci { 1430370b324cSopenharmony_ci UString u; 1431370b324cSopenharmony_ci ConvertUTF8ToUnicode(AString(pw->pw_name), u); 1432370b324cSopenharmony_ci OwnerNameMap.Add(i, u); 1433370b324cSopenharmony_ci OwnerNameMap.Add(i, u); 1434370b324cSopenharmony_ci OwnerNameMap.Add(i, u); 1435370b324cSopenharmony_ci } 1436370b324cSopenharmony_ci const group *gr = getgrgid(i); 1437370b324cSopenharmony_ci if (gr) 1438370b324cSopenharmony_ci { 1439370b324cSopenharmony_ci // we can use utf-8 here. 1440370b324cSopenharmony_ci UString u; 1441370b324cSopenharmony_ci ConvertUTF8ToUnicode(AString(gr->gr_name), u); 1442370b324cSopenharmony_ci OwnerGroupMap.Add(i, u); 1443370b324cSopenharmony_ci } 1444370b324cSopenharmony_ci } 1445370b324cSopenharmony_ci } 1446370b324cSopenharmony_ci */ 1447370b324cSopenharmony_ci /* 1448370b324cSopenharmony_ci { 1449370b324cSopenharmony_ci FOR_VECTOR (i, OwnerNameMap.Strings) 1450370b324cSopenharmony_ci { 1451370b324cSopenharmony_ci AString s; 1452370b324cSopenharmony_ci ConvertUnicodeToUTF8(OwnerNameMap.Strings[i], s); 1453370b324cSopenharmony_ci printf("\n%5d %s", (unsigned)OwnerNameMap.Numbers[i], s.Ptr()); 1454370b324cSopenharmony_ci } 1455370b324cSopenharmony_ci } 1456370b324cSopenharmony_ci { 1457370b324cSopenharmony_ci printf("\n\n=========Groups\n"); 1458370b324cSopenharmony_ci FOR_VECTOR (i, OwnerGroupMap.Strings) 1459370b324cSopenharmony_ci { 1460370b324cSopenharmony_ci AString s; 1461370b324cSopenharmony_ci ConvertUnicodeToUTF8(OwnerGroupMap.Strings[i], s); 1462370b324cSopenharmony_ci printf("\n%5d %s", (unsigned)OwnerGroupMap.Numbers[i], s.Ptr()); 1463370b324cSopenharmony_ci } 1464370b324cSopenharmony_ci } 1465370b324cSopenharmony_ci */ 1466370b324cSopenharmony_ci } 1467370b324cSopenharmony_ci /* 1468370b324cSopenharmony_ci for (unsigned i = 0 ; i < 100000000; i++) 1469370b324cSopenharmony_ci { 1470370b324cSopenharmony_ci // const passwd *pw = getpwuid(1000); 1471370b324cSopenharmony_ci // pw = pw; 1472370b324cSopenharmony_ci int pos = OwnerNameMap.Find(1000); 1473370b324cSopenharmony_ci if (pos < 0 - (int)i) 1474370b324cSopenharmony_ci throw 1; 1475370b324cSopenharmony_ci } 1476370b324cSopenharmony_ci */ 1477370b324cSopenharmony_ci 1478370b324cSopenharmony_ci return S_OK; 1479370b324cSopenharmony_ci} 1480370b324cSopenharmony_ci 1481370b324cSopenharmony_ci#endif 1482370b324cSopenharmony_ci 1483370b324cSopenharmony_ci 1484370b324cSopenharmony_ci 1485370b324cSopenharmony_cistatic const char * const kCannotFindArchive = "Cannot find archive"; 1486370b324cSopenharmony_ci 1487370b324cSopenharmony_ciHRESULT EnumerateDirItemsAndSort( 1488370b324cSopenharmony_ci NWildcard::CCensor &censor, 1489370b324cSopenharmony_ci NWildcard::ECensorPathMode censorPathMode, 1490370b324cSopenharmony_ci const UString &addPathPrefix, 1491370b324cSopenharmony_ci UStringVector &sortedPaths, 1492370b324cSopenharmony_ci UStringVector &sortedFullPaths, 1493370b324cSopenharmony_ci CDirItemsStat &st, 1494370b324cSopenharmony_ci IDirItemsCallback *callback) 1495370b324cSopenharmony_ci{ 1496370b324cSopenharmony_ci FStringVector paths; 1497370b324cSopenharmony_ci 1498370b324cSopenharmony_ci { 1499370b324cSopenharmony_ci CDirItems dirItems; 1500370b324cSopenharmony_ci dirItems.Callback = callback; 1501370b324cSopenharmony_ci { 1502370b324cSopenharmony_ci HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); 1503370b324cSopenharmony_ci st = dirItems.Stat; 1504370b324cSopenharmony_ci RINOK(res) 1505370b324cSopenharmony_ci } 1506370b324cSopenharmony_ci 1507370b324cSopenharmony_ci FOR_VECTOR (i, dirItems.Items) 1508370b324cSopenharmony_ci { 1509370b324cSopenharmony_ci const CDirItem &dirItem = dirItems.Items[i]; 1510370b324cSopenharmony_ci if (!dirItem.IsDir()) 1511370b324cSopenharmony_ci paths.Add(dirItems.GetPhyPath(i)); 1512370b324cSopenharmony_ci } 1513370b324cSopenharmony_ci } 1514370b324cSopenharmony_ci 1515370b324cSopenharmony_ci if (paths.Size() == 0) 1516370b324cSopenharmony_ci { 1517370b324cSopenharmony_ci // return S_OK; 1518370b324cSopenharmony_ci throw CMessagePathException(kCannotFindArchive); 1519370b324cSopenharmony_ci } 1520370b324cSopenharmony_ci 1521370b324cSopenharmony_ci UStringVector fullPaths; 1522370b324cSopenharmony_ci 1523370b324cSopenharmony_ci unsigned i; 1524370b324cSopenharmony_ci 1525370b324cSopenharmony_ci for (i = 0; i < paths.Size(); i++) 1526370b324cSopenharmony_ci { 1527370b324cSopenharmony_ci FString fullPath; 1528370b324cSopenharmony_ci NFile::NDir::MyGetFullPathName(paths[i], fullPath); 1529370b324cSopenharmony_ci fullPaths.Add(fs2us(fullPath)); 1530370b324cSopenharmony_ci } 1531370b324cSopenharmony_ci 1532370b324cSopenharmony_ci CUIntVector indices; 1533370b324cSopenharmony_ci SortFileNames(fullPaths, indices); 1534370b324cSopenharmony_ci sortedPaths.ClearAndReserve(indices.Size()); 1535370b324cSopenharmony_ci sortedFullPaths.ClearAndReserve(indices.Size()); 1536370b324cSopenharmony_ci 1537370b324cSopenharmony_ci for (i = 0; i < indices.Size(); i++) 1538370b324cSopenharmony_ci { 1539370b324cSopenharmony_ci unsigned index = indices[i]; 1540370b324cSopenharmony_ci sortedPaths.AddInReserved(fs2us(paths[index])); 1541370b324cSopenharmony_ci sortedFullPaths.AddInReserved(fullPaths[index]); 1542370b324cSopenharmony_ci if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0) 1543370b324cSopenharmony_ci throw CMessagePathException("Duplicate archive path:", sortedFullPaths[i]); 1544370b324cSopenharmony_ci } 1545370b324cSopenharmony_ci 1546370b324cSopenharmony_ci return S_OK; 1547370b324cSopenharmony_ci} 1548370b324cSopenharmony_ci 1549370b324cSopenharmony_ci 1550370b324cSopenharmony_ci 1551370b324cSopenharmony_ci 1552370b324cSopenharmony_ci#ifdef _WIN32 1553370b324cSopenharmony_ci 1554370b324cSopenharmony_cistatic bool IsDotsName(const wchar_t *s) 1555370b324cSopenharmony_ci{ 1556370b324cSopenharmony_ci return s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)); 1557370b324cSopenharmony_ci} 1558370b324cSopenharmony_ci 1559370b324cSopenharmony_ci// This code converts all short file names to long file names. 1560370b324cSopenharmony_ci 1561370b324cSopenharmony_cistatic void ConvertToLongName(const UString &prefix, UString &name) 1562370b324cSopenharmony_ci{ 1563370b324cSopenharmony_ci if (name.IsEmpty() 1564370b324cSopenharmony_ci || DoesNameContainWildcard(name) 1565370b324cSopenharmony_ci || IsDotsName(name)) 1566370b324cSopenharmony_ci return; 1567370b324cSopenharmony_ci NFind::CFileInfo fi; 1568370b324cSopenharmony_ci const FString path (us2fs(prefix + name)); 1569370b324cSopenharmony_ci #ifndef UNDER_CE 1570370b324cSopenharmony_ci if (NFile::NName::IsDevicePath(path)) 1571370b324cSopenharmony_ci return; 1572370b324cSopenharmony_ci #endif 1573370b324cSopenharmony_ci if (fi.Find(path)) 1574370b324cSopenharmony_ci name = fs2us(fi.Name); 1575370b324cSopenharmony_ci} 1576370b324cSopenharmony_ci 1577370b324cSopenharmony_cistatic void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items) 1578370b324cSopenharmony_ci{ 1579370b324cSopenharmony_ci FOR_VECTOR (i, items) 1580370b324cSopenharmony_ci { 1581370b324cSopenharmony_ci NWildcard::CItem &item = items[i]; 1582370b324cSopenharmony_ci if (item.Recursive || item.PathParts.Size() != 1) 1583370b324cSopenharmony_ci continue; 1584370b324cSopenharmony_ci if (prefix.IsEmpty() && item.IsDriveItem()) 1585370b324cSopenharmony_ci continue; 1586370b324cSopenharmony_ci ConvertToLongName(prefix, item.PathParts.Front()); 1587370b324cSopenharmony_ci } 1588370b324cSopenharmony_ci} 1589370b324cSopenharmony_ci 1590370b324cSopenharmony_cistatic void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) 1591370b324cSopenharmony_ci{ 1592370b324cSopenharmony_ci ConvertToLongNames(prefix, node.IncludeItems); 1593370b324cSopenharmony_ci ConvertToLongNames(prefix, node.ExcludeItems); 1594370b324cSopenharmony_ci unsigned i; 1595370b324cSopenharmony_ci for (i = 0; i < node.SubNodes.Size(); i++) 1596370b324cSopenharmony_ci { 1597370b324cSopenharmony_ci UString &name = node.SubNodes[i].Name; 1598370b324cSopenharmony_ci if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name)) 1599370b324cSopenharmony_ci continue; 1600370b324cSopenharmony_ci ConvertToLongName(prefix, name); 1601370b324cSopenharmony_ci } 1602370b324cSopenharmony_ci // mix folders with same name 1603370b324cSopenharmony_ci for (i = 0; i < node.SubNodes.Size(); i++) 1604370b324cSopenharmony_ci { 1605370b324cSopenharmony_ci NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; 1606370b324cSopenharmony_ci for (unsigned j = i + 1; j < node.SubNodes.Size();) 1607370b324cSopenharmony_ci { 1608370b324cSopenharmony_ci const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; 1609370b324cSopenharmony_ci if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name)) 1610370b324cSopenharmony_ci { 1611370b324cSopenharmony_ci nextNode1.IncludeItems += nextNode2.IncludeItems; 1612370b324cSopenharmony_ci nextNode1.ExcludeItems += nextNode2.ExcludeItems; 1613370b324cSopenharmony_ci node.SubNodes.Delete(j); 1614370b324cSopenharmony_ci } 1615370b324cSopenharmony_ci else 1616370b324cSopenharmony_ci j++; 1617370b324cSopenharmony_ci } 1618370b324cSopenharmony_ci } 1619370b324cSopenharmony_ci for (i = 0; i < node.SubNodes.Size(); i++) 1620370b324cSopenharmony_ci { 1621370b324cSopenharmony_ci NWildcard::CCensorNode &nextNode = node.SubNodes[i]; 1622370b324cSopenharmony_ci ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode); 1623370b324cSopenharmony_ci } 1624370b324cSopenharmony_ci} 1625370b324cSopenharmony_ci 1626370b324cSopenharmony_civoid ConvertToLongNames(NWildcard::CCensor &censor) 1627370b324cSopenharmony_ci{ 1628370b324cSopenharmony_ci FOR_VECTOR (i, censor.Pairs) 1629370b324cSopenharmony_ci { 1630370b324cSopenharmony_ci NWildcard::CPair &pair = censor.Pairs[i]; 1631370b324cSopenharmony_ci ConvertToLongNames(pair.Prefix, pair.Head); 1632370b324cSopenharmony_ci } 1633370b324cSopenharmony_ci} 1634370b324cSopenharmony_ci 1635370b324cSopenharmony_ci#endif 1636370b324cSopenharmony_ci 1637370b324cSopenharmony_ci 1638370b324cSopenharmony_ciCMessagePathException::CMessagePathException(const char *a, const wchar_t *u) 1639370b324cSopenharmony_ci{ 1640370b324cSopenharmony_ci (*this) += a; 1641370b324cSopenharmony_ci if (u) 1642370b324cSopenharmony_ci { 1643370b324cSopenharmony_ci Add_LF(); 1644370b324cSopenharmony_ci (*this) += u; 1645370b324cSopenharmony_ci } 1646370b324cSopenharmony_ci} 1647370b324cSopenharmony_ci 1648370b324cSopenharmony_ciCMessagePathException::CMessagePathException(const wchar_t *a, const wchar_t *u) 1649370b324cSopenharmony_ci{ 1650370b324cSopenharmony_ci (*this) += a; 1651370b324cSopenharmony_ci if (u) 1652370b324cSopenharmony_ci { 1653370b324cSopenharmony_ci Add_LF(); 1654370b324cSopenharmony_ci (*this) += u; 1655370b324cSopenharmony_ci } 1656370b324cSopenharmony_ci} 1657