xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/DirItem.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // DirItem.h
2 
3 #ifndef ZIP7_INC_DIR_ITEM_H
4 #define ZIP7_INC_DIR_ITEM_H
5 
6 #ifdef _WIN32
7 #include "../../../Common/MyLinux.h"
8 #endif
9 
10 #include "../../../Common/MyString.h"
11 
12 #include "../../../Windows/FileFind.h"
13 #include "../../../Windows/PropVariant.h"
14 #include "../../../Windows/TimeUtils.h"
15 
16 #include "../../Common/UniqBlocks.h"
17 
18 #include "../../Archive/IArchive.h"
19 
20 struct CDirItemsStat
21 {
22   UInt64 NumDirs;
23   UInt64 NumFiles;
24   UInt64 NumAltStreams;
25   UInt64 FilesSize;
26   UInt64 AltStreamsSize;
27 
28   UInt64 NumErrors;
29 
30   // UInt64 Get_NumItems() const { return NumDirs + NumFiles + NumAltStreams; }
Get_NumDataItemsCDirItemsStat31   UInt64 Get_NumDataItems() const { return NumFiles + NumAltStreams; }
GetTotalBytesCDirItemsStat32   UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; }
33 
IsEmptyCDirItemsStat34   bool IsEmpty() const { return
35            0 == NumDirs
36         && 0 == NumFiles
37         && 0 == NumAltStreams
38         && 0 == FilesSize
39         && 0 == AltStreamsSize
40         && 0 == NumErrors; }
41 
CDirItemsStatCDirItemsStat42   CDirItemsStat():
43       NumDirs(0),
44       NumFiles(0),
45       NumAltStreams(0),
46       FilesSize(0),
47       AltStreamsSize(0),
48       NumErrors(0)
49     {}
50 };
51 
52 
53 struct CDirItemsStat2: public CDirItemsStat
54 {
55   UInt64 Anti_NumDirs;
56   UInt64 Anti_NumFiles;
57   UInt64 Anti_NumAltStreams;
58 
59   // UInt64 Get_NumItems() const { return Anti_NumDirs + Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumItems(); }
Get_NumDataItems2CDirItemsStat260   UInt64 Get_NumDataItems2() const { return Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumDataItems(); }
61 
IsEmptyCDirItemsStat262   bool IsEmpty() const { return CDirItemsStat::IsEmpty()
63         && 0 == Anti_NumDirs
64         && 0 == Anti_NumFiles
65         && 0 == Anti_NumAltStreams; }
66 
CDirItemsStat2CDirItemsStat267   CDirItemsStat2():
68       Anti_NumDirs(0),
69       Anti_NumFiles(0),
70       Anti_NumAltStreams(0)
71     {}
72 };
73 
74 
75 Z7_PURE_INTERFACES_BEGIN
76 
77 #define Z7_IFACEN_IDirItemsCallback(x) \
78   virtual HRESULT ScanError(const FString &path, DWORD systemError) x \
79   virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x \
80 
81 Z7_IFACE_DECL_PURE(IDirItemsCallback)
82 
83 Z7_PURE_INTERFACES_END
84 
85 
86 struct CArcTime
87 {
88   FILETIME FT;
89   UInt16 Prec;
90   Byte Ns100;
91   bool Def;
92 
CArcTimeCArcTime93   CArcTime()
94   {
95     Clear();
96   }
97 
ClearCArcTime98   void Clear()
99   {
100     FT.dwHighDateTime = FT.dwLowDateTime = 0;
101     Prec = 0;
102     Ns100 = 0;
103     Def = false;
104   }
105 
IsZeroCArcTime106   bool IsZero() const
107   {
108     return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0;
109   }
110 
CompareWithCArcTime111   int CompareWith(const CArcTime &a) const
112   {
113     const int res = CompareFileTime(&FT, &a.FT);
114     if (res != 0)
115       return res;
116     if (Ns100 < a.Ns100) return -1;
117     if (Ns100 > a.Ns100) return 1;
118     return 0;
119   }
120 
Get_FILETIME_as_UInt64CArcTime121   UInt64 Get_FILETIME_as_UInt64() const
122   {
123     return (((UInt64)FT.dwHighDateTime) << 32) + FT.dwLowDateTime;
124   }
125 
Get_DosTimeCArcTime126   UInt32 Get_DosTime() const
127   {
128     FILETIME ft2 = FT;
129     if ((Prec == k_PropVar_TimePrec_Base + 8 ||
130          Prec == k_PropVar_TimePrec_Base + 9)
131         && Ns100 != 0)
132     {
133       UInt64 u64 = Get_FILETIME_as_UInt64();
134       // we round up even small (ns < 100ns) as FileTimeToDosTime()
135       if (u64 % 20000000 == 0)
136       {
137         u64++;
138         ft2.dwHighDateTime = (DWORD)(u64 >> 32);
139         ft2.dwHighDateTime = (DWORD)u64;
140       }
141     }
142     // FileTimeToDosTime() is expected to round up in Windows
143     UInt32 dosTime;
144     // we use simplified code with utctime->dos.
145     // do we need local time instead here?
146     NWindows::NTime::FileTime_To_DosTime(ft2, dosTime);
147     return dosTime;
148   }
149 
GetNumDigitsCArcTime150   int GetNumDigits() const
151   {
152     if (Prec == k_PropVar_TimePrec_Unix ||
153         Prec == k_PropVar_TimePrec_DOS)
154       return 0;
155     if (Prec == k_PropVar_TimePrec_HighPrec)
156       return 9;
157     if (Prec == k_PropVar_TimePrec_0)
158       return 7;
159     int digits = (int)Prec - (int)k_PropVar_TimePrec_Base;
160     if (digits < 0)
161       digits = 0;
162     return digits;
163   }
164 
Write_To_FiTimeCArcTime165   void Write_To_FiTime(CFiTime &dest) const
166   {
167    #ifdef _WIN32
168     dest = FT;
169    #else
170     if (FILETIME_To_timespec(FT, dest))
171     if ((Prec == k_PropVar_TimePrec_Base + 8 ||
172          Prec == k_PropVar_TimePrec_Base + 9)
173         && Ns100 != 0)
174     {
175       dest.tv_nsec += Ns100;
176     }
177    #endif
178   }
179 
180   // (Def) is not set
Set_From_FILETIMECArcTime181   void Set_From_FILETIME(const FILETIME &ft)
182   {
183     FT = ft;
184     // Prec = k_PropVar_TimePrec_CompatNTFS;
185     Prec = k_PropVar_TimePrec_Base + 7;
186     Ns100 = 0;
187   }
188 
189   // (Def) is not set
190   // it set full form precision: k_PropVar_TimePrec_Base + numDigits
Set_From_FiTimeCArcTime191   void Set_From_FiTime(const CFiTime &ts)
192   {
193    #ifdef _WIN32
194     FT = ts;
195     Prec = k_PropVar_TimePrec_Base + 7;
196     // Prec = k_PropVar_TimePrec_Base; // for debug
197     // Prec = 0; // for debug
198     Ns100 = 0;
199    #else
200     unsigned ns100;
201     FiTime_To_FILETIME_ns100(ts, FT, ns100);
202     Ns100 = (Byte)ns100;
203     Prec = k_PropVar_TimePrec_Base + 9;
204    #endif
205   }
206 
Set_From_PropCArcTime207   void Set_From_Prop(const PROPVARIANT &prop)
208   {
209     FT = prop.filetime;
210     unsigned prec = 0;
211     unsigned ns100 = 0;
212     const unsigned prec_Temp = prop.wReserved1;
213     if (prec_Temp != 0
214         && prec_Temp <= k_PropVar_TimePrec_1ns
215         && prop.wReserved3 == 0)
216     {
217       const unsigned ns100_Temp = prop.wReserved2;
218       if (ns100_Temp < 100)
219       {
220         ns100 = ns100_Temp;
221         prec = prec_Temp;
222       }
223     }
224     Prec = (UInt16)prec;
225     Ns100 = (Byte)ns100;
226     Def = true;
227   }
228 };
229 
230 
231 struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase
232 {
233   UString Name;
234 
235  #ifndef UNDER_CE
236   CByteBuffer ReparseData;
237 
238  #ifdef _WIN32
239   // UString ShortName;
240   CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format
AreReparseDataCDirItem241   bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; }
242  #else
AreReparseDataCDirItem243   bool AreReparseData() const { return ReparseData.Size() != 0; }
244  #endif // _WIN32
245 
246  #endif // !UNDER_CE
247 
Copy_From_FileInfoBaseCDirItem248   void Copy_From_FileInfoBase(const NWindows::NFile::NFind::CFileInfoBase &fi)
249   {
250     (NWindows::NFile::NFind::CFileInfoBase &)*this = fi;
251   }
252 
253   int PhyParent;
254   int LogParent;
255   int SecureIndex;
256 
257  #ifdef _WIN32
258  #else
259   int OwnerNameIndex;
260   int OwnerGroupIndex;
261  #endif
262 
263   // bool Attrib_IsDefined;
264 
CDirItemCDirItem265   CDirItem():
266       PhyParent(-1)
267     , LogParent(-1)
268     , SecureIndex(-1)
269    #ifdef _WIN32
270    #else
271     , OwnerNameIndex(-1)
272     , OwnerGroupIndex(-1)
273    #endif
274     // , Attrib_IsDefined(true)
275   {
276   }
277 
278 
CDirItemCDirItem279   CDirItem(const NWindows::NFile::NFind::CFileInfo &fi,
280       int phyParent, int logParent, int secureIndex):
281     CFileInfoBase(fi)
282     , Name(fs2us(fi.Name))
283    #if defined(_WIN32) && !defined(UNDER_CE)
284     // , ShortName(fs2us(fi.ShortName))
285    #endif
286     , PhyParent(phyParent)
287     , LogParent(logParent)
288     , SecureIndex(secureIndex)
289    #ifdef _WIN32
290    #else
291     , OwnerNameIndex(-1)
292     , OwnerGroupIndex(-1)
293    #endif
294     {}
295 };
296 
297 
298 
299 class CDirItems
300 {
301   UStringVector Prefixes;
302   CIntVector PhyParents;
303   CIntVector LogParents;
304 
305   UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const;
306 
307   HRESULT EnumerateDir(int phyParent, int logParent, const FString &phyPrefix);
308 
309 public:
310   CObjectVector<CDirItem> Items;
311 
312   bool SymLinks;
313   bool ScanAltStreams;
314   bool ExcludeDirItems;
315   bool ExcludeFileItems;
316   bool ShareForWrite;
317 
318   /* it must be called after anotrher checks */
CanIncludeItem(bool isDir)319   bool CanIncludeItem(bool isDir) const
320   {
321     return isDir ? !ExcludeDirItems : !ExcludeFileItems;
322   }
323 
324 
325   CDirItemsStat Stat;
326 
327   #if !defined(UNDER_CE)
328   HRESULT SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi,
329       const FString &phyPrefix);
330   #endif
331 
332  #if defined(_WIN32) && !defined(UNDER_CE)
333 
334   CUniqBlocks SecureBlocks;
335   CByteBuffer TempSecureBuf;
336   bool _saclEnabled;
337   bool ReadSecure;
338 
339   HRESULT AddSecurityItem(const FString &path, int &secureIndex);
340   HRESULT FillFixedReparse();
341 
342  #endif
343 
344  #ifndef _WIN32
345 
346   C_UInt32_UString_Map OwnerNameMap;
347   C_UInt32_UString_Map OwnerGroupMap;
348   bool StoreOwnerName;
349 
350   HRESULT FillDeviceSizes();
351 
352  #endif
353 
354   IDirItemsCallback *Callback;
355 
356   CDirItems();
357 
358   void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
359       const NWindows::NFile::NFind::CFileInfo &fi);
360 
361   HRESULT AddError(const FString &path, DWORD errorCode);
362   HRESULT AddError(const FString &path);
363 
364   HRESULT ScanProgress(const FString &path);
365 
366   // unsigned GetNumFolders() const { return Prefixes.Size(); }
367   FString GetPhyPath(unsigned index) const;
368   UString GetLogPath(unsigned index) const;
369 
370   unsigned AddPrefix(int phyParent, int logParent, const UString &prefix);
371   void DeleteLastPrefix();
372 
373   // HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CDirEntry> &files);
374   HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CFileInfo> &files);
375 
376   HRESULT EnumerateItems2(
377     const FString &phyPrefix,
378     const UString &logPrefix,
379     const FStringVector &filePaths,
380     FStringVector *requestedPaths);
381 
382   void ReserveDown();
383 };
384 
385 
386 
387 
388 struct CArcItem
389 {
390   UInt64 Size;
391   UString Name;
392   CArcTime MTime;  // it can be mtime of archive file, if MTime is not defined for item in archive
393   bool IsDir;
394   bool IsAltStream;
395   bool Size_Defined;
396   bool Censored;
397   UInt32 IndexInServer;
398 
CArcItemCArcItem399   CArcItem():
400       IsDir(false),
401       IsAltStream(false),
402       Size_Defined(false),
403       Censored(false)
404     {}
405 };
406 
407 #endif
408