xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // EnumDirItems.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include <wchar.h>
6*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
7*f6dc9357SAndroid Build Coastguard Worker 
8*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
9*f6dc9357SAndroid Build Coastguard Worker #include <grp.h>
10*f6dc9357SAndroid Build Coastguard Worker #include <pwd.h>
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/UTFConvert.h"
12*f6dc9357SAndroid Build Coastguard Worker #endif
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
15*f6dc9357SAndroid Build Coastguard Worker 
16*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
17*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileIO.h"
18*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
21*f6dc9357SAndroid Build Coastguard Worker #define Z7_USE_SECURITY_CODE
22*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/SecurityUtils.h"
23*f6dc9357SAndroid Build Coastguard Worker #endif
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #include "EnumDirItems.h"
26*f6dc9357SAndroid Build Coastguard Worker #include "SortUtils.h"
27*f6dc9357SAndroid Build Coastguard Worker 
28*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
29*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
30*f6dc9357SAndroid Build Coastguard Worker using namespace NName;
31*f6dc9357SAndroid Build Coastguard Worker 
32*f6dc9357SAndroid Build Coastguard Worker 
FindFile_KeepDots(NFile::NFind::CFileInfo & fi,const FString & path,bool followLink)33*f6dc9357SAndroid Build Coastguard Worker static bool FindFile_KeepDots(NFile::NFind::CFileInfo &fi, const FString &path, bool followLink)
34*f6dc9357SAndroid Build Coastguard Worker {
35*f6dc9357SAndroid Build Coastguard Worker   const bool res = fi.Find(path, followLink);
36*f6dc9357SAndroid Build Coastguard Worker   if (!res)
37*f6dc9357SAndroid Build Coastguard Worker     return res;
38*f6dc9357SAndroid Build Coastguard Worker   if (path.IsEmpty())
39*f6dc9357SAndroid Build Coastguard Worker     return res;
40*f6dc9357SAndroid Build Coastguard Worker   // we keep name "." and "..", if it's without tail slash
41*f6dc9357SAndroid Build Coastguard Worker   const FChar *p = path.RightPtr(1);
42*f6dc9357SAndroid Build Coastguard Worker   if (*p != '.')
43*f6dc9357SAndroid Build Coastguard Worker     return res;
44*f6dc9357SAndroid Build Coastguard Worker   if (p != path.Ptr())
45*f6dc9357SAndroid Build Coastguard Worker   {
46*f6dc9357SAndroid Build Coastguard Worker     FChar c = p[-1];
47*f6dc9357SAndroid Build Coastguard Worker     if (!IS_PATH_SEPAR(c))
48*f6dc9357SAndroid Build Coastguard Worker     {
49*f6dc9357SAndroid Build Coastguard Worker       if (c != '.')
50*f6dc9357SAndroid Build Coastguard Worker         return res;
51*f6dc9357SAndroid Build Coastguard Worker       p--;
52*f6dc9357SAndroid Build Coastguard Worker       if (p != path.Ptr())
53*f6dc9357SAndroid Build Coastguard Worker       {
54*f6dc9357SAndroid Build Coastguard Worker         c = p[-1];
55*f6dc9357SAndroid Build Coastguard Worker         if (!IS_PATH_SEPAR(c))
56*f6dc9357SAndroid Build Coastguard Worker           return res;
57*f6dc9357SAndroid Build Coastguard Worker       }
58*f6dc9357SAndroid Build Coastguard Worker     }
59*f6dc9357SAndroid Build Coastguard Worker   }
60*f6dc9357SAndroid Build Coastguard Worker   fi.Name = p;
61*f6dc9357SAndroid Build Coastguard Worker   return res;
62*f6dc9357SAndroid Build Coastguard Worker }
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker 
AddDirFileInfo(int phyParent,int logParent,int secureIndex,const NFind::CFileInfo & fi)65*f6dc9357SAndroid Build Coastguard Worker void CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex,
66*f6dc9357SAndroid Build Coastguard Worker     const NFind::CFileInfo &fi)
67*f6dc9357SAndroid Build Coastguard Worker {
68*f6dc9357SAndroid Build Coastguard Worker   /*
69*f6dc9357SAndroid Build Coastguard Worker   CDirItem di(fi);
70*f6dc9357SAndroid Build Coastguard Worker   di.PhyParent = phyParent;
71*f6dc9357SAndroid Build Coastguard Worker   di.LogParent = logParent;
72*f6dc9357SAndroid Build Coastguard Worker   di.SecureIndex = secureIndex;
73*f6dc9357SAndroid Build Coastguard Worker   Items.Add(di);
74*f6dc9357SAndroid Build Coastguard Worker   */
75*f6dc9357SAndroid Build Coastguard Worker   VECTOR_ADD_NEW_OBJECT (Items, CDirItem(fi, phyParent, logParent, secureIndex))
76*f6dc9357SAndroid Build Coastguard Worker 
77*f6dc9357SAndroid Build Coastguard Worker   if (fi.IsDir())
78*f6dc9357SAndroid Build Coastguard Worker     Stat.NumDirs++;
79*f6dc9357SAndroid Build Coastguard Worker  #ifdef _WIN32
80*f6dc9357SAndroid Build Coastguard Worker   else if (fi.IsAltStream)
81*f6dc9357SAndroid Build Coastguard Worker   {
82*f6dc9357SAndroid Build Coastguard Worker     Stat.NumAltStreams++;
83*f6dc9357SAndroid Build Coastguard Worker     Stat.AltStreamsSize += fi.Size;
84*f6dc9357SAndroid Build Coastguard Worker   }
85*f6dc9357SAndroid Build Coastguard Worker  #endif
86*f6dc9357SAndroid Build Coastguard Worker   else
87*f6dc9357SAndroid Build Coastguard Worker   {
88*f6dc9357SAndroid Build Coastguard Worker     Stat.NumFiles++;
89*f6dc9357SAndroid Build Coastguard Worker     Stat.FilesSize += fi.Size;
90*f6dc9357SAndroid Build Coastguard Worker   }
91*f6dc9357SAndroid Build Coastguard Worker }
92*f6dc9357SAndroid Build Coastguard Worker 
93*f6dc9357SAndroid Build Coastguard Worker // (DWORD)E_FAIL
94*f6dc9357SAndroid Build Coastguard Worker #define DI_DEFAULT_ERROR  ERROR_INVALID_FUNCTION
95*f6dc9357SAndroid Build Coastguard Worker 
AddError(const FString & path,DWORD errorCode)96*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::AddError(const FString &path, DWORD errorCode)
97*f6dc9357SAndroid Build Coastguard Worker {
98*f6dc9357SAndroid Build Coastguard Worker   if (errorCode == 0)
99*f6dc9357SAndroid Build Coastguard Worker     errorCode = DI_DEFAULT_ERROR;
100*f6dc9357SAndroid Build Coastguard Worker   Stat.NumErrors++;
101*f6dc9357SAndroid Build Coastguard Worker   if (Callback)
102*f6dc9357SAndroid Build Coastguard Worker     return Callback->ScanError(path, errorCode);
103*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
104*f6dc9357SAndroid Build Coastguard Worker }
105*f6dc9357SAndroid Build Coastguard Worker 
AddError(const FString & path)106*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::AddError(const FString &path)
107*f6dc9357SAndroid Build Coastguard Worker {
108*f6dc9357SAndroid Build Coastguard Worker   return AddError(path, ::GetLastError());
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker static const unsigned kScanProgressStepMask = (1 << 12) - 1;
112*f6dc9357SAndroid Build Coastguard Worker 
ScanProgress(const FString & dirPath)113*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::ScanProgress(const FString &dirPath)
114*f6dc9357SAndroid Build Coastguard Worker {
115*f6dc9357SAndroid Build Coastguard Worker   if (Callback)
116*f6dc9357SAndroid Build Coastguard Worker     return Callback->ScanProgress(Stat, dirPath, true);
117*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
118*f6dc9357SAndroid Build Coastguard Worker }
119*f6dc9357SAndroid Build Coastguard Worker 
GetPrefixesPath(const CIntVector & parents,int index,const UString & name) const120*f6dc9357SAndroid Build Coastguard Worker UString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const
121*f6dc9357SAndroid Build Coastguard Worker {
122*f6dc9357SAndroid Build Coastguard Worker   UString path;
123*f6dc9357SAndroid Build Coastguard Worker   unsigned len = name.Len();
124*f6dc9357SAndroid Build Coastguard Worker 
125*f6dc9357SAndroid Build Coastguard Worker   int i;
126*f6dc9357SAndroid Build Coastguard Worker   for (i = index; i >= 0; i = parents[(unsigned)i])
127*f6dc9357SAndroid Build Coastguard Worker     len += Prefixes[(unsigned)i].Len();
128*f6dc9357SAndroid Build Coastguard Worker 
129*f6dc9357SAndroid Build Coastguard Worker   wchar_t *p = path.GetBuf_SetEnd(len) + len;
130*f6dc9357SAndroid Build Coastguard Worker 
131*f6dc9357SAndroid Build Coastguard Worker   p -= name.Len();
132*f6dc9357SAndroid Build Coastguard Worker   wmemcpy(p, (const wchar_t *)name, name.Len());
133*f6dc9357SAndroid Build Coastguard Worker 
134*f6dc9357SAndroid Build Coastguard Worker   for (i = index; i >= 0; i = parents[(unsigned)i])
135*f6dc9357SAndroid Build Coastguard Worker   {
136*f6dc9357SAndroid Build Coastguard Worker     const UString &s = Prefixes[(unsigned)i];
137*f6dc9357SAndroid Build Coastguard Worker     p -= s.Len();
138*f6dc9357SAndroid Build Coastguard Worker     wmemcpy(p, (const wchar_t *)s, s.Len());
139*f6dc9357SAndroid Build Coastguard Worker   }
140*f6dc9357SAndroid Build Coastguard Worker 
141*f6dc9357SAndroid Build Coastguard Worker   return path;
142*f6dc9357SAndroid Build Coastguard Worker }
143*f6dc9357SAndroid Build Coastguard Worker 
GetPhyPath(unsigned index) const144*f6dc9357SAndroid Build Coastguard Worker FString CDirItems::GetPhyPath(unsigned index) const
145*f6dc9357SAndroid Build Coastguard Worker {
146*f6dc9357SAndroid Build Coastguard Worker   const CDirItem &di = Items[index];
147*f6dc9357SAndroid Build Coastguard Worker   return us2fs(GetPrefixesPath(PhyParents, di.PhyParent, di.Name));
148*f6dc9357SAndroid Build Coastguard Worker }
149*f6dc9357SAndroid Build Coastguard Worker 
GetLogPath(unsigned index) const150*f6dc9357SAndroid Build Coastguard Worker UString CDirItems::GetLogPath(unsigned index) const
151*f6dc9357SAndroid Build Coastguard Worker {
152*f6dc9357SAndroid Build Coastguard Worker   const CDirItem &di = Items[index];
153*f6dc9357SAndroid Build Coastguard Worker   return GetPrefixesPath(LogParents, di.LogParent, di.Name);
154*f6dc9357SAndroid Build Coastguard Worker }
155*f6dc9357SAndroid Build Coastguard Worker 
ReserveDown()156*f6dc9357SAndroid Build Coastguard Worker void CDirItems::ReserveDown()
157*f6dc9357SAndroid Build Coastguard Worker {
158*f6dc9357SAndroid Build Coastguard Worker   Prefixes.ReserveDown();
159*f6dc9357SAndroid Build Coastguard Worker   PhyParents.ReserveDown();
160*f6dc9357SAndroid Build Coastguard Worker   LogParents.ReserveDown();
161*f6dc9357SAndroid Build Coastguard Worker   Items.ReserveDown();
162*f6dc9357SAndroid Build Coastguard Worker }
163*f6dc9357SAndroid Build Coastguard Worker 
AddPrefix(int phyParent,int logParent,const UString & prefix)164*f6dc9357SAndroid Build Coastguard Worker unsigned CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix)
165*f6dc9357SAndroid Build Coastguard Worker {
166*f6dc9357SAndroid Build Coastguard Worker   PhyParents.Add(phyParent);
167*f6dc9357SAndroid Build Coastguard Worker   LogParents.Add(logParent);
168*f6dc9357SAndroid Build Coastguard Worker   return Prefixes.Add(prefix);
169*f6dc9357SAndroid Build Coastguard Worker }
170*f6dc9357SAndroid Build Coastguard Worker 
DeleteLastPrefix()171*f6dc9357SAndroid Build Coastguard Worker void CDirItems::DeleteLastPrefix()
172*f6dc9357SAndroid Build Coastguard Worker {
173*f6dc9357SAndroid Build Coastguard Worker   PhyParents.DeleteBack();
174*f6dc9357SAndroid Build Coastguard Worker   LogParents.DeleteBack();
175*f6dc9357SAndroid Build Coastguard Worker   Prefixes.DeleteBack();
176*f6dc9357SAndroid Build Coastguard Worker }
177*f6dc9357SAndroid Build Coastguard Worker 
178*f6dc9357SAndroid Build Coastguard Worker bool InitLocalPrivileges();
179*f6dc9357SAndroid Build Coastguard Worker 
CDirItems()180*f6dc9357SAndroid Build Coastguard Worker CDirItems::CDirItems():
181*f6dc9357SAndroid Build Coastguard Worker     SymLinks(false),
182*f6dc9357SAndroid Build Coastguard Worker     ScanAltStreams(false)
183*f6dc9357SAndroid Build Coastguard Worker     , ExcludeDirItems(false)
184*f6dc9357SAndroid Build Coastguard Worker     , ExcludeFileItems(false)
185*f6dc9357SAndroid Build Coastguard Worker     , ShareForWrite(false)
186*f6dc9357SAndroid Build Coastguard Worker    #ifdef Z7_USE_SECURITY_CODE
187*f6dc9357SAndroid Build Coastguard Worker     , ReadSecure(false)
188*f6dc9357SAndroid Build Coastguard Worker    #endif
189*f6dc9357SAndroid Build Coastguard Worker    #ifndef _WIN32
190*f6dc9357SAndroid Build Coastguard Worker     , StoreOwnerName(false)
191*f6dc9357SAndroid Build Coastguard Worker    #endif
192*f6dc9357SAndroid Build Coastguard Worker     , Callback(NULL)
193*f6dc9357SAndroid Build Coastguard Worker {
194*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_USE_SECURITY_CODE
195*f6dc9357SAndroid Build Coastguard Worker   _saclEnabled = InitLocalPrivileges();
196*f6dc9357SAndroid Build Coastguard Worker   #endif
197*f6dc9357SAndroid Build Coastguard Worker }
198*f6dc9357SAndroid Build Coastguard Worker 
199*f6dc9357SAndroid Build Coastguard Worker 
200*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_SECURITY_CODE
201*f6dc9357SAndroid Build Coastguard Worker 
AddSecurityItem(const FString & path,int & secureIndex)202*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex)
203*f6dc9357SAndroid Build Coastguard Worker {
204*f6dc9357SAndroid Build Coastguard Worker   secureIndex = -1;
205*f6dc9357SAndroid Build Coastguard Worker 
206*f6dc9357SAndroid Build Coastguard Worker   SECURITY_INFORMATION securInfo =
207*f6dc9357SAndroid Build Coastguard Worker       DACL_SECURITY_INFORMATION |
208*f6dc9357SAndroid Build Coastguard Worker       GROUP_SECURITY_INFORMATION |
209*f6dc9357SAndroid Build Coastguard Worker       OWNER_SECURITY_INFORMATION;
210*f6dc9357SAndroid Build Coastguard Worker   if (_saclEnabled)
211*f6dc9357SAndroid Build Coastguard Worker     securInfo |= SACL_SECURITY_INFORMATION;
212*f6dc9357SAndroid Build Coastguard Worker 
213*f6dc9357SAndroid Build Coastguard Worker   DWORD errorCode = 0;
214*f6dc9357SAndroid Build Coastguard Worker   DWORD secureSize;
215*f6dc9357SAndroid Build Coastguard Worker 
216*f6dc9357SAndroid Build Coastguard Worker   BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
217*f6dc9357SAndroid Build Coastguard Worker 
218*f6dc9357SAndroid Build Coastguard Worker   if (res)
219*f6dc9357SAndroid Build Coastguard Worker   {
220*f6dc9357SAndroid Build Coastguard Worker     if (secureSize == 0)
221*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
222*f6dc9357SAndroid Build Coastguard Worker     if (secureSize > TempSecureBuf.Size())
223*f6dc9357SAndroid Build Coastguard Worker       errorCode = ERROR_INVALID_FUNCTION;
224*f6dc9357SAndroid Build Coastguard Worker   }
225*f6dc9357SAndroid Build Coastguard Worker   else
226*f6dc9357SAndroid Build Coastguard Worker   {
227*f6dc9357SAndroid Build Coastguard Worker     errorCode = GetLastError();
228*f6dc9357SAndroid Build Coastguard Worker     if (errorCode == ERROR_INSUFFICIENT_BUFFER)
229*f6dc9357SAndroid Build Coastguard Worker     {
230*f6dc9357SAndroid Build Coastguard Worker       if (secureSize <= TempSecureBuf.Size())
231*f6dc9357SAndroid Build Coastguard Worker         errorCode = ERROR_INVALID_FUNCTION;
232*f6dc9357SAndroid Build Coastguard Worker       else
233*f6dc9357SAndroid Build Coastguard Worker       {
234*f6dc9357SAndroid Build Coastguard Worker         TempSecureBuf.Alloc(secureSize);
235*f6dc9357SAndroid Build Coastguard Worker         res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
236*f6dc9357SAndroid Build Coastguard Worker         if (res)
237*f6dc9357SAndroid Build Coastguard Worker         {
238*f6dc9357SAndroid Build Coastguard Worker           if (secureSize != TempSecureBuf.Size())
239*f6dc9357SAndroid Build Coastguard Worker             errorCode = ERROR_INVALID_FUNCTION;
240*f6dc9357SAndroid Build Coastguard Worker         }
241*f6dc9357SAndroid Build Coastguard Worker         else
242*f6dc9357SAndroid Build Coastguard Worker           errorCode = GetLastError();
243*f6dc9357SAndroid Build Coastguard Worker       }
244*f6dc9357SAndroid Build Coastguard Worker     }
245*f6dc9357SAndroid Build Coastguard Worker   }
246*f6dc9357SAndroid Build Coastguard Worker 
247*f6dc9357SAndroid Build Coastguard Worker   if (res)
248*f6dc9357SAndroid Build Coastguard Worker   {
249*f6dc9357SAndroid Build Coastguard Worker     secureIndex = (int)SecureBlocks.AddUniq(TempSecureBuf, secureSize);
250*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
251*f6dc9357SAndroid Build Coastguard Worker   }
252*f6dc9357SAndroid Build Coastguard Worker 
253*f6dc9357SAndroid Build Coastguard Worker   return AddError(path, errorCode);
254*f6dc9357SAndroid Build Coastguard Worker }
255*f6dc9357SAndroid Build Coastguard Worker 
256*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_USE_SECURITY_CODE
257*f6dc9357SAndroid Build Coastguard Worker 
258*f6dc9357SAndroid Build Coastguard Worker 
EnumerateOneDir(const FString & phyPrefix,CObjectVector<NFind::CFileInfo> & files)259*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::EnumerateOneDir(const FString &phyPrefix, CObjectVector<NFind::CFileInfo> &files)
260*f6dc9357SAndroid Build Coastguard Worker {
261*f6dc9357SAndroid Build Coastguard Worker   NFind::CEnumerator enumerator;
262*f6dc9357SAndroid Build Coastguard Worker   // printf("\n  enumerator.SetDirPrefix(phyPrefix) \n");
263*f6dc9357SAndroid Build Coastguard Worker 
264*f6dc9357SAndroid Build Coastguard Worker   enumerator.SetDirPrefix(phyPrefix);
265*f6dc9357SAndroid Build Coastguard Worker 
266*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
267*f6dc9357SAndroid Build Coastguard Worker 
268*f6dc9357SAndroid Build Coastguard Worker   NFind::CFileInfo fi;
269*f6dc9357SAndroid Build Coastguard Worker 
270*f6dc9357SAndroid Build Coastguard Worker   for (unsigned ttt = 0; ; ttt++)
271*f6dc9357SAndroid Build Coastguard Worker   {
272*f6dc9357SAndroid Build Coastguard Worker     bool found;
273*f6dc9357SAndroid Build Coastguard Worker     if (!enumerator.Next(fi, found))
274*f6dc9357SAndroid Build Coastguard Worker       return AddError(phyPrefix);
275*f6dc9357SAndroid Build Coastguard Worker     if (!found)
276*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
277*f6dc9357SAndroid Build Coastguard Worker     files.Add(fi);
278*f6dc9357SAndroid Build Coastguard Worker     if (Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask)
279*f6dc9357SAndroid Build Coastguard Worker     {
280*f6dc9357SAndroid Build Coastguard Worker       RINOK(ScanProgress(phyPrefix))
281*f6dc9357SAndroid Build Coastguard Worker     }
282*f6dc9357SAndroid Build Coastguard Worker   }
283*f6dc9357SAndroid Build Coastguard Worker 
284*f6dc9357SAndroid Build Coastguard Worker   #else // _WIN32
285*f6dc9357SAndroid Build Coastguard Worker 
286*f6dc9357SAndroid Build Coastguard Worker   // enumerator.SolveLinks = !SymLinks;
287*f6dc9357SAndroid Build Coastguard Worker 
288*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<NFind::CDirEntry> entries;
289*f6dc9357SAndroid Build Coastguard Worker 
290*f6dc9357SAndroid Build Coastguard Worker   for (;;)
291*f6dc9357SAndroid Build Coastguard Worker   {
292*f6dc9357SAndroid Build Coastguard Worker     bool found;
293*f6dc9357SAndroid Build Coastguard Worker     NFind::CDirEntry de;
294*f6dc9357SAndroid Build Coastguard Worker     if (!enumerator.Next(de, found))
295*f6dc9357SAndroid Build Coastguard Worker       return AddError(phyPrefix);
296*f6dc9357SAndroid Build Coastguard Worker     if (!found)
297*f6dc9357SAndroid Build Coastguard Worker       break;
298*f6dc9357SAndroid Build Coastguard Worker     entries.Add(de);
299*f6dc9357SAndroid Build Coastguard Worker   }
300*f6dc9357SAndroid Build Coastguard Worker 
301*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR(i, entries)
302*f6dc9357SAndroid Build Coastguard Worker   {
303*f6dc9357SAndroid Build Coastguard Worker     const NFind::CDirEntry &de = entries[i];
304*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo fi;
305*f6dc9357SAndroid Build Coastguard Worker     if (!enumerator.Fill_FileInfo(de, fi, !SymLinks))
306*f6dc9357SAndroid Build Coastguard Worker     // if (!fi.Find_AfterEnumerator(path))
307*f6dc9357SAndroid Build Coastguard Worker     {
308*f6dc9357SAndroid Build Coastguard Worker       const FString path = phyPrefix + de.Name;
309*f6dc9357SAndroid Build Coastguard Worker       {
310*f6dc9357SAndroid Build Coastguard Worker         RINOK(AddError(path))
311*f6dc9357SAndroid Build Coastguard Worker         continue;
312*f6dc9357SAndroid Build Coastguard Worker       }
313*f6dc9357SAndroid Build Coastguard Worker     }
314*f6dc9357SAndroid Build Coastguard Worker 
315*f6dc9357SAndroid Build Coastguard Worker     files.Add(fi);
316*f6dc9357SAndroid Build Coastguard Worker 
317*f6dc9357SAndroid Build Coastguard Worker     if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask)
318*f6dc9357SAndroid Build Coastguard Worker     {
319*f6dc9357SAndroid Build Coastguard Worker       RINOK(ScanProgress(phyPrefix))
320*f6dc9357SAndroid Build Coastguard Worker     }
321*f6dc9357SAndroid Build Coastguard Worker   }
322*f6dc9357SAndroid Build Coastguard Worker 
323*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
324*f6dc9357SAndroid Build Coastguard Worker 
325*f6dc9357SAndroid Build Coastguard Worker   #endif // _WIN32
326*f6dc9357SAndroid Build Coastguard Worker }
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker 
329*f6dc9357SAndroid Build Coastguard Worker 
330*f6dc9357SAndroid Build Coastguard Worker 
EnumerateDir(int phyParent,int logParent,const FString & phyPrefix)331*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix)
332*f6dc9357SAndroid Build Coastguard Worker {
333*f6dc9357SAndroid Build Coastguard Worker   RINOK(ScanProgress(phyPrefix))
334*f6dc9357SAndroid Build Coastguard Worker 
335*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<NFind::CFileInfo> files;
336*f6dc9357SAndroid Build Coastguard Worker   RINOK(EnumerateOneDir(phyPrefix, files))
337*f6dc9357SAndroid Build Coastguard Worker 
338*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, files)
339*f6dc9357SAndroid Build Coastguard Worker   {
340*f6dc9357SAndroid Build Coastguard Worker     #ifdef _WIN32
341*f6dc9357SAndroid Build Coastguard Worker     const NFind::CFileInfo &fi = files[i];
342*f6dc9357SAndroid Build Coastguard Worker     #else
343*f6dc9357SAndroid Build Coastguard Worker     const NFind::CFileInfo &fi = files[i];
344*f6dc9357SAndroid Build Coastguard Worker     /*
345*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo fi;
346*f6dc9357SAndroid Build Coastguard Worker     {
347*f6dc9357SAndroid Build Coastguard Worker       const NFind::CDirEntry &di = files[i];
348*f6dc9357SAndroid Build Coastguard Worker       const FString path = phyPrefix + di.Name;
349*f6dc9357SAndroid Build Coastguard Worker       if (!fi.Find_AfterEnumerator(path))
350*f6dc9357SAndroid Build Coastguard Worker       {
351*f6dc9357SAndroid Build Coastguard Worker         RINOK(AddError(path));
352*f6dc9357SAndroid Build Coastguard Worker         continue;
353*f6dc9357SAndroid Build Coastguard Worker       }
354*f6dc9357SAndroid Build Coastguard Worker       fi.Name = di.Name;
355*f6dc9357SAndroid Build Coastguard Worker     }
356*f6dc9357SAndroid Build Coastguard Worker     */
357*f6dc9357SAndroid Build Coastguard Worker     #endif
358*f6dc9357SAndroid Build Coastguard Worker 
359*f6dc9357SAndroid Build Coastguard Worker     if (CanIncludeItem(fi.IsDir()))
360*f6dc9357SAndroid Build Coastguard Worker     {
361*f6dc9357SAndroid Build Coastguard Worker     int secureIndex = -1;
362*f6dc9357SAndroid Build Coastguard Worker     #ifdef Z7_USE_SECURITY_CODE
363*f6dc9357SAndroid Build Coastguard Worker     if (ReadSecure)
364*f6dc9357SAndroid Build Coastguard Worker     {
365*f6dc9357SAndroid Build Coastguard Worker       RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex))
366*f6dc9357SAndroid Build Coastguard Worker     }
367*f6dc9357SAndroid Build Coastguard Worker     #endif
368*f6dc9357SAndroid Build Coastguard Worker     AddDirFileInfo(phyParent, logParent, secureIndex, fi);
369*f6dc9357SAndroid Build Coastguard Worker     }
370*f6dc9357SAndroid Build Coastguard Worker 
371*f6dc9357SAndroid Build Coastguard Worker     if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask)
372*f6dc9357SAndroid Build Coastguard Worker     {
373*f6dc9357SAndroid Build Coastguard Worker       RINOK(ScanProgress(phyPrefix))
374*f6dc9357SAndroid Build Coastguard Worker     }
375*f6dc9357SAndroid Build Coastguard Worker 
376*f6dc9357SAndroid Build Coastguard Worker     if (fi.IsDir())
377*f6dc9357SAndroid Build Coastguard Worker     {
378*f6dc9357SAndroid Build Coastguard Worker       const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
379*f6dc9357SAndroid Build Coastguard Worker       unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2));
380*f6dc9357SAndroid Build Coastguard Worker       RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + name2))
381*f6dc9357SAndroid Build Coastguard Worker     }
382*f6dc9357SAndroid Build Coastguard Worker   }
383*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
384*f6dc9357SAndroid Build Coastguard Worker }
385*f6dc9357SAndroid Build Coastguard Worker 
386*f6dc9357SAndroid Build Coastguard Worker 
387*f6dc9357SAndroid Build Coastguard Worker /*
388*f6dc9357SAndroid Build Coastguard Worker EnumerateItems2()
389*f6dc9357SAndroid Build Coastguard Worker   const FStringVector &filePaths - are path without tail slashes.
390*f6dc9357SAndroid Build Coastguard Worker   All dir prefixes of filePaths will be not stores in logical paths
391*f6dc9357SAndroid Build Coastguard Worker fix it: we can scan AltStream also.
392*f6dc9357SAndroid Build Coastguard Worker */
393*f6dc9357SAndroid Build Coastguard Worker 
394*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
395*f6dc9357SAndroid Build Coastguard Worker // #define FOLLOW_LINK_PARAM
396*f6dc9357SAndroid Build Coastguard Worker // #define FOLLOW_LINK_PARAM2
397*f6dc9357SAndroid Build Coastguard Worker #define FOLLOW_LINK_PARAM , (!SymLinks)
398*f6dc9357SAndroid Build Coastguard Worker #define FOLLOW_LINK_PARAM2 , (!dirItems.SymLinks)
399*f6dc9357SAndroid Build Coastguard Worker #else
400*f6dc9357SAndroid Build Coastguard Worker #define FOLLOW_LINK_PARAM , (!SymLinks)
401*f6dc9357SAndroid Build Coastguard Worker #define FOLLOW_LINK_PARAM2 , (!dirItems.SymLinks)
402*f6dc9357SAndroid Build Coastguard Worker #endif
403*f6dc9357SAndroid Build Coastguard Worker 
EnumerateItems2(const FString & phyPrefix,const UString & logPrefix,const FStringVector & filePaths,FStringVector * requestedPaths)404*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::EnumerateItems2(
405*f6dc9357SAndroid Build Coastguard Worker     const FString &phyPrefix,
406*f6dc9357SAndroid Build Coastguard Worker     const UString &logPrefix,
407*f6dc9357SAndroid Build Coastguard Worker     const FStringVector &filePaths,
408*f6dc9357SAndroid Build Coastguard Worker     FStringVector *requestedPaths)
409*f6dc9357SAndroid Build Coastguard Worker {
410*f6dc9357SAndroid Build Coastguard Worker   const int phyParent = phyPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, fs2us(phyPrefix));
411*f6dc9357SAndroid Build Coastguard Worker   const int logParent = logPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, logPrefix);
412*f6dc9357SAndroid Build Coastguard Worker 
413*f6dc9357SAndroid Build Coastguard Worker  #ifdef _WIN32
414*f6dc9357SAndroid Build Coastguard Worker   const bool phyPrefix_isAltStreamPrefix =
415*f6dc9357SAndroid Build Coastguard Worker       NFile::NName::IsAltStreamPrefixWithColon(fs2us(phyPrefix));
416*f6dc9357SAndroid Build Coastguard Worker  #endif
417*f6dc9357SAndroid Build Coastguard Worker 
418*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, filePaths)
419*f6dc9357SAndroid Build Coastguard Worker   {
420*f6dc9357SAndroid Build Coastguard Worker     const FString &filePath = filePaths[i];
421*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo fi;
422*f6dc9357SAndroid Build Coastguard Worker     const FString phyPath = phyPrefix + filePath;
423*f6dc9357SAndroid Build Coastguard Worker     if (!FindFile_KeepDots(fi, phyPath  FOLLOW_LINK_PARAM))
424*f6dc9357SAndroid Build Coastguard Worker     {
425*f6dc9357SAndroid Build Coastguard Worker       RINOK(AddError(phyPath))
426*f6dc9357SAndroid Build Coastguard Worker       continue;
427*f6dc9357SAndroid Build Coastguard Worker     }
428*f6dc9357SAndroid Build Coastguard Worker     if (requestedPaths)
429*f6dc9357SAndroid Build Coastguard Worker       requestedPaths->Add(phyPath);
430*f6dc9357SAndroid Build Coastguard Worker 
431*f6dc9357SAndroid Build Coastguard Worker     const int delimiter = filePath.ReverseFind_PathSepar();
432*f6dc9357SAndroid Build Coastguard Worker     FString phyPrefixCur;
433*f6dc9357SAndroid Build Coastguard Worker     int phyParentCur = phyParent;
434*f6dc9357SAndroid Build Coastguard Worker     if (delimiter >= 0)
435*f6dc9357SAndroid Build Coastguard Worker     {
436*f6dc9357SAndroid Build Coastguard Worker       phyPrefixCur.SetFrom(filePath, (unsigned)(delimiter + 1));
437*f6dc9357SAndroid Build Coastguard Worker       phyParentCur = (int)AddPrefix(phyParent, logParent, fs2us(phyPrefixCur));
438*f6dc9357SAndroid Build Coastguard Worker     }
439*f6dc9357SAndroid Build Coastguard Worker 
440*f6dc9357SAndroid Build Coastguard Worker     if (CanIncludeItem(fi.IsDir()))
441*f6dc9357SAndroid Build Coastguard Worker     {
442*f6dc9357SAndroid Build Coastguard Worker     int secureIndex = -1;
443*f6dc9357SAndroid Build Coastguard Worker     #ifdef Z7_USE_SECURITY_CODE
444*f6dc9357SAndroid Build Coastguard Worker     if (ReadSecure)
445*f6dc9357SAndroid Build Coastguard Worker     {
446*f6dc9357SAndroid Build Coastguard Worker       RINOK(AddSecurityItem(phyPath, secureIndex))
447*f6dc9357SAndroid Build Coastguard Worker     }
448*f6dc9357SAndroid Build Coastguard Worker     #endif
449*f6dc9357SAndroid Build Coastguard Worker    #ifdef _WIN32
450*f6dc9357SAndroid Build Coastguard Worker     if (phyPrefix_isAltStreamPrefix && fi.IsAltStream)
451*f6dc9357SAndroid Build Coastguard Worker     {
452*f6dc9357SAndroid Build Coastguard Worker       const int pos = fi.Name.Find(FChar(':'));
453*f6dc9357SAndroid Build Coastguard Worker       if (pos >= 0)
454*f6dc9357SAndroid Build Coastguard Worker         fi.Name.DeleteFrontal((unsigned)pos + 1);
455*f6dc9357SAndroid Build Coastguard Worker     }
456*f6dc9357SAndroid Build Coastguard Worker    #endif
457*f6dc9357SAndroid Build Coastguard Worker     AddDirFileInfo(phyParentCur, logParent, secureIndex, fi);
458*f6dc9357SAndroid Build Coastguard Worker     }
459*f6dc9357SAndroid Build Coastguard Worker 
460*f6dc9357SAndroid Build Coastguard Worker     if (fi.IsDir())
461*f6dc9357SAndroid Build Coastguard Worker     {
462*f6dc9357SAndroid Build Coastguard Worker       const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
463*f6dc9357SAndroid Build Coastguard Worker       const unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2));
464*f6dc9357SAndroid Build Coastguard Worker       RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + phyPrefixCur + name2))
465*f6dc9357SAndroid Build Coastguard Worker     }
466*f6dc9357SAndroid Build Coastguard Worker   }
467*f6dc9357SAndroid Build Coastguard Worker 
468*f6dc9357SAndroid Build Coastguard Worker   ReserveDown();
469*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
470*f6dc9357SAndroid Build Coastguard Worker }
471*f6dc9357SAndroid Build Coastguard Worker 
472*f6dc9357SAndroid Build Coastguard Worker 
473*f6dc9357SAndroid Build Coastguard Worker 
474*f6dc9357SAndroid Build Coastguard Worker 
475*f6dc9357SAndroid Build Coastguard Worker static HRESULT EnumerateDirItems(
476*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::CCensorNode &curNode,
477*f6dc9357SAndroid Build Coastguard Worker     const int phyParent, const int logParent,
478*f6dc9357SAndroid Build Coastguard Worker     const FString &phyPrefix,
479*f6dc9357SAndroid Build Coastguard Worker     const UStringVector &addParts, // additional parts from curNode
480*f6dc9357SAndroid Build Coastguard Worker     CDirItems &dirItems,
481*f6dc9357SAndroid Build Coastguard Worker     bool enterToSubFolders);
482*f6dc9357SAndroid Build Coastguard Worker 
483*f6dc9357SAndroid Build Coastguard Worker 
484*f6dc9357SAndroid Build Coastguard Worker /* EnumerateDirItems_Spec()
485*f6dc9357SAndroid Build Coastguard Worker    adds new Dir item prefix, and enumerates dir items,
486*f6dc9357SAndroid Build Coastguard Worker    then it can remove that Dir item prefix, if there are no items in that dir.
487*f6dc9357SAndroid Build Coastguard Worker */
488*f6dc9357SAndroid Build Coastguard Worker 
489*f6dc9357SAndroid Build Coastguard Worker 
490*f6dc9357SAndroid Build Coastguard Worker /*
491*f6dc9357SAndroid Build Coastguard Worker   EnumerateDirItems_Spec()
492*f6dc9357SAndroid Build Coastguard Worker   it's similar to EnumerateDirItems, but phyPrefix doesn't include (curFolderName)
493*f6dc9357SAndroid Build Coastguard Worker */
494*f6dc9357SAndroid Build Coastguard Worker 
EnumerateDirItems_Spec(const NWildcard::CCensorNode & curNode,const int phyParent,const int logParent,const FString & curFolderName,const FString & phyPrefix,const UStringVector & addParts,CDirItems & dirItems,bool enterToSubFolders)495*f6dc9357SAndroid Build Coastguard Worker static HRESULT EnumerateDirItems_Spec(
496*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::CCensorNode &curNode,
497*f6dc9357SAndroid Build Coastguard Worker     const int phyParent, const int logParent, const FString &curFolderName,
498*f6dc9357SAndroid Build Coastguard Worker     const FString &phyPrefix,      // without (curFolderName)
499*f6dc9357SAndroid Build Coastguard Worker     const UStringVector &addParts, // (curNode + addParts) includes (curFolderName)
500*f6dc9357SAndroid Build Coastguard Worker     CDirItems &dirItems,
501*f6dc9357SAndroid Build Coastguard Worker     bool enterToSubFolders)
502*f6dc9357SAndroid Build Coastguard Worker {
503*f6dc9357SAndroid Build Coastguard Worker   const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR;
504*f6dc9357SAndroid Build Coastguard Worker   const unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2));
505*f6dc9357SAndroid Build Coastguard Worker   const unsigned numItems = dirItems.Items.Size();
506*f6dc9357SAndroid Build Coastguard Worker   HRESULT res = EnumerateDirItems(
507*f6dc9357SAndroid Build Coastguard Worker       curNode, (int)parent, (int)parent, phyPrefix + name2,
508*f6dc9357SAndroid Build Coastguard Worker       addParts, dirItems, enterToSubFolders);
509*f6dc9357SAndroid Build Coastguard Worker   if (numItems == dirItems.Items.Size())
510*f6dc9357SAndroid Build Coastguard Worker     dirItems.DeleteLastPrefix();
511*f6dc9357SAndroid Build Coastguard Worker   return res;
512*f6dc9357SAndroid Build Coastguard Worker }
513*f6dc9357SAndroid Build Coastguard Worker 
514*f6dc9357SAndroid Build Coastguard Worker 
515*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
516*f6dc9357SAndroid Build Coastguard Worker 
517*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
518*f6dc9357SAndroid Build Coastguard Worker 
EnumerateAltStreams(const NFind::CFileInfo & fi,const NWildcard::CCensorNode & curNode,const int phyParent,const int logParent,const FString & phyPath,const UStringVector & addParts,bool addAllSubStreams,CDirItems & dirItems)519*f6dc9357SAndroid Build Coastguard Worker static HRESULT EnumerateAltStreams(
520*f6dc9357SAndroid Build Coastguard Worker     const NFind::CFileInfo &fi,
521*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::CCensorNode &curNode,
522*f6dc9357SAndroid Build Coastguard Worker     const int phyParent, const int logParent,
523*f6dc9357SAndroid Build Coastguard Worker     const FString &phyPath,         // with (fi.Name), without tail slash for folders
524*f6dc9357SAndroid Build Coastguard Worker     const UStringVector &addParts,  // with (fi.Name), prefix parts from curNode
525*f6dc9357SAndroid Build Coastguard Worker     bool addAllSubStreams,
526*f6dc9357SAndroid Build Coastguard Worker     CDirItems &dirItems)
527*f6dc9357SAndroid Build Coastguard Worker {
528*f6dc9357SAndroid Build Coastguard Worker   // we don't use (ExcludeFileItems) rules for AltStreams
529*f6dc9357SAndroid Build Coastguard Worker   // if (dirItems.ExcludeFileItems) return S_OK;
530*f6dc9357SAndroid Build Coastguard Worker 
531*f6dc9357SAndroid Build Coastguard Worker   NFind::CStreamEnumerator enumerator(phyPath);
532*f6dc9357SAndroid Build Coastguard Worker   for (;;)
533*f6dc9357SAndroid Build Coastguard Worker   {
534*f6dc9357SAndroid Build Coastguard Worker     NFind::CStreamInfo si;
535*f6dc9357SAndroid Build Coastguard Worker     bool found;
536*f6dc9357SAndroid Build Coastguard Worker     if (!enumerator.Next(si, found))
537*f6dc9357SAndroid Build Coastguard Worker     {
538*f6dc9357SAndroid Build Coastguard Worker       return dirItems.AddError(phyPath + FTEXT(":*")); // , (DWORD)E_FAIL
539*f6dc9357SAndroid Build Coastguard Worker     }
540*f6dc9357SAndroid Build Coastguard Worker     if (!found)
541*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
542*f6dc9357SAndroid Build Coastguard Worker     if (si.IsMainStream())
543*f6dc9357SAndroid Build Coastguard Worker       continue;
544*f6dc9357SAndroid Build Coastguard Worker     UStringVector parts = addParts;
545*f6dc9357SAndroid Build Coastguard Worker     const UString reducedName = si.GetReducedName();
546*f6dc9357SAndroid Build Coastguard Worker     parts.Back() += reducedName;
547*f6dc9357SAndroid Build Coastguard Worker     if (curNode.CheckPathToRoot(false, parts, true))
548*f6dc9357SAndroid Build Coastguard Worker       continue;
549*f6dc9357SAndroid Build Coastguard Worker     if (!addAllSubStreams)
550*f6dc9357SAndroid Build Coastguard Worker       if (!curNode.CheckPathToRoot(true, parts, true))
551*f6dc9357SAndroid Build Coastguard Worker         continue;
552*f6dc9357SAndroid Build Coastguard Worker 
553*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo fi2 = fi;
554*f6dc9357SAndroid Build Coastguard Worker     fi2.Name += us2fs(reducedName);
555*f6dc9357SAndroid Build Coastguard Worker     fi2.Size = si.Size;
556*f6dc9357SAndroid Build Coastguard Worker     fi2.Attrib &= ~(DWORD)(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
557*f6dc9357SAndroid Build Coastguard Worker     fi2.IsAltStream = true;
558*f6dc9357SAndroid Build Coastguard Worker     dirItems.AddDirFileInfo(phyParent, logParent, -1, fi2);
559*f6dc9357SAndroid Build Coastguard Worker   }
560*f6dc9357SAndroid Build Coastguard Worker }
561*f6dc9357SAndroid Build Coastguard Worker 
562*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
563*f6dc9357SAndroid Build Coastguard Worker 
564*f6dc9357SAndroid Build Coastguard Worker 
565*f6dc9357SAndroid Build Coastguard Worker /* We get Reparse data and parse it.
566*f6dc9357SAndroid Build Coastguard Worker    If there is Reparse error, we free dirItem.Reparse data.
567*f6dc9357SAndroid Build Coastguard Worker    Do we need to work with empty reparse data?
568*f6dc9357SAndroid Build Coastguard Worker */
569*f6dc9357SAndroid Build Coastguard Worker 
SetLinkInfo(CDirItem & dirItem,const NFind::CFileInfo & fi,const FString & phyPrefix)570*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi,
571*f6dc9357SAndroid Build Coastguard Worker     const FString &phyPrefix)
572*f6dc9357SAndroid Build Coastguard Worker {
573*f6dc9357SAndroid Build Coastguard Worker   if (!SymLinks)
574*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
575*f6dc9357SAndroid Build Coastguard Worker 
576*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
577*f6dc9357SAndroid Build Coastguard Worker     if (!fi.HasReparsePoint() || fi.IsAltStream)
578*f6dc9357SAndroid Build Coastguard Worker   #else // _WIN32
579*f6dc9357SAndroid Build Coastguard Worker     if (!fi.IsPosixLink())
580*f6dc9357SAndroid Build Coastguard Worker   #endif // _WIN32
581*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
582*f6dc9357SAndroid Build Coastguard Worker 
583*f6dc9357SAndroid Build Coastguard Worker   const FString path = phyPrefix + fi.Name;
584*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer &buf = dirItem.ReparseData;
585*f6dc9357SAndroid Build Coastguard Worker   if (NIO::GetReparseData(path, buf))
586*f6dc9357SAndroid Build Coastguard Worker   {
587*f6dc9357SAndroid Build Coastguard Worker     // if (dirItem.ReparseData.Size() != 0)
588*f6dc9357SAndroid Build Coastguard Worker     Stat.FilesSize -= fi.Size;
589*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
590*f6dc9357SAndroid Build Coastguard Worker   }
591*f6dc9357SAndroid Build Coastguard Worker 
592*f6dc9357SAndroid Build Coastguard Worker   DWORD res = ::GetLastError();
593*f6dc9357SAndroid Build Coastguard Worker   buf.Free();
594*f6dc9357SAndroid Build Coastguard Worker   return AddError(path, res);
595*f6dc9357SAndroid Build Coastguard Worker }
596*f6dc9357SAndroid Build Coastguard Worker 
597*f6dc9357SAndroid Build Coastguard Worker #endif // UNDER_CE
598*f6dc9357SAndroid Build Coastguard Worker 
599*f6dc9357SAndroid Build Coastguard Worker 
600*f6dc9357SAndroid Build Coastguard Worker 
EnumerateForItem(const NFind::CFileInfo & fi,const NWildcard::CCensorNode & curNode,const int phyParent,const int logParent,const FString & phyPrefix,const UStringVector & addParts,CDirItems & dirItems,bool enterToSubFolders)601*f6dc9357SAndroid Build Coastguard Worker static HRESULT EnumerateForItem(
602*f6dc9357SAndroid Build Coastguard Worker     const NFind::CFileInfo &fi,
603*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::CCensorNode &curNode,
604*f6dc9357SAndroid Build Coastguard Worker     const int phyParent, const int logParent, const FString &phyPrefix,
605*f6dc9357SAndroid Build Coastguard Worker     const UStringVector &addParts, // additional parts from curNode, without (fi.Name)
606*f6dc9357SAndroid Build Coastguard Worker     CDirItems &dirItems,
607*f6dc9357SAndroid Build Coastguard Worker     bool enterToSubFolders)
608*f6dc9357SAndroid Build Coastguard Worker {
609*f6dc9357SAndroid Build Coastguard Worker   const UString name = fs2us(fi.Name);
610*f6dc9357SAndroid Build Coastguard Worker   UStringVector newParts = addParts;
611*f6dc9357SAndroid Build Coastguard Worker   newParts.Add(name);
612*f6dc9357SAndroid Build Coastguard Worker 
613*f6dc9357SAndroid Build Coastguard Worker   // check the path in exclude rules
614*f6dc9357SAndroid Build Coastguard Worker   if (curNode.CheckPathToRoot(false, newParts, !fi.IsDir()))
615*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
616*f6dc9357SAndroid Build Coastguard Worker 
617*f6dc9357SAndroid Build Coastguard Worker   #if !defined(UNDER_CE)
618*f6dc9357SAndroid Build Coastguard Worker   int dirItemIndex = -1;
619*f6dc9357SAndroid Build Coastguard Worker   #if defined(_WIN32)
620*f6dc9357SAndroid Build Coastguard Worker   bool addAllSubStreams = false;
621*f6dc9357SAndroid Build Coastguard Worker   bool needAltStreams = true;
622*f6dc9357SAndroid Build Coastguard Worker   #endif // _WIN32
623*f6dc9357SAndroid Build Coastguard Worker   #endif // !defined(UNDER_CE)
624*f6dc9357SAndroid Build Coastguard Worker 
625*f6dc9357SAndroid Build Coastguard Worker   // check the path in inlcude rules
626*f6dc9357SAndroid Build Coastguard Worker   if (curNode.CheckPathToRoot(true, newParts, !fi.IsDir()))
627*f6dc9357SAndroid Build Coastguard Worker   {
628*f6dc9357SAndroid Build Coastguard Worker     #if !defined(UNDER_CE)
629*f6dc9357SAndroid Build Coastguard Worker     // dirItemIndex = (int)dirItems.Items.Size();
630*f6dc9357SAndroid Build Coastguard Worker     #if defined(_WIN32)
631*f6dc9357SAndroid Build Coastguard Worker     // we will not check include rules for substreams.
632*f6dc9357SAndroid Build Coastguard Worker     addAllSubStreams = true;
633*f6dc9357SAndroid Build Coastguard Worker     #endif // _WIN32
634*f6dc9357SAndroid Build Coastguard Worker     #endif // !defined(UNDER_CE)
635*f6dc9357SAndroid Build Coastguard Worker 
636*f6dc9357SAndroid Build Coastguard Worker     if (dirItems.CanIncludeItem(fi.IsDir()))
637*f6dc9357SAndroid Build Coastguard Worker     {
638*f6dc9357SAndroid Build Coastguard Worker       int secureIndex = -1;
639*f6dc9357SAndroid Build Coastguard Worker     #ifdef Z7_USE_SECURITY_CODE
640*f6dc9357SAndroid Build Coastguard Worker       if (dirItems.ReadSecure)
641*f6dc9357SAndroid Build Coastguard Worker       {
642*f6dc9357SAndroid Build Coastguard Worker         RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex))
643*f6dc9357SAndroid Build Coastguard Worker       }
644*f6dc9357SAndroid Build Coastguard Worker     #endif
645*f6dc9357SAndroid Build Coastguard Worker     #if !defined(UNDER_CE)
646*f6dc9357SAndroid Build Coastguard Worker       dirItemIndex = (int)dirItems.Items.Size();
647*f6dc9357SAndroid Build Coastguard Worker     #endif // !defined(UNDER_CE)
648*f6dc9357SAndroid Build Coastguard Worker       dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi);
649*f6dc9357SAndroid Build Coastguard Worker     }
650*f6dc9357SAndroid Build Coastguard Worker     else
651*f6dc9357SAndroid Build Coastguard Worker     {
652*f6dc9357SAndroid Build Coastguard Worker       #if defined(_WIN32) && !defined(UNDER_CE)
653*f6dc9357SAndroid Build Coastguard Worker         needAltStreams = false;
654*f6dc9357SAndroid Build Coastguard Worker       #endif
655*f6dc9357SAndroid Build Coastguard Worker     }
656*f6dc9357SAndroid Build Coastguard Worker 
657*f6dc9357SAndroid Build Coastguard Worker     if (fi.IsDir())
658*f6dc9357SAndroid Build Coastguard Worker       enterToSubFolders = true;
659*f6dc9357SAndroid Build Coastguard Worker   }
660*f6dc9357SAndroid Build Coastguard Worker 
661*f6dc9357SAndroid Build Coastguard Worker   #if !defined(UNDER_CE)
662*f6dc9357SAndroid Build Coastguard Worker 
663*f6dc9357SAndroid Build Coastguard Worker   // we don't scan AltStreams for link files
664*f6dc9357SAndroid Build Coastguard Worker 
665*f6dc9357SAndroid Build Coastguard Worker   if (dirItemIndex >= 0)
666*f6dc9357SAndroid Build Coastguard Worker   {
667*f6dc9357SAndroid Build Coastguard Worker     CDirItem &dirItem = dirItems.Items[(unsigned)dirItemIndex];
668*f6dc9357SAndroid Build Coastguard Worker     RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix))
669*f6dc9357SAndroid Build Coastguard Worker     if (dirItem.ReparseData.Size() != 0)
670*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
671*f6dc9357SAndroid Build Coastguard Worker   }
672*f6dc9357SAndroid Build Coastguard Worker 
673*f6dc9357SAndroid Build Coastguard Worker   #if defined(_WIN32)
674*f6dc9357SAndroid Build Coastguard Worker   if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream)
675*f6dc9357SAndroid Build Coastguard Worker   {
676*f6dc9357SAndroid Build Coastguard Worker     RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
677*f6dc9357SAndroid Build Coastguard Worker         phyPrefix + fi.Name,    // with (fi.Name)
678*f6dc9357SAndroid Build Coastguard Worker         newParts,               // with (fi.Name)
679*f6dc9357SAndroid Build Coastguard Worker         addAllSubStreams,
680*f6dc9357SAndroid Build Coastguard Worker         dirItems))
681*f6dc9357SAndroid Build Coastguard Worker   }
682*f6dc9357SAndroid Build Coastguard Worker   #endif
683*f6dc9357SAndroid Build Coastguard Worker 
684*f6dc9357SAndroid Build Coastguard Worker   #endif // !defined(UNDER_CE)
685*f6dc9357SAndroid Build Coastguard Worker 
686*f6dc9357SAndroid Build Coastguard Worker 
687*f6dc9357SAndroid Build Coastguard Worker   #ifndef _WIN32
688*f6dc9357SAndroid Build Coastguard Worker   if (!fi.IsPosixLink()) // posix link can follow to dir
689*f6dc9357SAndroid Build Coastguard Worker   #endif
690*f6dc9357SAndroid Build Coastguard Worker   if (!fi.IsDir())
691*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
692*f6dc9357SAndroid Build Coastguard Worker 
693*f6dc9357SAndroid Build Coastguard Worker   const NWildcard::CCensorNode *nextNode = NULL;
694*f6dc9357SAndroid Build Coastguard Worker 
695*f6dc9357SAndroid Build Coastguard Worker   if (addParts.IsEmpty())
696*f6dc9357SAndroid Build Coastguard Worker   {
697*f6dc9357SAndroid Build Coastguard Worker     int index = curNode.FindSubNode(name);
698*f6dc9357SAndroid Build Coastguard Worker     if (index >= 0)
699*f6dc9357SAndroid Build Coastguard Worker     {
700*f6dc9357SAndroid Build Coastguard Worker       nextNode = &curNode.SubNodes[(unsigned)index];
701*f6dc9357SAndroid Build Coastguard Worker       newParts.Clear();
702*f6dc9357SAndroid Build Coastguard Worker     }
703*f6dc9357SAndroid Build Coastguard Worker   }
704*f6dc9357SAndroid Build Coastguard Worker 
705*f6dc9357SAndroid Build Coastguard Worker   if (!nextNode)
706*f6dc9357SAndroid Build Coastguard Worker   {
707*f6dc9357SAndroid Build Coastguard Worker     if (!enterToSubFolders)
708*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
709*f6dc9357SAndroid Build Coastguard Worker 
710*f6dc9357SAndroid Build Coastguard Worker    #ifndef _WIN32
711*f6dc9357SAndroid Build Coastguard Worker     if (fi.IsPosixLink())
712*f6dc9357SAndroid Build Coastguard Worker     {
713*f6dc9357SAndroid Build Coastguard Worker       // here we can try to resolve posix link
714*f6dc9357SAndroid Build Coastguard Worker       // if the link to dir, then can we follow it
715*f6dc9357SAndroid Build Coastguard Worker       return S_OK; // we don't follow posix link
716*f6dc9357SAndroid Build Coastguard Worker     }
717*f6dc9357SAndroid Build Coastguard Worker    #else
718*f6dc9357SAndroid Build Coastguard Worker     if (dirItems.SymLinks && fi.HasReparsePoint())
719*f6dc9357SAndroid Build Coastguard Worker     {
720*f6dc9357SAndroid Build Coastguard Worker       /* 20.03: in SymLinks mode: we don't enter to directory that
721*f6dc9357SAndroid Build Coastguard Worker          has reparse point and has no CCensorNode
722*f6dc9357SAndroid Build Coastguard Worker          NOTE: (curNode and parent nodes) still can have wildcard rules
723*f6dc9357SAndroid Build Coastguard Worker          to include some items of target directory (of reparse point),
724*f6dc9357SAndroid Build Coastguard Worker          but we ignore these rules here.
725*f6dc9357SAndroid Build Coastguard Worker       */
726*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
727*f6dc9357SAndroid Build Coastguard Worker     }
728*f6dc9357SAndroid Build Coastguard Worker    #endif
729*f6dc9357SAndroid Build Coastguard Worker     nextNode = &curNode;
730*f6dc9357SAndroid Build Coastguard Worker   }
731*f6dc9357SAndroid Build Coastguard Worker 
732*f6dc9357SAndroid Build Coastguard Worker   return EnumerateDirItems_Spec(
733*f6dc9357SAndroid Build Coastguard Worker       *nextNode, phyParent, logParent, fi.Name,
734*f6dc9357SAndroid Build Coastguard Worker       phyPrefix,   // without (fi.Name)
735*f6dc9357SAndroid Build Coastguard Worker       newParts,    // relative to (*nextNode). (*nextNode + newParts) includes (fi.Name)
736*f6dc9357SAndroid Build Coastguard Worker       dirItems,
737*f6dc9357SAndroid Build Coastguard Worker       enterToSubFolders);
738*f6dc9357SAndroid Build Coastguard Worker }
739*f6dc9357SAndroid Build Coastguard Worker 
740*f6dc9357SAndroid Build Coastguard Worker 
CanUseFsDirect(const NWildcard::CCensorNode & curNode)741*f6dc9357SAndroid Build Coastguard Worker static bool CanUseFsDirect(const NWildcard::CCensorNode &curNode)
742*f6dc9357SAndroid Build Coastguard Worker {
743*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, curNode.IncludeItems)
744*f6dc9357SAndroid Build Coastguard Worker   {
745*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::CItem &item = curNode.IncludeItems[i];
746*f6dc9357SAndroid Build Coastguard Worker     if (item.Recursive || item.PathParts.Size() != 1)
747*f6dc9357SAndroid Build Coastguard Worker       return false;
748*f6dc9357SAndroid Build Coastguard Worker     const UString &name = item.PathParts.Front();
749*f6dc9357SAndroid Build Coastguard Worker     /*
750*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEmpty())
751*f6dc9357SAndroid Build Coastguard Worker       return false;
752*f6dc9357SAndroid Build Coastguard Worker     */
753*f6dc9357SAndroid Build Coastguard Worker 
754*f6dc9357SAndroid Build Coastguard Worker     /* Windows doesn't support file name with wildcard
755*f6dc9357SAndroid Build Coastguard Worker        But if another system supports file name with wildcard,
756*f6dc9357SAndroid Build Coastguard Worker        and wildcard mode is disabled, we can ignore wildcard in name
757*f6dc9357SAndroid Build Coastguard Worker     */
758*f6dc9357SAndroid Build Coastguard Worker     /*
759*f6dc9357SAndroid Build Coastguard Worker     #ifndef _WIN32
760*f6dc9357SAndroid Build Coastguard Worker     if (!item.WildcardParsing)
761*f6dc9357SAndroid Build Coastguard Worker       continue;
762*f6dc9357SAndroid Build Coastguard Worker     #endif
763*f6dc9357SAndroid Build Coastguard Worker     */
764*f6dc9357SAndroid Build Coastguard Worker     if (DoesNameContainWildcard(name))
765*f6dc9357SAndroid Build Coastguard Worker       return false;
766*f6dc9357SAndroid Build Coastguard Worker   }
767*f6dc9357SAndroid Build Coastguard Worker   return true;
768*f6dc9357SAndroid Build Coastguard Worker }
769*f6dc9357SAndroid Build Coastguard Worker 
770*f6dc9357SAndroid Build Coastguard Worker 
771*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
772*f6dc9357SAndroid Build Coastguard Worker 
IsVirtualFsFolder(const FString & prefix,const UString & name)773*f6dc9357SAndroid Build Coastguard Worker static bool IsVirtualFsFolder(const FString &prefix, const UString &name)
774*f6dc9357SAndroid Build Coastguard Worker {
775*f6dc9357SAndroid Build Coastguard Worker   UString s = fs2us(prefix);
776*f6dc9357SAndroid Build Coastguard Worker   s += name;
777*f6dc9357SAndroid Build Coastguard Worker   s.Add_PathSepar();
778*f6dc9357SAndroid Build Coastguard Worker   // it returns (true) for non real FS folder path like - "\\SERVER\"
779*f6dc9357SAndroid Build Coastguard Worker   return IsPathSepar(s[0]) && GetRootPrefixSize(s) == 0;
780*f6dc9357SAndroid Build Coastguard Worker }
781*f6dc9357SAndroid Build Coastguard Worker 
782*f6dc9357SAndroid Build Coastguard Worker #endif
783*f6dc9357SAndroid Build Coastguard Worker 
784*f6dc9357SAndroid Build Coastguard Worker 
785*f6dc9357SAndroid Build Coastguard Worker 
EnumerateDirItems(const NWildcard::CCensorNode & curNode,const int phyParent,const int logParent,const FString & phyPrefix,const UStringVector & addParts,CDirItems & dirItems,bool enterToSubFolders)786*f6dc9357SAndroid Build Coastguard Worker static HRESULT EnumerateDirItems(
787*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::CCensorNode &curNode,
788*f6dc9357SAndroid Build Coastguard Worker     const int phyParent, const int logParent, const FString &phyPrefix,
789*f6dc9357SAndroid Build Coastguard Worker     const UStringVector &addParts,  // prefix from curNode including
790*f6dc9357SAndroid Build Coastguard Worker     CDirItems &dirItems,
791*f6dc9357SAndroid Build Coastguard Worker     bool enterToSubFolders)
792*f6dc9357SAndroid Build Coastguard Worker {
793*f6dc9357SAndroid Build Coastguard Worker   if (!enterToSubFolders)
794*f6dc9357SAndroid Build Coastguard Worker   {
795*f6dc9357SAndroid Build Coastguard Worker     /* if there are IncludeItems censor rules that affect items in subdirs,
796*f6dc9357SAndroid Build Coastguard Worker        then we will enter to all subfolders */
797*f6dc9357SAndroid Build Coastguard Worker     if (curNode.NeedCheckSubDirs())
798*f6dc9357SAndroid Build Coastguard Worker       enterToSubFolders = true;
799*f6dc9357SAndroid Build Coastguard Worker   }
800*f6dc9357SAndroid Build Coastguard Worker 
801*f6dc9357SAndroid Build Coastguard Worker   RINOK(dirItems.ScanProgress(phyPrefix))
802*f6dc9357SAndroid Build Coastguard Worker 
803*f6dc9357SAndroid Build Coastguard Worker   // try direct_names case at first
804*f6dc9357SAndroid Build Coastguard Worker   if (addParts.IsEmpty() && !enterToSubFolders)
805*f6dc9357SAndroid Build Coastguard Worker   {
806*f6dc9357SAndroid Build Coastguard Worker     if (CanUseFsDirect(curNode))
807*f6dc9357SAndroid Build Coastguard Worker     {
808*f6dc9357SAndroid Build Coastguard Worker       // all names are direct (no wildcards)
809*f6dc9357SAndroid Build Coastguard Worker       // so we don't need file_system's dir enumerator
810*f6dc9357SAndroid Build Coastguard Worker       CRecordVector<bool> needEnterVector;
811*f6dc9357SAndroid Build Coastguard Worker       unsigned i;
812*f6dc9357SAndroid Build Coastguard Worker 
813*f6dc9357SAndroid Build Coastguard Worker       for (i = 0; i < curNode.IncludeItems.Size(); i++)
814*f6dc9357SAndroid Build Coastguard Worker       {
815*f6dc9357SAndroid Build Coastguard Worker         const NWildcard::CItem &item = curNode.IncludeItems[i];
816*f6dc9357SAndroid Build Coastguard Worker         const UString &name = item.PathParts.Front();
817*f6dc9357SAndroid Build Coastguard Worker         FString fullPath = phyPrefix + us2fs(name);
818*f6dc9357SAndroid Build Coastguard Worker 
819*f6dc9357SAndroid Build Coastguard Worker         /*
820*f6dc9357SAndroid Build Coastguard Worker         // not possible now
821*f6dc9357SAndroid Build Coastguard Worker         if (!item.ForDir && !item.ForFile)
822*f6dc9357SAndroid Build Coastguard Worker         {
823*f6dc9357SAndroid Build Coastguard Worker           RINOK(dirItems.AddError(fullPath, ERROR_INVALID_PARAMETER));
824*f6dc9357SAndroid Build Coastguard Worker           continue;
825*f6dc9357SAndroid Build Coastguard Worker         }
826*f6dc9357SAndroid Build Coastguard Worker         */
827*f6dc9357SAndroid Build Coastguard Worker 
828*f6dc9357SAndroid Build Coastguard Worker         #if defined(_WIN32) && !defined(UNDER_CE)
829*f6dc9357SAndroid Build Coastguard Worker         bool needAltStreams = true;
830*f6dc9357SAndroid Build Coastguard Worker         #endif
831*f6dc9357SAndroid Build Coastguard Worker 
832*f6dc9357SAndroid Build Coastguard Worker         #ifdef Z7_USE_SECURITY_CODE
833*f6dc9357SAndroid Build Coastguard Worker         bool needSecurity = true;
834*f6dc9357SAndroid Build Coastguard Worker         #endif
835*f6dc9357SAndroid Build Coastguard Worker 
836*f6dc9357SAndroid Build Coastguard Worker         if (phyPrefix.IsEmpty())
837*f6dc9357SAndroid Build Coastguard Worker         {
838*f6dc9357SAndroid Build Coastguard Worker           if (!item.ForFile)
839*f6dc9357SAndroid Build Coastguard Worker           {
840*f6dc9357SAndroid Build Coastguard Worker             /* we don't like some names for alt streams inside archive:
841*f6dc9357SAndroid Build Coastguard Worker                ":sname"     for "\"
842*f6dc9357SAndroid Build Coastguard Worker                "c:::sname"  for "C:\"
843*f6dc9357SAndroid Build Coastguard Worker                So we ignore alt streams for these cases */
844*f6dc9357SAndroid Build Coastguard Worker             if (name.IsEmpty())
845*f6dc9357SAndroid Build Coastguard Worker             {
846*f6dc9357SAndroid Build Coastguard Worker               #if defined(_WIN32) && !defined(UNDER_CE)
847*f6dc9357SAndroid Build Coastguard Worker               needAltStreams = false;
848*f6dc9357SAndroid Build Coastguard Worker               #endif
849*f6dc9357SAndroid Build Coastguard Worker 
850*f6dc9357SAndroid Build Coastguard Worker               /*
851*f6dc9357SAndroid Build Coastguard Worker               // do we need to ignore security info for "\\" folder ?
852*f6dc9357SAndroid Build Coastguard Worker               #ifdef Z7_USE_SECURITY_CODE
853*f6dc9357SAndroid Build Coastguard Worker               needSecurity = false;
854*f6dc9357SAndroid Build Coastguard Worker               #endif
855*f6dc9357SAndroid Build Coastguard Worker               */
856*f6dc9357SAndroid Build Coastguard Worker 
857*f6dc9357SAndroid Build Coastguard Worker               fullPath = CHAR_PATH_SEPARATOR;
858*f6dc9357SAndroid Build Coastguard Worker             }
859*f6dc9357SAndroid Build Coastguard Worker             #if defined(_WIN32) && !defined(UNDER_CE)
860*f6dc9357SAndroid Build Coastguard Worker             else if (item.IsDriveItem())
861*f6dc9357SAndroid Build Coastguard Worker             {
862*f6dc9357SAndroid Build Coastguard Worker               needAltStreams = false;
863*f6dc9357SAndroid Build Coastguard Worker               fullPath.Add_PathSepar();
864*f6dc9357SAndroid Build Coastguard Worker             }
865*f6dc9357SAndroid Build Coastguard Worker             #endif
866*f6dc9357SAndroid Build Coastguard Worker           }
867*f6dc9357SAndroid Build Coastguard Worker         }
868*f6dc9357SAndroid Build Coastguard Worker 
869*f6dc9357SAndroid Build Coastguard Worker         NFind::CFileInfo fi;
870*f6dc9357SAndroid Build Coastguard Worker         #if defined(_WIN32) && !defined(UNDER_CE)
871*f6dc9357SAndroid Build Coastguard Worker         if (IsVirtualFsFolder(phyPrefix, name))
872*f6dc9357SAndroid Build Coastguard Worker         {
873*f6dc9357SAndroid Build Coastguard Worker           fi.SetAsDir();
874*f6dc9357SAndroid Build Coastguard Worker           fi.Name = us2fs(name);
875*f6dc9357SAndroid Build Coastguard Worker         }
876*f6dc9357SAndroid Build Coastguard Worker         else
877*f6dc9357SAndroid Build Coastguard Worker         #endif
878*f6dc9357SAndroid Build Coastguard Worker         if (!FindFile_KeepDots(fi, fullPath  FOLLOW_LINK_PARAM2))
879*f6dc9357SAndroid Build Coastguard Worker         {
880*f6dc9357SAndroid Build Coastguard Worker           RINOK(dirItems.AddError(fullPath))
881*f6dc9357SAndroid Build Coastguard Worker           continue;
882*f6dc9357SAndroid Build Coastguard Worker         }
883*f6dc9357SAndroid Build Coastguard Worker 
884*f6dc9357SAndroid Build Coastguard Worker         /*
885*f6dc9357SAndroid Build Coastguard Worker         #ifdef _WIN32
886*f6dc9357SAndroid Build Coastguard Worker           #define MY_ERROR_IS_DIR     ERROR_FILE_NOT_FOUND
887*f6dc9357SAndroid Build Coastguard Worker           #define MY_ERROR_NOT_DIR    DI_DEFAULT_ERROR
888*f6dc9357SAndroid Build Coastguard Worker         #else
889*f6dc9357SAndroid Build Coastguard Worker           #define MY_ERROR_IS_DIR     EISDIR
890*f6dc9357SAndroid Build Coastguard Worker           #define MY_ERROR_NOT_DIR    ENOTDIR
891*f6dc9357SAndroid Build Coastguard Worker         #endif
892*f6dc9357SAndroid Build Coastguard Worker         */
893*f6dc9357SAndroid Build Coastguard Worker 
894*f6dc9357SAndroid Build Coastguard Worker         const bool isDir = fi.IsDir();
895*f6dc9357SAndroid Build Coastguard Worker         if (isDir ? !item.ForDir : !item.ForFile)
896*f6dc9357SAndroid Build Coastguard Worker         {
897*f6dc9357SAndroid Build Coastguard Worker           // RINOK(dirItems.AddError(fullPath, isDir ? MY_ERROR_IS_DIR: MY_ERROR_NOT_DIR));
898*f6dc9357SAndroid Build Coastguard Worker           RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR))
899*f6dc9357SAndroid Build Coastguard Worker           continue;
900*f6dc9357SAndroid Build Coastguard Worker         }
901*f6dc9357SAndroid Build Coastguard Worker         {
902*f6dc9357SAndroid Build Coastguard Worker           UStringVector pathParts;
903*f6dc9357SAndroid Build Coastguard Worker           pathParts.Add(fs2us(fi.Name));
904*f6dc9357SAndroid Build Coastguard Worker           if (curNode.CheckPathToRoot(false, pathParts, !isDir))
905*f6dc9357SAndroid Build Coastguard Worker             continue;
906*f6dc9357SAndroid Build Coastguard Worker         }
907*f6dc9357SAndroid Build Coastguard Worker 
908*f6dc9357SAndroid Build Coastguard Worker 
909*f6dc9357SAndroid Build Coastguard Worker        if (dirItems.CanIncludeItem(fi.IsDir()))
910*f6dc9357SAndroid Build Coastguard Worker        {
911*f6dc9357SAndroid Build Coastguard Worker         int secureIndex = -1;
912*f6dc9357SAndroid Build Coastguard Worker         #ifdef Z7_USE_SECURITY_CODE
913*f6dc9357SAndroid Build Coastguard Worker         if (needSecurity && dirItems.ReadSecure)
914*f6dc9357SAndroid Build Coastguard Worker         {
915*f6dc9357SAndroid Build Coastguard Worker           RINOK(dirItems.AddSecurityItem(fullPath, secureIndex))
916*f6dc9357SAndroid Build Coastguard Worker         }
917*f6dc9357SAndroid Build Coastguard Worker         #endif
918*f6dc9357SAndroid Build Coastguard Worker 
919*f6dc9357SAndroid Build Coastguard Worker         dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi);
920*f6dc9357SAndroid Build Coastguard Worker 
921*f6dc9357SAndroid Build Coastguard Worker         // we don't scan AltStreams for link files
922*f6dc9357SAndroid Build Coastguard Worker 
923*f6dc9357SAndroid Build Coastguard Worker         #if !defined(UNDER_CE)
924*f6dc9357SAndroid Build Coastguard Worker         {
925*f6dc9357SAndroid Build Coastguard Worker           CDirItem &dirItem = dirItems.Items.Back();
926*f6dc9357SAndroid Build Coastguard Worker           RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix))
927*f6dc9357SAndroid Build Coastguard Worker           if (dirItem.ReparseData.Size() != 0)
928*f6dc9357SAndroid Build Coastguard Worker             continue;
929*f6dc9357SAndroid Build Coastguard Worker         }
930*f6dc9357SAndroid Build Coastguard Worker 
931*f6dc9357SAndroid Build Coastguard Worker         #if defined(_WIN32)
932*f6dc9357SAndroid Build Coastguard Worker         if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream)
933*f6dc9357SAndroid Build Coastguard Worker         {
934*f6dc9357SAndroid Build Coastguard Worker           UStringVector pathParts;
935*f6dc9357SAndroid Build Coastguard Worker           pathParts.Add(fs2us(fi.Name));
936*f6dc9357SAndroid Build Coastguard Worker           RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
937*f6dc9357SAndroid Build Coastguard Worker               fullPath,  // including (name)
938*f6dc9357SAndroid Build Coastguard Worker               pathParts, // including (fi.Name)
939*f6dc9357SAndroid Build Coastguard Worker               true, /* addAllSubStreams */
940*f6dc9357SAndroid Build Coastguard Worker               dirItems))
941*f6dc9357SAndroid Build Coastguard Worker         }
942*f6dc9357SAndroid Build Coastguard Worker         #endif // defined(_WIN32)
943*f6dc9357SAndroid Build Coastguard Worker 
944*f6dc9357SAndroid Build Coastguard Worker         #endif // !defined(UNDER_CE)
945*f6dc9357SAndroid Build Coastguard Worker        }
946*f6dc9357SAndroid Build Coastguard Worker 
947*f6dc9357SAndroid Build Coastguard Worker 
948*f6dc9357SAndroid Build Coastguard Worker         #ifndef _WIN32
949*f6dc9357SAndroid Build Coastguard Worker         if (!fi.IsPosixLink()) // posix link can follow to dir
950*f6dc9357SAndroid Build Coastguard Worker         #endif
951*f6dc9357SAndroid Build Coastguard Worker         if (!isDir)
952*f6dc9357SAndroid Build Coastguard Worker           continue;
953*f6dc9357SAndroid Build Coastguard Worker 
954*f6dc9357SAndroid Build Coastguard Worker         UStringVector newParts;
955*f6dc9357SAndroid Build Coastguard Worker         const NWildcard::CCensorNode *nextNode = NULL;
956*f6dc9357SAndroid Build Coastguard Worker         int index = curNode.FindSubNode(name);
957*f6dc9357SAndroid Build Coastguard Worker         if (index >= 0)
958*f6dc9357SAndroid Build Coastguard Worker         {
959*f6dc9357SAndroid Build Coastguard Worker           for (int t = (int)needEnterVector.Size(); t <= index; t++)
960*f6dc9357SAndroid Build Coastguard Worker             needEnterVector.Add(true);
961*f6dc9357SAndroid Build Coastguard Worker           needEnterVector[(unsigned)index] = false;
962*f6dc9357SAndroid Build Coastguard Worker           nextNode = &curNode.SubNodes[(unsigned)index];
963*f6dc9357SAndroid Build Coastguard Worker         }
964*f6dc9357SAndroid Build Coastguard Worker         else
965*f6dc9357SAndroid Build Coastguard Worker         {
966*f6dc9357SAndroid Build Coastguard Worker          #ifndef _WIN32
967*f6dc9357SAndroid Build Coastguard Worker           if (fi.IsPosixLink())
968*f6dc9357SAndroid Build Coastguard Worker           {
969*f6dc9357SAndroid Build Coastguard Worker             // here we can try to resolve posix link
970*f6dc9357SAndroid Build Coastguard Worker             // if the link to dir, then can we follow it
971*f6dc9357SAndroid Build Coastguard Worker             continue; // we don't follow posix link
972*f6dc9357SAndroid Build Coastguard Worker           }
973*f6dc9357SAndroid Build Coastguard Worker          #else
974*f6dc9357SAndroid Build Coastguard Worker           if (dirItems.SymLinks)
975*f6dc9357SAndroid Build Coastguard Worker           {
976*f6dc9357SAndroid Build Coastguard Worker             if (fi.HasReparsePoint())
977*f6dc9357SAndroid Build Coastguard Worker             {
978*f6dc9357SAndroid Build Coastguard Worker               /* 20.03: in SymLinks mode: we don't enter to directory that
979*f6dc9357SAndroid Build Coastguard Worker               has reparse point and has no CCensorNode */
980*f6dc9357SAndroid Build Coastguard Worker               continue;
981*f6dc9357SAndroid Build Coastguard Worker             }
982*f6dc9357SAndroid Build Coastguard Worker           }
983*f6dc9357SAndroid Build Coastguard Worker          #endif
984*f6dc9357SAndroid Build Coastguard Worker           nextNode = &curNode;
985*f6dc9357SAndroid Build Coastguard Worker           newParts.Add(name); // don't change it to fi.Name. It's for shortnames support
986*f6dc9357SAndroid Build Coastguard Worker         }
987*f6dc9357SAndroid Build Coastguard Worker 
988*f6dc9357SAndroid Build Coastguard Worker         RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
989*f6dc9357SAndroid Build Coastguard Worker             newParts, dirItems, true))
990*f6dc9357SAndroid Build Coastguard Worker       }
991*f6dc9357SAndroid Build Coastguard Worker 
992*f6dc9357SAndroid Build Coastguard Worker       for (i = 0; i < curNode.SubNodes.Size(); i++)
993*f6dc9357SAndroid Build Coastguard Worker       {
994*f6dc9357SAndroid Build Coastguard Worker         if (i < needEnterVector.Size())
995*f6dc9357SAndroid Build Coastguard Worker           if (!needEnterVector[i])
996*f6dc9357SAndroid Build Coastguard Worker             continue;
997*f6dc9357SAndroid Build Coastguard Worker         const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
998*f6dc9357SAndroid Build Coastguard Worker         FString fullPath = phyPrefix + us2fs(nextNode.Name);
999*f6dc9357SAndroid Build Coastguard Worker         NFind::CFileInfo fi;
1000*f6dc9357SAndroid Build Coastguard Worker 
1001*f6dc9357SAndroid Build Coastguard Worker         if (nextNode.Name.IsEmpty())
1002*f6dc9357SAndroid Build Coastguard Worker         {
1003*f6dc9357SAndroid Build Coastguard Worker           if (phyPrefix.IsEmpty())
1004*f6dc9357SAndroid Build Coastguard Worker             fullPath = CHAR_PATH_SEPARATOR;
1005*f6dc9357SAndroid Build Coastguard Worker         }
1006*f6dc9357SAndroid Build Coastguard Worker       #ifdef _WIN32
1007*f6dc9357SAndroid Build Coastguard Worker         else if(phyPrefix.IsEmpty()
1008*f6dc9357SAndroid Build Coastguard Worker             || (phyPrefix.Len() == NName::kSuperPathPrefixSize
1009*f6dc9357SAndroid Build Coastguard Worker                 && IsSuperPath(phyPrefix)))
1010*f6dc9357SAndroid Build Coastguard Worker         {
1011*f6dc9357SAndroid Build Coastguard Worker           if (NWildcard::IsDriveColonName(nextNode.Name))
1012*f6dc9357SAndroid Build Coastguard Worker             fullPath.Add_PathSepar();
1013*f6dc9357SAndroid Build Coastguard Worker         }
1014*f6dc9357SAndroid Build Coastguard Worker       #endif
1015*f6dc9357SAndroid Build Coastguard Worker 
1016*f6dc9357SAndroid Build Coastguard Worker         // we don't want to call fi.Find() for root folder or virtual folder
1017*f6dc9357SAndroid Build Coastguard Worker         if ((phyPrefix.IsEmpty() && nextNode.Name.IsEmpty())
1018*f6dc9357SAndroid Build Coastguard Worker             #if defined(_WIN32) && !defined(UNDER_CE)
1019*f6dc9357SAndroid Build Coastguard Worker             || IsVirtualFsFolder(phyPrefix, nextNode.Name)
1020*f6dc9357SAndroid Build Coastguard Worker             #endif
1021*f6dc9357SAndroid Build Coastguard Worker             )
1022*f6dc9357SAndroid Build Coastguard Worker         {
1023*f6dc9357SAndroid Build Coastguard Worker           fi.SetAsDir();
1024*f6dc9357SAndroid Build Coastguard Worker           fi.Name = us2fs(nextNode.Name);
1025*f6dc9357SAndroid Build Coastguard Worker         }
1026*f6dc9357SAndroid Build Coastguard Worker         else
1027*f6dc9357SAndroid Build Coastguard Worker         {
1028*f6dc9357SAndroid Build Coastguard Worker           if (!FindFile_KeepDots(fi, fullPath  FOLLOW_LINK_PARAM2))
1029*f6dc9357SAndroid Build Coastguard Worker           {
1030*f6dc9357SAndroid Build Coastguard Worker             if (!nextNode.AreThereIncludeItems())
1031*f6dc9357SAndroid Build Coastguard Worker               continue;
1032*f6dc9357SAndroid Build Coastguard Worker             RINOK(dirItems.AddError(fullPath))
1033*f6dc9357SAndroid Build Coastguard Worker             continue;
1034*f6dc9357SAndroid Build Coastguard Worker           }
1035*f6dc9357SAndroid Build Coastguard Worker 
1036*f6dc9357SAndroid Build Coastguard Worker           if (!fi.IsDir())
1037*f6dc9357SAndroid Build Coastguard Worker           {
1038*f6dc9357SAndroid Build Coastguard Worker             RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR))
1039*f6dc9357SAndroid Build Coastguard Worker             continue;
1040*f6dc9357SAndroid Build Coastguard Worker           }
1041*f6dc9357SAndroid Build Coastguard Worker         }
1042*f6dc9357SAndroid Build Coastguard Worker 
1043*f6dc9357SAndroid Build Coastguard Worker         RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix,
1044*f6dc9357SAndroid Build Coastguard Worker             UStringVector(), dirItems, false))
1045*f6dc9357SAndroid Build Coastguard Worker       }
1046*f6dc9357SAndroid Build Coastguard Worker 
1047*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1048*f6dc9357SAndroid Build Coastguard Worker     }
1049*f6dc9357SAndroid Build Coastguard Worker   }
1050*f6dc9357SAndroid Build Coastguard Worker 
1051*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
1052*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
1053*f6dc9357SAndroid Build Coastguard Worker 
1054*f6dc9357SAndroid Build Coastguard Worker   // scan drives, if wildcard is "*:\"
1055*f6dc9357SAndroid Build Coastguard Worker 
1056*f6dc9357SAndroid Build Coastguard Worker   if (phyPrefix.IsEmpty() && curNode.IncludeItems.Size() > 0)
1057*f6dc9357SAndroid Build Coastguard Worker   {
1058*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
1059*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < curNode.IncludeItems.Size(); i++)
1060*f6dc9357SAndroid Build Coastguard Worker     {
1061*f6dc9357SAndroid Build Coastguard Worker       const NWildcard::CItem &item = curNode.IncludeItems[i];
1062*f6dc9357SAndroid Build Coastguard Worker       if (item.PathParts.Size() < 1)
1063*f6dc9357SAndroid Build Coastguard Worker         break;
1064*f6dc9357SAndroid Build Coastguard Worker       const UString &name = item.PathParts.Front();
1065*f6dc9357SAndroid Build Coastguard Worker       if (name.Len() != 2 || name[1] != ':')
1066*f6dc9357SAndroid Build Coastguard Worker         break;
1067*f6dc9357SAndroid Build Coastguard Worker       if (item.PathParts.Size() == 1)
1068*f6dc9357SAndroid Build Coastguard Worker         if (item.ForFile || !item.ForDir)
1069*f6dc9357SAndroid Build Coastguard Worker           break;
1070*f6dc9357SAndroid Build Coastguard Worker       if (NWildcard::IsDriveColonName(name))
1071*f6dc9357SAndroid Build Coastguard Worker         continue;
1072*f6dc9357SAndroid Build Coastguard Worker       if (name[0] != '*' && name[0] != '?')
1073*f6dc9357SAndroid Build Coastguard Worker         break;
1074*f6dc9357SAndroid Build Coastguard Worker     }
1075*f6dc9357SAndroid Build Coastguard Worker     if (i == curNode.IncludeItems.Size())
1076*f6dc9357SAndroid Build Coastguard Worker     {
1077*f6dc9357SAndroid Build Coastguard Worker       FStringVector driveStrings;
1078*f6dc9357SAndroid Build Coastguard Worker       NFind::MyGetLogicalDriveStrings(driveStrings);
1079*f6dc9357SAndroid Build Coastguard Worker       for (i = 0; i < driveStrings.Size(); i++)
1080*f6dc9357SAndroid Build Coastguard Worker       {
1081*f6dc9357SAndroid Build Coastguard Worker         FString driveName = driveStrings[i];
1082*f6dc9357SAndroid Build Coastguard Worker         if (driveName.Len() < 3 || driveName.Back() != '\\')
1083*f6dc9357SAndroid Build Coastguard Worker           return E_FAIL;
1084*f6dc9357SAndroid Build Coastguard Worker         driveName.DeleteBack();
1085*f6dc9357SAndroid Build Coastguard Worker         NFind::CFileInfo fi;
1086*f6dc9357SAndroid Build Coastguard Worker         fi.SetAsDir();
1087*f6dc9357SAndroid Build Coastguard Worker         fi.Name = driveName;
1088*f6dc9357SAndroid Build Coastguard Worker 
1089*f6dc9357SAndroid Build Coastguard Worker         RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix,
1090*f6dc9357SAndroid Build Coastguard Worker             addParts, dirItems, enterToSubFolders))
1091*f6dc9357SAndroid Build Coastguard Worker       }
1092*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1093*f6dc9357SAndroid Build Coastguard Worker     }
1094*f6dc9357SAndroid Build Coastguard Worker   }
1095*f6dc9357SAndroid Build Coastguard Worker 
1096*f6dc9357SAndroid Build Coastguard Worker   #endif
1097*f6dc9357SAndroid Build Coastguard Worker   #endif
1098*f6dc9357SAndroid Build Coastguard Worker 
1099*f6dc9357SAndroid Build Coastguard Worker 
1100*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<NFind::CFileInfo> files;
1101*f6dc9357SAndroid Build Coastguard Worker 
1102*f6dc9357SAndroid Build Coastguard Worker   // for (int y = 0; y < 1; y++)
1103*f6dc9357SAndroid Build Coastguard Worker   {
1104*f6dc9357SAndroid Build Coastguard Worker     // files.Clear();
1105*f6dc9357SAndroid Build Coastguard Worker     RINOK(dirItems.EnumerateOneDir(phyPrefix, files))
1106*f6dc9357SAndroid Build Coastguard Worker   /*
1107*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, files)
1108*f6dc9357SAndroid Build Coastguard Worker   {
1109*f6dc9357SAndroid Build Coastguard Worker     #ifdef _WIN32
1110*f6dc9357SAndroid Build Coastguard Worker     // const NFind::CFileInfo &fi = files[i];
1111*f6dc9357SAndroid Build Coastguard Worker     #else
1112*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo &fi = files[i];
1113*f6dc9357SAndroid Build Coastguard Worker     {
1114*f6dc9357SAndroid Build Coastguard Worker       const NFind::CFileInfo &di = files[i];
1115*f6dc9357SAndroid Build Coastguard Worker       const FString path = phyPrefix + di.Name;
1116*f6dc9357SAndroid Build Coastguard Worker       if (!fi.Find_AfterEnumerator(path))
1117*f6dc9357SAndroid Build Coastguard Worker       {
1118*f6dc9357SAndroid Build Coastguard Worker         RINOK(dirItems.AddError(path));
1119*f6dc9357SAndroid Build Coastguard Worker         continue;
1120*f6dc9357SAndroid Build Coastguard Worker       }
1121*f6dc9357SAndroid Build Coastguard Worker       fi.Name = di.Name;
1122*f6dc9357SAndroid Build Coastguard Worker     }
1123*f6dc9357SAndroid Build Coastguard Worker     #endif
1124*f6dc9357SAndroid Build Coastguard Worker 
1125*f6dc9357SAndroid Build Coastguard Worker   }
1126*f6dc9357SAndroid Build Coastguard Worker   */
1127*f6dc9357SAndroid Build Coastguard Worker   }
1128*f6dc9357SAndroid Build Coastguard Worker 
1129*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, files)
1130*f6dc9357SAndroid Build Coastguard Worker   {
1131*f6dc9357SAndroid Build Coastguard Worker     #ifdef _WIN32
1132*f6dc9357SAndroid Build Coastguard Worker     const NFind::CFileInfo &fi = files[i];
1133*f6dc9357SAndroid Build Coastguard Worker     #else
1134*f6dc9357SAndroid Build Coastguard Worker     const NFind::CFileInfo &fi = files[i];
1135*f6dc9357SAndroid Build Coastguard Worker     /*
1136*f6dc9357SAndroid Build Coastguard Worker     NFind::CFileInfo fi;
1137*f6dc9357SAndroid Build Coastguard Worker     {
1138*f6dc9357SAndroid Build Coastguard Worker       const NFind::CDirEntry &di = files[i];
1139*f6dc9357SAndroid Build Coastguard Worker       const FString path = phyPrefix + di.Name;
1140*f6dc9357SAndroid Build Coastguard Worker       if (!fi.Find_AfterEnumerator(path))
1141*f6dc9357SAndroid Build Coastguard Worker       {
1142*f6dc9357SAndroid Build Coastguard Worker         RINOK(dirItems.AddError(path));
1143*f6dc9357SAndroid Build Coastguard Worker         continue;
1144*f6dc9357SAndroid Build Coastguard Worker       }
1145*f6dc9357SAndroid Build Coastguard Worker       fi.Name = di.Name;
1146*f6dc9357SAndroid Build Coastguard Worker     }
1147*f6dc9357SAndroid Build Coastguard Worker     */
1148*f6dc9357SAndroid Build Coastguard Worker     #endif
1149*f6dc9357SAndroid Build Coastguard Worker 
1150*f6dc9357SAndroid Build Coastguard Worker     RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix,
1151*f6dc9357SAndroid Build Coastguard Worker           addParts, dirItems, enterToSubFolders))
1152*f6dc9357SAndroid Build Coastguard Worker     if (dirItems.Callback && (i & kScanProgressStepMask) == kScanProgressStepMask)
1153*f6dc9357SAndroid Build Coastguard Worker     {
1154*f6dc9357SAndroid Build Coastguard Worker       RINOK(dirItems.ScanProgress(phyPrefix))
1155*f6dc9357SAndroid Build Coastguard Worker     }
1156*f6dc9357SAndroid Build Coastguard Worker   }
1157*f6dc9357SAndroid Build Coastguard Worker 
1158*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1159*f6dc9357SAndroid Build Coastguard Worker }
1160*f6dc9357SAndroid Build Coastguard Worker 
1161*f6dc9357SAndroid Build Coastguard Worker 
1162*f6dc9357SAndroid Build Coastguard Worker 
1163*f6dc9357SAndroid Build Coastguard Worker 
EnumerateItems(const NWildcard::CCensor & censor,const NWildcard::ECensorPathMode pathMode,const UString & addPathPrefix,CDirItems & dirItems)1164*f6dc9357SAndroid Build Coastguard Worker HRESULT EnumerateItems(
1165*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::CCensor &censor,
1166*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::ECensorPathMode pathMode,
1167*f6dc9357SAndroid Build Coastguard Worker     const UString &addPathPrefix, // prefix that will be added to Logical Path
1168*f6dc9357SAndroid Build Coastguard Worker     CDirItems &dirItems)
1169*f6dc9357SAndroid Build Coastguard Worker {
1170*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, censor.Pairs)
1171*f6dc9357SAndroid Build Coastguard Worker   {
1172*f6dc9357SAndroid Build Coastguard Worker     const NWildcard::CPair &pair = censor.Pairs[i];
1173*f6dc9357SAndroid Build Coastguard Worker     const int phyParent = pair.Prefix.IsEmpty() ? -1 : (int)dirItems.AddPrefix(-1, -1, pair.Prefix);
1174*f6dc9357SAndroid Build Coastguard Worker     int logParent = -1;
1175*f6dc9357SAndroid Build Coastguard Worker 
1176*f6dc9357SAndroid Build Coastguard Worker     if (pathMode == NWildcard::k_AbsPath)
1177*f6dc9357SAndroid Build Coastguard Worker       logParent = phyParent;
1178*f6dc9357SAndroid Build Coastguard Worker     else
1179*f6dc9357SAndroid Build Coastguard Worker     {
1180*f6dc9357SAndroid Build Coastguard Worker       if (!addPathPrefix.IsEmpty())
1181*f6dc9357SAndroid Build Coastguard Worker         logParent = (int)dirItems.AddPrefix(-1, -1, addPathPrefix);
1182*f6dc9357SAndroid Build Coastguard Worker     }
1183*f6dc9357SAndroid Build Coastguard Worker 
1184*f6dc9357SAndroid Build Coastguard Worker     RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(),
1185*f6dc9357SAndroid Build Coastguard Worker         dirItems,
1186*f6dc9357SAndroid Build Coastguard Worker         false // enterToSubFolders
1187*f6dc9357SAndroid Build Coastguard Worker         ))
1188*f6dc9357SAndroid Build Coastguard Worker   }
1189*f6dc9357SAndroid Build Coastguard Worker   dirItems.ReserveDown();
1190*f6dc9357SAndroid Build Coastguard Worker 
1191*f6dc9357SAndroid Build Coastguard Worker  #if defined(_WIN32) && !defined(UNDER_CE)
1192*f6dc9357SAndroid Build Coastguard Worker   RINOK(dirItems.FillFixedReparse())
1193*f6dc9357SAndroid Build Coastguard Worker  #endif
1194*f6dc9357SAndroid Build Coastguard Worker 
1195*f6dc9357SAndroid Build Coastguard Worker  #ifndef _WIN32
1196*f6dc9357SAndroid Build Coastguard Worker   RINOK(dirItems.FillDeviceSizes())
1197*f6dc9357SAndroid Build Coastguard Worker  #endif
1198*f6dc9357SAndroid Build Coastguard Worker 
1199*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1200*f6dc9357SAndroid Build Coastguard Worker }
1201*f6dc9357SAndroid Build Coastguard Worker 
1202*f6dc9357SAndroid Build Coastguard Worker 
1203*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
1204*f6dc9357SAndroid Build Coastguard Worker 
FillFixedReparse()1205*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::FillFixedReparse()
1206*f6dc9357SAndroid Build Coastguard Worker {
1207*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR(i, Items)
1208*f6dc9357SAndroid Build Coastguard Worker   {
1209*f6dc9357SAndroid Build Coastguard Worker     CDirItem &item = Items[i];
1210*f6dc9357SAndroid Build Coastguard Worker 
1211*f6dc9357SAndroid Build Coastguard Worker     if (!SymLinks)
1212*f6dc9357SAndroid Build Coastguard Worker     {
1213*f6dc9357SAndroid Build Coastguard Worker       // continue; // for debug
1214*f6dc9357SAndroid Build Coastguard Worker       if (!item.Has_Attrib_ReparsePoint())
1215*f6dc9357SAndroid Build Coastguard Worker         continue;
1216*f6dc9357SAndroid Build Coastguard Worker 
1217*f6dc9357SAndroid Build Coastguard Worker       // if (item.IsDir()) continue;
1218*f6dc9357SAndroid Build Coastguard Worker 
1219*f6dc9357SAndroid Build Coastguard Worker       const FString phyPath = GetPhyPath(i);
1220*f6dc9357SAndroid Build Coastguard Worker 
1221*f6dc9357SAndroid Build Coastguard Worker       NFind::CFileInfo fi;
1222*f6dc9357SAndroid Build Coastguard Worker       if (fi.Fill_From_ByHandleFileInfo(phyPath)) // item.IsDir()
1223*f6dc9357SAndroid Build Coastguard Worker       {
1224*f6dc9357SAndroid Build Coastguard Worker         item.Size = fi.Size;
1225*f6dc9357SAndroid Build Coastguard Worker         item.CTime = fi.CTime;
1226*f6dc9357SAndroid Build Coastguard Worker         item.ATime = fi.ATime;
1227*f6dc9357SAndroid Build Coastguard Worker         item.MTime = fi.MTime;
1228*f6dc9357SAndroid Build Coastguard Worker         item.Attrib = fi.Attrib;
1229*f6dc9357SAndroid Build Coastguard Worker         continue;
1230*f6dc9357SAndroid Build Coastguard Worker       }
1231*f6dc9357SAndroid Build Coastguard Worker 
1232*f6dc9357SAndroid Build Coastguard Worker       /*
1233*f6dc9357SAndroid Build Coastguard Worker       // we request properties of target file instead of properies of symbolic link
1234*f6dc9357SAndroid Build Coastguard Worker       // here we also can manually parse unsupported links (like WSL links)
1235*f6dc9357SAndroid Build Coastguard Worker       NIO::CInFile inFile;
1236*f6dc9357SAndroid Build Coastguard Worker       if (inFile.Open(phyPath))
1237*f6dc9357SAndroid Build Coastguard Worker       {
1238*f6dc9357SAndroid Build Coastguard Worker         BY_HANDLE_FILE_INFORMATION info;
1239*f6dc9357SAndroid Build Coastguard Worker         if (inFile.GetFileInformation(&info))
1240*f6dc9357SAndroid Build Coastguard Worker         {
1241*f6dc9357SAndroid Build Coastguard Worker           // Stat.FilesSize doesn't contain item.Size already
1242*f6dc9357SAndroid Build Coastguard Worker           // Stat.FilesSize -= item.Size;
1243*f6dc9357SAndroid Build Coastguard Worker           item.Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
1244*f6dc9357SAndroid Build Coastguard Worker           Stat.FilesSize += item.Size;
1245*f6dc9357SAndroid Build Coastguard Worker           item.CTime = info.ftCreationTime;
1246*f6dc9357SAndroid Build Coastguard Worker           item.ATime = info.ftLastAccessTime;
1247*f6dc9357SAndroid Build Coastguard Worker           item.MTime = info.ftLastWriteTime;
1248*f6dc9357SAndroid Build Coastguard Worker           item.Attrib = info.dwFileAttributes;
1249*f6dc9357SAndroid Build Coastguard Worker           continue;
1250*f6dc9357SAndroid Build Coastguard Worker         }
1251*f6dc9357SAndroid Build Coastguard Worker       }
1252*f6dc9357SAndroid Build Coastguard Worker       */
1253*f6dc9357SAndroid Build Coastguard Worker 
1254*f6dc9357SAndroid Build Coastguard Worker       RINOK(AddError(phyPath))
1255*f6dc9357SAndroid Build Coastguard Worker       continue;
1256*f6dc9357SAndroid Build Coastguard Worker     }
1257*f6dc9357SAndroid Build Coastguard Worker 
1258*f6dc9357SAndroid Build Coastguard Worker     // (SymLinks == true) here
1259*f6dc9357SAndroid Build Coastguard Worker 
1260*f6dc9357SAndroid Build Coastguard Worker     if (item.ReparseData.Size() == 0)
1261*f6dc9357SAndroid Build Coastguard Worker       continue;
1262*f6dc9357SAndroid Build Coastguard Worker 
1263*f6dc9357SAndroid Build Coastguard Worker     // if (item.Size == 0)
1264*f6dc9357SAndroid Build Coastguard Worker     {
1265*f6dc9357SAndroid Build Coastguard Worker       // 20.03: we use Reparse Data instead of real data
1266*f6dc9357SAndroid Build Coastguard Worker       item.Size = item.ReparseData.Size();
1267*f6dc9357SAndroid Build Coastguard Worker     }
1268*f6dc9357SAndroid Build Coastguard Worker 
1269*f6dc9357SAndroid Build Coastguard Worker     CReparseAttr attr;
1270*f6dc9357SAndroid Build Coastguard Worker     if (!attr.Parse(item.ReparseData, item.ReparseData.Size()))
1271*f6dc9357SAndroid Build Coastguard Worker     {
1272*f6dc9357SAndroid Build Coastguard Worker       const FString phyPath = GetPhyPath(i);
1273*f6dc9357SAndroid Build Coastguard Worker       AddError(phyPath, attr.ErrorCode);
1274*f6dc9357SAndroid Build Coastguard Worker       continue;
1275*f6dc9357SAndroid Build Coastguard Worker     }
1276*f6dc9357SAndroid Build Coastguard Worker 
1277*f6dc9357SAndroid Build Coastguard Worker     /* imagex/WIM reduces absolute paths in links (raparse data),
1278*f6dc9357SAndroid Build Coastguard Worker        if we archive non root folder. We do same thing here */
1279*f6dc9357SAndroid Build Coastguard Worker 
1280*f6dc9357SAndroid Build Coastguard Worker     bool isWSL = false;
1281*f6dc9357SAndroid Build Coastguard Worker     if (attr.IsSymLink_WSL())
1282*f6dc9357SAndroid Build Coastguard Worker     {
1283*f6dc9357SAndroid Build Coastguard Worker       // isWSL = true;
1284*f6dc9357SAndroid Build Coastguard Worker       // we don't change WSL symlinks
1285*f6dc9357SAndroid Build Coastguard Worker       continue;
1286*f6dc9357SAndroid Build Coastguard Worker     }
1287*f6dc9357SAndroid Build Coastguard Worker     else
1288*f6dc9357SAndroid Build Coastguard Worker     {
1289*f6dc9357SAndroid Build Coastguard Worker       if (attr.IsRelative_Win())
1290*f6dc9357SAndroid Build Coastguard Worker         continue;
1291*f6dc9357SAndroid Build Coastguard Worker     }
1292*f6dc9357SAndroid Build Coastguard Worker 
1293*f6dc9357SAndroid Build Coastguard Worker     const UString &link = attr.GetPath();
1294*f6dc9357SAndroid Build Coastguard Worker     if (!IsDrivePath(link))
1295*f6dc9357SAndroid Build Coastguard Worker       continue;
1296*f6dc9357SAndroid Build Coastguard Worker     // maybe we need to support networks paths also ?
1297*f6dc9357SAndroid Build Coastguard Worker 
1298*f6dc9357SAndroid Build Coastguard Worker     FString fullPathF;
1299*f6dc9357SAndroid Build Coastguard Worker     if (!NDir::MyGetFullPathName(GetPhyPath(i), fullPathF))
1300*f6dc9357SAndroid Build Coastguard Worker       continue;
1301*f6dc9357SAndroid Build Coastguard Worker     const UString fullPath = fs2us(fullPathF);
1302*f6dc9357SAndroid Build Coastguard Worker     const UString logPath = GetLogPath(i);
1303*f6dc9357SAndroid Build Coastguard Worker     if (logPath.Len() >= fullPath.Len())
1304*f6dc9357SAndroid Build Coastguard Worker       continue;
1305*f6dc9357SAndroid Build Coastguard Worker     if (CompareFileNames(logPath, fullPath.RightPtr(logPath.Len())) != 0)
1306*f6dc9357SAndroid Build Coastguard Worker       continue;
1307*f6dc9357SAndroid Build Coastguard Worker 
1308*f6dc9357SAndroid Build Coastguard Worker     const UString prefix = fullPath.Left(fullPath.Len() - logPath.Len());
1309*f6dc9357SAndroid Build Coastguard Worker     if (!IsPathSepar(prefix.Back()))
1310*f6dc9357SAndroid Build Coastguard Worker       continue;
1311*f6dc9357SAndroid Build Coastguard Worker 
1312*f6dc9357SAndroid Build Coastguard Worker     const unsigned rootPrefixSize = GetRootPrefixSize(prefix);
1313*f6dc9357SAndroid Build Coastguard Worker     if (rootPrefixSize == 0)
1314*f6dc9357SAndroid Build Coastguard Worker       continue;
1315*f6dc9357SAndroid Build Coastguard Worker     if (rootPrefixSize == prefix.Len())
1316*f6dc9357SAndroid Build Coastguard Worker       continue; // simple case: paths are from root
1317*f6dc9357SAndroid Build Coastguard Worker 
1318*f6dc9357SAndroid Build Coastguard Worker     if (link.Len() <= prefix.Len())
1319*f6dc9357SAndroid Build Coastguard Worker       continue;
1320*f6dc9357SAndroid Build Coastguard Worker 
1321*f6dc9357SAndroid Build Coastguard Worker     if (CompareFileNames(link.Left(prefix.Len()), prefix) != 0)
1322*f6dc9357SAndroid Build Coastguard Worker       continue;
1323*f6dc9357SAndroid Build Coastguard Worker 
1324*f6dc9357SAndroid Build Coastguard Worker     UString newLink = prefix.Left(rootPrefixSize);
1325*f6dc9357SAndroid Build Coastguard Worker     newLink += link.Ptr(prefix.Len());
1326*f6dc9357SAndroid Build Coastguard Worker 
1327*f6dc9357SAndroid Build Coastguard Worker     CByteBuffer data;
1328*f6dc9357SAndroid Build Coastguard Worker     bool isSymLink = !attr.IsMountPoint();
1329*f6dc9357SAndroid Build Coastguard Worker     if (!FillLinkData(data, newLink, isSymLink, isWSL))
1330*f6dc9357SAndroid Build Coastguard Worker       continue;
1331*f6dc9357SAndroid Build Coastguard Worker     item.ReparseData2 = data;
1332*f6dc9357SAndroid Build Coastguard Worker   }
1333*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1334*f6dc9357SAndroid Build Coastguard Worker }
1335*f6dc9357SAndroid Build Coastguard Worker 
1336*f6dc9357SAndroid Build Coastguard Worker #endif
1337*f6dc9357SAndroid Build Coastguard Worker 
1338*f6dc9357SAndroid Build Coastguard Worker 
1339*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
1340*f6dc9357SAndroid Build Coastguard Worker 
FillDeviceSizes()1341*f6dc9357SAndroid Build Coastguard Worker HRESULT CDirItems::FillDeviceSizes()
1342*f6dc9357SAndroid Build Coastguard Worker {
1343*f6dc9357SAndroid Build Coastguard Worker   {
1344*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, Items)
1345*f6dc9357SAndroid Build Coastguard Worker     {
1346*f6dc9357SAndroid Build Coastguard Worker       CDirItem &item = Items[i];
1347*f6dc9357SAndroid Build Coastguard Worker 
1348*f6dc9357SAndroid Build Coastguard Worker       if (S_ISBLK(item.mode) && item.Size == 0)
1349*f6dc9357SAndroid Build Coastguard Worker       {
1350*f6dc9357SAndroid Build Coastguard Worker         const FString phyPath = GetPhyPath(i);
1351*f6dc9357SAndroid Build Coastguard Worker         NIO::CInFile inFile;
1352*f6dc9357SAndroid Build Coastguard Worker         inFile.PreserveATime = true;
1353*f6dc9357SAndroid Build Coastguard Worker         if (inFile.OpenShared(phyPath, ShareForWrite)) // fixme: OpenShared ??
1354*f6dc9357SAndroid Build Coastguard Worker         {
1355*f6dc9357SAndroid Build Coastguard Worker           UInt64 size = 0;
1356*f6dc9357SAndroid Build Coastguard Worker           if (inFile.GetLength(size))
1357*f6dc9357SAndroid Build Coastguard Worker             item.Size = size;
1358*f6dc9357SAndroid Build Coastguard Worker         }
1359*f6dc9357SAndroid Build Coastguard Worker       }
1360*f6dc9357SAndroid Build Coastguard Worker       if (StoreOwnerName)
1361*f6dc9357SAndroid Build Coastguard Worker       {
1362*f6dc9357SAndroid Build Coastguard Worker         OwnerNameMap.Add_UInt32(item.uid);
1363*f6dc9357SAndroid Build Coastguard Worker         OwnerGroupMap.Add_UInt32(item.gid);
1364*f6dc9357SAndroid Build Coastguard Worker       }
1365*f6dc9357SAndroid Build Coastguard Worker     }
1366*f6dc9357SAndroid Build Coastguard Worker   }
1367*f6dc9357SAndroid Build Coastguard Worker 
1368*f6dc9357SAndroid Build Coastguard Worker   if (StoreOwnerName)
1369*f6dc9357SAndroid Build Coastguard Worker   {
1370*f6dc9357SAndroid Build Coastguard Worker     UString u;
1371*f6dc9357SAndroid Build Coastguard Worker     AString a;
1372*f6dc9357SAndroid Build Coastguard Worker     {
1373*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR (i, OwnerNameMap.Numbers)
1374*f6dc9357SAndroid Build Coastguard Worker       {
1375*f6dc9357SAndroid Build Coastguard Worker         // 200K/sec speed
1376*f6dc9357SAndroid Build Coastguard Worker         u.Empty();
1377*f6dc9357SAndroid Build Coastguard Worker         const passwd *pw = getpwuid(OwnerNameMap.Numbers[i]);
1378*f6dc9357SAndroid Build Coastguard Worker         // printf("\ngetpwuid=%s\n", pw->pw_name);
1379*f6dc9357SAndroid Build Coastguard Worker         if (pw)
1380*f6dc9357SAndroid Build Coastguard Worker         {
1381*f6dc9357SAndroid Build Coastguard Worker           a = pw->pw_name;
1382*f6dc9357SAndroid Build Coastguard Worker           ConvertUTF8ToUnicode(a, u);
1383*f6dc9357SAndroid Build Coastguard Worker         }
1384*f6dc9357SAndroid Build Coastguard Worker         OwnerNameMap.Strings.Add(u);
1385*f6dc9357SAndroid Build Coastguard Worker       }
1386*f6dc9357SAndroid Build Coastguard Worker     }
1387*f6dc9357SAndroid Build Coastguard Worker     {
1388*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR (i, OwnerGroupMap.Numbers)
1389*f6dc9357SAndroid Build Coastguard Worker       {
1390*f6dc9357SAndroid Build Coastguard Worker         u.Empty();
1391*f6dc9357SAndroid Build Coastguard Worker         const group *gr = getgrgid(OwnerGroupMap.Numbers[i]);
1392*f6dc9357SAndroid Build Coastguard Worker         if (gr)
1393*f6dc9357SAndroid Build Coastguard Worker         {
1394*f6dc9357SAndroid Build Coastguard Worker           // printf("\ngetgrgid %d %s\n", OwnerGroupMap.Numbers[i], gr->gr_name);
1395*f6dc9357SAndroid Build Coastguard Worker           a = gr->gr_name;
1396*f6dc9357SAndroid Build Coastguard Worker           ConvertUTF8ToUnicode(a, u);
1397*f6dc9357SAndroid Build Coastguard Worker         }
1398*f6dc9357SAndroid Build Coastguard Worker         OwnerGroupMap.Strings.Add(u);
1399*f6dc9357SAndroid Build Coastguard Worker       }
1400*f6dc9357SAndroid Build Coastguard Worker     }
1401*f6dc9357SAndroid Build Coastguard Worker 
1402*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, Items)
1403*f6dc9357SAndroid Build Coastguard Worker     {
1404*f6dc9357SAndroid Build Coastguard Worker       CDirItem &item = Items[i];
1405*f6dc9357SAndroid Build Coastguard Worker       {
1406*f6dc9357SAndroid Build Coastguard Worker         const int index = OwnerNameMap.Find(item.uid);
1407*f6dc9357SAndroid Build Coastguard Worker         if (index < 0) throw 1;
1408*f6dc9357SAndroid Build Coastguard Worker         item.OwnerNameIndex = index;
1409*f6dc9357SAndroid Build Coastguard Worker       }
1410*f6dc9357SAndroid Build Coastguard Worker       {
1411*f6dc9357SAndroid Build Coastguard Worker         const int index = OwnerGroupMap.Find(item.gid);
1412*f6dc9357SAndroid Build Coastguard Worker         if (index < 0) throw 1;
1413*f6dc9357SAndroid Build Coastguard Worker         item.OwnerGroupIndex = index;
1414*f6dc9357SAndroid Build Coastguard Worker       }
1415*f6dc9357SAndroid Build Coastguard Worker     }
1416*f6dc9357SAndroid Build Coastguard Worker   }
1417*f6dc9357SAndroid Build Coastguard Worker 
1418*f6dc9357SAndroid Build Coastguard Worker 
1419*f6dc9357SAndroid Build Coastguard Worker   // if (NeedOwnerNames)
1420*f6dc9357SAndroid Build Coastguard Worker   {
1421*f6dc9357SAndroid Build Coastguard Worker     /*
1422*f6dc9357SAndroid Build Coastguard Worker     {
1423*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0 ; i < 10000; i++)
1424*f6dc9357SAndroid Build Coastguard Worker       {
1425*f6dc9357SAndroid Build Coastguard Worker         const passwd *pw = getpwuid(i);
1426*f6dc9357SAndroid Build Coastguard Worker         if (pw)
1427*f6dc9357SAndroid Build Coastguard Worker         {
1428*f6dc9357SAndroid Build Coastguard Worker           UString u;
1429*f6dc9357SAndroid Build Coastguard Worker           ConvertUTF8ToUnicode(AString(pw->pw_name), u);
1430*f6dc9357SAndroid Build Coastguard Worker           OwnerNameMap.Add(i, u);
1431*f6dc9357SAndroid Build Coastguard Worker           OwnerNameMap.Add(i, u);
1432*f6dc9357SAndroid Build Coastguard Worker           OwnerNameMap.Add(i, u);
1433*f6dc9357SAndroid Build Coastguard Worker         }
1434*f6dc9357SAndroid Build Coastguard Worker         const group *gr = getgrgid(i);
1435*f6dc9357SAndroid Build Coastguard Worker         if (gr)
1436*f6dc9357SAndroid Build Coastguard Worker         {
1437*f6dc9357SAndroid Build Coastguard Worker           // we can use utf-8 here.
1438*f6dc9357SAndroid Build Coastguard Worker           UString u;
1439*f6dc9357SAndroid Build Coastguard Worker           ConvertUTF8ToUnicode(AString(gr->gr_name), u);
1440*f6dc9357SAndroid Build Coastguard Worker           OwnerGroupMap.Add(i, u);
1441*f6dc9357SAndroid Build Coastguard Worker         }
1442*f6dc9357SAndroid Build Coastguard Worker       }
1443*f6dc9357SAndroid Build Coastguard Worker     }
1444*f6dc9357SAndroid Build Coastguard Worker     */
1445*f6dc9357SAndroid Build Coastguard Worker     /*
1446*f6dc9357SAndroid Build Coastguard Worker     {
1447*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR (i, OwnerNameMap.Strings)
1448*f6dc9357SAndroid Build Coastguard Worker       {
1449*f6dc9357SAndroid Build Coastguard Worker         AString s;
1450*f6dc9357SAndroid Build Coastguard Worker         ConvertUnicodeToUTF8(OwnerNameMap.Strings[i], s);
1451*f6dc9357SAndroid Build Coastguard Worker         printf("\n%5d %s", (unsigned)OwnerNameMap.Numbers[i], s.Ptr());
1452*f6dc9357SAndroid Build Coastguard Worker       }
1453*f6dc9357SAndroid Build Coastguard Worker     }
1454*f6dc9357SAndroid Build Coastguard Worker     {
1455*f6dc9357SAndroid Build Coastguard Worker       printf("\n\n=========Groups\n");
1456*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR (i, OwnerGroupMap.Strings)
1457*f6dc9357SAndroid Build Coastguard Worker       {
1458*f6dc9357SAndroid Build Coastguard Worker         AString s;
1459*f6dc9357SAndroid Build Coastguard Worker         ConvertUnicodeToUTF8(OwnerGroupMap.Strings[i], s);
1460*f6dc9357SAndroid Build Coastguard Worker         printf("\n%5d %s", (unsigned)OwnerGroupMap.Numbers[i], s.Ptr());
1461*f6dc9357SAndroid Build Coastguard Worker       }
1462*f6dc9357SAndroid Build Coastguard Worker     }
1463*f6dc9357SAndroid Build Coastguard Worker     */
1464*f6dc9357SAndroid Build Coastguard Worker   }
1465*f6dc9357SAndroid Build Coastguard Worker       /*
1466*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0 ; i < 100000000; i++)
1467*f6dc9357SAndroid Build Coastguard Worker       {
1468*f6dc9357SAndroid Build Coastguard Worker         // const passwd *pw = getpwuid(1000);
1469*f6dc9357SAndroid Build Coastguard Worker         // pw = pw;
1470*f6dc9357SAndroid Build Coastguard Worker         int pos = OwnerNameMap.Find(1000);
1471*f6dc9357SAndroid Build Coastguard Worker         if (pos < 0 - (int)i)
1472*f6dc9357SAndroid Build Coastguard Worker           throw 1;
1473*f6dc9357SAndroid Build Coastguard Worker       }
1474*f6dc9357SAndroid Build Coastguard Worker       */
1475*f6dc9357SAndroid Build Coastguard Worker 
1476*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1477*f6dc9357SAndroid Build Coastguard Worker }
1478*f6dc9357SAndroid Build Coastguard Worker 
1479*f6dc9357SAndroid Build Coastguard Worker #endif
1480*f6dc9357SAndroid Build Coastguard Worker 
1481*f6dc9357SAndroid Build Coastguard Worker 
1482*f6dc9357SAndroid Build Coastguard Worker 
1483*f6dc9357SAndroid Build Coastguard Worker static const char * const kCannotFindArchive = "Cannot find archive";
1484*f6dc9357SAndroid Build Coastguard Worker 
EnumerateDirItemsAndSort(NWildcard::CCensor & censor,NWildcard::ECensorPathMode censorPathMode,const UString & addPathPrefix,UStringVector & sortedPaths,UStringVector & sortedFullPaths,CDirItemsStat & st,IDirItemsCallback * callback)1485*f6dc9357SAndroid Build Coastguard Worker HRESULT EnumerateDirItemsAndSort(
1486*f6dc9357SAndroid Build Coastguard Worker     NWildcard::CCensor &censor,
1487*f6dc9357SAndroid Build Coastguard Worker     NWildcard::ECensorPathMode censorPathMode,
1488*f6dc9357SAndroid Build Coastguard Worker     const UString &addPathPrefix,
1489*f6dc9357SAndroid Build Coastguard Worker     UStringVector &sortedPaths,
1490*f6dc9357SAndroid Build Coastguard Worker     UStringVector &sortedFullPaths,
1491*f6dc9357SAndroid Build Coastguard Worker     CDirItemsStat &st,
1492*f6dc9357SAndroid Build Coastguard Worker     IDirItemsCallback *callback)
1493*f6dc9357SAndroid Build Coastguard Worker {
1494*f6dc9357SAndroid Build Coastguard Worker   FStringVector paths;
1495*f6dc9357SAndroid Build Coastguard Worker 
1496*f6dc9357SAndroid Build Coastguard Worker   {
1497*f6dc9357SAndroid Build Coastguard Worker     CDirItems dirItems;
1498*f6dc9357SAndroid Build Coastguard Worker     dirItems.Callback = callback;
1499*f6dc9357SAndroid Build Coastguard Worker     {
1500*f6dc9357SAndroid Build Coastguard Worker       HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems);
1501*f6dc9357SAndroid Build Coastguard Worker       st = dirItems.Stat;
1502*f6dc9357SAndroid Build Coastguard Worker       RINOK(res)
1503*f6dc9357SAndroid Build Coastguard Worker     }
1504*f6dc9357SAndroid Build Coastguard Worker 
1505*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, dirItems.Items)
1506*f6dc9357SAndroid Build Coastguard Worker     {
1507*f6dc9357SAndroid Build Coastguard Worker       const CDirItem &dirItem = dirItems.Items[i];
1508*f6dc9357SAndroid Build Coastguard Worker       if (!dirItem.IsDir())
1509*f6dc9357SAndroid Build Coastguard Worker         paths.Add(dirItems.GetPhyPath(i));
1510*f6dc9357SAndroid Build Coastguard Worker     }
1511*f6dc9357SAndroid Build Coastguard Worker   }
1512*f6dc9357SAndroid Build Coastguard Worker 
1513*f6dc9357SAndroid Build Coastguard Worker   if (paths.Size() == 0)
1514*f6dc9357SAndroid Build Coastguard Worker   {
1515*f6dc9357SAndroid Build Coastguard Worker     // return S_OK;
1516*f6dc9357SAndroid Build Coastguard Worker     throw CMessagePathException(kCannotFindArchive);
1517*f6dc9357SAndroid Build Coastguard Worker   }
1518*f6dc9357SAndroid Build Coastguard Worker 
1519*f6dc9357SAndroid Build Coastguard Worker   UStringVector fullPaths;
1520*f6dc9357SAndroid Build Coastguard Worker 
1521*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
1522*f6dc9357SAndroid Build Coastguard Worker 
1523*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < paths.Size(); i++)
1524*f6dc9357SAndroid Build Coastguard Worker   {
1525*f6dc9357SAndroid Build Coastguard Worker     FString fullPath;
1526*f6dc9357SAndroid Build Coastguard Worker     NFile::NDir::MyGetFullPathName(paths[i], fullPath);
1527*f6dc9357SAndroid Build Coastguard Worker     fullPaths.Add(fs2us(fullPath));
1528*f6dc9357SAndroid Build Coastguard Worker   }
1529*f6dc9357SAndroid Build Coastguard Worker 
1530*f6dc9357SAndroid Build Coastguard Worker   CUIntVector indices;
1531*f6dc9357SAndroid Build Coastguard Worker   SortFileNames(fullPaths, indices);
1532*f6dc9357SAndroid Build Coastguard Worker   sortedPaths.ClearAndReserve(indices.Size());
1533*f6dc9357SAndroid Build Coastguard Worker   sortedFullPaths.ClearAndReserve(indices.Size());
1534*f6dc9357SAndroid Build Coastguard Worker 
1535*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < indices.Size(); i++)
1536*f6dc9357SAndroid Build Coastguard Worker   {
1537*f6dc9357SAndroid Build Coastguard Worker     unsigned index = indices[i];
1538*f6dc9357SAndroid Build Coastguard Worker     sortedPaths.AddInReserved(fs2us(paths[index]));
1539*f6dc9357SAndroid Build Coastguard Worker     sortedFullPaths.AddInReserved(fullPaths[index]);
1540*f6dc9357SAndroid Build Coastguard Worker     if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
1541*f6dc9357SAndroid Build Coastguard Worker       throw CMessagePathException("Duplicate archive path:", sortedFullPaths[i]);
1542*f6dc9357SAndroid Build Coastguard Worker   }
1543*f6dc9357SAndroid Build Coastguard Worker 
1544*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1545*f6dc9357SAndroid Build Coastguard Worker }
1546*f6dc9357SAndroid Build Coastguard Worker 
1547*f6dc9357SAndroid Build Coastguard Worker 
1548*f6dc9357SAndroid Build Coastguard Worker 
1549*f6dc9357SAndroid Build Coastguard Worker 
1550*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
1551*f6dc9357SAndroid Build Coastguard Worker 
IsDotsName(const wchar_t * s)1552*f6dc9357SAndroid Build Coastguard Worker static bool IsDotsName(const wchar_t *s)
1553*f6dc9357SAndroid Build Coastguard Worker {
1554*f6dc9357SAndroid Build Coastguard Worker   return s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0));
1555*f6dc9357SAndroid Build Coastguard Worker }
1556*f6dc9357SAndroid Build Coastguard Worker 
1557*f6dc9357SAndroid Build Coastguard Worker // This code converts all short file names to long file names.
1558*f6dc9357SAndroid Build Coastguard Worker 
ConvertToLongName(const UString & prefix,UString & name)1559*f6dc9357SAndroid Build Coastguard Worker static void ConvertToLongName(const UString &prefix, UString &name)
1560*f6dc9357SAndroid Build Coastguard Worker {
1561*f6dc9357SAndroid Build Coastguard Worker   if (name.IsEmpty()
1562*f6dc9357SAndroid Build Coastguard Worker       || DoesNameContainWildcard(name)
1563*f6dc9357SAndroid Build Coastguard Worker       || IsDotsName(name))
1564*f6dc9357SAndroid Build Coastguard Worker     return;
1565*f6dc9357SAndroid Build Coastguard Worker   NFind::CFileInfo fi;
1566*f6dc9357SAndroid Build Coastguard Worker   const FString path (us2fs(prefix + name));
1567*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
1568*f6dc9357SAndroid Build Coastguard Worker   if (NFile::NName::IsDevicePath(path))
1569*f6dc9357SAndroid Build Coastguard Worker     return;
1570*f6dc9357SAndroid Build Coastguard Worker   #endif
1571*f6dc9357SAndroid Build Coastguard Worker   if (fi.Find(path))
1572*f6dc9357SAndroid Build Coastguard Worker     name = fs2us(fi.Name);
1573*f6dc9357SAndroid Build Coastguard Worker }
1574*f6dc9357SAndroid Build Coastguard Worker 
ConvertToLongNames(const UString & prefix,CObjectVector<NWildcard::CItem> & items)1575*f6dc9357SAndroid Build Coastguard Worker static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
1576*f6dc9357SAndroid Build Coastguard Worker {
1577*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, items)
1578*f6dc9357SAndroid Build Coastguard Worker   {
1579*f6dc9357SAndroid Build Coastguard Worker     NWildcard::CItem &item = items[i];
1580*f6dc9357SAndroid Build Coastguard Worker     if (item.Recursive || item.PathParts.Size() != 1)
1581*f6dc9357SAndroid Build Coastguard Worker       continue;
1582*f6dc9357SAndroid Build Coastguard Worker     if (prefix.IsEmpty() && item.IsDriveItem())
1583*f6dc9357SAndroid Build Coastguard Worker       continue;
1584*f6dc9357SAndroid Build Coastguard Worker     ConvertToLongName(prefix, item.PathParts.Front());
1585*f6dc9357SAndroid Build Coastguard Worker   }
1586*f6dc9357SAndroid Build Coastguard Worker }
1587*f6dc9357SAndroid Build Coastguard Worker 
ConvertToLongNames(const UString & prefix,NWildcard::CCensorNode & node)1588*f6dc9357SAndroid Build Coastguard Worker static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
1589*f6dc9357SAndroid Build Coastguard Worker {
1590*f6dc9357SAndroid Build Coastguard Worker   ConvertToLongNames(prefix, node.IncludeItems);
1591*f6dc9357SAndroid Build Coastguard Worker   ConvertToLongNames(prefix, node.ExcludeItems);
1592*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
1593*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < node.SubNodes.Size(); i++)
1594*f6dc9357SAndroid Build Coastguard Worker   {
1595*f6dc9357SAndroid Build Coastguard Worker     UString &name = node.SubNodes[i].Name;
1596*f6dc9357SAndroid Build Coastguard Worker     if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name))
1597*f6dc9357SAndroid Build Coastguard Worker       continue;
1598*f6dc9357SAndroid Build Coastguard Worker     ConvertToLongName(prefix, name);
1599*f6dc9357SAndroid Build Coastguard Worker   }
1600*f6dc9357SAndroid Build Coastguard Worker   // mix folders with same name
1601*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < node.SubNodes.Size(); i++)
1602*f6dc9357SAndroid Build Coastguard Worker   {
1603*f6dc9357SAndroid Build Coastguard Worker     NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
1604*f6dc9357SAndroid Build Coastguard Worker     for (unsigned j = i + 1; j < node.SubNodes.Size();)
1605*f6dc9357SAndroid Build Coastguard Worker     {
1606*f6dc9357SAndroid Build Coastguard Worker       const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
1607*f6dc9357SAndroid Build Coastguard Worker       if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name))
1608*f6dc9357SAndroid Build Coastguard Worker       {
1609*f6dc9357SAndroid Build Coastguard Worker         nextNode1.IncludeItems += nextNode2.IncludeItems;
1610*f6dc9357SAndroid Build Coastguard Worker         nextNode1.ExcludeItems += nextNode2.ExcludeItems;
1611*f6dc9357SAndroid Build Coastguard Worker         node.SubNodes.Delete(j);
1612*f6dc9357SAndroid Build Coastguard Worker       }
1613*f6dc9357SAndroid Build Coastguard Worker       else
1614*f6dc9357SAndroid Build Coastguard Worker         j++;
1615*f6dc9357SAndroid Build Coastguard Worker     }
1616*f6dc9357SAndroid Build Coastguard Worker   }
1617*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < node.SubNodes.Size(); i++)
1618*f6dc9357SAndroid Build Coastguard Worker   {
1619*f6dc9357SAndroid Build Coastguard Worker     NWildcard::CCensorNode &nextNode = node.SubNodes[i];
1620*f6dc9357SAndroid Build Coastguard Worker     ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
1621*f6dc9357SAndroid Build Coastguard Worker   }
1622*f6dc9357SAndroid Build Coastguard Worker }
1623*f6dc9357SAndroid Build Coastguard Worker 
ConvertToLongNames(NWildcard::CCensor & censor)1624*f6dc9357SAndroid Build Coastguard Worker void ConvertToLongNames(NWildcard::CCensor &censor)
1625*f6dc9357SAndroid Build Coastguard Worker {
1626*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, censor.Pairs)
1627*f6dc9357SAndroid Build Coastguard Worker   {
1628*f6dc9357SAndroid Build Coastguard Worker     NWildcard::CPair &pair = censor.Pairs[i];
1629*f6dc9357SAndroid Build Coastguard Worker     ConvertToLongNames(pair.Prefix, pair.Head);
1630*f6dc9357SAndroid Build Coastguard Worker   }
1631*f6dc9357SAndroid Build Coastguard Worker }
1632*f6dc9357SAndroid Build Coastguard Worker 
1633*f6dc9357SAndroid Build Coastguard Worker #endif
1634*f6dc9357SAndroid Build Coastguard Worker 
1635*f6dc9357SAndroid Build Coastguard Worker 
CMessagePathException(const char * a,const wchar_t * u)1636*f6dc9357SAndroid Build Coastguard Worker CMessagePathException::CMessagePathException(const char *a, const wchar_t *u)
1637*f6dc9357SAndroid Build Coastguard Worker {
1638*f6dc9357SAndroid Build Coastguard Worker   (*this) += a;
1639*f6dc9357SAndroid Build Coastguard Worker   if (u)
1640*f6dc9357SAndroid Build Coastguard Worker   {
1641*f6dc9357SAndroid Build Coastguard Worker     Add_LF();
1642*f6dc9357SAndroid Build Coastguard Worker     (*this) += u;
1643*f6dc9357SAndroid Build Coastguard Worker   }
1644*f6dc9357SAndroid Build Coastguard Worker }
1645*f6dc9357SAndroid Build Coastguard Worker 
CMessagePathException(const wchar_t * a,const wchar_t * u)1646*f6dc9357SAndroid Build Coastguard Worker CMessagePathException::CMessagePathException(const wchar_t *a, const wchar_t *u)
1647*f6dc9357SAndroid Build Coastguard Worker {
1648*f6dc9357SAndroid Build Coastguard Worker   (*this) += a;
1649*f6dc9357SAndroid Build Coastguard Worker   if (u)
1650*f6dc9357SAndroid Build Coastguard Worker   {
1651*f6dc9357SAndroid Build Coastguard Worker     Add_LF();
1652*f6dc9357SAndroid Build Coastguard Worker     (*this) += u;
1653*f6dc9357SAndroid Build Coastguard Worker   }
1654*f6dc9357SAndroid Build Coastguard Worker }
1655