xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // AltStreamsFolder.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/StringConvert.h"
28*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
29*f6dc9357SAndroid Build Coastguard Worker 
30*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/DLL.h"
31*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/ErrorMsg.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 "../Common/ExtractingFilePath.h"
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker #include "../Agent/IFolderArchive.h"
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker #include "AltStreamsFolder.h"
42*f6dc9357SAndroid Build Coastguard Worker #include "FSDrives.h"
43*f6dc9357SAndroid Build Coastguard Worker #include "FSFolder.h"
44*f6dc9357SAndroid Build Coastguard Worker 
45*f6dc9357SAndroid Build Coastguard Worker #include "SysIconUtils.h"
46*f6dc9357SAndroid Build Coastguard Worker 
47*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
48*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
49*f6dc9357SAndroid Build Coastguard Worker using namespace NFind;
50*f6dc9357SAndroid Build Coastguard Worker using namespace NDir;
51*f6dc9357SAndroid Build Coastguard Worker using namespace NName;
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
54*f6dc9357SAndroid Build Coastguard Worker int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2);
55*f6dc9357SAndroid Build Coastguard Worker #endif
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker namespace NFsFolder
60*f6dc9357SAndroid Build Coastguard Worker {
61*f6dc9357SAndroid Build Coastguard Worker bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size);
62*f6dc9357SAndroid Build Coastguard Worker }
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker #endif
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker namespace NAltStreamsFolder {
67*f6dc9357SAndroid Build Coastguard Worker 
68*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
69*f6dc9357SAndroid Build Coastguard Worker {
70*f6dc9357SAndroid Build Coastguard Worker   kpidName,
71*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
72*f6dc9357SAndroid Build Coastguard Worker   kpidPackSize
73*f6dc9357SAndroid Build Coastguard Worker };
74*f6dc9357SAndroid Build Coastguard Worker 
GetFsParentPrefixSize(const FString & path)75*f6dc9357SAndroid Build Coastguard Worker static unsigned GetFsParentPrefixSize(const FString &path)
76*f6dc9357SAndroid Build Coastguard Worker {
77*f6dc9357SAndroid Build Coastguard Worker   if (IsNetworkShareRootPath(path))
78*f6dc9357SAndroid Build Coastguard Worker     return 0;
79*f6dc9357SAndroid Build Coastguard Worker   const unsigned prefixSize = GetRootPrefixSize(path);
80*f6dc9357SAndroid Build Coastguard Worker   if (prefixSize == 0 || prefixSize >= path.Len())
81*f6dc9357SAndroid Build Coastguard Worker     return 0;
82*f6dc9357SAndroid Build Coastguard Worker   FString parentPath = path;
83*f6dc9357SAndroid Build Coastguard Worker   int pos = parentPath.ReverseFind_PathSepar();
84*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
85*f6dc9357SAndroid Build Coastguard Worker     return 0;
86*f6dc9357SAndroid Build Coastguard Worker   if (pos == (int)parentPath.Len() - 1)
87*f6dc9357SAndroid Build Coastguard Worker   {
88*f6dc9357SAndroid Build Coastguard Worker     parentPath.DeleteBack();
89*f6dc9357SAndroid Build Coastguard Worker     pos = parentPath.ReverseFind_PathSepar();
90*f6dc9357SAndroid Build Coastguard Worker     if (pos < 0)
91*f6dc9357SAndroid Build Coastguard Worker       return 0;
92*f6dc9357SAndroid Build Coastguard Worker   }
93*f6dc9357SAndroid Build Coastguard Worker   if ((unsigned)pos + 1 < prefixSize)
94*f6dc9357SAndroid Build Coastguard Worker     return 0;
95*f6dc9357SAndroid Build Coastguard Worker   return (unsigned)pos + 1;
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker 
Init(const FString & path)98*f6dc9357SAndroid Build Coastguard Worker HRESULT CAltStreamsFolder::Init(const FString &path /* , IFolderFolder *parentFolder */)
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker    // _parentFolder = parentFolder;
101*f6dc9357SAndroid Build Coastguard Worker    if (path.Back() != ':')
102*f6dc9357SAndroid Build Coastguard Worker      return E_FAIL;
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker   _pathPrefix = path;
105*f6dc9357SAndroid Build Coastguard Worker   _pathBaseFile = path;
106*f6dc9357SAndroid Build Coastguard Worker   _pathBaseFile.DeleteBack();
107*f6dc9357SAndroid Build Coastguard Worker 
108*f6dc9357SAndroid Build Coastguard Worker   {
109*f6dc9357SAndroid Build Coastguard Worker     CFileInfo fi;
110*f6dc9357SAndroid Build Coastguard Worker     if (!fi.Find(_pathBaseFile))
111*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
112*f6dc9357SAndroid Build Coastguard Worker   }
113*f6dc9357SAndroid Build Coastguard Worker 
114*f6dc9357SAndroid Build Coastguard Worker   unsigned prefixSize = GetFsParentPrefixSize(_pathBaseFile);
115*f6dc9357SAndroid Build Coastguard Worker   if (prefixSize == 0)
116*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
117*f6dc9357SAndroid Build Coastguard Worker   FString parentPath = _pathBaseFile;
118*f6dc9357SAndroid Build Coastguard Worker   parentPath.DeleteFrom(prefixSize);
119*f6dc9357SAndroid Build Coastguard Worker 
120*f6dc9357SAndroid Build Coastguard Worker   _findChangeNotification.FindFirst(parentPath, false,
121*f6dc9357SAndroid Build Coastguard Worker         FILE_NOTIFY_CHANGE_FILE_NAME
122*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_DIR_NAME
123*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_ATTRIBUTES
124*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_SIZE
125*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_LAST_WRITE
126*f6dc9357SAndroid Build Coastguard Worker       /*
127*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_LAST_ACCESS
128*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_CREATION
129*f6dc9357SAndroid Build Coastguard Worker       | FILE_NOTIFY_CHANGE_SECURITY
130*f6dc9357SAndroid Build Coastguard Worker       */
131*f6dc9357SAndroid Build Coastguard Worker       );
132*f6dc9357SAndroid Build Coastguard Worker   /*
133*f6dc9357SAndroid Build Coastguard Worker   if (_findChangeNotification.IsHandleAllocated())
134*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
135*f6dc9357SAndroid Build Coastguard Worker   return GetLastError();
136*f6dc9357SAndroid Build Coastguard Worker   */
137*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
138*f6dc9357SAndroid Build Coastguard Worker }
139*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::LoadItems ())140*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::LoadItems())
141*f6dc9357SAndroid Build Coastguard Worker {
142*f6dc9357SAndroid Build Coastguard Worker   Int32 dummy;
143*f6dc9357SAndroid Build Coastguard Worker   WasChanged(&dummy);
144*f6dc9357SAndroid Build Coastguard Worker   Clear();
145*f6dc9357SAndroid Build Coastguard Worker 
146*f6dc9357SAndroid Build Coastguard Worker   CStreamEnumerator enumerator(_pathBaseFile);
147*f6dc9357SAndroid Build Coastguard Worker 
148*f6dc9357SAndroid Build Coastguard Worker   CStreamInfo si;
149*f6dc9357SAndroid Build Coastguard Worker   for (;;)
150*f6dc9357SAndroid Build Coastguard Worker   {
151*f6dc9357SAndroid Build Coastguard Worker     bool found;
152*f6dc9357SAndroid Build Coastguard Worker     if (!enumerator.Next(si, found))
153*f6dc9357SAndroid Build Coastguard Worker     {
154*f6dc9357SAndroid Build Coastguard Worker       // if (GetLastError() == ERROR_ACCESS_DENIED)
155*f6dc9357SAndroid Build Coastguard Worker       //   break;
156*f6dc9357SAndroid Build Coastguard Worker       // return E_FAIL;
157*f6dc9357SAndroid Build Coastguard Worker       break;
158*f6dc9357SAndroid Build Coastguard Worker     }
159*f6dc9357SAndroid Build Coastguard Worker     if (!found)
160*f6dc9357SAndroid Build Coastguard Worker       break;
161*f6dc9357SAndroid Build Coastguard Worker     if (si.IsMainStream())
162*f6dc9357SAndroid Build Coastguard Worker       continue;
163*f6dc9357SAndroid Build Coastguard Worker     CAltStream ss;
164*f6dc9357SAndroid Build Coastguard Worker     ss.Name = si.GetReducedName();
165*f6dc9357SAndroid Build Coastguard Worker     if (!ss.Name.IsEmpty() && ss.Name[0] == ':')
166*f6dc9357SAndroid Build Coastguard Worker       ss.Name.Delete(0);
167*f6dc9357SAndroid Build Coastguard Worker 
168*f6dc9357SAndroid Build Coastguard Worker     ss.Size = si.Size;
169*f6dc9357SAndroid Build Coastguard Worker     ss.PackSize_Defined = false;
170*f6dc9357SAndroid Build Coastguard Worker     ss.PackSize = si.Size;
171*f6dc9357SAndroid Build Coastguard Worker     Streams.Add(ss);
172*f6dc9357SAndroid Build Coastguard Worker   }
173*f6dc9357SAndroid Build Coastguard Worker 
174*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
175*f6dc9357SAndroid Build Coastguard Worker }
176*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::GetNumberOfItems (UInt32 * numItems))177*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::GetNumberOfItems(UInt32 *numItems))
178*f6dc9357SAndroid Build Coastguard Worker {
179*f6dc9357SAndroid Build Coastguard Worker   *numItems = Streams.Size();
180*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
181*f6dc9357SAndroid Build Coastguard Worker }
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_UNICODE_FSTRING
184*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::GetItemPrefix (UInt32,const wchar_t ** name,unsigned * len))185*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::GetItemPrefix(UInt32 /* index */, const wchar_t **name, unsigned *len))
186*f6dc9357SAndroid Build Coastguard Worker {
187*f6dc9357SAndroid Build Coastguard Worker   *name = NULL;
188*f6dc9357SAndroid Build Coastguard Worker   *len = 0;
189*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
190*f6dc9357SAndroid Build Coastguard Worker }
191*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::GetItemName (UInt32 index,const wchar_t ** name,unsigned * len))192*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len))
193*f6dc9357SAndroid Build Coastguard Worker {
194*f6dc9357SAndroid Build Coastguard Worker   *name = NULL;
195*f6dc9357SAndroid Build Coastguard Worker   *len = 0;
196*f6dc9357SAndroid Build Coastguard Worker   {
197*f6dc9357SAndroid Build Coastguard Worker     const CAltStream &ss = Streams[index];
198*f6dc9357SAndroid Build Coastguard Worker     *name = ss.Name;
199*f6dc9357SAndroid Build Coastguard Worker     *len = ss.Name.Len();
200*f6dc9357SAndroid Build Coastguard Worker   }
201*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
202*f6dc9357SAndroid Build Coastguard Worker }
203*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF2(UInt64,CAltStreamsFolder::GetItemSize (UInt32 index))204*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF2(UInt64, CAltStreamsFolder::GetItemSize(UInt32 index))
205*f6dc9357SAndroid Build Coastguard Worker {
206*f6dc9357SAndroid Build Coastguard Worker   return Streams[index].Size;
207*f6dc9357SAndroid Build Coastguard Worker }
208*f6dc9357SAndroid Build Coastguard Worker 
209*f6dc9357SAndroid Build Coastguard Worker #endif
210*f6dc9357SAndroid Build Coastguard Worker 
211*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::GetProperty (UInt32 index,PROPID propID,PROPVARIANT * value))212*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
213*f6dc9357SAndroid Build Coastguard Worker {
214*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
215*f6dc9357SAndroid Build Coastguard Worker   {
216*f6dc9357SAndroid Build Coastguard Worker     CAltStream &ss = Streams[index];
217*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
218*f6dc9357SAndroid Build Coastguard Worker     {
219*f6dc9357SAndroid Build Coastguard Worker       case kpidIsDir: prop = false; break;
220*f6dc9357SAndroid Build Coastguard Worker       case kpidIsAltStream: prop = true; break;
221*f6dc9357SAndroid Build Coastguard Worker       case kpidName: prop = ss.Name; break;
222*f6dc9357SAndroid Build Coastguard Worker       case kpidSize: prop = ss.Size; break;
223*f6dc9357SAndroid Build Coastguard Worker       case kpidPackSize:
224*f6dc9357SAndroid Build Coastguard Worker         #ifdef UNDER_CE
225*f6dc9357SAndroid Build Coastguard Worker         prop = ss.Size;
226*f6dc9357SAndroid Build Coastguard Worker         #else
227*f6dc9357SAndroid Build Coastguard Worker         if (!ss.PackSize_Defined)
228*f6dc9357SAndroid Build Coastguard Worker         {
229*f6dc9357SAndroid Build Coastguard Worker           ss.PackSize_Defined = true;
230*f6dc9357SAndroid Build Coastguard Worker           if (!NFsFolder::MyGetCompressedFileSizeW(_pathPrefix + us2fs(ss.Name), ss.PackSize))
231*f6dc9357SAndroid Build Coastguard Worker             ss.PackSize = ss.Size;
232*f6dc9357SAndroid Build Coastguard Worker         }
233*f6dc9357SAndroid Build Coastguard Worker         prop = ss.PackSize;
234*f6dc9357SAndroid Build Coastguard Worker         #endif
235*f6dc9357SAndroid Build Coastguard Worker         break;
236*f6dc9357SAndroid Build Coastguard Worker     }
237*f6dc9357SAndroid Build Coastguard Worker   }
238*f6dc9357SAndroid Build Coastguard Worker 
239*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
240*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
241*f6dc9357SAndroid Build Coastguard Worker }
242*f6dc9357SAndroid Build Coastguard Worker 
243*f6dc9357SAndroid Build Coastguard Worker 
244*f6dc9357SAndroid Build Coastguard Worker // returns Position of extension including '.'
245*f6dc9357SAndroid Build Coastguard Worker 
GetExtensionPtr(const UString & name)246*f6dc9357SAndroid Build Coastguard Worker static inline const wchar_t *GetExtensionPtr(const UString &name)
247*f6dc9357SAndroid Build Coastguard Worker {
248*f6dc9357SAndroid Build Coastguard Worker   const int dotPos = name.ReverseFind_Dot();
249*f6dc9357SAndroid Build Coastguard Worker   return name.Ptr(dotPos < 0 ? name.Len() : (unsigned)dotPos);
250*f6dc9357SAndroid Build Coastguard Worker }
251*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF2(Int32,CAltStreamsFolder::CompareItems (UInt32 index1,UInt32 index2,PROPID propID,Int32))252*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF2(Int32, CAltStreamsFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */))
253*f6dc9357SAndroid Build Coastguard Worker {
254*f6dc9357SAndroid Build Coastguard Worker   const CAltStream &ss1 = Streams[index1];
255*f6dc9357SAndroid Build Coastguard Worker   const CAltStream &ss2 = Streams[index2];
256*f6dc9357SAndroid Build Coastguard Worker 
257*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
258*f6dc9357SAndroid Build Coastguard Worker   {
259*f6dc9357SAndroid Build Coastguard Worker     case kpidName:
260*f6dc9357SAndroid Build Coastguard Worker     {
261*f6dc9357SAndroid Build Coastguard Worker       return CompareFileNames_ForFolderList(ss1.Name, ss2.Name);
262*f6dc9357SAndroid Build Coastguard Worker       // return MyStringCompareNoCase(ss1.Name, ss2.Name);
263*f6dc9357SAndroid Build Coastguard Worker     }
264*f6dc9357SAndroid Build Coastguard Worker     case kpidSize:
265*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(ss1.Size, ss2.Size);
266*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize:
267*f6dc9357SAndroid Build Coastguard Worker     {
268*f6dc9357SAndroid Build Coastguard Worker       #ifdef UNDER_CE
269*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(ss1.Size, ss2.Size);
270*f6dc9357SAndroid Build Coastguard Worker       #else
271*f6dc9357SAndroid Build Coastguard Worker       // PackSize can be undefined here
272*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(
273*f6dc9357SAndroid Build Coastguard Worker           ss1.PackSize,
274*f6dc9357SAndroid Build Coastguard Worker           ss2.PackSize);
275*f6dc9357SAndroid Build Coastguard Worker       #endif
276*f6dc9357SAndroid Build Coastguard Worker     }
277*f6dc9357SAndroid Build Coastguard Worker 
278*f6dc9357SAndroid Build Coastguard Worker     case kpidExtension:
279*f6dc9357SAndroid Build Coastguard Worker       return CompareFileNames_ForFolderList(
280*f6dc9357SAndroid Build Coastguard Worker           GetExtensionPtr(ss1.Name),
281*f6dc9357SAndroid Build Coastguard Worker           GetExtensionPtr(ss2.Name));
282*f6dc9357SAndroid Build Coastguard Worker   }
283*f6dc9357SAndroid Build Coastguard Worker 
284*f6dc9357SAndroid Build Coastguard Worker   return 0;
285*f6dc9357SAndroid Build Coastguard Worker }
286*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::BindToFolder (UInt32,IFolderFolder ** resultFolder))287*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::BindToFolder(UInt32 /* index */, IFolderFolder **resultFolder))
288*f6dc9357SAndroid Build Coastguard Worker {
289*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
290*f6dc9357SAndroid Build Coastguard Worker   return E_INVALIDARG;
291*f6dc9357SAndroid Build Coastguard Worker }
292*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::BindToFolder (const wchar_t *,IFolderFolder ** resultFolder))293*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder **resultFolder))
294*f6dc9357SAndroid Build Coastguard Worker {
295*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
296*f6dc9357SAndroid Build Coastguard Worker   return E_INVALIDARG;
297*f6dc9357SAndroid Build Coastguard Worker }
298*f6dc9357SAndroid Build Coastguard Worker 
299*f6dc9357SAndroid Build Coastguard Worker // static CFSTR const kSuperPrefix = FTEXT("\\\\?\\");
300*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::BindToParentFolder (IFolderFolder ** resultFolder))301*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::BindToParentFolder(IFolderFolder **resultFolder))
302*f6dc9357SAndroid Build Coastguard Worker {
303*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
304*f6dc9357SAndroid Build Coastguard Worker   /*
305*f6dc9357SAndroid Build Coastguard Worker   if (_parentFolder)
306*f6dc9357SAndroid Build Coastguard Worker   {
307*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
308*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = parentFolder.Detach();
309*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
310*f6dc9357SAndroid Build Coastguard Worker   }
311*f6dc9357SAndroid Build Coastguard Worker   */
312*f6dc9357SAndroid Build Coastguard Worker 
313*f6dc9357SAndroid Build Coastguard Worker   if (IsDriveRootPath_SuperAllowed(_pathBaseFile))
314*f6dc9357SAndroid Build Coastguard Worker   {
315*f6dc9357SAndroid Build Coastguard Worker     CFSDrives *drivesFolderSpec = new CFSDrives;
316*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
317*f6dc9357SAndroid Build Coastguard Worker     drivesFolderSpec->Init();
318*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = drivesFolder.Detach();
319*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
320*f6dc9357SAndroid Build Coastguard Worker   }
321*f6dc9357SAndroid Build Coastguard Worker 
322*f6dc9357SAndroid Build Coastguard Worker   /*
323*f6dc9357SAndroid Build Coastguard Worker   parentPath.DeleteFrom(pos + 1);
324*f6dc9357SAndroid Build Coastguard Worker 
325*f6dc9357SAndroid Build Coastguard Worker   if (parentPath == kSuperPrefix)
326*f6dc9357SAndroid Build Coastguard Worker   {
327*f6dc9357SAndroid Build Coastguard Worker     #ifdef UNDER_CE
328*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = 0;
329*f6dc9357SAndroid Build Coastguard Worker     #else
330*f6dc9357SAndroid Build Coastguard Worker     CFSDrives *drivesFolderSpec = new CFSDrives;
331*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
332*f6dc9357SAndroid Build Coastguard Worker     drivesFolderSpec->Init(false, true);
333*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = drivesFolder.Detach();
334*f6dc9357SAndroid Build Coastguard Worker     #endif
335*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
336*f6dc9357SAndroid Build Coastguard Worker   }
337*f6dc9357SAndroid Build Coastguard Worker 
338*f6dc9357SAndroid Build Coastguard Worker   FString parentPathReduced = parentPath.Left(pos);
339*f6dc9357SAndroid Build Coastguard Worker 
340*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
341*f6dc9357SAndroid Build Coastguard Worker   pos = parentPathReduced.ReverseFind_PathSepar();
342*f6dc9357SAndroid Build Coastguard Worker   if (pos == 1)
343*f6dc9357SAndroid Build Coastguard Worker   {
344*f6dc9357SAndroid Build Coastguard Worker     if (!IS_PATH_SEPAR_CHAR(parentPath[0]))
345*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
346*f6dc9357SAndroid Build Coastguard Worker     CNetFolder *netFolderSpec = new CNetFolder;
347*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
348*f6dc9357SAndroid Build Coastguard Worker     netFolderSpec->Init(fs2us(parentPath));
349*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = netFolder.Detach();
350*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
351*f6dc9357SAndroid Build Coastguard Worker   }
352*f6dc9357SAndroid Build Coastguard Worker   #endif
353*f6dc9357SAndroid Build Coastguard Worker 
354*f6dc9357SAndroid Build Coastguard Worker   CFSFolder *parentFolderSpec = new CFSFolder;
355*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
356*f6dc9357SAndroid Build Coastguard Worker   RINOK(parentFolderSpec->Init(parentPath, 0));
357*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = parentFolder.Detach();
358*f6dc9357SAndroid Build Coastguard Worker   */
359*f6dc9357SAndroid Build Coastguard Worker 
360*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
361*f6dc9357SAndroid Build Coastguard Worker }
362*f6dc9357SAndroid Build Coastguard Worker 
363*f6dc9357SAndroid Build Coastguard Worker IMP_IFolderFolder_Props(CAltStreamsFolder)
364*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::GetFolderProperty (PROPID propID,PROPVARIANT * value))365*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value))
366*f6dc9357SAndroid Build Coastguard Worker {
367*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
368*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
369*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
370*f6dc9357SAndroid Build Coastguard Worker   {
371*f6dc9357SAndroid Build Coastguard Worker     case kpidType: prop = "AltStreamsFolder"; break;
372*f6dc9357SAndroid Build Coastguard Worker     case kpidPath: prop = fs2us(_pathPrefix); break;
373*f6dc9357SAndroid Build Coastguard Worker   }
374*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
375*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
376*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
377*f6dc9357SAndroid Build Coastguard Worker }
378*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::WasChanged (Int32 * wasChanged))379*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::WasChanged(Int32 *wasChanged))
380*f6dc9357SAndroid Build Coastguard Worker {
381*f6dc9357SAndroid Build Coastguard Worker   bool wasChangedMain = false;
382*f6dc9357SAndroid Build Coastguard Worker   for (;;)
383*f6dc9357SAndroid Build Coastguard Worker   {
384*f6dc9357SAndroid Build Coastguard Worker     if (!_findChangeNotification.IsHandleAllocated())
385*f6dc9357SAndroid Build Coastguard Worker     {
386*f6dc9357SAndroid Build Coastguard Worker       *wasChanged = BoolToInt(false);
387*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
388*f6dc9357SAndroid Build Coastguard Worker     }
389*f6dc9357SAndroid Build Coastguard Worker 
390*f6dc9357SAndroid Build Coastguard Worker     const DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
391*f6dc9357SAndroid Build Coastguard Worker     const bool wasChangedLoc = (waitResult == WAIT_OBJECT_0);
392*f6dc9357SAndroid Build Coastguard Worker     if (wasChangedLoc)
393*f6dc9357SAndroid Build Coastguard Worker     {
394*f6dc9357SAndroid Build Coastguard Worker       _findChangeNotification.FindNext();
395*f6dc9357SAndroid Build Coastguard Worker       wasChangedMain = true;
396*f6dc9357SAndroid Build Coastguard Worker     }
397*f6dc9357SAndroid Build Coastguard Worker     else
398*f6dc9357SAndroid Build Coastguard Worker       break;
399*f6dc9357SAndroid Build Coastguard Worker   }
400*f6dc9357SAndroid Build Coastguard Worker   *wasChanged = BoolToInt(wasChangedMain);
401*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
402*f6dc9357SAndroid Build Coastguard Worker }
403*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::Clone (IFolderFolder ** resultFolder))404*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::Clone(IFolderFolder **resultFolder))
405*f6dc9357SAndroid Build Coastguard Worker {
406*f6dc9357SAndroid Build Coastguard Worker   CAltStreamsFolder *folderSpec = new CAltStreamsFolder;
407*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderFolder> folderNew = folderSpec;
408*f6dc9357SAndroid Build Coastguard Worker   folderSpec->Init(_pathPrefix);
409*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = folderNew.Detach();
410*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
411*f6dc9357SAndroid Build Coastguard Worker }
412*f6dc9357SAndroid Build Coastguard Worker 
GetAbsPath(const wchar_t * name,FString & absPath)413*f6dc9357SAndroid Build Coastguard Worker void CAltStreamsFolder::GetAbsPath(const wchar_t *name, FString &absPath)
414*f6dc9357SAndroid Build Coastguard Worker {
415*f6dc9357SAndroid Build Coastguard Worker   absPath.Empty();
416*f6dc9357SAndroid Build Coastguard Worker   if (!IsAbsolutePath(name))
417*f6dc9357SAndroid Build Coastguard Worker     absPath += _pathPrefix;
418*f6dc9357SAndroid Build Coastguard Worker   absPath += us2fs(name);
419*f6dc9357SAndroid Build Coastguard Worker }
420*f6dc9357SAndroid Build Coastguard Worker 
421*f6dc9357SAndroid Build Coastguard Worker 
422*f6dc9357SAndroid Build Coastguard Worker 
SendMessageError(IFolderOperationsExtractCallback * callback,const wchar_t * message,const FString & fileName)423*f6dc9357SAndroid Build Coastguard Worker static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
424*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *message, const FString &fileName)
425*f6dc9357SAndroid Build Coastguard Worker {
426*f6dc9357SAndroid Build Coastguard Worker   UString s = message;
427*f6dc9357SAndroid Build Coastguard Worker   s += " : ";
428*f6dc9357SAndroid Build Coastguard Worker   s += fs2us(fileName);
429*f6dc9357SAndroid Build Coastguard Worker   return callback->ShowMessage(s);
430*f6dc9357SAndroid Build Coastguard Worker }
431*f6dc9357SAndroid Build Coastguard Worker 
SendMessageError(IFolderArchiveUpdateCallback * callback,const wchar_t * message,const FString & fileName)432*f6dc9357SAndroid Build Coastguard Worker static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback,
433*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *message, const FString &fileName)
434*f6dc9357SAndroid Build Coastguard Worker {
435*f6dc9357SAndroid Build Coastguard Worker   UString s = message;
436*f6dc9357SAndroid Build Coastguard Worker   s += " : ";
437*f6dc9357SAndroid Build Coastguard Worker   s += fs2us(fileName);
438*f6dc9357SAndroid Build Coastguard Worker   return callback->UpdateErrorMessage(s);
439*f6dc9357SAndroid Build Coastguard Worker }
440*f6dc9357SAndroid Build Coastguard Worker 
SendMessageError(IFolderOperationsExtractCallback * callback,const char * message,const FString & fileName)441*f6dc9357SAndroid Build Coastguard Worker static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
442*f6dc9357SAndroid Build Coastguard Worker     const char *message, const FString &fileName)
443*f6dc9357SAndroid Build Coastguard Worker {
444*f6dc9357SAndroid Build Coastguard Worker   return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
445*f6dc9357SAndroid Build Coastguard Worker }
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker /*
448*f6dc9357SAndroid Build Coastguard Worker static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback,
449*f6dc9357SAndroid Build Coastguard Worker     const char *message, const FString &fileName)
450*f6dc9357SAndroid Build Coastguard Worker {
451*f6dc9357SAndroid Build Coastguard Worker   return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
452*f6dc9357SAndroid Build Coastguard Worker }
453*f6dc9357SAndroid Build Coastguard Worker */
454*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::CreateFolder (const wchar_t *,IProgress *))455*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */))
456*f6dc9357SAndroid Build Coastguard Worker {
457*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
458*f6dc9357SAndroid Build Coastguard Worker }
459*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::CreateFile (const wchar_t * name,IProgress *))460*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::CreateFile(const wchar_t *name, IProgress * /* progress */))
461*f6dc9357SAndroid Build Coastguard Worker {
462*f6dc9357SAndroid Build Coastguard Worker   FString absPath;
463*f6dc9357SAndroid Build Coastguard Worker   GetAbsPath(name, absPath);
464*f6dc9357SAndroid Build Coastguard Worker   NIO::COutFile outFile;
465*f6dc9357SAndroid Build Coastguard Worker   if (!outFile.Create_NEW(absPath))
466*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
467*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
468*f6dc9357SAndroid Build Coastguard Worker }
469*f6dc9357SAndroid Build Coastguard Worker 
GetLastErrorMessage()470*f6dc9357SAndroid Build Coastguard Worker static UString GetLastErrorMessage()
471*f6dc9357SAndroid Build Coastguard Worker {
472*f6dc9357SAndroid Build Coastguard Worker   return NError::MyFormatMessage(GetLastError_noZero_HRESULT());
473*f6dc9357SAndroid Build Coastguard Worker }
474*f6dc9357SAndroid Build Coastguard Worker 
UpdateFile(NFsFolder::CCopyStateIO & state,CFSTR inPath,CFSTR outPath,IFolderArchiveUpdateCallback * callback)475*f6dc9357SAndroid Build Coastguard Worker static HRESULT UpdateFile(NFsFolder::CCopyStateIO &state, CFSTR inPath, CFSTR outPath, IFolderArchiveUpdateCallback *callback)
476*f6dc9357SAndroid Build Coastguard Worker {
477*f6dc9357SAndroid Build Coastguard Worker   if (NFind::DoesFileOrDirExist(outPath))
478*f6dc9357SAndroid Build Coastguard Worker   {
479*f6dc9357SAndroid Build Coastguard Worker     RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), FString(outPath)))
480*f6dc9357SAndroid Build Coastguard Worker     CFileInfo fi;
481*f6dc9357SAndroid Build Coastguard Worker     if (fi.Find(inPath))
482*f6dc9357SAndroid Build Coastguard Worker     {
483*f6dc9357SAndroid Build Coastguard Worker       if (state.TotalSize >= fi.Size)
484*f6dc9357SAndroid Build Coastguard Worker         state.TotalSize -= fi.Size;
485*f6dc9357SAndroid Build Coastguard Worker     }
486*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
487*f6dc9357SAndroid Build Coastguard Worker   }
488*f6dc9357SAndroid Build Coastguard Worker 
489*f6dc9357SAndroid Build Coastguard Worker   {
490*f6dc9357SAndroid Build Coastguard Worker     if (callback)
491*f6dc9357SAndroid Build Coastguard Worker       RINOK(callback->CompressOperation(fs2us(inPath)))
492*f6dc9357SAndroid Build Coastguard Worker     RINOK(state.MyCopyFile(inPath, outPath))
493*f6dc9357SAndroid Build Coastguard Worker     if (state.ErrorFileIndex >= 0)
494*f6dc9357SAndroid Build Coastguard Worker     {
495*f6dc9357SAndroid Build Coastguard Worker       if (state.ErrorMessage.IsEmpty())
496*f6dc9357SAndroid Build Coastguard Worker         state.ErrorMessage = GetLastErrorMessage();
497*f6dc9357SAndroid Build Coastguard Worker       FString errorName;
498*f6dc9357SAndroid Build Coastguard Worker       if (state.ErrorFileIndex == 0)
499*f6dc9357SAndroid Build Coastguard Worker         errorName = inPath;
500*f6dc9357SAndroid Build Coastguard Worker       else
501*f6dc9357SAndroid Build Coastguard Worker         errorName = outPath;
502*f6dc9357SAndroid Build Coastguard Worker       if (callback)
503*f6dc9357SAndroid Build Coastguard Worker         RINOK(SendMessageError(callback, state.ErrorMessage, errorName))
504*f6dc9357SAndroid Build Coastguard Worker     }
505*f6dc9357SAndroid Build Coastguard Worker     if (callback)
506*f6dc9357SAndroid Build Coastguard Worker       RINOK(callback->OperationResult(0))
507*f6dc9357SAndroid Build Coastguard Worker   }
508*f6dc9357SAndroid Build Coastguard Worker 
509*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
510*f6dc9357SAndroid Build Coastguard Worker }
511*f6dc9357SAndroid Build Coastguard Worker 
512*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
513*f6dc9357SAndroid Build Coastguard Worker 
514*f6dc9357SAndroid Build Coastguard Worker typedef enum
515*f6dc9357SAndroid Build Coastguard Worker {
516*f6dc9357SAndroid Build Coastguard Worker   Z7_WIN_FileRenameInformation = 10
517*f6dc9357SAndroid Build Coastguard Worker }
518*f6dc9357SAndroid Build Coastguard Worker Z7_WIN_FILE_INFORMATION_CLASS;
519*f6dc9357SAndroid Build Coastguard Worker 
520*f6dc9357SAndroid Build Coastguard Worker 
521*f6dc9357SAndroid Build Coastguard Worker typedef struct
522*f6dc9357SAndroid Build Coastguard Worker {
523*f6dc9357SAndroid Build Coastguard Worker   // #if (_WIN32_WINNT >= _WIN32_WINNT_WIN10_RS1)
524*f6dc9357SAndroid Build Coastguard Worker   union
525*f6dc9357SAndroid Build Coastguard Worker   {
526*f6dc9357SAndroid Build Coastguard Worker     BOOLEAN ReplaceIfExists;  // FileRenameInformation
527*f6dc9357SAndroid Build Coastguard Worker     ULONG Flags;              // FileRenameInformationEx
528*f6dc9357SAndroid Build Coastguard Worker   } DUMMYUNIONNAME;
529*f6dc9357SAndroid Build Coastguard Worker   // #else
530*f6dc9357SAndroid Build Coastguard Worker   // BOOLEAN ReplaceIfExists;
531*f6dc9357SAndroid Build Coastguard Worker   // #endif
532*f6dc9357SAndroid Build Coastguard Worker   HANDLE RootDirectory;
533*f6dc9357SAndroid Build Coastguard Worker   ULONG FileNameLength;
534*f6dc9357SAndroid Build Coastguard Worker   WCHAR FileName[1];
535*f6dc9357SAndroid Build Coastguard Worker } Z7_WIN_FILE_RENAME_INFORMATION;
536*f6dc9357SAndroid Build Coastguard Worker 
537*f6dc9357SAndroid Build Coastguard Worker #if (_WIN32_WINNT >= 0x0500) && !defined(_M_IA64)
538*f6dc9357SAndroid Build Coastguard Worker #define Z7_WIN_NTSTATUS  NTSTATUS
539*f6dc9357SAndroid Build Coastguard Worker #define Z7_WIN_IO_STATUS_BLOCK  IO_STATUS_BLOCK
540*f6dc9357SAndroid Build Coastguard Worker #else
541*f6dc9357SAndroid Build Coastguard Worker typedef LONG Z7_WIN_NTSTATUS;
542*f6dc9357SAndroid Build Coastguard Worker typedef struct
543*f6dc9357SAndroid Build Coastguard Worker {
544*f6dc9357SAndroid Build Coastguard Worker   union
545*f6dc9357SAndroid Build Coastguard Worker   {
546*f6dc9357SAndroid Build Coastguard Worker     Z7_WIN_NTSTATUS Status;
547*f6dc9357SAndroid Build Coastguard Worker     PVOID Pointer;
548*f6dc9357SAndroid Build Coastguard Worker   } DUMMYUNIONNAME;
549*f6dc9357SAndroid Build Coastguard Worker   ULONG_PTR Information;
550*f6dc9357SAndroid Build Coastguard Worker } Z7_WIN_IO_STATUS_BLOCK;
551*f6dc9357SAndroid Build Coastguard Worker #endif
552*f6dc9357SAndroid Build Coastguard Worker 
553*f6dc9357SAndroid Build Coastguard Worker typedef Z7_WIN_NTSTATUS (WINAPI *Func_NtSetInformationFile)(
554*f6dc9357SAndroid Build Coastguard Worker     HANDLE FileHandle,
555*f6dc9357SAndroid Build Coastguard Worker     Z7_WIN_IO_STATUS_BLOCK *IoStatusBlock,
556*f6dc9357SAndroid Build Coastguard Worker     PVOID FileInformation,
557*f6dc9357SAndroid Build Coastguard Worker     ULONG Length,
558*f6dc9357SAndroid Build Coastguard Worker     Z7_WIN_FILE_INFORMATION_CLASS FileInformationClass);
559*f6dc9357SAndroid Build Coastguard Worker 
560*f6dc9357SAndroid Build Coastguard Worker // NTAPI
561*f6dc9357SAndroid Build Coastguard Worker typedef ULONG (WINAPI *Func_RtlNtStatusToDosError)(Z7_WIN_NTSTATUS Status);
562*f6dc9357SAndroid Build Coastguard Worker 
563*f6dc9357SAndroid Build Coastguard Worker #define MY_STATUS_SUCCESS 0
564*f6dc9357SAndroid Build Coastguard Worker 
565*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
566*f6dc9357SAndroid Build Coastguard Worker 
567*f6dc9357SAndroid Build Coastguard Worker // static Func_NtSetInformationFile f_NtSetInformationFile;
568*f6dc9357SAndroid Build Coastguard Worker // static bool g_NtSetInformationFile_WasRequested = false;
569*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
570*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::Rename (UInt32 index,const wchar_t * newName,IProgress * progress))571*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress))
572*f6dc9357SAndroid Build Coastguard Worker {
573*f6dc9357SAndroid Build Coastguard Worker   const CAltStream &ss = Streams[index];
574*f6dc9357SAndroid Build Coastguard Worker   const FString srcPath = _pathPrefix + us2fs(ss.Name);
575*f6dc9357SAndroid Build Coastguard Worker 
576*f6dc9357SAndroid Build Coastguard Worker   const HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll");
577*f6dc9357SAndroid Build Coastguard Worker   // if (!g_NtSetInformationFile_WasRequested) {
578*f6dc9357SAndroid Build Coastguard Worker   // g_NtSetInformationFile_WasRequested = true;
579*f6dc9357SAndroid Build Coastguard Worker   const
580*f6dc9357SAndroid Build Coastguard Worker    Func_NtSetInformationFile
581*f6dc9357SAndroid Build Coastguard Worker       f_NtSetInformationFile = Z7_GET_PROC_ADDRESS(
582*f6dc9357SAndroid Build Coastguard Worker    Func_NtSetInformationFile, ntdll,
583*f6dc9357SAndroid Build Coastguard Worker        "NtSetInformationFile");
584*f6dc9357SAndroid Build Coastguard Worker   if (f_NtSetInformationFile)
585*f6dc9357SAndroid Build Coastguard Worker   {
586*f6dc9357SAndroid Build Coastguard Worker     NIO::CInFile inFile;
587*f6dc9357SAndroid Build Coastguard Worker     if (inFile.Open_for_FileRenameInformation(srcPath))
588*f6dc9357SAndroid Build Coastguard Worker     {
589*f6dc9357SAndroid Build Coastguard Worker       UString destPath (':');
590*f6dc9357SAndroid Build Coastguard Worker       destPath += newName;
591*f6dc9357SAndroid Build Coastguard Worker       const ULONG len = (ULONG)sizeof(wchar_t) * destPath.Len();
592*f6dc9357SAndroid Build Coastguard Worker       CByteBuffer buffer(sizeof(Z7_WIN_FILE_RENAME_INFORMATION) + len);
593*f6dc9357SAndroid Build Coastguard Worker       // buffer is 4 bytes larger than required.
594*f6dc9357SAndroid Build Coastguard Worker       Z7_WIN_FILE_RENAME_INFORMATION *fri = (Z7_WIN_FILE_RENAME_INFORMATION *)(void *)(Byte *)buffer;
595*f6dc9357SAndroid Build Coastguard Worker       memset(fri, 0, sizeof(Z7_WIN_FILE_RENAME_INFORMATION));
596*f6dc9357SAndroid Build Coastguard Worker       /* DOCS: If ReplaceIfExists is set to TRUE, the rename operation will succeed only
597*f6dc9357SAndroid Build Coastguard Worker          if a stream with the same name does not exist or is a zero-length data stream. */
598*f6dc9357SAndroid Build Coastguard Worker       fri->ReplaceIfExists = FALSE;
599*f6dc9357SAndroid Build Coastguard Worker       fri->RootDirectory = NULL;
600*f6dc9357SAndroid Build Coastguard Worker       fri->FileNameLength = len;
601*f6dc9357SAndroid Build Coastguard Worker       memcpy(fri->FileName, destPath.Ptr(), len);
602*f6dc9357SAndroid Build Coastguard Worker       Z7_WIN_IO_STATUS_BLOCK iosb;
603*f6dc9357SAndroid Build Coastguard Worker       const Z7_WIN_NTSTATUS status = f_NtSetInformationFile (inFile.GetHandle(),
604*f6dc9357SAndroid Build Coastguard Worker           &iosb, fri, (ULONG)buffer.Size(), Z7_WIN_FileRenameInformation);
605*f6dc9357SAndroid Build Coastguard Worker       if (status != MY_STATUS_SUCCESS)
606*f6dc9357SAndroid Build Coastguard Worker       {
607*f6dc9357SAndroid Build Coastguard Worker         const
608*f6dc9357SAndroid Build Coastguard Worker          Func_RtlNtStatusToDosError
609*f6dc9357SAndroid Build Coastguard Worker             f_RtlNtStatusToDosError = Z7_GET_PROC_ADDRESS(
610*f6dc9357SAndroid Build Coastguard Worker          Func_RtlNtStatusToDosError, ntdll,
611*f6dc9357SAndroid Build Coastguard Worker              "RtlNtStatusToDosError");
612*f6dc9357SAndroid Build Coastguard Worker         if (f_RtlNtStatusToDosError)
613*f6dc9357SAndroid Build Coastguard Worker         {
614*f6dc9357SAndroid Build Coastguard Worker           const ULONG res = f_RtlNtStatusToDosError(status);
615*f6dc9357SAndroid Build Coastguard Worker           if (res != ERROR_MR_MID_NOT_FOUND)
616*f6dc9357SAndroid Build Coastguard Worker             return HRESULT_FROM_WIN32(res);
617*f6dc9357SAndroid Build Coastguard Worker         }
618*f6dc9357SAndroid Build Coastguard Worker       }
619*f6dc9357SAndroid Build Coastguard Worker       return status;
620*f6dc9357SAndroid Build Coastguard Worker     }
621*f6dc9357SAndroid Build Coastguard Worker   }
622*f6dc9357SAndroid Build Coastguard Worker 
623*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderArchiveUpdateCallback> callback;
624*f6dc9357SAndroid Build Coastguard Worker   if (progress)
625*f6dc9357SAndroid Build Coastguard Worker   {
626*f6dc9357SAndroid Build Coastguard Worker     RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback))
627*f6dc9357SAndroid Build Coastguard Worker   }
628*f6dc9357SAndroid Build Coastguard Worker 
629*f6dc9357SAndroid Build Coastguard Worker   if (callback)
630*f6dc9357SAndroid Build Coastguard Worker   {
631*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->SetNumFiles(1))
632*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->SetTotal(ss.Size))
633*f6dc9357SAndroid Build Coastguard Worker   }
634*f6dc9357SAndroid Build Coastguard Worker 
635*f6dc9357SAndroid Build Coastguard Worker   NFsFolder::CCopyStateIO state;
636*f6dc9357SAndroid Build Coastguard Worker   state.Progress = progress;
637*f6dc9357SAndroid Build Coastguard Worker   state.TotalSize = 0;
638*f6dc9357SAndroid Build Coastguard Worker   state.DeleteSrcFile = true;
639*f6dc9357SAndroid Build Coastguard Worker 
640*f6dc9357SAndroid Build Coastguard Worker   const FString destPath = _pathPrefix + us2fs(newName);
641*f6dc9357SAndroid Build Coastguard Worker   return UpdateFile(state, srcPath, destPath, callback);
642*f6dc9357SAndroid Build Coastguard Worker }
643*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::Delete (const UInt32 * indices,UInt32 numItems,IProgress * progress))644*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress))
645*f6dc9357SAndroid Build Coastguard Worker {
646*f6dc9357SAndroid Build Coastguard Worker   RINOK(progress->SetTotal(numItems))
647*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItems; i++)
648*f6dc9357SAndroid Build Coastguard Worker   {
649*f6dc9357SAndroid Build Coastguard Worker     const CAltStream &ss = Streams[indices[i]];
650*f6dc9357SAndroid Build Coastguard Worker     const FString fullPath = _pathPrefix + us2fs(ss.Name);
651*f6dc9357SAndroid Build Coastguard Worker     const bool result = DeleteFileAlways(fullPath);
652*f6dc9357SAndroid Build Coastguard Worker     if (!result)
653*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
654*f6dc9357SAndroid Build Coastguard Worker     const UInt64 completed = i;
655*f6dc9357SAndroid Build Coastguard Worker     RINOK(progress->SetCompleted(&completed))
656*f6dc9357SAndroid Build Coastguard Worker   }
657*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
658*f6dc9357SAndroid Build Coastguard Worker }
659*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::SetProperty (UInt32,PROPID,const PROPVARIANT *,IProgress *))660*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::SetProperty(UInt32 /* index */, PROPID /* propID */,
661*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT * /* value */, IProgress * /* progress */))
662*f6dc9357SAndroid Build Coastguard Worker {
663*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
664*f6dc9357SAndroid Build Coastguard Worker }
665*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::GetSystemIconIndex (UInt32 index,Int32 * iconIndex))666*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex))
667*f6dc9357SAndroid Build Coastguard Worker {
668*f6dc9357SAndroid Build Coastguard Worker   const CAltStream &ss = Streams[index];
669*f6dc9357SAndroid Build Coastguard Worker   return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
670*f6dc9357SAndroid Build Coastguard Worker       _pathPrefix + us2fs(ss.Name),
671*f6dc9357SAndroid Build Coastguard Worker       FILE_ATTRIBUTE_ARCHIVE,
672*f6dc9357SAndroid Build Coastguard Worker       iconIndex);
673*f6dc9357SAndroid Build Coastguard Worker }
674*f6dc9357SAndroid Build Coastguard Worker 
675*f6dc9357SAndroid Build Coastguard Worker /*
676*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
677*f6dc9357SAndroid Build Coastguard Worker   CGetProp
678*f6dc9357SAndroid Build Coastguard Worker   , IGetProp
679*f6dc9357SAndroid Build Coastguard Worker )
680*f6dc9357SAndroid Build Coastguard Worker public:
681*f6dc9357SAndroid Build Coastguard Worker   // const CArc *Arc;
682*f6dc9357SAndroid Build Coastguard Worker   // UInt32 IndexInArc;
683*f6dc9357SAndroid Build Coastguard Worker   UString Name; // relative path
684*f6dc9357SAndroid Build Coastguard Worker   UInt64 Size;
685*f6dc9357SAndroid Build Coastguard Worker };
686*f6dc9357SAndroid Build Coastguard Worker 
687*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value))
688*f6dc9357SAndroid Build Coastguard Worker {
689*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidName)
690*f6dc9357SAndroid Build Coastguard Worker   {
691*f6dc9357SAndroid Build Coastguard Worker     COM_TRY_BEGIN
692*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop;
693*f6dc9357SAndroid Build Coastguard Worker     prop = Name;
694*f6dc9357SAndroid Build Coastguard Worker     prop.Detach(value);
695*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
696*f6dc9357SAndroid Build Coastguard Worker     COM_TRY_END
697*f6dc9357SAndroid Build Coastguard Worker   }
698*f6dc9357SAndroid Build Coastguard Worker   if (propID == kpidSize)
699*f6dc9357SAndroid Build Coastguard Worker   {
700*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant prop = Size;
701*f6dc9357SAndroid Build Coastguard Worker     prop.Detach(value);
702*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
703*f6dc9357SAndroid Build Coastguard Worker   }
704*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
705*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
706*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
707*f6dc9357SAndroid Build Coastguard Worker }
708*f6dc9357SAndroid Build Coastguard Worker */
709*f6dc9357SAndroid Build Coastguard Worker 
CopyStream(NFsFolder::CCopyStateIO & state,const FString & srcPath,const CFileInfo & srcFileInfo,const CAltStream & srcAltStream,const FString & destPathSpec,IFolderOperationsExtractCallback * callback)710*f6dc9357SAndroid Build Coastguard Worker static HRESULT CopyStream(
711*f6dc9357SAndroid Build Coastguard Worker     NFsFolder::CCopyStateIO &state,
712*f6dc9357SAndroid Build Coastguard Worker     const FString &srcPath,
713*f6dc9357SAndroid Build Coastguard Worker     const CFileInfo &srcFileInfo,
714*f6dc9357SAndroid Build Coastguard Worker     const CAltStream &srcAltStream,
715*f6dc9357SAndroid Build Coastguard Worker     const FString &destPathSpec,
716*f6dc9357SAndroid Build Coastguard Worker     IFolderOperationsExtractCallback *callback)
717*f6dc9357SAndroid Build Coastguard Worker {
718*f6dc9357SAndroid Build Coastguard Worker   FString destPath = destPathSpec;
719*f6dc9357SAndroid Build Coastguard Worker   if (CompareFileNames(destPath, srcPath) == 0)
720*f6dc9357SAndroid Build Coastguard Worker   {
721*f6dc9357SAndroid Build Coastguard Worker     RINOK(SendMessageError(callback, "Cannot copy file onto itself", destPath))
722*f6dc9357SAndroid Build Coastguard Worker     return E_ABORT;
723*f6dc9357SAndroid Build Coastguard Worker   }
724*f6dc9357SAndroid Build Coastguard Worker 
725*f6dc9357SAndroid Build Coastguard Worker   Int32 writeAskResult;
726*f6dc9357SAndroid Build Coastguard Worker   CMyComBSTR destPathResult;
727*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->AskWrite(
728*f6dc9357SAndroid Build Coastguard Worker       fs2us(srcPath),
729*f6dc9357SAndroid Build Coastguard Worker       BoolToInt(false),
730*f6dc9357SAndroid Build Coastguard Worker       &srcFileInfo.MTime, &srcAltStream.Size,
731*f6dc9357SAndroid Build Coastguard Worker       fs2us(destPath),
732*f6dc9357SAndroid Build Coastguard Worker       &destPathResult,
733*f6dc9357SAndroid Build Coastguard Worker       &writeAskResult))
734*f6dc9357SAndroid Build Coastguard Worker 
735*f6dc9357SAndroid Build Coastguard Worker   if (IntToBool(writeAskResult))
736*f6dc9357SAndroid Build Coastguard Worker   {
737*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->SetCurrentFilePath(fs2us(srcPath)))
738*f6dc9357SAndroid Build Coastguard Worker     FString destPathNew (us2fs((LPCOLESTR)destPathResult));
739*f6dc9357SAndroid Build Coastguard Worker     RINOK(state.MyCopyFile(srcPath, destPathNew))
740*f6dc9357SAndroid Build Coastguard Worker     if (state.ErrorFileIndex >= 0)
741*f6dc9357SAndroid Build Coastguard Worker     {
742*f6dc9357SAndroid Build Coastguard Worker       if (state.ErrorMessage.IsEmpty())
743*f6dc9357SAndroid Build Coastguard Worker         state.ErrorMessage = GetLastErrorMessage();
744*f6dc9357SAndroid Build Coastguard Worker       FString errorName;
745*f6dc9357SAndroid Build Coastguard Worker       if (state.ErrorFileIndex == 0)
746*f6dc9357SAndroid Build Coastguard Worker         errorName = srcPath;
747*f6dc9357SAndroid Build Coastguard Worker       else
748*f6dc9357SAndroid Build Coastguard Worker         errorName = destPathNew;
749*f6dc9357SAndroid Build Coastguard Worker       RINOK(SendMessageError(callback, state.ErrorMessage, errorName))
750*f6dc9357SAndroid Build Coastguard Worker       return E_ABORT;
751*f6dc9357SAndroid Build Coastguard Worker     }
752*f6dc9357SAndroid Build Coastguard Worker     state.StartPos += state.CurrentSize;
753*f6dc9357SAndroid Build Coastguard Worker   }
754*f6dc9357SAndroid Build Coastguard Worker   else
755*f6dc9357SAndroid Build Coastguard Worker   {
756*f6dc9357SAndroid Build Coastguard Worker     if (state.TotalSize >= srcAltStream.Size)
757*f6dc9357SAndroid Build Coastguard Worker     {
758*f6dc9357SAndroid Build Coastguard Worker       state.TotalSize -= srcAltStream.Size;
759*f6dc9357SAndroid Build Coastguard Worker       RINOK(state.Progress->SetTotal(state.TotalSize))
760*f6dc9357SAndroid Build Coastguard Worker     }
761*f6dc9357SAndroid Build Coastguard Worker   }
762*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
763*f6dc9357SAndroid Build Coastguard Worker }
764*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::CopyTo (Int32 moveMode,const UInt32 * indices,UInt32 numItems,Int32,Int32,const wchar_t * path,IFolderOperationsExtractCallback * callback))765*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
766*f6dc9357SAndroid Build Coastguard Worker     Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */,
767*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *path, IFolderOperationsExtractCallback *callback))
768*f6dc9357SAndroid Build Coastguard Worker {
769*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
770*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
771*f6dc9357SAndroid Build Coastguard Worker 
772*f6dc9357SAndroid Build Coastguard Worker   /*
773*f6dc9357SAndroid Build Coastguard Worker   Z7_DECL_CMyComPtr_QI_FROM(
774*f6dc9357SAndroid Build Coastguard Worker       IFolderExtractToStreamCallback,
775*f6dc9357SAndroid Build Coastguard Worker       ExtractToStreamCallback, callback)
776*f6dc9357SAndroid Build Coastguard Worker   if (ExtractToStreamCallback)
777*f6dc9357SAndroid Build Coastguard Worker   {
778*f6dc9357SAndroid Build Coastguard Worker     Int32 useStreams = 0;
779*f6dc9357SAndroid Build Coastguard Worker     if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK)
780*f6dc9357SAndroid Build Coastguard Worker       useStreams = 0;
781*f6dc9357SAndroid Build Coastguard Worker     if (useStreams == 0)
782*f6dc9357SAndroid Build Coastguard Worker       ExtractToStreamCallback.Release();
783*f6dc9357SAndroid Build Coastguard Worker   }
784*f6dc9357SAndroid Build Coastguard Worker   */
785*f6dc9357SAndroid Build Coastguard Worker 
786*f6dc9357SAndroid Build Coastguard Worker   UInt64 totalSize = 0;
787*f6dc9357SAndroid Build Coastguard Worker   {
788*f6dc9357SAndroid Build Coastguard Worker     UInt32 i;
789*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numItems; i++)
790*f6dc9357SAndroid Build Coastguard Worker     {
791*f6dc9357SAndroid Build Coastguard Worker       totalSize += Streams[indices[i]].Size;
792*f6dc9357SAndroid Build Coastguard Worker     }
793*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->SetTotal(totalSize))
794*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->SetNumFiles(numItems))
795*f6dc9357SAndroid Build Coastguard Worker   }
796*f6dc9357SAndroid Build Coastguard Worker 
797*f6dc9357SAndroid Build Coastguard Worker   /*
798*f6dc9357SAndroid Build Coastguard Worker   if (ExtractToStreamCallback)
799*f6dc9357SAndroid Build Coastguard Worker   {
800*f6dc9357SAndroid Build Coastguard Worker     CGetProp *GetProp_Spec = new CGetProp;
801*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IGetProp> GetProp= GetProp_Spec;
802*f6dc9357SAndroid Build Coastguard Worker 
803*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 i = 0; i < numItems; i++)
804*f6dc9357SAndroid Build Coastguard Worker     {
805*f6dc9357SAndroid Build Coastguard Worker       UInt32 index = indices[i];
806*f6dc9357SAndroid Build Coastguard Worker       const CAltStream &ss = Streams[index];
807*f6dc9357SAndroid Build Coastguard Worker       GetProp_Spec->Name = ss.Name;
808*f6dc9357SAndroid Build Coastguard Worker       GetProp_Spec->Size = ss.Size;
809*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISequentialOutStream> outStream;
810*f6dc9357SAndroid Build Coastguard Worker       RINOK(ExtractToStreamCallback->GetStream7(GetProp_Spec->Name, BoolToInt(false), &outStream,
811*f6dc9357SAndroid Build Coastguard Worker         NArchive::NExtract::NAskMode::kExtract, GetProp)); // isDir
812*f6dc9357SAndroid Build Coastguard Worker       FString srcPath;
813*f6dc9357SAndroid Build Coastguard Worker       GetFullPath(ss, srcPath);
814*f6dc9357SAndroid Build Coastguard Worker       RINOK(ExtractToStreamCallback->PrepareOperation7(NArchive::NExtract::NAskMode::kExtract));
815*f6dc9357SAndroid Build Coastguard Worker       RINOK(ExtractToStreamCallback->SetOperationResult7(NArchive::NExtract::NOperationResult::kOK, BoolToInt(false))); // _encrypted
816*f6dc9357SAndroid Build Coastguard Worker       // RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback, completedSize));
817*f6dc9357SAndroid Build Coastguard Worker     }
818*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
819*f6dc9357SAndroid Build Coastguard Worker   }
820*f6dc9357SAndroid Build Coastguard Worker   */
821*f6dc9357SAndroid Build Coastguard Worker 
822*f6dc9357SAndroid Build Coastguard Worker   FString destPath (us2fs(path));
823*f6dc9357SAndroid Build Coastguard Worker   if (destPath.IsEmpty() /* && !ExtractToStreamCallback */)
824*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
825*f6dc9357SAndroid Build Coastguard Worker 
826*f6dc9357SAndroid Build Coastguard Worker   const bool isAltDest = NName::IsAltPathPrefix(destPath);
827*f6dc9357SAndroid Build Coastguard Worker   const bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
828*f6dc9357SAndroid Build Coastguard Worker 
829*f6dc9357SAndroid Build Coastguard Worker   if (isDirectPath)
830*f6dc9357SAndroid Build Coastguard Worker   {
831*f6dc9357SAndroid Build Coastguard Worker     if (numItems > 1)
832*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
833*f6dc9357SAndroid Build Coastguard Worker   }
834*f6dc9357SAndroid Build Coastguard Worker 
835*f6dc9357SAndroid Build Coastguard Worker   CFileInfo fi;
836*f6dc9357SAndroid Build Coastguard Worker   if (!fi.Find(_pathBaseFile))
837*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
838*f6dc9357SAndroid Build Coastguard Worker 
839*f6dc9357SAndroid Build Coastguard Worker   NFsFolder::CCopyStateIO state;
840*f6dc9357SAndroid Build Coastguard Worker   state.Progress = callback;
841*f6dc9357SAndroid Build Coastguard Worker   state.DeleteSrcFile = IntToBool(moveMode);
842*f6dc9357SAndroid Build Coastguard Worker   state.TotalSize = totalSize;
843*f6dc9357SAndroid Build Coastguard Worker 
844*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItems; i++)
845*f6dc9357SAndroid Build Coastguard Worker   {
846*f6dc9357SAndroid Build Coastguard Worker     const UInt32 index = indices[i];
847*f6dc9357SAndroid Build Coastguard Worker     const CAltStream &ss = Streams[index];
848*f6dc9357SAndroid Build Coastguard Worker     FString destPath2 = destPath;
849*f6dc9357SAndroid Build Coastguard Worker     if (!isDirectPath)
850*f6dc9357SAndroid Build Coastguard Worker       destPath2 += us2fs(Get_Correct_FsFile_Name(ss.Name));
851*f6dc9357SAndroid Build Coastguard Worker     FString srcPath;
852*f6dc9357SAndroid Build Coastguard Worker     GetFullPath(ss, srcPath);
853*f6dc9357SAndroid Build Coastguard Worker     RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback))
854*f6dc9357SAndroid Build Coastguard Worker   }
855*f6dc9357SAndroid Build Coastguard Worker 
856*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
857*f6dc9357SAndroid Build Coastguard Worker }
858*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::CopyFrom (Int32,const wchar_t *,const wchar_t * const *,UInt32,IProgress *))859*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
860*f6dc9357SAndroid Build Coastguard Worker     const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */))
861*f6dc9357SAndroid Build Coastguard Worker {
862*f6dc9357SAndroid Build Coastguard Worker   /*
863*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
864*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
865*f6dc9357SAndroid Build Coastguard Worker 
866*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderArchiveUpdateCallback> callback;
867*f6dc9357SAndroid Build Coastguard Worker   if (progress)
868*f6dc9357SAndroid Build Coastguard Worker   {
869*f6dc9357SAndroid Build Coastguard Worker     RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback));
870*f6dc9357SAndroid Build Coastguard Worker   }
871*f6dc9357SAndroid Build Coastguard Worker 
872*f6dc9357SAndroid Build Coastguard Worker   if (CompareFileNames(fromFolderPath, fs2us(_pathPrefix)) == 0)
873*f6dc9357SAndroid Build Coastguard Worker   {
874*f6dc9357SAndroid Build Coastguard Worker     RINOK(SendMessageError(callback, "Cannot copy file onto itself", _pathPrefix));
875*f6dc9357SAndroid Build Coastguard Worker     return E_ABORT;
876*f6dc9357SAndroid Build Coastguard Worker   }
877*f6dc9357SAndroid Build Coastguard Worker 
878*f6dc9357SAndroid Build Coastguard Worker   if (callback)
879*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->SetNumFiles(numItems));
880*f6dc9357SAndroid Build Coastguard Worker 
881*f6dc9357SAndroid Build Coastguard Worker   UInt64 totalSize = 0;
882*f6dc9357SAndroid Build Coastguard Worker 
883*f6dc9357SAndroid Build Coastguard Worker   UInt32 i;
884*f6dc9357SAndroid Build Coastguard Worker 
885*f6dc9357SAndroid Build Coastguard Worker   FString path;
886*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numItems; i++)
887*f6dc9357SAndroid Build Coastguard Worker   {
888*f6dc9357SAndroid Build Coastguard Worker     path = us2fs(fromFolderPath);
889*f6dc9357SAndroid Build Coastguard Worker     path += us2fs(itemsPaths[i]);
890*f6dc9357SAndroid Build Coastguard Worker 
891*f6dc9357SAndroid Build Coastguard Worker     CFileInfo fi;
892*f6dc9357SAndroid Build Coastguard Worker     if (!fi.Find(path))
893*f6dc9357SAndroid Build Coastguard Worker       return ::GetLastError();
894*f6dc9357SAndroid Build Coastguard Worker     if (fi.IsDir())
895*f6dc9357SAndroid Build Coastguard Worker       return E_NOTIMPL;
896*f6dc9357SAndroid Build Coastguard Worker     totalSize += fi.Size;
897*f6dc9357SAndroid Build Coastguard Worker   }
898*f6dc9357SAndroid Build Coastguard Worker 
899*f6dc9357SAndroid Build Coastguard Worker   RINOK(progress->SetTotal(totalSize));
900*f6dc9357SAndroid Build Coastguard Worker 
901*f6dc9357SAndroid Build Coastguard Worker   // UInt64 completedSize = 0;
902*f6dc9357SAndroid Build Coastguard Worker 
903*f6dc9357SAndroid Build Coastguard Worker   NFsFolder::CCopyStateIO state;
904*f6dc9357SAndroid Build Coastguard Worker   state.Progress = progress;
905*f6dc9357SAndroid Build Coastguard Worker   state.DeleteSrcFile = IntToBool(moveMode);
906*f6dc9357SAndroid Build Coastguard Worker   state.TotalSize = totalSize;
907*f6dc9357SAndroid Build Coastguard Worker 
908*f6dc9357SAndroid Build Coastguard Worker   // we need to clear READ-ONLY of parent before creating alt stream
909*f6dc9357SAndroid Build Coastguard Worker   {
910*f6dc9357SAndroid Build Coastguard Worker     DWORD attrib = GetFileAttrib(_pathBaseFile);
911*f6dc9357SAndroid Build Coastguard Worker     if (attrib != INVALID_FILE_ATTRIBUTES
912*f6dc9357SAndroid Build Coastguard Worker         && (attrib & FILE_ATTRIBUTE_READONLY) != 0)
913*f6dc9357SAndroid Build Coastguard Worker     {
914*f6dc9357SAndroid Build Coastguard Worker       if (!SetFileAttrib(_pathBaseFile, attrib & ~FILE_ATTRIBUTE_READONLY))
915*f6dc9357SAndroid Build Coastguard Worker       {
916*f6dc9357SAndroid Build Coastguard Worker         if (callback)
917*f6dc9357SAndroid Build Coastguard Worker         {
918*f6dc9357SAndroid Build Coastguard Worker           RINOK(SendMessageError(callback, GetLastErrorMessage(), _pathBaseFile));
919*f6dc9357SAndroid Build Coastguard Worker           return S_OK;
920*f6dc9357SAndroid Build Coastguard Worker         }
921*f6dc9357SAndroid Build Coastguard Worker         return Return_LastError_or_FAIL();
922*f6dc9357SAndroid Build Coastguard Worker       }
923*f6dc9357SAndroid Build Coastguard Worker     }
924*f6dc9357SAndroid Build Coastguard Worker   }
925*f6dc9357SAndroid Build Coastguard Worker 
926*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numItems; i++)
927*f6dc9357SAndroid Build Coastguard Worker   {
928*f6dc9357SAndroid Build Coastguard Worker     path = us2fs(fromFolderPath);
929*f6dc9357SAndroid Build Coastguard Worker     path += us2fs(itemsPaths[i]);
930*f6dc9357SAndroid Build Coastguard Worker 
931*f6dc9357SAndroid Build Coastguard Worker     FString destPath = _pathPrefix + us2fs(itemsPaths[i]);
932*f6dc9357SAndroid Build Coastguard Worker 
933*f6dc9357SAndroid Build Coastguard Worker     RINOK(UpdateFile(state, path, destPath, callback));
934*f6dc9357SAndroid Build Coastguard Worker   }
935*f6dc9357SAndroid Build Coastguard Worker 
936*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
937*f6dc9357SAndroid Build Coastguard Worker   */
938*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
939*f6dc9357SAndroid Build Coastguard Worker }
940*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CAltStreamsFolder::CopyFromFile (UInt32,const wchar_t *,IProgress *))941*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CAltStreamsFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */))
942*f6dc9357SAndroid Build Coastguard Worker {
943*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
944*f6dc9357SAndroid Build Coastguard Worker }
945*f6dc9357SAndroid Build Coastguard Worker 
946*f6dc9357SAndroid Build Coastguard Worker }
947