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