1370b324cSopenharmony_ci// DirItem.h 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#ifndef ZIP7_INC_DIR_ITEM_H 4370b324cSopenharmony_ci#define ZIP7_INC_DIR_ITEM_H 5370b324cSopenharmony_ci 6370b324cSopenharmony_ci#ifdef _WIN32 7370b324cSopenharmony_ci#include "../../../Common/MyLinux.h" 8370b324cSopenharmony_ci#endif 9370b324cSopenharmony_ci 10370b324cSopenharmony_ci#include "../../../Common/MyString.h" 11370b324cSopenharmony_ci 12370b324cSopenharmony_ci#include "../../../Windows/FileFind.h" 13370b324cSopenharmony_ci#include "../../../Windows/PropVariant.h" 14370b324cSopenharmony_ci#include "../../../Windows/TimeUtils.h" 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci#include "../../Common/UniqBlocks.h" 17370b324cSopenharmony_ci 18370b324cSopenharmony_ci#include "../../Archive/IArchive.h" 19370b324cSopenharmony_ci 20370b324cSopenharmony_cistruct CDirItemsStat 21370b324cSopenharmony_ci{ 22370b324cSopenharmony_ci UInt64 NumDirs; 23370b324cSopenharmony_ci UInt64 NumFiles; 24370b324cSopenharmony_ci UInt64 NumAltStreams; 25370b324cSopenharmony_ci UInt64 FilesSize; 26370b324cSopenharmony_ci UInt64 AltStreamsSize; 27370b324cSopenharmony_ci 28370b324cSopenharmony_ci UInt64 NumErrors; 29370b324cSopenharmony_ci 30370b324cSopenharmony_ci // UInt64 Get_NumItems() const { return NumDirs + NumFiles + NumAltStreams; } 31370b324cSopenharmony_ci UInt64 Get_NumDataItems() const { return NumFiles + NumAltStreams; } 32370b324cSopenharmony_ci UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; } 33370b324cSopenharmony_ci 34370b324cSopenharmony_ci bool IsEmpty() const { return 35370b324cSopenharmony_ci 0 == NumDirs 36370b324cSopenharmony_ci && 0 == NumFiles 37370b324cSopenharmony_ci && 0 == NumAltStreams 38370b324cSopenharmony_ci && 0 == FilesSize 39370b324cSopenharmony_ci && 0 == AltStreamsSize 40370b324cSopenharmony_ci && 0 == NumErrors; } 41370b324cSopenharmony_ci 42370b324cSopenharmony_ci CDirItemsStat(): 43370b324cSopenharmony_ci NumDirs(0), 44370b324cSopenharmony_ci NumFiles(0), 45370b324cSopenharmony_ci NumAltStreams(0), 46370b324cSopenharmony_ci FilesSize(0), 47370b324cSopenharmony_ci AltStreamsSize(0), 48370b324cSopenharmony_ci NumErrors(0) 49370b324cSopenharmony_ci {} 50370b324cSopenharmony_ci}; 51370b324cSopenharmony_ci 52370b324cSopenharmony_ci 53370b324cSopenharmony_cistruct CDirItemsStat2: public CDirItemsStat 54370b324cSopenharmony_ci{ 55370b324cSopenharmony_ci UInt64 Anti_NumDirs; 56370b324cSopenharmony_ci UInt64 Anti_NumFiles; 57370b324cSopenharmony_ci UInt64 Anti_NumAltStreams; 58370b324cSopenharmony_ci 59370b324cSopenharmony_ci // UInt64 Get_NumItems() const { return Anti_NumDirs + Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumItems(); } 60370b324cSopenharmony_ci UInt64 Get_NumDataItems2() const { return Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumDataItems(); } 61370b324cSopenharmony_ci 62370b324cSopenharmony_ci bool IsEmpty() const { return CDirItemsStat::IsEmpty() 63370b324cSopenharmony_ci && 0 == Anti_NumDirs 64370b324cSopenharmony_ci && 0 == Anti_NumFiles 65370b324cSopenharmony_ci && 0 == Anti_NumAltStreams; } 66370b324cSopenharmony_ci 67370b324cSopenharmony_ci CDirItemsStat2(): 68370b324cSopenharmony_ci Anti_NumDirs(0), 69370b324cSopenharmony_ci Anti_NumFiles(0), 70370b324cSopenharmony_ci Anti_NumAltStreams(0) 71370b324cSopenharmony_ci {} 72370b324cSopenharmony_ci}; 73370b324cSopenharmony_ci 74370b324cSopenharmony_ci 75370b324cSopenharmony_ciZ7_PURE_INTERFACES_BEGIN 76370b324cSopenharmony_ci 77370b324cSopenharmony_ci#define Z7_IFACEN_IDirItemsCallback(x) \ 78370b324cSopenharmony_ci virtual HRESULT ScanError(const FString &path, DWORD systemError) x \ 79370b324cSopenharmony_ci virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x \ 80370b324cSopenharmony_ci 81370b324cSopenharmony_ciZ7_IFACE_DECL_PURE(IDirItemsCallback) 82370b324cSopenharmony_ci 83370b324cSopenharmony_ciZ7_PURE_INTERFACES_END 84370b324cSopenharmony_ci 85370b324cSopenharmony_ci 86370b324cSopenharmony_cistruct CArcTime 87370b324cSopenharmony_ci{ 88370b324cSopenharmony_ci FILETIME FT; 89370b324cSopenharmony_ci UInt16 Prec; 90370b324cSopenharmony_ci Byte Ns100; 91370b324cSopenharmony_ci bool Def; 92370b324cSopenharmony_ci 93370b324cSopenharmony_ci CArcTime() 94370b324cSopenharmony_ci { 95370b324cSopenharmony_ci Clear(); 96370b324cSopenharmony_ci } 97370b324cSopenharmony_ci 98370b324cSopenharmony_ci void Clear() 99370b324cSopenharmony_ci { 100370b324cSopenharmony_ci FT.dwHighDateTime = FT.dwLowDateTime = 0; 101370b324cSopenharmony_ci Prec = 0; 102370b324cSopenharmony_ci Ns100 = 0; 103370b324cSopenharmony_ci Def = false; 104370b324cSopenharmony_ci } 105370b324cSopenharmony_ci 106370b324cSopenharmony_ci bool IsZero() const 107370b324cSopenharmony_ci { 108370b324cSopenharmony_ci return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0; 109370b324cSopenharmony_ci } 110370b324cSopenharmony_ci 111370b324cSopenharmony_ci int CompareWith(const CArcTime &a) const 112370b324cSopenharmony_ci { 113370b324cSopenharmony_ci const int res = CompareFileTime(&FT, &a.FT); 114370b324cSopenharmony_ci if (res != 0) 115370b324cSopenharmony_ci return res; 116370b324cSopenharmony_ci if (Ns100 < a.Ns100) return -1; 117370b324cSopenharmony_ci if (Ns100 > a.Ns100) return 1; 118370b324cSopenharmony_ci return 0; 119370b324cSopenharmony_ci } 120370b324cSopenharmony_ci 121370b324cSopenharmony_ci UInt64 Get_FILETIME_as_UInt64() const 122370b324cSopenharmony_ci { 123370b324cSopenharmony_ci return (((UInt64)FT.dwHighDateTime) << 32) + FT.dwLowDateTime; 124370b324cSopenharmony_ci } 125370b324cSopenharmony_ci 126370b324cSopenharmony_ci UInt32 Get_DosTime() const 127370b324cSopenharmony_ci { 128370b324cSopenharmony_ci FILETIME ft2 = FT; 129370b324cSopenharmony_ci if ((Prec == k_PropVar_TimePrec_Base + 8 || 130370b324cSopenharmony_ci Prec == k_PropVar_TimePrec_Base + 9) 131370b324cSopenharmony_ci && Ns100 != 0) 132370b324cSopenharmony_ci { 133370b324cSopenharmony_ci UInt64 u64 = Get_FILETIME_as_UInt64(); 134370b324cSopenharmony_ci // we round up even small (ns < 100ns) as FileTimeToDosTime() 135370b324cSopenharmony_ci if (u64 % 20000000 == 0) 136370b324cSopenharmony_ci { 137370b324cSopenharmony_ci u64++; 138370b324cSopenharmony_ci ft2.dwHighDateTime = (DWORD)(u64 >> 32); 139370b324cSopenharmony_ci ft2.dwHighDateTime = (DWORD)u64; 140370b324cSopenharmony_ci } 141370b324cSopenharmony_ci } 142370b324cSopenharmony_ci // FileTimeToDosTime() is expected to round up in Windows 143370b324cSopenharmony_ci UInt32 dosTime; 144370b324cSopenharmony_ci // we use simplified code with utctime->dos. 145370b324cSopenharmony_ci // do we need local time instead here? 146370b324cSopenharmony_ci NWindows::NTime::FileTime_To_DosTime(ft2, dosTime); 147370b324cSopenharmony_ci return dosTime; 148370b324cSopenharmony_ci } 149370b324cSopenharmony_ci 150370b324cSopenharmony_ci int GetNumDigits() const 151370b324cSopenharmony_ci { 152370b324cSopenharmony_ci if (Prec == k_PropVar_TimePrec_Unix || 153370b324cSopenharmony_ci Prec == k_PropVar_TimePrec_DOS) 154370b324cSopenharmony_ci return 0; 155370b324cSopenharmony_ci if (Prec == k_PropVar_TimePrec_HighPrec) 156370b324cSopenharmony_ci return 9; 157370b324cSopenharmony_ci if (Prec == k_PropVar_TimePrec_0) 158370b324cSopenharmony_ci return 7; 159370b324cSopenharmony_ci int digits = (int)Prec - (int)k_PropVar_TimePrec_Base; 160370b324cSopenharmony_ci if (digits < 0) 161370b324cSopenharmony_ci digits = 0; 162370b324cSopenharmony_ci return digits; 163370b324cSopenharmony_ci } 164370b324cSopenharmony_ci 165370b324cSopenharmony_ci void Write_To_FiTime(CFiTime &dest) const 166370b324cSopenharmony_ci { 167370b324cSopenharmony_ci #ifdef _WIN32 168370b324cSopenharmony_ci dest = FT; 169370b324cSopenharmony_ci #else 170370b324cSopenharmony_ci if (FILETIME_To_timespec(FT, dest)) 171370b324cSopenharmony_ci if ((Prec == k_PropVar_TimePrec_Base + 8 || 172370b324cSopenharmony_ci Prec == k_PropVar_TimePrec_Base + 9) 173370b324cSopenharmony_ci && Ns100 != 0) 174370b324cSopenharmony_ci { 175370b324cSopenharmony_ci dest.tv_nsec += Ns100; 176370b324cSopenharmony_ci } 177370b324cSopenharmony_ci #endif 178370b324cSopenharmony_ci } 179370b324cSopenharmony_ci 180370b324cSopenharmony_ci // (Def) is not set 181370b324cSopenharmony_ci void Set_From_FILETIME(const FILETIME &ft) 182370b324cSopenharmony_ci { 183370b324cSopenharmony_ci FT = ft; 184370b324cSopenharmony_ci // Prec = k_PropVar_TimePrec_CompatNTFS; 185370b324cSopenharmony_ci Prec = k_PropVar_TimePrec_Base + 7; 186370b324cSopenharmony_ci Ns100 = 0; 187370b324cSopenharmony_ci } 188370b324cSopenharmony_ci 189370b324cSopenharmony_ci // (Def) is not set 190370b324cSopenharmony_ci // it set full form precision: k_PropVar_TimePrec_Base + numDigits 191370b324cSopenharmony_ci void Set_From_FiTime(const CFiTime &ts) 192370b324cSopenharmony_ci { 193370b324cSopenharmony_ci #ifdef _WIN32 194370b324cSopenharmony_ci FT = ts; 195370b324cSopenharmony_ci Prec = k_PropVar_TimePrec_Base + 7; 196370b324cSopenharmony_ci // Prec = k_PropVar_TimePrec_Base; // for debug 197370b324cSopenharmony_ci // Prec = 0; // for debug 198370b324cSopenharmony_ci Ns100 = 0; 199370b324cSopenharmony_ci #else 200370b324cSopenharmony_ci unsigned ns100; 201370b324cSopenharmony_ci FiTime_To_FILETIME_ns100(ts, FT, ns100); 202370b324cSopenharmony_ci Ns100 = (Byte)ns100; 203370b324cSopenharmony_ci Prec = k_PropVar_TimePrec_Base + 9; 204370b324cSopenharmony_ci #endif 205370b324cSopenharmony_ci } 206370b324cSopenharmony_ci 207370b324cSopenharmony_ci void Set_From_Prop(const PROPVARIANT &prop) 208370b324cSopenharmony_ci { 209370b324cSopenharmony_ci FT = prop.filetime; 210370b324cSopenharmony_ci unsigned prec = 0; 211370b324cSopenharmony_ci unsigned ns100 = 0; 212370b324cSopenharmony_ci const unsigned prec_Temp = prop.wReserved1; 213370b324cSopenharmony_ci if (prec_Temp != 0 214370b324cSopenharmony_ci && prec_Temp <= k_PropVar_TimePrec_1ns 215370b324cSopenharmony_ci && prop.wReserved3 == 0) 216370b324cSopenharmony_ci { 217370b324cSopenharmony_ci const unsigned ns100_Temp = prop.wReserved2; 218370b324cSopenharmony_ci if (ns100_Temp < 100) 219370b324cSopenharmony_ci { 220370b324cSopenharmony_ci ns100 = ns100_Temp; 221370b324cSopenharmony_ci prec = prec_Temp; 222370b324cSopenharmony_ci } 223370b324cSopenharmony_ci } 224370b324cSopenharmony_ci Prec = (UInt16)prec; 225370b324cSopenharmony_ci Ns100 = (Byte)ns100; 226370b324cSopenharmony_ci Def = true; 227370b324cSopenharmony_ci } 228370b324cSopenharmony_ci}; 229370b324cSopenharmony_ci 230370b324cSopenharmony_ci 231370b324cSopenharmony_cistruct CDirItem: public NWindows::NFile::NFind::CFileInfoBase 232370b324cSopenharmony_ci{ 233370b324cSopenharmony_ci UString Name; 234370b324cSopenharmony_ci 235370b324cSopenharmony_ci #ifndef UNDER_CE 236370b324cSopenharmony_ci CByteBuffer ReparseData; 237370b324cSopenharmony_ci 238370b324cSopenharmony_ci #ifdef _WIN32 239370b324cSopenharmony_ci // UString ShortName; 240370b324cSopenharmony_ci CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format 241370b324cSopenharmony_ci bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; } 242370b324cSopenharmony_ci #else 243370b324cSopenharmony_ci bool AreReparseData() const { return ReparseData.Size() != 0; } 244370b324cSopenharmony_ci #endif // _WIN32 245370b324cSopenharmony_ci 246370b324cSopenharmony_ci #endif // !UNDER_CE 247370b324cSopenharmony_ci 248370b324cSopenharmony_ci void Copy_From_FileInfoBase(const NWindows::NFile::NFind::CFileInfoBase &fi) 249370b324cSopenharmony_ci { 250370b324cSopenharmony_ci (NWindows::NFile::NFind::CFileInfoBase &)*this = fi; 251370b324cSopenharmony_ci } 252370b324cSopenharmony_ci 253370b324cSopenharmony_ci int PhyParent; 254370b324cSopenharmony_ci int LogParent; 255370b324cSopenharmony_ci int SecureIndex; 256370b324cSopenharmony_ci 257370b324cSopenharmony_ci #ifdef _WIN32 258370b324cSopenharmony_ci #else 259370b324cSopenharmony_ci int OwnerNameIndex; 260370b324cSopenharmony_ci int OwnerGroupIndex; 261370b324cSopenharmony_ci #endif 262370b324cSopenharmony_ci 263370b324cSopenharmony_ci CDirItem(): 264370b324cSopenharmony_ci PhyParent(-1) 265370b324cSopenharmony_ci , LogParent(-1) 266370b324cSopenharmony_ci , SecureIndex(-1) 267370b324cSopenharmony_ci #ifdef _WIN32 268370b324cSopenharmony_ci #else 269370b324cSopenharmony_ci , OwnerNameIndex(-1) 270370b324cSopenharmony_ci , OwnerGroupIndex(-1) 271370b324cSopenharmony_ci #endif 272370b324cSopenharmony_ci { 273370b324cSopenharmony_ci } 274370b324cSopenharmony_ci 275370b324cSopenharmony_ci 276370b324cSopenharmony_ci CDirItem(const NWindows::NFile::NFind::CFileInfo &fi, 277370b324cSopenharmony_ci int phyParent, int logParent, int secureIndex): 278370b324cSopenharmony_ci CFileInfoBase(fi) 279370b324cSopenharmony_ci , Name(fs2us(fi.Name)) 280370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 281370b324cSopenharmony_ci // , ShortName(fs2us(fi.ShortName)) 282370b324cSopenharmony_ci #endif 283370b324cSopenharmony_ci , PhyParent(phyParent) 284370b324cSopenharmony_ci , LogParent(logParent) 285370b324cSopenharmony_ci , SecureIndex(secureIndex) 286370b324cSopenharmony_ci #ifdef _WIN32 287370b324cSopenharmony_ci #else 288370b324cSopenharmony_ci , OwnerNameIndex(-1) 289370b324cSopenharmony_ci , OwnerGroupIndex(-1) 290370b324cSopenharmony_ci #endif 291370b324cSopenharmony_ci {} 292370b324cSopenharmony_ci}; 293370b324cSopenharmony_ci 294370b324cSopenharmony_ci 295370b324cSopenharmony_ci 296370b324cSopenharmony_ciclass CDirItems 297370b324cSopenharmony_ci{ 298370b324cSopenharmony_ci UStringVector Prefixes; 299370b324cSopenharmony_ci CIntVector PhyParents; 300370b324cSopenharmony_ci CIntVector LogParents; 301370b324cSopenharmony_ci 302370b324cSopenharmony_ci UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const; 303370b324cSopenharmony_ci 304370b324cSopenharmony_ci HRESULT EnumerateDir(int phyParent, int logParent, const FString &phyPrefix); 305370b324cSopenharmony_ci 306370b324cSopenharmony_cipublic: 307370b324cSopenharmony_ci CObjectVector<CDirItem> Items; 308370b324cSopenharmony_ci 309370b324cSopenharmony_ci bool SymLinks; 310370b324cSopenharmony_ci bool ScanAltStreams; 311370b324cSopenharmony_ci bool ExcludeDirItems; 312370b324cSopenharmony_ci bool ExcludeFileItems; 313370b324cSopenharmony_ci bool ShareForWrite; 314370b324cSopenharmony_ci 315370b324cSopenharmony_ci /* it must be called after anotrher checks */ 316370b324cSopenharmony_ci bool CanIncludeItem(bool isDir) const 317370b324cSopenharmony_ci { 318370b324cSopenharmony_ci return isDir ? !ExcludeDirItems : !ExcludeFileItems; 319370b324cSopenharmony_ci } 320370b324cSopenharmony_ci 321370b324cSopenharmony_ci 322370b324cSopenharmony_ci CDirItemsStat Stat; 323370b324cSopenharmony_ci 324370b324cSopenharmony_ci #if !defined(UNDER_CE) 325370b324cSopenharmony_ci HRESULT SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi, 326370b324cSopenharmony_ci const FString &phyPrefix); 327370b324cSopenharmony_ci #endif 328370b324cSopenharmony_ci 329370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 330370b324cSopenharmony_ci 331370b324cSopenharmony_ci CUniqBlocks SecureBlocks; 332370b324cSopenharmony_ci CByteBuffer TempSecureBuf; 333370b324cSopenharmony_ci bool _saclEnabled; 334370b324cSopenharmony_ci bool ReadSecure; 335370b324cSopenharmony_ci 336370b324cSopenharmony_ci HRESULT AddSecurityItem(const FString &path, int &secureIndex); 337370b324cSopenharmony_ci HRESULT FillFixedReparse(); 338370b324cSopenharmony_ci 339370b324cSopenharmony_ci #endif 340370b324cSopenharmony_ci 341370b324cSopenharmony_ci #ifndef _WIN32 342370b324cSopenharmony_ci 343370b324cSopenharmony_ci C_UInt32_UString_Map OwnerNameMap; 344370b324cSopenharmony_ci C_UInt32_UString_Map OwnerGroupMap; 345370b324cSopenharmony_ci bool StoreOwnerName; 346370b324cSopenharmony_ci 347370b324cSopenharmony_ci HRESULT FillDeviceSizes(); 348370b324cSopenharmony_ci 349370b324cSopenharmony_ci #endif 350370b324cSopenharmony_ci 351370b324cSopenharmony_ci IDirItemsCallback *Callback; 352370b324cSopenharmony_ci 353370b324cSopenharmony_ci CDirItems(); 354370b324cSopenharmony_ci 355370b324cSopenharmony_ci void AddDirFileInfo(int phyParent, int logParent, int secureIndex, 356370b324cSopenharmony_ci const NWindows::NFile::NFind::CFileInfo &fi); 357370b324cSopenharmony_ci 358370b324cSopenharmony_ci HRESULT AddError(const FString &path, DWORD errorCode); 359370b324cSopenharmony_ci HRESULT AddError(const FString &path); 360370b324cSopenharmony_ci 361370b324cSopenharmony_ci HRESULT ScanProgress(const FString &path); 362370b324cSopenharmony_ci 363370b324cSopenharmony_ci // unsigned GetNumFolders() const { return Prefixes.Size(); } 364370b324cSopenharmony_ci FString GetPhyPath(unsigned index) const; 365370b324cSopenharmony_ci UString GetLogPath(unsigned index) const; 366370b324cSopenharmony_ci 367370b324cSopenharmony_ci unsigned AddPrefix(int phyParent, int logParent, const UString &prefix); 368370b324cSopenharmony_ci void DeleteLastPrefix(); 369370b324cSopenharmony_ci 370370b324cSopenharmony_ci // HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CDirEntry> &files); 371370b324cSopenharmony_ci HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CFileInfo> &files); 372370b324cSopenharmony_ci 373370b324cSopenharmony_ci HRESULT EnumerateItems2( 374370b324cSopenharmony_ci const FString &phyPrefix, 375370b324cSopenharmony_ci const UString &logPrefix, 376370b324cSopenharmony_ci const FStringVector &filePaths, 377370b324cSopenharmony_ci FStringVector *requestedPaths); 378370b324cSopenharmony_ci 379370b324cSopenharmony_ci void ReserveDown(); 380370b324cSopenharmony_ci}; 381370b324cSopenharmony_ci 382370b324cSopenharmony_ci 383370b324cSopenharmony_ci 384370b324cSopenharmony_ci 385370b324cSopenharmony_cistruct CArcItem 386370b324cSopenharmony_ci{ 387370b324cSopenharmony_ci UInt64 Size; 388370b324cSopenharmony_ci UString Name; 389370b324cSopenharmony_ci CArcTime MTime; // it can be mtime of archive file, if MTime is not defined for item in archive 390370b324cSopenharmony_ci bool IsDir; 391370b324cSopenharmony_ci bool IsAltStream; 392370b324cSopenharmony_ci bool Size_Defined; 393370b324cSopenharmony_ci bool Censored; 394370b324cSopenharmony_ci UInt32 IndexInServer; 395370b324cSopenharmony_ci 396370b324cSopenharmony_ci CArcItem(): 397370b324cSopenharmony_ci IsDir(false), 398370b324cSopenharmony_ci IsAltStream(false), 399370b324cSopenharmony_ci Size_Defined(false), 400370b324cSopenharmony_ci Censored(false) 401370b324cSopenharmony_ci {} 402370b324cSopenharmony_ci}; 403370b324cSopenharmony_ci 404370b324cSopenharmony_ci#endif 405