xref: /third_party/lzma/CPP/7zip/UI/Common/DirItem.h (revision 370b324c)
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
20struct 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; }
31  UInt64 Get_NumDataItems() const { return NumFiles + NumAltStreams; }
32  UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; }
33
34  bool IsEmpty() const { return
35           0 == NumDirs
36        && 0 == NumFiles
37        && 0 == NumAltStreams
38        && 0 == FilesSize
39        && 0 == AltStreamsSize
40        && 0 == NumErrors; }
41
42  CDirItemsStat():
43      NumDirs(0),
44      NumFiles(0),
45      NumAltStreams(0),
46      FilesSize(0),
47      AltStreamsSize(0),
48      NumErrors(0)
49    {}
50};
51
52
53struct 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(); }
60  UInt64 Get_NumDataItems2() const { return Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumDataItems(); }
61
62  bool IsEmpty() const { return CDirItemsStat::IsEmpty()
63        && 0 == Anti_NumDirs
64        && 0 == Anti_NumFiles
65        && 0 == Anti_NumAltStreams; }
66
67  CDirItemsStat2():
68      Anti_NumDirs(0),
69      Anti_NumFiles(0),
70      Anti_NumAltStreams(0)
71    {}
72};
73
74
75Z7_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
81Z7_IFACE_DECL_PURE(IDirItemsCallback)
82
83Z7_PURE_INTERFACES_END
84
85
86struct CArcTime
87{
88  FILETIME FT;
89  UInt16 Prec;
90  Byte Ns100;
91  bool Def;
92
93  CArcTime()
94  {
95    Clear();
96  }
97
98  void Clear()
99  {
100    FT.dwHighDateTime = FT.dwLowDateTime = 0;
101    Prec = 0;
102    Ns100 = 0;
103    Def = false;
104  }
105
106  bool IsZero() const
107  {
108    return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0;
109  }
110
111  int CompareWith(const CArcTime &a) const
112  {
113    const int res = CompareFileTime(&FT, &a.FT);
114    if (res != 0)
115      return res;
116    if (Ns100 < a.Ns100) return -1;
117    if (Ns100 > a.Ns100) return 1;
118    return 0;
119  }
120
121  UInt64 Get_FILETIME_as_UInt64() const
122  {
123    return (((UInt64)FT.dwHighDateTime) << 32) + FT.dwLowDateTime;
124  }
125
126  UInt32 Get_DosTime() const
127  {
128    FILETIME ft2 = FT;
129    if ((Prec == k_PropVar_TimePrec_Base + 8 ||
130         Prec == k_PropVar_TimePrec_Base + 9)
131        && Ns100 != 0)
132    {
133      UInt64 u64 = Get_FILETIME_as_UInt64();
134      // we round up even small (ns < 100ns) as FileTimeToDosTime()
135      if (u64 % 20000000 == 0)
136      {
137        u64++;
138        ft2.dwHighDateTime = (DWORD)(u64 >> 32);
139        ft2.dwHighDateTime = (DWORD)u64;
140      }
141    }
142    // FileTimeToDosTime() is expected to round up in Windows
143    UInt32 dosTime;
144    // we use simplified code with utctime->dos.
145    // do we need local time instead here?
146    NWindows::NTime::FileTime_To_DosTime(ft2, dosTime);
147    return dosTime;
148  }
149
150  int GetNumDigits() const
151  {
152    if (Prec == k_PropVar_TimePrec_Unix ||
153        Prec == k_PropVar_TimePrec_DOS)
154      return 0;
155    if (Prec == k_PropVar_TimePrec_HighPrec)
156      return 9;
157    if (Prec == k_PropVar_TimePrec_0)
158      return 7;
159    int digits = (int)Prec - (int)k_PropVar_TimePrec_Base;
160    if (digits < 0)
161      digits = 0;
162    return digits;
163  }
164
165  void Write_To_FiTime(CFiTime &dest) const
166  {
167   #ifdef _WIN32
168    dest = FT;
169   #else
170    if (FILETIME_To_timespec(FT, dest))
171    if ((Prec == k_PropVar_TimePrec_Base + 8 ||
172         Prec == k_PropVar_TimePrec_Base + 9)
173        && Ns100 != 0)
174    {
175      dest.tv_nsec += Ns100;
176    }
177   #endif
178  }
179
180  // (Def) is not set
181  void Set_From_FILETIME(const FILETIME &ft)
182  {
183    FT = ft;
184    // Prec = k_PropVar_TimePrec_CompatNTFS;
185    Prec = k_PropVar_TimePrec_Base + 7;
186    Ns100 = 0;
187  }
188
189  // (Def) is not set
190  // it set full form precision: k_PropVar_TimePrec_Base + numDigits
191  void Set_From_FiTime(const CFiTime &ts)
192  {
193   #ifdef _WIN32
194    FT = ts;
195    Prec = k_PropVar_TimePrec_Base + 7;
196    // Prec = k_PropVar_TimePrec_Base; // for debug
197    // Prec = 0; // for debug
198    Ns100 = 0;
199   #else
200    unsigned ns100;
201    FiTime_To_FILETIME_ns100(ts, FT, ns100);
202    Ns100 = (Byte)ns100;
203    Prec = k_PropVar_TimePrec_Base + 9;
204   #endif
205  }
206
207  void Set_From_Prop(const PROPVARIANT &prop)
208  {
209    FT = prop.filetime;
210    unsigned prec = 0;
211    unsigned ns100 = 0;
212    const unsigned prec_Temp = prop.wReserved1;
213    if (prec_Temp != 0
214        && prec_Temp <= k_PropVar_TimePrec_1ns
215        && prop.wReserved3 == 0)
216    {
217      const unsigned ns100_Temp = prop.wReserved2;
218      if (ns100_Temp < 100)
219      {
220        ns100 = ns100_Temp;
221        prec = prec_Temp;
222      }
223    }
224    Prec = (UInt16)prec;
225    Ns100 = (Byte)ns100;
226    Def = true;
227  }
228};
229
230
231struct 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
241  bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; }
242 #else
243  bool AreReparseData() const { return ReparseData.Size() != 0; }
244 #endif // _WIN32
245
246 #endif // !UNDER_CE
247
248  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  CDirItem():
264      PhyParent(-1)
265    , LogParent(-1)
266    , SecureIndex(-1)
267   #ifdef _WIN32
268   #else
269    , OwnerNameIndex(-1)
270    , OwnerGroupIndex(-1)
271   #endif
272  {
273  }
274
275
276  CDirItem(const NWindows::NFile::NFind::CFileInfo &fi,
277      int phyParent, int logParent, int secureIndex):
278    CFileInfoBase(fi)
279    , Name(fs2us(fi.Name))
280   #if defined(_WIN32) && !defined(UNDER_CE)
281    // , ShortName(fs2us(fi.ShortName))
282   #endif
283    , PhyParent(phyParent)
284    , LogParent(logParent)
285    , SecureIndex(secureIndex)
286   #ifdef _WIN32
287   #else
288    , OwnerNameIndex(-1)
289    , OwnerGroupIndex(-1)
290   #endif
291    {}
292};
293
294
295
296class CDirItems
297{
298  UStringVector Prefixes;
299  CIntVector PhyParents;
300  CIntVector LogParents;
301
302  UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const;
303
304  HRESULT EnumerateDir(int phyParent, int logParent, const FString &phyPrefix);
305
306public:
307  CObjectVector<CDirItem> Items;
308
309  bool SymLinks;
310  bool ScanAltStreams;
311  bool ExcludeDirItems;
312  bool ExcludeFileItems;
313  bool ShareForWrite;
314
315  /* it must be called after anotrher checks */
316  bool CanIncludeItem(bool isDir) const
317  {
318    return isDir ? !ExcludeDirItems : !ExcludeFileItems;
319  }
320
321
322  CDirItemsStat Stat;
323
324  #if !defined(UNDER_CE)
325  HRESULT SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi,
326      const FString &phyPrefix);
327  #endif
328
329 #if defined(_WIN32) && !defined(UNDER_CE)
330
331  CUniqBlocks SecureBlocks;
332  CByteBuffer TempSecureBuf;
333  bool _saclEnabled;
334  bool ReadSecure;
335
336  HRESULT AddSecurityItem(const FString &path, int &secureIndex);
337  HRESULT FillFixedReparse();
338
339 #endif
340
341 #ifndef _WIN32
342
343  C_UInt32_UString_Map OwnerNameMap;
344  C_UInt32_UString_Map OwnerGroupMap;
345  bool StoreOwnerName;
346
347  HRESULT FillDeviceSizes();
348
349 #endif
350
351  IDirItemsCallback *Callback;
352
353  CDirItems();
354
355  void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
356      const NWindows::NFile::NFind::CFileInfo &fi);
357
358  HRESULT AddError(const FString &path, DWORD errorCode);
359  HRESULT AddError(const FString &path);
360
361  HRESULT ScanProgress(const FString &path);
362
363  // unsigned GetNumFolders() const { return Prefixes.Size(); }
364  FString GetPhyPath(unsigned index) const;
365  UString GetLogPath(unsigned index) const;
366
367  unsigned AddPrefix(int phyParent, int logParent, const UString &prefix);
368  void DeleteLastPrefix();
369
370  // HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CDirEntry> &files);
371  HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CFileInfo> &files);
372
373  HRESULT EnumerateItems2(
374    const FString &phyPrefix,
375    const UString &logPrefix,
376    const FStringVector &filePaths,
377    FStringVector *requestedPaths);
378
379  void ReserveDown();
380};
381
382
383
384
385struct CArcItem
386{
387  UInt64 Size;
388  UString Name;
389  CArcTime MTime;  // it can be mtime of archive file, if MTime is not defined for item in archive
390  bool IsDir;
391  bool IsAltStream;
392  bool Size_Defined;
393  bool Censored;
394  UInt32 IndexInServer;
395
396  CArcItem():
397      IsDir(false),
398      IsAltStream(false),
399      Size_Defined(false),
400      Censored(false)
401    {}
402};
403
404#endif
405