xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/FSFolder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // FSFolder.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #ifdef __MINGW32_VERSION
6*f6dc9357SAndroid Build Coastguard Worker // #if !defined(_MSC_VER) && (__GNUC__) && (__GNUC__ < 10)
7*f6dc9357SAndroid Build Coastguard Worker // for old mingw
8*f6dc9357SAndroid Build Coastguard Worker #include <ddk/ntddk.h>
9*f6dc9357SAndroid Build Coastguard Worker #else
10*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_OLD_WIN_SDK
11*f6dc9357SAndroid Build Coastguard Worker   #if !defined(_M_IA64)
12*f6dc9357SAndroid Build Coastguard Worker     #include <winternl.h>
13*f6dc9357SAndroid Build Coastguard Worker   #endif
14*f6dc9357SAndroid Build Coastguard Worker #else
15*f6dc9357SAndroid Build Coastguard Worker typedef LONG NTSTATUS;
16*f6dc9357SAndroid Build Coastguard Worker typedef struct _IO_STATUS_BLOCK {
17*f6dc9357SAndroid Build Coastguard Worker     union {
18*f6dc9357SAndroid Build Coastguard Worker         NTSTATUS Status;
19*f6dc9357SAndroid Build Coastguard Worker         PVOID Pointer;
20*f6dc9357SAndroid Build Coastguard Worker     };
21*f6dc9357SAndroid Build Coastguard Worker     ULONG_PTR Information;
22*f6dc9357SAndroid Build Coastguard Worker } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
23*f6dc9357SAndroid Build Coastguard Worker #endif
24*f6dc9357SAndroid Build Coastguard Worker #endif
25*f6dc9357SAndroid Build Coastguard Worker 
26*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
27*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Defs.h"
28*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
29*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/UTFConvert.h"
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/DLL.h"
32*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
33*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileIO.h"
34*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
35*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker #include "../../PropID.h"
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker #include "FSDrives.h"
40*f6dc9357SAndroid Build Coastguard Worker #include "FSFolder.h"
41*f6dc9357SAndroid Build Coastguard Worker 
42*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
43*f6dc9357SAndroid Build Coastguard Worker #include "NetFolder.h"
44*f6dc9357SAndroid Build Coastguard Worker #endif
45*f6dc9357SAndroid Build Coastguard Worker 
46*f6dc9357SAndroid Build Coastguard Worker #include "SysIconUtils.h"
47*f6dc9357SAndroid Build Coastguard Worker 
48*f6dc9357SAndroid Build Coastguard Worker #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0501
49*f6dc9357SAndroid Build Coastguard Worker #ifdef _APISETFILE_
50*f6dc9357SAndroid Build Coastguard Worker // Windows SDK 8.1 defines in fileapi.h the function GetCompressedFileSizeW only if _WIN32_WINNT >= 0x0501
51*f6dc9357SAndroid Build Coastguard Worker // But real support version for that function is NT 3.1 (probably)
52*f6dc9357SAndroid Build Coastguard Worker // So we must define GetCompressedFileSizeW
53*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
54*f6dc9357SAndroid Build Coastguard Worker WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh);
55*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
56*f6dc9357SAndroid Build Coastguard Worker #endif
57*f6dc9357SAndroid Build Coastguard Worker #endif
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
60*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
61*f6dc9357SAndroid Build Coastguard Worker using namespace NFind;
62*f6dc9357SAndroid Build Coastguard Worker using namespace NDir;
63*f6dc9357SAndroid Build Coastguard Worker using namespace NName;
64*f6dc9357SAndroid Build Coastguard Worker 
65*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
66*f6dc9357SAndroid Build Coastguard Worker int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2);
CompareFileNames_ForFolderList(const FChar * s1,const FChar * s2)67*f6dc9357SAndroid Build Coastguard Worker int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2)
68*f6dc9357SAndroid Build Coastguard Worker {
69*f6dc9357SAndroid Build Coastguard Worker   return CompareFileNames_ForFolderList(fs2us(s1), fs2us(s2));
70*f6dc9357SAndroid Build Coastguard Worker }
71*f6dc9357SAndroid Build Coastguard Worker #endif
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker namespace NFsFolder {
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
76*f6dc9357SAndroid Build Coastguard Worker {
77*f6dc9357SAndroid Build Coastguard Worker   kpidName,
78*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
79*f6dc9357SAndroid Build Coastguard Worker   kpidMTime,
80*f6dc9357SAndroid Build Coastguard Worker   kpidCTime,
81*f6dc9357SAndroid Build Coastguard Worker   kpidATime,
82*f6dc9357SAndroid Build Coastguard Worker  #ifdef FS_SHOW_LINKS_INFO
83*f6dc9357SAndroid Build Coastguard Worker   kpidChangeTime,
84*f6dc9357SAndroid Build Coastguard Worker  #endif
85*f6dc9357SAndroid Build Coastguard Worker   kpidAttrib,
86*f6dc9357SAndroid Build Coastguard Worker   kpidPackSize,
87*f6dc9357SAndroid Build Coastguard Worker  #ifdef FS_SHOW_LINKS_INFO
88*f6dc9357SAndroid Build Coastguard Worker   kpidINode,
89*f6dc9357SAndroid Build Coastguard Worker   kpidLinks,
90*f6dc9357SAndroid Build Coastguard Worker  #endif
91*f6dc9357SAndroid Build Coastguard Worker   kpidComment,
92*f6dc9357SAndroid Build Coastguard Worker   kpidNumSubDirs,
93*f6dc9357SAndroid Build Coastguard Worker   kpidNumSubFiles,
94*f6dc9357SAndroid Build Coastguard Worker   kpidPrefix
95*f6dc9357SAndroid Build Coastguard Worker };
96*f6dc9357SAndroid Build Coastguard Worker 
Init(const FString & path)97*f6dc9357SAndroid Build Coastguard Worker HRESULT CFSFolder::Init(const FString &path /* , IFolderFolder *parentFolder */)
98*f6dc9357SAndroid Build Coastguard Worker {
99*f6dc9357SAndroid Build Coastguard Worker   // _parentFolder = parentFolder;
100*f6dc9357SAndroid Build Coastguard Worker   _path = path;
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker   _findChangeNotification.FindFirst(_path, false,
105*f6dc9357SAndroid Build Coastguard Worker         FILE_NOTIFY_CHANGE_FILE_NAME
106*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_DIR_NAME
107*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_ATTRIBUTES
108*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_SIZE
109*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_LAST_WRITE
110*f6dc9357SAndroid Build Coastguard Worker       /*
111*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_LAST_ACCESS
112*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_CREATION
113*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_SECURITY
114*f6dc9357SAndroid Build Coastguard Worker       */
115*f6dc9357SAndroid Build Coastguard Worker       );
116*f6dc9357SAndroid Build Coastguard Worker 
117*f6dc9357SAndroid Build Coastguard Worker   if (!_findChangeNotification.IsHandleAllocated())
118*f6dc9357SAndroid Build Coastguard Worker   {
119*f6dc9357SAndroid Build Coastguard Worker     const HRESULT lastError = GetLastError_noZero_HRESULT();
120*f6dc9357SAndroid Build Coastguard Worker     CFindFile findFile;
121*f6dc9357SAndroid Build Coastguard Worker     CFileInfo fi;
122*f6dc9357SAndroid Build Coastguard Worker     FString path2 = _path;
123*f6dc9357SAndroid Build Coastguard Worker     path2.Add_Char('*'); // CHAR_ANY_MASK;
124*f6dc9357SAndroid Build Coastguard Worker     if (!findFile.FindFirst(path2, fi))
125*f6dc9357SAndroid Build Coastguard Worker       return lastError;
126*f6dc9357SAndroid Build Coastguard Worker   }
127*f6dc9357SAndroid Build Coastguard Worker 
128*f6dc9357SAndroid Build Coastguard Worker   #endif
129*f6dc9357SAndroid Build Coastguard Worker 
130*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
131*f6dc9357SAndroid Build Coastguard Worker }
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker 
Enumerate()134*f6dc9357SAndroid Build Coastguard Worker HRESULT CFsFolderStat::Enumerate()
135*f6dc9357SAndroid Build Coastguard Worker {
136*f6dc9357SAndroid Build Coastguard Worker   if (Progress)
137*f6dc9357SAndroid Build Coastguard Worker   {
138*f6dc9357SAndroid Build Coastguard Worker     RINOK(Progress->SetCompleted(NULL))
139*f6dc9357SAndroid Build Coastguard Worker   }
140*f6dc9357SAndroid Build Coastguard Worker   Path.Add_PathSepar();
141*f6dc9357SAndroid Build Coastguard Worker   const unsigned len = Path.Len();
142*f6dc9357SAndroid Build Coastguard Worker   CEnumerator enumerator;
143*f6dc9357SAndroid Build Coastguard Worker   enumerator.SetDirPrefix(Path);
144*f6dc9357SAndroid Build Coastguard Worker   CDirEntry fi;
145*f6dc9357SAndroid Build Coastguard Worker   while (enumerator.Next(fi))
146*f6dc9357SAndroid Build Coastguard Worker   {
147*f6dc9357SAndroid Build Coastguard Worker     if (fi.IsDir())
148*f6dc9357SAndroid Build Coastguard Worker     {
149*f6dc9357SAndroid Build Coastguard Worker       NumFolders++;
150*f6dc9357SAndroid Build Coastguard Worker       Path.DeleteFrom(len);
151*f6dc9357SAndroid Build Coastguard Worker       Path += fi.Name;
152*f6dc9357SAndroid Build Coastguard Worker       RINOK(Enumerate())
153*f6dc9357SAndroid Build Coastguard Worker     }
154*f6dc9357SAndroid Build Coastguard Worker     else
155*f6dc9357SAndroid Build Coastguard Worker     {
156*f6dc9357SAndroid Build Coastguard Worker       NumFiles++;
157*f6dc9357SAndroid Build Coastguard Worker       Size += fi.Size;
158*f6dc9357SAndroid Build Coastguard Worker     }
159*f6dc9357SAndroid Build Coastguard Worker   }
160*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
161*f6dc9357SAndroid Build Coastguard Worker }
162*f6dc9357SAndroid Build Coastguard Worker 
163*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size);
MyGetCompressedFileSizeW(CFSTR path,UInt64 & size)166*f6dc9357SAndroid Build Coastguard Worker bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
167*f6dc9357SAndroid Build Coastguard Worker {
168*f6dc9357SAndroid Build Coastguard Worker   DWORD highPart;
169*f6dc9357SAndroid Build Coastguard Worker   DWORD lowPart = INVALID_FILE_SIZE;
170*f6dc9357SAndroid Build Coastguard Worker   IF_USE_MAIN_PATH
171*f6dc9357SAndroid Build Coastguard Worker   {
172*f6dc9357SAndroid Build Coastguard Worker     lowPart = ::GetCompressedFileSizeW(fs2us(path), &highPart);
173*f6dc9357SAndroid Build Coastguard Worker     if (lowPart != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR)
174*f6dc9357SAndroid Build Coastguard Worker     {
175*f6dc9357SAndroid Build Coastguard Worker       size = ((UInt64)highPart << 32) | lowPart;
176*f6dc9357SAndroid Build Coastguard Worker       return true;
177*f6dc9357SAndroid Build Coastguard Worker     }
178*f6dc9357SAndroid Build Coastguard Worker   }
179*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_LONG_PATH
180*f6dc9357SAndroid Build Coastguard Worker   if (USE_SUPER_PATH)
181*f6dc9357SAndroid Build Coastguard Worker   {
182*f6dc9357SAndroid Build Coastguard Worker     UString superPath;
183*f6dc9357SAndroid Build Coastguard Worker     if (GetSuperPath(path, superPath, USE_MAIN_PATH))
184*f6dc9357SAndroid Build Coastguard Worker     {
185*f6dc9357SAndroid Build Coastguard Worker       lowPart = ::GetCompressedFileSizeW(superPath, &highPart);
186*f6dc9357SAndroid Build Coastguard Worker       if (lowPart != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR)
187*f6dc9357SAndroid Build Coastguard Worker       {
188*f6dc9357SAndroid Build Coastguard Worker         size = ((UInt64)highPart << 32) | lowPart;
189*f6dc9357SAndroid Build Coastguard Worker         return true;
190*f6dc9357SAndroid Build Coastguard Worker       }
191*f6dc9357SAndroid Build Coastguard Worker     }
192*f6dc9357SAndroid Build Coastguard Worker   }
193*f6dc9357SAndroid Build Coastguard Worker   #endif
194*f6dc9357SAndroid Build Coastguard Worker   return false;
195*f6dc9357SAndroid Build Coastguard Worker }
196*f6dc9357SAndroid Build Coastguard Worker 
197*f6dc9357SAndroid Build Coastguard Worker #endif
198*f6dc9357SAndroid Build Coastguard Worker 
LoadSubItems(int dirItem,const FString & relPrefix)199*f6dc9357SAndroid Build Coastguard Worker HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix)
200*f6dc9357SAndroid Build Coastguard Worker {
201*f6dc9357SAndroid Build Coastguard Worker   const unsigned startIndex = Folders.Size();
202*f6dc9357SAndroid Build Coastguard Worker   {
203*f6dc9357SAndroid Build Coastguard Worker     CEnumerator enumerator;
204*f6dc9357SAndroid Build Coastguard Worker     enumerator.SetDirPrefix(_path + relPrefix);
205*f6dc9357SAndroid Build Coastguard Worker     CDirItem fi;
206*f6dc9357SAndroid Build Coastguard Worker     fi.FolderStat_Defined = false;
207*f6dc9357SAndroid Build Coastguard Worker     fi.NumFolders = 0;
208*f6dc9357SAndroid Build Coastguard Worker     fi.NumFiles = 0;
209*f6dc9357SAndroid Build Coastguard Worker     fi.Parent = dirItem;
210*f6dc9357SAndroid Build Coastguard Worker 
211*f6dc9357SAndroid Build Coastguard Worker     while (enumerator.Next(fi))
212*f6dc9357SAndroid Build Coastguard Worker     {
213*f6dc9357SAndroid Build Coastguard Worker       if (fi.IsDir())
214*f6dc9357SAndroid Build Coastguard Worker       {
215*f6dc9357SAndroid Build Coastguard Worker         fi.Size = 0;
216*f6dc9357SAndroid Build Coastguard Worker         if (_flatMode)
217*f6dc9357SAndroid Build Coastguard Worker           Folders.Add(relPrefix + fi.Name + FCHAR_PATH_SEPARATOR);
218*f6dc9357SAndroid Build Coastguard Worker       }
219*f6dc9357SAndroid Build Coastguard Worker       else
220*f6dc9357SAndroid Build Coastguard Worker       {
221*f6dc9357SAndroid Build Coastguard Worker         /*
222*f6dc9357SAndroid Build Coastguard Worker         fi.PackSize_Defined = true;
223*f6dc9357SAndroid Build Coastguard Worker         if (!MyGetCompressedFileSizeW(_path + relPrefix + fi.Name, fi.PackSize))
224*f6dc9357SAndroid Build Coastguard Worker           fi.PackSize = fi.Size;
225*f6dc9357SAndroid Build Coastguard Worker         */
226*f6dc9357SAndroid Build Coastguard Worker       }
227*f6dc9357SAndroid Build Coastguard Worker 
228*f6dc9357SAndroid Build Coastguard Worker      #ifndef UNDER_CE
229*f6dc9357SAndroid Build Coastguard Worker 
230*f6dc9357SAndroid Build Coastguard Worker       fi.Reparse.Free();
231*f6dc9357SAndroid Build Coastguard Worker       fi.PackSize_Defined = false;
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker      #ifdef FS_SHOW_LINKS_INFO
234*f6dc9357SAndroid Build Coastguard Worker       fi.FileInfo_Defined = false;
235*f6dc9357SAndroid Build Coastguard Worker       fi.FileInfo_WasRequested = false;
236*f6dc9357SAndroid Build Coastguard Worker       fi.FileIndex = 0;
237*f6dc9357SAndroid Build Coastguard Worker       fi.NumLinks = 0;
238*f6dc9357SAndroid Build Coastguard Worker       fi.ChangeTime_Defined = false;
239*f6dc9357SAndroid Build Coastguard Worker       fi.ChangeTime_WasRequested = false;
240*f6dc9357SAndroid Build Coastguard Worker      #endif
241*f6dc9357SAndroid Build Coastguard Worker 
242*f6dc9357SAndroid Build Coastguard Worker       fi.PackSize = fi.Size;
243*f6dc9357SAndroid Build Coastguard Worker 
244*f6dc9357SAndroid Build Coastguard Worker      #ifdef FS_SHOW_LINKS_INFO
245*f6dc9357SAndroid Build Coastguard Worker       if (fi.HasReparsePoint())
246*f6dc9357SAndroid Build Coastguard Worker       {
247*f6dc9357SAndroid Build Coastguard Worker         fi.FileInfo_WasRequested = true;
248*f6dc9357SAndroid Build Coastguard Worker         BY_HANDLE_FILE_INFORMATION info;
249*f6dc9357SAndroid Build Coastguard Worker         NIO::GetReparseData(_path + relPrefix + fi.Name, fi.Reparse, &info);
250*f6dc9357SAndroid Build Coastguard Worker         fi.NumLinks = info.nNumberOfLinks;
251*f6dc9357SAndroid Build Coastguard Worker         fi.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
252*f6dc9357SAndroid Build Coastguard Worker         fi.FileInfo_Defined = true;
253*f6dc9357SAndroid Build Coastguard Worker       }
254*f6dc9357SAndroid Build Coastguard Worker      #endif
255*f6dc9357SAndroid Build Coastguard Worker 
256*f6dc9357SAndroid Build Coastguard Worker      #endif // UNDER_CE
257*f6dc9357SAndroid Build Coastguard Worker 
258*f6dc9357SAndroid Build Coastguard Worker       /* unsigned fileIndex = */ Files.Add(fi);
259*f6dc9357SAndroid Build Coastguard Worker 
260*f6dc9357SAndroid Build Coastguard Worker       #if defined(_WIN32) && !defined(UNDER_CE)
261*f6dc9357SAndroid Build Coastguard Worker       /*
262*f6dc9357SAndroid Build Coastguard Worker       if (_scanAltStreams)
263*f6dc9357SAndroid Build Coastguard Worker       {
264*f6dc9357SAndroid Build Coastguard Worker         CStreamEnumerator enumerator(_path + relPrefix + fi.Name);
265*f6dc9357SAndroid Build Coastguard Worker         CStreamInfo si;
266*f6dc9357SAndroid Build Coastguard Worker         for (;;)
267*f6dc9357SAndroid Build Coastguard Worker         {
268*f6dc9357SAndroid Build Coastguard Worker           bool found;
269*f6dc9357SAndroid Build Coastguard Worker           if (!enumerator.Next(si, found))
270*f6dc9357SAndroid Build Coastguard Worker           {
271*f6dc9357SAndroid Build Coastguard Worker             // if (GetLastError() == ERROR_ACCESS_DENIED)
272*f6dc9357SAndroid Build Coastguard Worker             //   break;
273*f6dc9357SAndroid Build Coastguard Worker             // return E_FAIL;
274*f6dc9357SAndroid Build Coastguard Worker             break;
275*f6dc9357SAndroid Build Coastguard Worker           }
276*f6dc9357SAndroid Build Coastguard Worker           if (!found)
277*f6dc9357SAndroid Build Coastguard Worker             break;
278*f6dc9357SAndroid Build Coastguard Worker           if (si.IsMainStream())
279*f6dc9357SAndroid Build Coastguard Worker             continue;
280*f6dc9357SAndroid Build Coastguard Worker           CAltStream ss;
281*f6dc9357SAndroid Build Coastguard Worker           ss.Parent = fileIndex;
282*f6dc9357SAndroid Build Coastguard Worker           ss.Name = si.GetReducedName();
283*f6dc9357SAndroid Build Coastguard Worker           ss.Size = si.Size;
284*f6dc9357SAndroid Build Coastguard Worker           ss.PackSize_Defined = false;
285*f6dc9357SAndroid Build Coastguard Worker           ss.PackSize = si.Size;
286*f6dc9357SAndroid Build Coastguard Worker           Streams.Add(ss);
287*f6dc9357SAndroid Build Coastguard Worker         }
288*f6dc9357SAndroid Build Coastguard Worker       }
289*f6dc9357SAndroid Build Coastguard Worker       */
290*f6dc9357SAndroid Build Coastguard Worker       #endif
291*f6dc9357SAndroid Build Coastguard Worker     }
292*f6dc9357SAndroid Build Coastguard Worker   }
293*f6dc9357SAndroid Build Coastguard Worker   if (!_flatMode)
294*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
295*f6dc9357SAndroid Build Coastguard Worker 
296*f6dc9357SAndroid Build Coastguard Worker   const unsigned endIndex = Folders.Size();
297*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = startIndex; i < endIndex; i++)
298*f6dc9357SAndroid Build Coastguard Worker     LoadSubItems((int)i, Folders[i]);
299*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
300*f6dc9357SAndroid Build Coastguard Worker }
301*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::LoadItems ())302*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::LoadItems())
303*f6dc9357SAndroid Build Coastguard Worker {
304*f6dc9357SAndroid Build Coastguard Worker   Int32 dummy;
305*f6dc9357SAndroid Build Coastguard Worker   WasChanged(&dummy);
306*f6dc9357SAndroid Build Coastguard Worker   Clear();
307*f6dc9357SAndroid Build Coastguard Worker   RINOK(LoadSubItems(-1, FString()))
308*f6dc9357SAndroid Build Coastguard Worker   _commentsAreLoaded = false;
309*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
310*f6dc9357SAndroid Build Coastguard Worker }
311*f6dc9357SAndroid Build Coastguard Worker 
312*f6dc9357SAndroid Build Coastguard Worker static CFSTR const kDescriptionFileName = FTEXT("descript.ion");
313*f6dc9357SAndroid Build Coastguard Worker 
LoadComments()314*f6dc9357SAndroid Build Coastguard Worker bool CFSFolder::LoadComments()
315*f6dc9357SAndroid Build Coastguard Worker {
316*f6dc9357SAndroid Build Coastguard Worker   _comments.Clear();
317*f6dc9357SAndroid Build Coastguard Worker   _commentsAreLoaded = true;
318*f6dc9357SAndroid Build Coastguard Worker   NIO::CInFile file;
319*f6dc9357SAndroid Build Coastguard Worker   if (!file.Open(_path + kDescriptionFileName))
320*f6dc9357SAndroid Build Coastguard Worker     return false;
321*f6dc9357SAndroid Build Coastguard Worker   UInt64 len;
322*f6dc9357SAndroid Build Coastguard Worker   if (!file.GetLength(len))
323*f6dc9357SAndroid Build Coastguard Worker     return false;
324*f6dc9357SAndroid Build Coastguard Worker   if (len >= (1 << 28))
325*f6dc9357SAndroid Build Coastguard Worker     return false;
326*f6dc9357SAndroid Build Coastguard Worker   AString s;
327*f6dc9357SAndroid Build Coastguard Worker   char *p = s.GetBuf((unsigned)(size_t)len);
328*f6dc9357SAndroid Build Coastguard Worker   size_t processedSize;
329*f6dc9357SAndroid Build Coastguard Worker   if (!file.ReadFull(p, (unsigned)(size_t)len, processedSize))
330*f6dc9357SAndroid Build Coastguard Worker     return false;
331*f6dc9357SAndroid Build Coastguard Worker   s.ReleaseBuf_CalcLen((unsigned)(size_t)len);
332*f6dc9357SAndroid Build Coastguard Worker   if (processedSize != len)
333*f6dc9357SAndroid Build Coastguard Worker     return false;
334*f6dc9357SAndroid Build Coastguard Worker   file.Close();
335*f6dc9357SAndroid Build Coastguard Worker   UString unicodeString;
336*f6dc9357SAndroid Build Coastguard Worker   if (!ConvertUTF8ToUnicode(s, unicodeString))
337*f6dc9357SAndroid Build Coastguard Worker     return false;
338*f6dc9357SAndroid Build Coastguard Worker   return _comments.ReadFromString(unicodeString);
339*f6dc9357SAndroid Build Coastguard Worker }
340*f6dc9357SAndroid Build Coastguard Worker 
SaveComments()341*f6dc9357SAndroid Build Coastguard Worker bool CFSFolder::SaveComments()
342*f6dc9357SAndroid Build Coastguard Worker {
343*f6dc9357SAndroid Build Coastguard Worker   AString utf;
344*f6dc9357SAndroid Build Coastguard Worker   {
345*f6dc9357SAndroid Build Coastguard Worker     UString unicode;
346*f6dc9357SAndroid Build Coastguard Worker     _comments.SaveToString(unicode);
347*f6dc9357SAndroid Build Coastguard Worker     ConvertUnicodeToUTF8(unicode, utf);
348*f6dc9357SAndroid Build Coastguard Worker   }
349*f6dc9357SAndroid Build Coastguard Worker   if (!utf.IsAscii())
350*f6dc9357SAndroid Build Coastguard Worker     utf.Insert(0, "\xEF\xBB\xBF" "\r\n");
351*f6dc9357SAndroid Build Coastguard Worker 
352*f6dc9357SAndroid Build Coastguard Worker   FString path = _path + kDescriptionFileName;
353*f6dc9357SAndroid Build Coastguard Worker   // We must set same attrib. COutFile::CreateAlways can fail, if file has another attrib.
354*f6dc9357SAndroid Build Coastguard Worker   DWORD attrib = FILE_ATTRIBUTE_NORMAL;
355*f6dc9357SAndroid Build Coastguard Worker   {
356*f6dc9357SAndroid Build Coastguard Worker     CFileInfo fi;
357*f6dc9357SAndroid Build Coastguard Worker     if (fi.Find(path))
358*f6dc9357SAndroid Build Coastguard Worker       attrib = fi.Attrib;
359*f6dc9357SAndroid Build Coastguard Worker   }
360*f6dc9357SAndroid Build Coastguard Worker   NIO::COutFile file;
361*f6dc9357SAndroid Build Coastguard Worker   if (!file.Create_ALWAYS_with_Attribs(path, attrib))
362*f6dc9357SAndroid Build Coastguard Worker     return false;
363*f6dc9357SAndroid Build Coastguard Worker   UInt32 processed;
364*f6dc9357SAndroid Build Coastguard Worker   file.Write(utf, utf.Len(), processed);
365*f6dc9357SAndroid Build Coastguard Worker   _commentsAreLoaded = false;
366*f6dc9357SAndroid Build Coastguard Worker   return true;
367*f6dc9357SAndroid Build Coastguard Worker }
368*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetNumberOfItems (UInt32 * numItems))369*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetNumberOfItems(UInt32 *numItems))
370*f6dc9357SAndroid Build Coastguard Worker {
371*f6dc9357SAndroid Build Coastguard Worker   *numItems = Files.Size() /* + Streams.Size() */;
372*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
373*f6dc9357SAndroid Build Coastguard Worker }
374*f6dc9357SAndroid Build Coastguard Worker 
375*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_UNICODE_FSTRING
376*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetItemPrefix (UInt32 index,const wchar_t ** name,unsigned * len))377*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetItemPrefix(UInt32 index, const wchar_t **name, unsigned *len))
378*f6dc9357SAndroid Build Coastguard Worker {
379*f6dc9357SAndroid Build Coastguard Worker   *name = NULL;
380*f6dc9357SAndroid Build Coastguard Worker   *len = 0;
381*f6dc9357SAndroid Build Coastguard Worker   /*
382*f6dc9357SAndroid Build Coastguard Worker   if (index >= Files.Size())
383*f6dc9357SAndroid Build Coastguard Worker     index = Streams[index - Files.Size()].Parent;
384*f6dc9357SAndroid Build Coastguard Worker   */
385*f6dc9357SAndroid Build Coastguard Worker   CDirItem &fi = Files[index];
386*f6dc9357SAndroid Build Coastguard Worker   if (fi.Parent >= 0)
387*f6dc9357SAndroid Build Coastguard Worker   {
388*f6dc9357SAndroid Build Coastguard Worker     const FString &fo = Folders[fi.Parent];
389*f6dc9357SAndroid Build Coastguard Worker     USE_UNICODE_FSTRING
390*f6dc9357SAndroid Build Coastguard Worker     *name = fo;
391*f6dc9357SAndroid Build Coastguard Worker     *len = fo.Len();
392*f6dc9357SAndroid Build Coastguard Worker   }
393*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
394*f6dc9357SAndroid Build Coastguard Worker }
395*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetItemName (UInt32 index,const wchar_t ** name,unsigned * len))396*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len))
397*f6dc9357SAndroid Build Coastguard Worker {
398*f6dc9357SAndroid Build Coastguard Worker   *name = NULL;
399*f6dc9357SAndroid Build Coastguard Worker   *len = 0;
400*f6dc9357SAndroid Build Coastguard Worker   if (index < Files.Size())
401*f6dc9357SAndroid Build Coastguard Worker   {
402*f6dc9357SAndroid Build Coastguard Worker     CDirItem &fi = Files[index];
403*f6dc9357SAndroid Build Coastguard Worker     *name = fi.Name;
404*f6dc9357SAndroid Build Coastguard Worker     *len = fi.Name.Len();
405*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
406*f6dc9357SAndroid Build Coastguard Worker   }
407*f6dc9357SAndroid Build Coastguard Worker   else
408*f6dc9357SAndroid Build Coastguard Worker   {
409*f6dc9357SAndroid Build Coastguard Worker     // const CAltStream &ss = Streams[index - Files.Size()];
410*f6dc9357SAndroid Build Coastguard Worker     // *name = ss.Name;
411*f6dc9357SAndroid Build Coastguard Worker     // *len = ss.Name.Len();
412*f6dc9357SAndroid Build Coastguard Worker     //
413*f6dc9357SAndroid Build Coastguard Worker     // change it;
414*f6dc9357SAndroid Build Coastguard Worker   }
415*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
416*f6dc9357SAndroid Build Coastguard Worker }
417*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF2(UInt64,CFSFolder::GetItemSize (UInt32 index))418*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF2(UInt64, CFSFolder::GetItemSize(UInt32 index))
419*f6dc9357SAndroid Build Coastguard Worker {
420*f6dc9357SAndroid Build Coastguard Worker   /*
421*f6dc9357SAndroid Build Coastguard Worker   if (index >= Files.Size())
422*f6dc9357SAndroid Build Coastguard Worker     return Streams[index - Files.Size()].Size;
423*f6dc9357SAndroid Build Coastguard Worker   */
424*f6dc9357SAndroid Build Coastguard Worker   CDirItem &fi = Files[index];
425*f6dc9357SAndroid Build Coastguard Worker   return fi.IsDir() ? 0 : fi.Size;
426*f6dc9357SAndroid Build Coastguard Worker }
427*f6dc9357SAndroid Build Coastguard Worker 
428*f6dc9357SAndroid Build Coastguard Worker #endif
429*f6dc9357SAndroid Build Coastguard Worker 
430*f6dc9357SAndroid Build Coastguard Worker 
431*f6dc9357SAndroid Build Coastguard Worker #ifdef FS_SHOW_LINKS_INFO
432*f6dc9357SAndroid Build Coastguard Worker 
ReadFileInfo(CDirItem & di)433*f6dc9357SAndroid Build Coastguard Worker bool CFSFolder::ReadFileInfo(CDirItem &di)
434*f6dc9357SAndroid Build Coastguard Worker {
435*f6dc9357SAndroid Build Coastguard Worker   di.FileInfo_WasRequested = true;
436*f6dc9357SAndroid Build Coastguard Worker   BY_HANDLE_FILE_INFORMATION info;
437*f6dc9357SAndroid Build Coastguard Worker   memset(&info, 0, sizeof(info)); // for vc6-O2
438*f6dc9357SAndroid Build Coastguard Worker   if (!NIO::CFileBase::GetFileInformation(_path + GetRelPath(di), &info))
439*f6dc9357SAndroid Build Coastguard Worker     return false;
440*f6dc9357SAndroid Build Coastguard Worker   di.NumLinks = info.nNumberOfLinks;
441*f6dc9357SAndroid Build Coastguard Worker   di.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
442*f6dc9357SAndroid Build Coastguard Worker   di.FileInfo_Defined = true;
443*f6dc9357SAndroid Build Coastguard Worker   return true;
444*f6dc9357SAndroid Build Coastguard Worker }
445*f6dc9357SAndroid Build Coastguard Worker 
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
448*f6dc9357SAndroid Build Coastguard Worker 
449*f6dc9357SAndroid Build Coastguard Worker typedef struct
450*f6dc9357SAndroid Build Coastguard Worker {
451*f6dc9357SAndroid Build Coastguard Worker   LARGE_INTEGER CreationTime;
452*f6dc9357SAndroid Build Coastguard Worker   LARGE_INTEGER LastAccessTime;
453*f6dc9357SAndroid Build Coastguard Worker   LARGE_INTEGER LastWriteTime;
454*f6dc9357SAndroid Build Coastguard Worker   LARGE_INTEGER ChangeTime;
455*f6dc9357SAndroid Build Coastguard Worker   ULONG FileAttributes;
456*f6dc9357SAndroid Build Coastguard Worker   UInt32 Reserved; // it's expected for alignment
457*f6dc9357SAndroid Build Coastguard Worker }
458*f6dc9357SAndroid Build Coastguard Worker Z7_WIN_FILE_BASIC_INFORMATION;
459*f6dc9357SAndroid Build Coastguard Worker 
460*f6dc9357SAndroid Build Coastguard Worker 
461*f6dc9357SAndroid Build Coastguard Worker typedef enum
462*f6dc9357SAndroid Build Coastguard Worker {
463*f6dc9357SAndroid Build Coastguard Worker   Z7_WIN_FileDirectoryInformation = 1,
464*f6dc9357SAndroid Build Coastguard Worker   Z7_WIN_FileFullDirectoryInformation,
465*f6dc9357SAndroid Build Coastguard Worker   Z7_WIN_FileBothDirectoryInformation,
466*f6dc9357SAndroid Build Coastguard Worker   Z7_WIN_FileBasicInformation
467*f6dc9357SAndroid Build Coastguard Worker }
468*f6dc9357SAndroid Build Coastguard Worker Z7_WIN_FILE_INFORMATION_CLASS;
469*f6dc9357SAndroid Build Coastguard Worker 
470*f6dc9357SAndroid Build Coastguard Worker 
471*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500) && !defined(_M_IA64)
472*f6dc9357SAndroid Build Coastguard Worker #define Z7_WIN_NTSTATUS  NTSTATUS
473*f6dc9357SAndroid Build Coastguard Worker #define Z7_WIN_IO_STATUS_BLOCK  IO_STATUS_BLOCK
474*f6dc9357SAndroid Build Coastguard Worker #else
475*f6dc9357SAndroid Build Coastguard Worker typedef LONG Z7_WIN_NTSTATUS;
476*f6dc9357SAndroid Build Coastguard Worker typedef struct
477*f6dc9357SAndroid Build Coastguard Worker {
478*f6dc9357SAndroid Build Coastguard Worker   union
479*f6dc9357SAndroid Build Coastguard Worker   {
480*f6dc9357SAndroid Build Coastguard Worker     Z7_WIN_NTSTATUS Status;
481*f6dc9357SAndroid Build Coastguard Worker     PVOID Pointer;
482*f6dc9357SAndroid Build Coastguard Worker   } DUMMYUNIONNAME;
483*f6dc9357SAndroid Build Coastguard Worker   ULONG_PTR Information;
484*f6dc9357SAndroid Build Coastguard Worker } Z7_WIN_IO_STATUS_BLOCK;
485*f6dc9357SAndroid Build Coastguard Worker #endif
486*f6dc9357SAndroid Build Coastguard Worker 
487*f6dc9357SAndroid Build Coastguard Worker 
488*f6dc9357SAndroid Build Coastguard Worker typedef Z7_WIN_NTSTATUS (WINAPI * Func_NtQueryInformationFile)(
489*f6dc9357SAndroid Build Coastguard Worker     HANDLE handle, Z7_WIN_IO_STATUS_BLOCK *io,
490*f6dc9357SAndroid Build Coastguard Worker     void *ptr, LONG len, Z7_WIN_FILE_INFORMATION_CLASS cls);
491*f6dc9357SAndroid Build Coastguard Worker 
492*f6dc9357SAndroid Build Coastguard Worker #define MY_STATUS_SUCCESS 0
493*f6dc9357SAndroid Build Coastguard Worker 
494*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
495*f6dc9357SAndroid Build Coastguard Worker 
496*f6dc9357SAndroid Build Coastguard Worker static Func_NtQueryInformationFile f_NtQueryInformationFile;
497*f6dc9357SAndroid Build Coastguard Worker static bool g_NtQueryInformationFile_WasRequested = false;
498*f6dc9357SAndroid Build Coastguard Worker 
499*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
500*f6dc9357SAndroid Build Coastguard Worker 
ReadChangeTime(CDirItem & di)501*f6dc9357SAndroid Build Coastguard Worker void CFSFolder::ReadChangeTime(CDirItem &di)
502*f6dc9357SAndroid Build Coastguard Worker {
503*f6dc9357SAndroid Build Coastguard Worker   di.ChangeTime_WasRequested = true;
504*f6dc9357SAndroid Build Coastguard Worker 
505*f6dc9357SAndroid Build Coastguard Worker   if (!g_NtQueryInformationFile_WasRequested)
506*f6dc9357SAndroid Build Coastguard Worker   {
507*f6dc9357SAndroid Build Coastguard Worker        g_NtQueryInformationFile_WasRequested = true;
508*f6dc9357SAndroid Build Coastguard Worker        f_NtQueryInformationFile = Z7_GET_PROC_ADDRESS(
509*f6dc9357SAndroid Build Coastguard Worker     Func_NtQueryInformationFile, ::GetModuleHandleW(L"ntdll.dll"),
510*f6dc9357SAndroid Build Coastguard Worker         "NtQueryInformationFile");
511*f6dc9357SAndroid Build Coastguard Worker   }
512*f6dc9357SAndroid Build Coastguard Worker   if (!f_NtQueryInformationFile)
513*f6dc9357SAndroid Build Coastguard Worker     return;
514*f6dc9357SAndroid Build Coastguard Worker 
515*f6dc9357SAndroid Build Coastguard Worker   NIO::CInFile file;
516*f6dc9357SAndroid Build Coastguard Worker   if (!file.Open_for_ReadAttributes(_path + GetRelPath(di)))
517*f6dc9357SAndroid Build Coastguard Worker     return;
518*f6dc9357SAndroid Build Coastguard Worker   Z7_WIN_FILE_BASIC_INFORMATION fbi;
519*f6dc9357SAndroid Build Coastguard Worker   Z7_WIN_IO_STATUS_BLOCK IoStatusBlock;
520*f6dc9357SAndroid Build Coastguard Worker   const Z7_WIN_NTSTATUS status = f_NtQueryInformationFile(file.GetHandle(), &IoStatusBlock,
521*f6dc9357SAndroid Build Coastguard Worker       &fbi, sizeof(fbi), Z7_WIN_FileBasicInformation);
522*f6dc9357SAndroid Build Coastguard Worker   if (status != MY_STATUS_SUCCESS)
523*f6dc9357SAndroid Build Coastguard Worker     return;
524*f6dc9357SAndroid Build Coastguard Worker   if (IoStatusBlock.Information != sizeof(fbi))
525*f6dc9357SAndroid Build Coastguard Worker     return;
526*f6dc9357SAndroid Build Coastguard Worker   di.ChangeTime.dwLowDateTime = fbi.ChangeTime.u.LowPart;
527*f6dc9357SAndroid Build Coastguard Worker   di.ChangeTime.dwHighDateTime = (DWORD)fbi.ChangeTime.u.HighPart;
528*f6dc9357SAndroid Build Coastguard Worker   di.ChangeTime_Defined = true;
529*f6dc9357SAndroid Build Coastguard Worker }
530*f6dc9357SAndroid Build Coastguard Worker 
531*f6dc9357SAndroid Build Coastguard Worker #endif // FS_SHOW_LINKS_INFO
532*f6dc9357SAndroid Build Coastguard Worker 
533*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetProperty (UInt32 index,PROPID propID,PROPVARIANT * value))534*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
535*f6dc9357SAndroid Build Coastguard Worker {
536*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
537*f6dc9357SAndroid Build Coastguard Worker   /*
538*f6dc9357SAndroid Build Coastguard Worker   if (index >= Files.Size())
539*f6dc9357SAndroid Build Coastguard Worker   {
540*f6dc9357SAndroid Build Coastguard Worker     CAltStream &ss = Streams[index - Files.Size()];
541*f6dc9357SAndroid Build Coastguard Worker     CDirItem &fi = Files[ss.Parent];
542*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
543*f6dc9357SAndroid Build Coastguard Worker     {
544*f6dc9357SAndroid Build Coastguard Worker       case kpidIsDir: prop = false; break;
545*f6dc9357SAndroid Build Coastguard Worker       case kpidIsAltStream: prop = true; break;
546*f6dc9357SAndroid Build Coastguard Worker       case kpidName: prop = fs2us(fi.Name) + ss.Name; break;
547*f6dc9357SAndroid Build Coastguard Worker       case kpidSize: prop = ss.Size; break;
548*f6dc9357SAndroid Build Coastguard Worker       case kpidPackSize:
549*f6dc9357SAndroid Build Coastguard Worker         #ifdef UNDER_CE
550*f6dc9357SAndroid Build Coastguard Worker         prop = ss.Size;
551*f6dc9357SAndroid Build Coastguard Worker         #else
552*f6dc9357SAndroid Build Coastguard Worker         if (!ss.PackSize_Defined)
553*f6dc9357SAndroid Build Coastguard Worker         {
554*f6dc9357SAndroid Build Coastguard Worker           ss.PackSize_Defined = true;
555*f6dc9357SAndroid Build Coastguard Worker           if (!MyGetCompressedFileSizeW(_path + GetRelPath(fi) + us2fs(ss.Name), ss.PackSize))
556*f6dc9357SAndroid Build Coastguard Worker             ss.PackSize = ss.Size;
557*f6dc9357SAndroid Build Coastguard Worker         }
558*f6dc9357SAndroid Build Coastguard Worker         prop = ss.PackSize;
559*f6dc9357SAndroid Build Coastguard Worker         #endif
560*f6dc9357SAndroid Build Coastguard Worker         break;
561*f6dc9357SAndroid Build Coastguard Worker       case kpidComment: break;
562*f6dc9357SAndroid Build Coastguard Worker       default: index = ss.Parent;
563*f6dc9357SAndroid Build Coastguard Worker     }
564*f6dc9357SAndroid Build Coastguard Worker     if (index >= Files.Size())
565*f6dc9357SAndroid Build Coastguard Worker     {
566*f6dc9357SAndroid Build Coastguard Worker       prop.Detach(value);
567*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
568*f6dc9357SAndroid Build Coastguard Worker     }
569*f6dc9357SAndroid Build Coastguard Worker   }
570*f6dc9357SAndroid Build Coastguard Worker   */
571*f6dc9357SAndroid Build Coastguard Worker   CDirItem &fi = Files[index];
572*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
573*f6dc9357SAndroid Build Coastguard Worker   {
574*f6dc9357SAndroid Build Coastguard Worker     case kpidIsDir: prop = fi.IsDir(); break;
575*f6dc9357SAndroid Build Coastguard Worker     case kpidIsAltStream: prop = false; break;
576*f6dc9357SAndroid Build Coastguard Worker     case kpidName: prop = fs2us(fi.Name); break;
577*f6dc9357SAndroid Build Coastguard Worker     case kpidSize: if (!fi.IsDir() || fi.FolderStat_Defined) prop = fi.Size; break;
578*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize:
579*f6dc9357SAndroid Build Coastguard Worker       #ifdef UNDER_CE
580*f6dc9357SAndroid Build Coastguard Worker       prop = fi.Size;
581*f6dc9357SAndroid Build Coastguard Worker       #else
582*f6dc9357SAndroid Build Coastguard Worker       if (!fi.PackSize_Defined)
583*f6dc9357SAndroid Build Coastguard Worker       {
584*f6dc9357SAndroid Build Coastguard Worker         fi.PackSize_Defined = true;
585*f6dc9357SAndroid Build Coastguard Worker         if (fi.IsDir () || !MyGetCompressedFileSizeW(_path + GetRelPath(fi), fi.PackSize))
586*f6dc9357SAndroid Build Coastguard Worker           fi.PackSize = fi.Size;
587*f6dc9357SAndroid Build Coastguard Worker       }
588*f6dc9357SAndroid Build Coastguard Worker       prop = fi.PackSize;
589*f6dc9357SAndroid Build Coastguard Worker       #endif
590*f6dc9357SAndroid Build Coastguard Worker       break;
591*f6dc9357SAndroid Build Coastguard Worker 
592*f6dc9357SAndroid Build Coastguard Worker     #ifdef FS_SHOW_LINKS_INFO
593*f6dc9357SAndroid Build Coastguard Worker 
594*f6dc9357SAndroid Build Coastguard Worker     case kpidLinks:
595*f6dc9357SAndroid Build Coastguard Worker       #ifdef UNDER_CE
596*f6dc9357SAndroid Build Coastguard Worker       // prop = fi.NumLinks;
597*f6dc9357SAndroid Build Coastguard Worker       #else
598*f6dc9357SAndroid Build Coastguard Worker       if (!fi.FileInfo_WasRequested)
599*f6dc9357SAndroid Build Coastguard Worker         ReadFileInfo(fi);
600*f6dc9357SAndroid Build Coastguard Worker       if (fi.FileInfo_Defined)
601*f6dc9357SAndroid Build Coastguard Worker         prop = fi.NumLinks;
602*f6dc9357SAndroid Build Coastguard Worker       #endif
603*f6dc9357SAndroid Build Coastguard Worker       break;
604*f6dc9357SAndroid Build Coastguard Worker 
605*f6dc9357SAndroid Build Coastguard Worker     case kpidINode:
606*f6dc9357SAndroid Build Coastguard Worker       #ifdef UNDER_CE
607*f6dc9357SAndroid Build Coastguard Worker       // prop = fi.FileIndex;
608*f6dc9357SAndroid Build Coastguard Worker       #else
609*f6dc9357SAndroid Build Coastguard Worker       if (!fi.FileInfo_WasRequested)
610*f6dc9357SAndroid Build Coastguard Worker         ReadFileInfo(fi);
611*f6dc9357SAndroid Build Coastguard Worker       if (fi.FileInfo_Defined)
612*f6dc9357SAndroid Build Coastguard Worker         prop = fi.FileIndex;
613*f6dc9357SAndroid Build Coastguard Worker       #endif
614*f6dc9357SAndroid Build Coastguard Worker       break;
615*f6dc9357SAndroid Build Coastguard Worker 
616*f6dc9357SAndroid Build Coastguard Worker     case kpidChangeTime:
617*f6dc9357SAndroid Build Coastguard Worker       if (!fi.ChangeTime_WasRequested)
618*f6dc9357SAndroid Build Coastguard Worker         ReadChangeTime(fi);
619*f6dc9357SAndroid Build Coastguard Worker       if (fi.ChangeTime_Defined)
620*f6dc9357SAndroid Build Coastguard Worker         prop = fi.ChangeTime;
621*f6dc9357SAndroid Build Coastguard Worker       break;
622*f6dc9357SAndroid Build Coastguard Worker 
623*f6dc9357SAndroid Build Coastguard Worker     #endif
624*f6dc9357SAndroid Build Coastguard Worker 
625*f6dc9357SAndroid Build Coastguard Worker     case kpidAttrib: prop = (UInt32)fi.Attrib; break;
626*f6dc9357SAndroid Build Coastguard Worker     case kpidCTime: prop = fi.CTime; break;
627*f6dc9357SAndroid Build Coastguard Worker     case kpidATime: prop = fi.ATime; break;
628*f6dc9357SAndroid Build Coastguard Worker     case kpidMTime: prop = fi.MTime; break;
629*f6dc9357SAndroid Build Coastguard Worker     case kpidComment:
630*f6dc9357SAndroid Build Coastguard Worker     {
631*f6dc9357SAndroid Build Coastguard Worker       if (!_commentsAreLoaded)
632*f6dc9357SAndroid Build Coastguard Worker         LoadComments();
633*f6dc9357SAndroid Build Coastguard Worker       UString comment;
634*f6dc9357SAndroid Build Coastguard Worker       if (_comments.GetValue(fs2us(GetRelPath(fi)), comment))
635*f6dc9357SAndroid Build Coastguard Worker       {
636*f6dc9357SAndroid Build Coastguard Worker         int pos = comment.Find((wchar_t)4);
637*f6dc9357SAndroid Build Coastguard Worker         if (pos >= 0)
638*f6dc9357SAndroid Build Coastguard Worker           comment.DeleteFrom((unsigned)pos);
639*f6dc9357SAndroid Build Coastguard Worker         prop = comment;
640*f6dc9357SAndroid Build Coastguard Worker       }
641*f6dc9357SAndroid Build Coastguard Worker       break;
642*f6dc9357SAndroid Build Coastguard Worker     }
643*f6dc9357SAndroid Build Coastguard Worker     case kpidPrefix:
644*f6dc9357SAndroid Build Coastguard Worker       if (fi.Parent >= 0)
645*f6dc9357SAndroid Build Coastguard Worker         prop = fs2us(Folders[fi.Parent]);
646*f6dc9357SAndroid Build Coastguard Worker       break;
647*f6dc9357SAndroid Build Coastguard Worker     case kpidNumSubDirs: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFolders; break;
648*f6dc9357SAndroid Build Coastguard Worker     case kpidNumSubFiles: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFiles; break;
649*f6dc9357SAndroid Build Coastguard Worker   }
650*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
651*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
652*f6dc9357SAndroid Build Coastguard Worker }
653*f6dc9357SAndroid Build Coastguard Worker 
654*f6dc9357SAndroid Build Coastguard Worker 
655*f6dc9357SAndroid Build Coastguard Worker // ---------- IArchiveGetRawProps ----------
656*f6dc9357SAndroid Build Coastguard Worker 
657*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetNumRawProps (UInt32 * numProps))658*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetNumRawProps(UInt32 *numProps))
659*f6dc9357SAndroid Build Coastguard Worker {
660*f6dc9357SAndroid Build Coastguard Worker   *numProps = 1;
661*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
662*f6dc9357SAndroid Build Coastguard Worker }
663*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetRawPropInfo (UInt32,BSTR * name,PROPID * propID))664*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID))
665*f6dc9357SAndroid Build Coastguard Worker {
666*f6dc9357SAndroid Build Coastguard Worker   *name = NULL;
667*f6dc9357SAndroid Build Coastguard Worker   *propID = kpidNtReparse;
668*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
669*f6dc9357SAndroid Build Coastguard Worker }
670*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetParent (UInt32,UInt32 *,UInt32 *))671*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetParent(UInt32 /* index */, UInt32 * /* parent */, UInt32 * /* parentType */))
672*f6dc9357SAndroid Build Coastguard Worker {
673*f6dc9357SAndroid Build Coastguard Worker   return E_FAIL;
674*f6dc9357SAndroid Build Coastguard Worker }
675*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetRawProp (UInt32 index,PROPID propID,const void ** data,UInt32 * dataSize,UInt32 * propType))676*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetRawProp(UInt32 index, PROPID propID,
677*f6dc9357SAndroid Build Coastguard Worker     const void **data, UInt32 *dataSize, UInt32 *propType))
678*f6dc9357SAndroid Build Coastguard Worker {
679*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
680*f6dc9357SAndroid Build Coastguard Worker   UNUSED(index)
681*f6dc9357SAndroid Build Coastguard Worker   UNUSED(propID)
682*f6dc9357SAndroid Build Coastguard Worker   #endif
683*f6dc9357SAndroid Build Coastguard Worker 
684*f6dc9357SAndroid Build Coastguard Worker   *data = NULL;
685*f6dc9357SAndroid Build Coastguard Worker   *dataSize = 0;
686*f6dc9357SAndroid Build Coastguard Worker   *propType = 0;
687*f6dc9357SAndroid Build Coastguard Worker 
688*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
689*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidNtReparse)
690*f6dc9357SAndroid Build Coastguard Worker   {
691*f6dc9357SAndroid Build Coastguard Worker     const CDirItem &fi = Files[index];
692*f6dc9357SAndroid Build Coastguard Worker     const CByteBuffer &buf = fi.Reparse;
693*f6dc9357SAndroid Build Coastguard Worker     if (buf.Size() == 0)
694*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
695*f6dc9357SAndroid Build Coastguard Worker     *data = buf;
696*f6dc9357SAndroid Build Coastguard Worker     *dataSize = (UInt32)buf.Size();
697*f6dc9357SAndroid Build Coastguard Worker     *propType = NPropDataType::kRaw;
698*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
699*f6dc9357SAndroid Build Coastguard Worker   }
700*f6dc9357SAndroid Build Coastguard Worker   #endif
701*f6dc9357SAndroid Build Coastguard Worker 
702*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
703*f6dc9357SAndroid Build Coastguard Worker }
704*f6dc9357SAndroid Build Coastguard Worker 
705*f6dc9357SAndroid Build Coastguard Worker 
706*f6dc9357SAndroid Build Coastguard Worker // returns Position of extension including '.'
707*f6dc9357SAndroid Build Coastguard Worker 
GetExtensionPtr(const FString & name)708*f6dc9357SAndroid Build Coastguard Worker static inline CFSTR GetExtensionPtr(const FString &name)
709*f6dc9357SAndroid Build Coastguard Worker {
710*f6dc9357SAndroid Build Coastguard Worker   const int dotPos = name.ReverseFind_Dot();
711*f6dc9357SAndroid Build Coastguard Worker   return name.Ptr((dotPos < 0) ? name.Len() : (unsigned)dotPos);
712*f6dc9357SAndroid Build Coastguard Worker }
713*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF2(Int32,CFSFolder::CompareItems (UInt32 index1,UInt32 index2,PROPID propID,Int32))714*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF2(Int32, CFSFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */))
715*f6dc9357SAndroid Build Coastguard Worker {
716*f6dc9357SAndroid Build Coastguard Worker   /*
717*f6dc9357SAndroid Build Coastguard Worker   const CAltStream *ss1 = NULL;
718*f6dc9357SAndroid Build Coastguard Worker   const CAltStream *ss2 = NULL;
719*f6dc9357SAndroid Build Coastguard Worker   if (index1 >= Files.Size()) { ss1 = &Streams[index1 - Files.Size()]; index1 = ss1->Parent; }
720*f6dc9357SAndroid Build Coastguard Worker   if (index2 >= Files.Size()) { ss2 = &Streams[index2 - Files.Size()]; index2 = ss2->Parent; }
721*f6dc9357SAndroid Build Coastguard Worker   */
722*f6dc9357SAndroid Build Coastguard Worker   CDirItem &fi1 = Files[index1];
723*f6dc9357SAndroid Build Coastguard Worker   CDirItem &fi2 = Files[index2];
724*f6dc9357SAndroid Build Coastguard Worker 
725*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
726*f6dc9357SAndroid Build Coastguard Worker   {
727*f6dc9357SAndroid Build Coastguard Worker     case kpidName:
728*f6dc9357SAndroid Build Coastguard Worker     {
729*f6dc9357SAndroid Build Coastguard Worker       const int comp = CompareFileNames_ForFolderList(fi1.Name, fi2.Name);
730*f6dc9357SAndroid Build Coastguard Worker       /*
731*f6dc9357SAndroid Build Coastguard Worker       if (comp != 0)
732*f6dc9357SAndroid Build Coastguard Worker         return comp;
733*f6dc9357SAndroid Build Coastguard Worker       if (!ss1)
734*f6dc9357SAndroid Build Coastguard Worker         return ss2 ? -1 : 0;
735*f6dc9357SAndroid Build Coastguard Worker       if (!ss2)
736*f6dc9357SAndroid Build Coastguard Worker         return 1;
737*f6dc9357SAndroid Build Coastguard Worker       return MyStringCompareNoCase(ss1->Name, ss2->Name);
738*f6dc9357SAndroid Build Coastguard Worker       */
739*f6dc9357SAndroid Build Coastguard Worker       return comp;
740*f6dc9357SAndroid Build Coastguard Worker     }
741*f6dc9357SAndroid Build Coastguard Worker     case kpidSize:
742*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(
743*f6dc9357SAndroid Build Coastguard Worker           /* ss1 ? ss1->Size : */ fi1.Size,
744*f6dc9357SAndroid Build Coastguard Worker           /* ss2 ? ss2->Size : */ fi2.Size);
745*f6dc9357SAndroid Build Coastguard Worker     case kpidAttrib: return MyCompare(fi1.Attrib, fi2.Attrib);
746*f6dc9357SAndroid Build Coastguard Worker     case kpidCTime: return CompareFileTime(&fi1.CTime, &fi2.CTime);
747*f6dc9357SAndroid Build Coastguard Worker     case kpidATime: return CompareFileTime(&fi1.ATime, &fi2.ATime);
748*f6dc9357SAndroid Build Coastguard Worker     case kpidMTime: return CompareFileTime(&fi1.MTime, &fi2.MTime);
749*f6dc9357SAndroid Build Coastguard Worker     case kpidIsDir:
750*f6dc9357SAndroid Build Coastguard Worker     {
751*f6dc9357SAndroid Build Coastguard Worker       bool isDir1 = /* ss1 ? false : */ fi1.IsDir();
752*f6dc9357SAndroid Build Coastguard Worker       bool isDir2 = /* ss2 ? false : */ fi2.IsDir();
753*f6dc9357SAndroid Build Coastguard Worker       if (isDir1 == isDir2)
754*f6dc9357SAndroid Build Coastguard Worker         return 0;
755*f6dc9357SAndroid Build Coastguard Worker       return isDir1 ? -1 : 1;
756*f6dc9357SAndroid Build Coastguard Worker     }
757*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize:
758*f6dc9357SAndroid Build Coastguard Worker     {
759*f6dc9357SAndroid Build Coastguard Worker       #ifdef UNDER_CE
760*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(fi1.Size, fi2.Size);
761*f6dc9357SAndroid Build Coastguard Worker       #else
762*f6dc9357SAndroid Build Coastguard Worker       // PackSize can be undefined here
763*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(
764*f6dc9357SAndroid Build Coastguard Worker           /* ss1 ? ss1->PackSize : */ fi1.PackSize,
765*f6dc9357SAndroid Build Coastguard Worker           /* ss2 ? ss2->PackSize : */ fi2.PackSize);
766*f6dc9357SAndroid Build Coastguard Worker       #endif
767*f6dc9357SAndroid Build Coastguard Worker     }
768*f6dc9357SAndroid Build Coastguard Worker 
769*f6dc9357SAndroid Build Coastguard Worker     #ifdef FS_SHOW_LINKS_INFO
770*f6dc9357SAndroid Build Coastguard Worker     case kpidINode:
771*f6dc9357SAndroid Build Coastguard Worker     {
772*f6dc9357SAndroid Build Coastguard Worker       #ifndef UNDER_CE
773*f6dc9357SAndroid Build Coastguard Worker       if (!fi1.FileInfo_WasRequested) ReadFileInfo(fi1);
774*f6dc9357SAndroid Build Coastguard Worker       if (!fi2.FileInfo_WasRequested) ReadFileInfo(fi2);
775*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(
776*f6dc9357SAndroid Build Coastguard Worker           fi1.FileIndex,
777*f6dc9357SAndroid Build Coastguard Worker           fi2.FileIndex);
778*f6dc9357SAndroid Build Coastguard Worker       #endif
779*f6dc9357SAndroid Build Coastguard Worker     }
780*f6dc9357SAndroid Build Coastguard Worker     case kpidLinks:
781*f6dc9357SAndroid Build Coastguard Worker     {
782*f6dc9357SAndroid Build Coastguard Worker       #ifndef UNDER_CE
783*f6dc9357SAndroid Build Coastguard Worker       if (!fi1.FileInfo_WasRequested) ReadFileInfo(fi1);
784*f6dc9357SAndroid Build Coastguard Worker       if (!fi2.FileInfo_WasRequested) ReadFileInfo(fi2);
785*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(
786*f6dc9357SAndroid Build Coastguard Worker           fi1.NumLinks,
787*f6dc9357SAndroid Build Coastguard Worker           fi2.NumLinks);
788*f6dc9357SAndroid Build Coastguard Worker       #endif
789*f6dc9357SAndroid Build Coastguard Worker     }
790*f6dc9357SAndroid Build Coastguard Worker     #endif
791*f6dc9357SAndroid Build Coastguard Worker 
792*f6dc9357SAndroid Build Coastguard Worker     case kpidComment:
793*f6dc9357SAndroid Build Coastguard Worker     {
794*f6dc9357SAndroid Build Coastguard Worker       // change it !
795*f6dc9357SAndroid Build Coastguard Worker       UString comment1, comment2;
796*f6dc9357SAndroid Build Coastguard Worker       _comments.GetValue(fs2us(GetRelPath(fi1)), comment1);
797*f6dc9357SAndroid Build Coastguard Worker       _comments.GetValue(fs2us(GetRelPath(fi2)), comment2);
798*f6dc9357SAndroid Build Coastguard Worker       return MyStringCompareNoCase(comment1, comment2);
799*f6dc9357SAndroid Build Coastguard Worker     }
800*f6dc9357SAndroid Build Coastguard Worker     case kpidPrefix:
801*f6dc9357SAndroid Build Coastguard Worker       if (fi1.Parent < 0) return (fi2.Parent < 0) ? 0 : -1;
802*f6dc9357SAndroid Build Coastguard Worker       if (fi2.Parent < 0) return 1;
803*f6dc9357SAndroid Build Coastguard Worker       return CompareFileNames_ForFolderList(
804*f6dc9357SAndroid Build Coastguard Worker           Folders[fi1.Parent],
805*f6dc9357SAndroid Build Coastguard Worker           Folders[fi2.Parent]);
806*f6dc9357SAndroid Build Coastguard Worker     case kpidExtension:
807*f6dc9357SAndroid Build Coastguard Worker       return CompareFileNames_ForFolderList(
808*f6dc9357SAndroid Build Coastguard Worker           GetExtensionPtr(fi1.Name),
809*f6dc9357SAndroid Build Coastguard Worker           GetExtensionPtr(fi2.Name));
810*f6dc9357SAndroid Build Coastguard Worker   }
811*f6dc9357SAndroid Build Coastguard Worker 
812*f6dc9357SAndroid Build Coastguard Worker   return 0;
813*f6dc9357SAndroid Build Coastguard Worker }
814*f6dc9357SAndroid Build Coastguard Worker 
BindToFolderSpec(CFSTR name,IFolderFolder ** resultFolder)815*f6dc9357SAndroid Build Coastguard Worker HRESULT CFSFolder::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
816*f6dc9357SAndroid Build Coastguard Worker {
817*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
818*f6dc9357SAndroid Build Coastguard Worker   CFSFolder *folderSpec = new CFSFolder;
819*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderFolder> subFolder = folderSpec;
820*f6dc9357SAndroid Build Coastguard Worker   RINOK(folderSpec->Init(_path + name + FCHAR_PATH_SEPARATOR))
821*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = subFolder.Detach();
822*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
823*f6dc9357SAndroid Build Coastguard Worker }
824*f6dc9357SAndroid Build Coastguard Worker 
825*f6dc9357SAndroid Build Coastguard Worker /*
826*f6dc9357SAndroid Build Coastguard Worker void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const
827*f6dc9357SAndroid Build Coastguard Worker {
828*f6dc9357SAndroid Build Coastguard Worker   if (item.Parent >= 0)
829*f6dc9357SAndroid Build Coastguard Worker     prefix = Folders[item.Parent];
830*f6dc9357SAndroid Build Coastguard Worker   else
831*f6dc9357SAndroid Build Coastguard Worker     prefix.Empty();
832*f6dc9357SAndroid Build Coastguard Worker }
833*f6dc9357SAndroid Build Coastguard Worker */
834*f6dc9357SAndroid Build Coastguard Worker 
835*f6dc9357SAndroid Build Coastguard Worker /*
836*f6dc9357SAndroid Build Coastguard Worker void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const
837*f6dc9357SAndroid Build Coastguard Worker {
838*f6dc9357SAndroid Build Coastguard Worker   int parent = item.Parent;
839*f6dc9357SAndroid Build Coastguard Worker 
840*f6dc9357SAndroid Build Coastguard Worker   unsigned len = 0;
841*f6dc9357SAndroid Build Coastguard Worker 
842*f6dc9357SAndroid Build Coastguard Worker   while (parent >= 0)
843*f6dc9357SAndroid Build Coastguard Worker   {
844*f6dc9357SAndroid Build Coastguard Worker     const CDirItem &cur = Files[parent];
845*f6dc9357SAndroid Build Coastguard Worker     len += cur.Name.Len() + 1;
846*f6dc9357SAndroid Build Coastguard Worker     parent = cur.Parent;
847*f6dc9357SAndroid Build Coastguard Worker   }
848*f6dc9357SAndroid Build Coastguard Worker 
849*f6dc9357SAndroid Build Coastguard Worker   wchar_t *p = prefix.GetBuf_SetEnd(len) + len;
850*f6dc9357SAndroid Build Coastguard Worker   parent = item.Parent;
851*f6dc9357SAndroid Build Coastguard Worker 
852*f6dc9357SAndroid Build Coastguard Worker   while (parent >= 0)
853*f6dc9357SAndroid Build Coastguard Worker   {
854*f6dc9357SAndroid Build Coastguard Worker     const CDirItem &cur = Files[parent];
855*f6dc9357SAndroid Build Coastguard Worker     *(--p) = FCHAR_PATH_SEPARATOR;
856*f6dc9357SAndroid Build Coastguard Worker     p -= cur.Name.Len();
857*f6dc9357SAndroid Build Coastguard Worker     wmemcpy(p, cur.Name, cur.Name.Len());
858*f6dc9357SAndroid Build Coastguard Worker     parent = cur.Parent;
859*f6dc9357SAndroid Build Coastguard Worker   }
860*f6dc9357SAndroid Build Coastguard Worker }
861*f6dc9357SAndroid Build Coastguard Worker */
862*f6dc9357SAndroid Build Coastguard Worker 
GetRelPath(const CDirItem & item) const863*f6dc9357SAndroid Build Coastguard Worker FString CFSFolder::GetRelPath(const CDirItem &item) const
864*f6dc9357SAndroid Build Coastguard Worker {
865*f6dc9357SAndroid Build Coastguard Worker   if (item.Parent < 0)
866*f6dc9357SAndroid Build Coastguard Worker     return item.Name;
867*f6dc9357SAndroid Build Coastguard Worker   return Folders[item.Parent] + item.Name;
868*f6dc9357SAndroid Build Coastguard Worker }
869*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::BindToFolder (UInt32 index,IFolderFolder ** resultFolder))870*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder))
871*f6dc9357SAndroid Build Coastguard Worker {
872*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
873*f6dc9357SAndroid Build Coastguard Worker   const CDirItem &fi = Files[index];
874*f6dc9357SAndroid Build Coastguard Worker   if (!fi.IsDir())
875*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
876*f6dc9357SAndroid Build Coastguard Worker   return BindToFolderSpec(GetRelPath(fi), resultFolder);
877*f6dc9357SAndroid Build Coastguard Worker }
878*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::BindToFolder (const wchar_t * name,IFolderFolder ** resultFolder))879*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder))
880*f6dc9357SAndroid Build Coastguard Worker {
881*f6dc9357SAndroid Build Coastguard Worker   return BindToFolderSpec(us2fs(name), resultFolder);
882*f6dc9357SAndroid Build Coastguard Worker }
883*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::BindToParentFolder (IFolderFolder ** resultFolder))884*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::BindToParentFolder(IFolderFolder **resultFolder))
885*f6dc9357SAndroid Build Coastguard Worker {
886*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
887*f6dc9357SAndroid Build Coastguard Worker   /*
888*f6dc9357SAndroid Build Coastguard Worker   if (_parentFolder)
889*f6dc9357SAndroid Build Coastguard Worker   {
890*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
891*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = parentFolder.Detach();
892*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
893*f6dc9357SAndroid Build Coastguard Worker   }
894*f6dc9357SAndroid Build Coastguard Worker   */
895*f6dc9357SAndroid Build Coastguard Worker   if (_path.IsEmpty())
896*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
897*f6dc9357SAndroid Build Coastguard Worker 
898*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
899*f6dc9357SAndroid Build Coastguard Worker 
900*f6dc9357SAndroid Build Coastguard Worker   if (IsDriveRootPath_SuperAllowed(_path))
901*f6dc9357SAndroid Build Coastguard Worker   {
902*f6dc9357SAndroid Build Coastguard Worker     CFSDrives *drivesFolderSpec = new CFSDrives;
903*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
904*f6dc9357SAndroid Build Coastguard Worker     drivesFolderSpec->Init(false, IsSuperPath(_path));
905*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = drivesFolder.Detach();
906*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
907*f6dc9357SAndroid Build Coastguard Worker   }
908*f6dc9357SAndroid Build Coastguard Worker 
909*f6dc9357SAndroid Build Coastguard Worker   int pos = _path.ReverseFind_PathSepar();
910*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0 || pos != (int)_path.Len() - 1)
911*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
912*f6dc9357SAndroid Build Coastguard Worker   FString parentPath = _path.Left((unsigned)pos);
913*f6dc9357SAndroid Build Coastguard Worker   pos = parentPath.ReverseFind_PathSepar();
914*f6dc9357SAndroid Build Coastguard Worker   parentPath.DeleteFrom((unsigned)(pos + 1));
915*f6dc9357SAndroid Build Coastguard Worker 
916*f6dc9357SAndroid Build Coastguard Worker   if (NName::IsDrivePath_SuperAllowed(parentPath))
917*f6dc9357SAndroid Build Coastguard Worker   {
918*f6dc9357SAndroid Build Coastguard Worker     CFSFolder *parentFolderSpec = new CFSFolder;
919*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
920*f6dc9357SAndroid Build Coastguard Worker     if (parentFolderSpec->Init(parentPath) == S_OK)
921*f6dc9357SAndroid Build Coastguard Worker     {
922*f6dc9357SAndroid Build Coastguard Worker       *resultFolder = parentFolder.Detach();
923*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
924*f6dc9357SAndroid Build Coastguard Worker     }
925*f6dc9357SAndroid Build Coastguard Worker   }
926*f6dc9357SAndroid Build Coastguard Worker 
927*f6dc9357SAndroid Build Coastguard Worker   /*
928*f6dc9357SAndroid Build Coastguard Worker   FString parentPathReduced = parentPath.Left(pos);
929*f6dc9357SAndroid Build Coastguard Worker 
930*f6dc9357SAndroid Build Coastguard Worker   pos = parentPathReduced.ReverseFind_PathSepar();
931*f6dc9357SAndroid Build Coastguard Worker   if (pos == 1)
932*f6dc9357SAndroid Build Coastguard Worker   {
933*f6dc9357SAndroid Build Coastguard Worker     if (!IS_PATH_SEPAR_CHAR(parentPath[0]))
934*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
935*f6dc9357SAndroid Build Coastguard Worker     CNetFolder *netFolderSpec = new CNetFolder;
936*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
937*f6dc9357SAndroid Build Coastguard Worker     netFolderSpec->Init(fs2us(parentPath));
938*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = netFolder.Detach();
939*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
940*f6dc9357SAndroid Build Coastguard Worker   }
941*f6dc9357SAndroid Build Coastguard Worker   */
942*f6dc9357SAndroid Build Coastguard Worker 
943*f6dc9357SAndroid Build Coastguard Worker   #endif
944*f6dc9357SAndroid Build Coastguard Worker 
945*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
946*f6dc9357SAndroid Build Coastguard Worker }
947*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetNumberOfProperties (UInt32 * numProperties))948*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetNumberOfProperties(UInt32 *numProperties))
949*f6dc9357SAndroid Build Coastguard Worker {
950*f6dc9357SAndroid Build Coastguard Worker   *numProperties = Z7_ARRAY_SIZE(kProps);
951*f6dc9357SAndroid Build Coastguard Worker   if (!_flatMode)
952*f6dc9357SAndroid Build Coastguard Worker     (*numProperties)--;
953*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
954*f6dc9357SAndroid Build Coastguard Worker }
955*f6dc9357SAndroid Build Coastguard Worker 
IMP_IFolderFolder_GetProp(CFSFolder::GetPropertyInfo,kProps)956*f6dc9357SAndroid Build Coastguard Worker IMP_IFolderFolder_GetProp(CFSFolder::GetPropertyInfo, kProps)
957*f6dc9357SAndroid Build Coastguard Worker 
958*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value))
959*f6dc9357SAndroid Build Coastguard Worker {
960*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
961*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
962*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
963*f6dc9357SAndroid Build Coastguard Worker   {
964*f6dc9357SAndroid Build Coastguard Worker     case kpidType: prop = "FSFolder"; break;
965*f6dc9357SAndroid Build Coastguard Worker     case kpidPath: prop = fs2us(_path); break;
966*f6dc9357SAndroid Build Coastguard Worker   }
967*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
968*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
969*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
970*f6dc9357SAndroid Build Coastguard Worker }
971*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::WasChanged (Int32 * wasChanged))972*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::WasChanged(Int32 *wasChanged))
973*f6dc9357SAndroid Build Coastguard Worker {
974*f6dc9357SAndroid Build Coastguard Worker   bool wasChangedMain = false;
975*f6dc9357SAndroid Build Coastguard Worker 
976*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
977*f6dc9357SAndroid Build Coastguard Worker 
978*f6dc9357SAndroid Build Coastguard Worker   for (;;)
979*f6dc9357SAndroid Build Coastguard Worker   {
980*f6dc9357SAndroid Build Coastguard Worker     if (!_findChangeNotification.IsHandleAllocated())
981*f6dc9357SAndroid Build Coastguard Worker       break;
982*f6dc9357SAndroid Build Coastguard Worker     DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
983*f6dc9357SAndroid Build Coastguard Worker     if (waitResult != WAIT_OBJECT_0)
984*f6dc9357SAndroid Build Coastguard Worker       break;
985*f6dc9357SAndroid Build Coastguard Worker     _findChangeNotification.FindNext();
986*f6dc9357SAndroid Build Coastguard Worker     wasChangedMain = true;
987*f6dc9357SAndroid Build Coastguard Worker   }
988*f6dc9357SAndroid Build Coastguard Worker 
989*f6dc9357SAndroid Build Coastguard Worker   #endif
990*f6dc9357SAndroid Build Coastguard Worker 
991*f6dc9357SAndroid Build Coastguard Worker   *wasChanged = BoolToInt(wasChangedMain);
992*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
993*f6dc9357SAndroid Build Coastguard Worker }
994*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::Clone (IFolderFolder ** resultFolder))995*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::Clone(IFolderFolder **resultFolder))
996*f6dc9357SAndroid Build Coastguard Worker {
997*f6dc9357SAndroid Build Coastguard Worker   CFSFolder *fsFolderSpec = new CFSFolder;
998*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderFolder> folderNew = fsFolderSpec;
999*f6dc9357SAndroid Build Coastguard Worker   fsFolderSpec->Init(_path);
1000*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = folderNew.Detach();
1001*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1002*f6dc9357SAndroid Build Coastguard Worker }
1003*f6dc9357SAndroid Build Coastguard Worker 
1004*f6dc9357SAndroid Build Coastguard Worker 
1005*f6dc9357SAndroid Build Coastguard Worker /*
1006*f6dc9357SAndroid Build Coastguard Worker HRESULT CFSFolder::GetItemFullSize(unsigned index, UInt64 &size, IProgress *progress)
1007*f6dc9357SAndroid Build Coastguard Worker {
1008*f6dc9357SAndroid Build Coastguard Worker   if (index >= Files.Size())
1009*f6dc9357SAndroid Build Coastguard Worker   {
1010*f6dc9357SAndroid Build Coastguard Worker     size = Streams[index - Files.Size()].Size;
1011*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
1012*f6dc9357SAndroid Build Coastguard Worker   }
1013*f6dc9357SAndroid Build Coastguard Worker   const CDirItem &fi = Files[index];
1014*f6dc9357SAndroid Build Coastguard Worker   if (fi.IsDir())
1015*f6dc9357SAndroid Build Coastguard Worker   {
1016*f6dc9357SAndroid Build Coastguard Worker     UInt64 numFolders = 0, numFiles = 0;
1017*f6dc9357SAndroid Build Coastguard Worker     size = 0;
1018*f6dc9357SAndroid Build Coastguard Worker     return GetFolderSize(_path + GetRelPath(fi), numFolders, numFiles, size, progress);
1019*f6dc9357SAndroid Build Coastguard Worker   }
1020*f6dc9357SAndroid Build Coastguard Worker   size = fi.Size;
1021*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1022*f6dc9357SAndroid Build Coastguard Worker }
1023*f6dc9357SAndroid Build Coastguard Worker 
1024*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress)
1025*f6dc9357SAndroid Build Coastguard Worker {
1026*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
1027*f6dc9357SAndroid Build Coastguard Worker   UInt64 size = 0;
1028*f6dc9357SAndroid Build Coastguard Worker   HRESULT result = GetItemFullSize(index, size, progress);
1029*f6dc9357SAndroid Build Coastguard Worker   prop = size;
1030*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
1031*f6dc9357SAndroid Build Coastguard Worker   return result;
1032*f6dc9357SAndroid Build Coastguard Worker }
1033*f6dc9357SAndroid Build Coastguard Worker */
1034*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::CalcItemFullSize (UInt32 index,IProgress * progress))1035*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::CalcItemFullSize(UInt32 index, IProgress *progress))
1036*f6dc9357SAndroid Build Coastguard Worker {
1037*f6dc9357SAndroid Build Coastguard Worker   if (index >= Files.Size())
1038*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
1039*f6dc9357SAndroid Build Coastguard Worker   CDirItem &fi = Files[index];
1040*f6dc9357SAndroid Build Coastguard Worker   if (!fi.IsDir())
1041*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
1042*f6dc9357SAndroid Build Coastguard Worker   CFsFolderStat stat(_path + GetRelPath(fi), progress);
1043*f6dc9357SAndroid Build Coastguard Worker   RINOK(stat.Enumerate())
1044*f6dc9357SAndroid Build Coastguard Worker   fi.Size = stat.Size;
1045*f6dc9357SAndroid Build Coastguard Worker   fi.NumFolders = stat.NumFolders;
1046*f6dc9357SAndroid Build Coastguard Worker   fi.NumFiles = stat.NumFiles;
1047*f6dc9357SAndroid Build Coastguard Worker   fi.FolderStat_Defined = true;
1048*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1049*f6dc9357SAndroid Build Coastguard Worker }
1050*f6dc9357SAndroid Build Coastguard Worker 
GetAbsPath(const wchar_t * name,FString & absPath)1051*f6dc9357SAndroid Build Coastguard Worker void CFSFolder::GetAbsPath(const wchar_t *name, FString &absPath)
1052*f6dc9357SAndroid Build Coastguard Worker {
1053*f6dc9357SAndroid Build Coastguard Worker   absPath.Empty();
1054*f6dc9357SAndroid Build Coastguard Worker   if (!IsAbsolutePath(name))
1055*f6dc9357SAndroid Build Coastguard Worker     absPath += _path;
1056*f6dc9357SAndroid Build Coastguard Worker   absPath += us2fs(name);
1057*f6dc9357SAndroid Build Coastguard Worker }
1058*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::CreateFolder (const wchar_t * name,IProgress *))1059*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */))
1060*f6dc9357SAndroid Build Coastguard Worker {
1061*f6dc9357SAndroid Build Coastguard Worker   FString absPath;
1062*f6dc9357SAndroid Build Coastguard Worker   GetAbsPath(name, absPath);
1063*f6dc9357SAndroid Build Coastguard Worker   if (CreateDir(absPath))
1064*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
1065*f6dc9357SAndroid Build Coastguard Worker   if (::GetLastError() != ERROR_ALREADY_EXISTS)
1066*f6dc9357SAndroid Build Coastguard Worker     if (CreateComplexDir(absPath))
1067*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1068*f6dc9357SAndroid Build Coastguard Worker   return GetLastError_noZero_HRESULT();
1069*f6dc9357SAndroid Build Coastguard Worker }
1070*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::CreateFile (const wchar_t * name,IProgress *))1071*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */))
1072*f6dc9357SAndroid Build Coastguard Worker {
1073*f6dc9357SAndroid Build Coastguard Worker   FString absPath;
1074*f6dc9357SAndroid Build Coastguard Worker   GetAbsPath(name, absPath);
1075*f6dc9357SAndroid Build Coastguard Worker   NIO::COutFile outFile;
1076*f6dc9357SAndroid Build Coastguard Worker   if (!outFile.Create_NEW(absPath))
1077*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
1078*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1079*f6dc9357SAndroid Build Coastguard Worker }
1080*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::Rename (UInt32 index,const wchar_t * newName,IProgress *))1081*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */))
1082*f6dc9357SAndroid Build Coastguard Worker {
1083*f6dc9357SAndroid Build Coastguard Worker   if (index >= Files.Size())
1084*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
1085*f6dc9357SAndroid Build Coastguard Worker   const CDirItem &fi = Files[index];
1086*f6dc9357SAndroid Build Coastguard Worker   // FString prefix;
1087*f6dc9357SAndroid Build Coastguard Worker   // GetPrefix(fi, prefix);
1088*f6dc9357SAndroid Build Coastguard Worker   FString fullPrefix = _path;
1089*f6dc9357SAndroid Build Coastguard Worker   if (fi.Parent >= 0)
1090*f6dc9357SAndroid Build Coastguard Worker     fullPrefix += Folders[fi.Parent];
1091*f6dc9357SAndroid Build Coastguard Worker   if (!MyMoveFile(fullPrefix + fi.Name, fullPrefix + us2fs(newName)))
1092*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
1093*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1094*f6dc9357SAndroid Build Coastguard Worker }
1095*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::Delete (const UInt32 * indices,UInt32 numItems,IProgress * progress))1096*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress))
1097*f6dc9357SAndroid Build Coastguard Worker {
1098*f6dc9357SAndroid Build Coastguard Worker   RINOK(progress->SetTotal(numItems))
1099*f6dc9357SAndroid Build Coastguard Worker   // int prevDeletedFileIndex = -1;
1100*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItems; i++)
1101*f6dc9357SAndroid Build Coastguard Worker   {
1102*f6dc9357SAndroid Build Coastguard Worker     // Sleep(200);
1103*f6dc9357SAndroid Build Coastguard Worker     UInt32 index = indices[i];
1104*f6dc9357SAndroid Build Coastguard Worker     bool result = true;
1105*f6dc9357SAndroid Build Coastguard Worker     /*
1106*f6dc9357SAndroid Build Coastguard Worker     if (index >= Files.Size())
1107*f6dc9357SAndroid Build Coastguard Worker     {
1108*f6dc9357SAndroid Build Coastguard Worker       const CAltStream &ss = Streams[index - Files.Size()];
1109*f6dc9357SAndroid Build Coastguard Worker       if (prevDeletedFileIndex != ss.Parent)
1110*f6dc9357SAndroid Build Coastguard Worker       {
1111*f6dc9357SAndroid Build Coastguard Worker         const CDirItem &fi = Files[ss.Parent];
1112*f6dc9357SAndroid Build Coastguard Worker         result = DeleteFileAlways(_path + GetRelPath(fi) + us2fs(ss.Name));
1113*f6dc9357SAndroid Build Coastguard Worker       }
1114*f6dc9357SAndroid Build Coastguard Worker     }
1115*f6dc9357SAndroid Build Coastguard Worker     else
1116*f6dc9357SAndroid Build Coastguard Worker     */
1117*f6dc9357SAndroid Build Coastguard Worker     {
1118*f6dc9357SAndroid Build Coastguard Worker       const CDirItem &fi = Files[index];
1119*f6dc9357SAndroid Build Coastguard Worker       const FString fullPath = _path + GetRelPath(fi);
1120*f6dc9357SAndroid Build Coastguard Worker       // prevDeletedFileIndex = index;
1121*f6dc9357SAndroid Build Coastguard Worker       if (fi.IsDir())
1122*f6dc9357SAndroid Build Coastguard Worker         result = RemoveDirWithSubItems(fullPath);
1123*f6dc9357SAndroid Build Coastguard Worker       else
1124*f6dc9357SAndroid Build Coastguard Worker         result = DeleteFileAlways(fullPath);
1125*f6dc9357SAndroid Build Coastguard Worker     }
1126*f6dc9357SAndroid Build Coastguard Worker     if (!result)
1127*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
1128*f6dc9357SAndroid Build Coastguard Worker     const UInt64 completed = i;
1129*f6dc9357SAndroid Build Coastguard Worker     RINOK(progress->SetCompleted(&completed))
1130*f6dc9357SAndroid Build Coastguard Worker   }
1131*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1132*f6dc9357SAndroid Build Coastguard Worker }
1133*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::SetProperty (UInt32 index,PROPID propID,const PROPVARIANT * value,IProgress *))1134*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::SetProperty(UInt32 index, PROPID propID,
1135*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT *value, IProgress * /* progress */))
1136*f6dc9357SAndroid Build Coastguard Worker {
1137*f6dc9357SAndroid Build Coastguard Worker   if (index >= Files.Size())
1138*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
1139*f6dc9357SAndroid Build Coastguard Worker   CDirItem &fi = Files[index];
1140*f6dc9357SAndroid Build Coastguard Worker   if (fi.Parent >= 0)
1141*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
1142*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
1143*f6dc9357SAndroid Build Coastguard Worker   {
1144*f6dc9357SAndroid Build Coastguard Worker     case kpidComment:
1145*f6dc9357SAndroid Build Coastguard Worker     {
1146*f6dc9357SAndroid Build Coastguard Worker       UString filename = fs2us(fi.Name);
1147*f6dc9357SAndroid Build Coastguard Worker       filename.Trim();
1148*f6dc9357SAndroid Build Coastguard Worker       if (value->vt == VT_EMPTY)
1149*f6dc9357SAndroid Build Coastguard Worker         _comments.DeletePair(filename);
1150*f6dc9357SAndroid Build Coastguard Worker       else if (value->vt == VT_BSTR)
1151*f6dc9357SAndroid Build Coastguard Worker       {
1152*f6dc9357SAndroid Build Coastguard Worker         CTextPair pair;
1153*f6dc9357SAndroid Build Coastguard Worker         pair.ID = filename;
1154*f6dc9357SAndroid Build Coastguard Worker         pair.ID.Trim();
1155*f6dc9357SAndroid Build Coastguard Worker         pair.Value.SetFromBstr(value->bstrVal);
1156*f6dc9357SAndroid Build Coastguard Worker         pair.Value.Trim();
1157*f6dc9357SAndroid Build Coastguard Worker         if (pair.Value.IsEmpty())
1158*f6dc9357SAndroid Build Coastguard Worker           _comments.DeletePair(filename);
1159*f6dc9357SAndroid Build Coastguard Worker         else
1160*f6dc9357SAndroid Build Coastguard Worker           _comments.AddPair(pair);
1161*f6dc9357SAndroid Build Coastguard Worker       }
1162*f6dc9357SAndroid Build Coastguard Worker       else
1163*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
1164*f6dc9357SAndroid Build Coastguard Worker       SaveComments();
1165*f6dc9357SAndroid Build Coastguard Worker       break;
1166*f6dc9357SAndroid Build Coastguard Worker     }
1167*f6dc9357SAndroid Build Coastguard Worker     default:
1168*f6dc9357SAndroid Build Coastguard Worker       return E_NOTIMPL;
1169*f6dc9357SAndroid Build Coastguard Worker   }
1170*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1171*f6dc9357SAndroid Build Coastguard Worker }
1172*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::GetSystemIconIndex (UInt32 index,Int32 * iconIndex))1173*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex))
1174*f6dc9357SAndroid Build Coastguard Worker {
1175*f6dc9357SAndroid Build Coastguard Worker   *iconIndex = -1;
1176*f6dc9357SAndroid Build Coastguard Worker   if (index >= Files.Size())
1177*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
1178*f6dc9357SAndroid Build Coastguard Worker   const CDirItem &fi = Files[index];
1179*f6dc9357SAndroid Build Coastguard Worker   return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
1180*f6dc9357SAndroid Build Coastguard Worker       _path + GetRelPath(fi), fi.Attrib, iconIndex);
1181*f6dc9357SAndroid Build Coastguard Worker }
1182*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSFolder::SetFlatMode (Int32 flatMode))1183*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::SetFlatMode(Int32 flatMode))
1184*f6dc9357SAndroid Build Coastguard Worker {
1185*f6dc9357SAndroid Build Coastguard Worker   _flatMode = IntToBool(flatMode);
1186*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1187*f6dc9357SAndroid Build Coastguard Worker }
1188*f6dc9357SAndroid Build Coastguard Worker 
1189*f6dc9357SAndroid Build Coastguard Worker /*
1190*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::SetShowNtfsStreamsMode(Int32 showStreamsMode)
1191*f6dc9357SAndroid Build Coastguard Worker {
1192*f6dc9357SAndroid Build Coastguard Worker   _scanAltStreams = IntToBool(showStreamsMode);
1193*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1194*f6dc9357SAndroid Build Coastguard Worker }
1195*f6dc9357SAndroid Build Coastguard Worker */
1196*f6dc9357SAndroid Build Coastguard Worker 
1197*f6dc9357SAndroid Build Coastguard Worker }
1198