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