1*f6dc9357SAndroid Build Coastguard Worker // FSFolderCopy.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyWindows.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Defs.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
10*f6dc9357SAndroid Build Coastguard Worker
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/DLL.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/ErrorMsg.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
15*f6dc9357SAndroid Build Coastguard Worker
16*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FilePathAutoRename.h"
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker #include "FSFolder.h"
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
21*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
22*f6dc9357SAndroid Build Coastguard Worker using namespace NDir;
23*f6dc9357SAndroid Build Coastguard Worker using namespace NName;
24*f6dc9357SAndroid Build Coastguard Worker using namespace NFind;
25*f6dc9357SAndroid Build Coastguard Worker
26*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
27*f6dc9357SAndroid Build Coastguard Worker extern bool g_IsNT;
28*f6dc9357SAndroid Build Coastguard Worker #endif
29*f6dc9357SAndroid Build Coastguard Worker
30*f6dc9357SAndroid Build Coastguard Worker namespace NFsFolder {
31*f6dc9357SAndroid Build Coastguard Worker
32*f6dc9357SAndroid Build Coastguard Worker static const char * const k_CannotCopyDirToAltStream = "Cannot copy folder as alternate stream";
33*f6dc9357SAndroid Build Coastguard Worker
34*f6dc9357SAndroid Build Coastguard Worker
MyCopyFile(CFSTR inPath,CFSTR outPath,DWORD attrib)35*f6dc9357SAndroid Build Coastguard Worker HRESULT CCopyStateIO::MyCopyFile(CFSTR inPath, CFSTR outPath, DWORD attrib)
36*f6dc9357SAndroid Build Coastguard Worker {
37*f6dc9357SAndroid Build Coastguard Worker ErrorFileIndex = -1;
38*f6dc9357SAndroid Build Coastguard Worker ErrorMessage.Empty();
39*f6dc9357SAndroid Build Coastguard Worker CurrentSize = 0;
40*f6dc9357SAndroid Build Coastguard Worker
41*f6dc9357SAndroid Build Coastguard Worker {
42*f6dc9357SAndroid Build Coastguard Worker const size_t kBufSize = 1 << 16;
43*f6dc9357SAndroid Build Coastguard Worker CByteArr buf(kBufSize);
44*f6dc9357SAndroid Build Coastguard Worker
45*f6dc9357SAndroid Build Coastguard Worker NIO::CInFile inFile;
46*f6dc9357SAndroid Build Coastguard Worker NIO::COutFile outFile;
47*f6dc9357SAndroid Build Coastguard Worker
48*f6dc9357SAndroid Build Coastguard Worker if (!inFile.Open(inPath))
49*f6dc9357SAndroid Build Coastguard Worker {
50*f6dc9357SAndroid Build Coastguard Worker ErrorFileIndex = 0;
51*f6dc9357SAndroid Build Coastguard Worker return S_OK;
52*f6dc9357SAndroid Build Coastguard Worker }
53*f6dc9357SAndroid Build Coastguard Worker
54*f6dc9357SAndroid Build Coastguard Worker if (!outFile.Create_ALWAYS(outPath))
55*f6dc9357SAndroid Build Coastguard Worker {
56*f6dc9357SAndroid Build Coastguard Worker ErrorFileIndex = 1;
57*f6dc9357SAndroid Build Coastguard Worker return S_OK;
58*f6dc9357SAndroid Build Coastguard Worker }
59*f6dc9357SAndroid Build Coastguard Worker
60*f6dc9357SAndroid Build Coastguard Worker for (;;)
61*f6dc9357SAndroid Build Coastguard Worker {
62*f6dc9357SAndroid Build Coastguard Worker UInt32 num;
63*f6dc9357SAndroid Build Coastguard Worker if (!inFile.Read(buf, kBufSize, num))
64*f6dc9357SAndroid Build Coastguard Worker {
65*f6dc9357SAndroid Build Coastguard Worker ErrorFileIndex = 0;
66*f6dc9357SAndroid Build Coastguard Worker return S_OK;
67*f6dc9357SAndroid Build Coastguard Worker }
68*f6dc9357SAndroid Build Coastguard Worker if (num == 0)
69*f6dc9357SAndroid Build Coastguard Worker break;
70*f6dc9357SAndroid Build Coastguard Worker
71*f6dc9357SAndroid Build Coastguard Worker UInt32 written = 0;
72*f6dc9357SAndroid Build Coastguard Worker if (!outFile.Write(buf, num, written))
73*f6dc9357SAndroid Build Coastguard Worker {
74*f6dc9357SAndroid Build Coastguard Worker ErrorFileIndex = 1;
75*f6dc9357SAndroid Build Coastguard Worker return S_OK;
76*f6dc9357SAndroid Build Coastguard Worker }
77*f6dc9357SAndroid Build Coastguard Worker if (written != num)
78*f6dc9357SAndroid Build Coastguard Worker {
79*f6dc9357SAndroid Build Coastguard Worker ErrorMessage = "Write error";
80*f6dc9357SAndroid Build Coastguard Worker return S_OK;
81*f6dc9357SAndroid Build Coastguard Worker }
82*f6dc9357SAndroid Build Coastguard Worker CurrentSize += num;
83*f6dc9357SAndroid Build Coastguard Worker if (Progress)
84*f6dc9357SAndroid Build Coastguard Worker {
85*f6dc9357SAndroid Build Coastguard Worker UInt64 completed = StartPos + CurrentSize;
86*f6dc9357SAndroid Build Coastguard Worker RINOK(Progress->SetCompleted(&completed))
87*f6dc9357SAndroid Build Coastguard Worker }
88*f6dc9357SAndroid Build Coastguard Worker }
89*f6dc9357SAndroid Build Coastguard Worker }
90*f6dc9357SAndroid Build Coastguard Worker
91*f6dc9357SAndroid Build Coastguard Worker /* SetFileAttrib("path:alt_stream_name") sets attributes for main file "path".
92*f6dc9357SAndroid Build Coastguard Worker But we don't want to change attributes of main file, when we write alt stream.
93*f6dc9357SAndroid Build Coastguard Worker So we need INVALID_FILE_ATTRIBUTES for alt stream here */
94*f6dc9357SAndroid Build Coastguard Worker
95*f6dc9357SAndroid Build Coastguard Worker if (attrib != INVALID_FILE_ATTRIBUTES)
96*f6dc9357SAndroid Build Coastguard Worker SetFileAttrib(outPath, attrib);
97*f6dc9357SAndroid Build Coastguard Worker
98*f6dc9357SAndroid Build Coastguard Worker if (DeleteSrcFile)
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker if (!DeleteFileAlways(inPath))
101*f6dc9357SAndroid Build Coastguard Worker {
102*f6dc9357SAndroid Build Coastguard Worker ErrorFileIndex = 0;
103*f6dc9357SAndroid Build Coastguard Worker return S_OK;
104*f6dc9357SAndroid Build Coastguard Worker }
105*f6dc9357SAndroid Build Coastguard Worker }
106*f6dc9357SAndroid Build Coastguard Worker
107*f6dc9357SAndroid Build Coastguard Worker return S_OK;
108*f6dc9357SAndroid Build Coastguard Worker }
109*f6dc9357SAndroid Build Coastguard Worker
110*f6dc9357SAndroid Build Coastguard Worker
111*f6dc9357SAndroid Build Coastguard Worker /*
112*f6dc9357SAndroid Build Coastguard Worker static bool IsItWindows2000orHigher()
113*f6dc9357SAndroid Build Coastguard Worker {
114*f6dc9357SAndroid Build Coastguard Worker OSVERSIONINFO versionInfo;
115*f6dc9357SAndroid Build Coastguard Worker versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
116*f6dc9357SAndroid Build Coastguard Worker if (!::GetVersionEx(&versionInfo))
117*f6dc9357SAndroid Build Coastguard Worker return false;
118*f6dc9357SAndroid Build Coastguard Worker return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
119*f6dc9357SAndroid Build Coastguard Worker (versionInfo.dwMajorVersion >= 5);
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker */
122*f6dc9357SAndroid Build Coastguard Worker
123*f6dc9357SAndroid Build Coastguard Worker struct CProgressInfo
124*f6dc9357SAndroid Build Coastguard Worker {
125*f6dc9357SAndroid Build Coastguard Worker UInt64 TotalSize;
126*f6dc9357SAndroid Build Coastguard Worker UInt64 StartPos;
127*f6dc9357SAndroid Build Coastguard Worker UInt64 FileSize;
128*f6dc9357SAndroid Build Coastguard Worker IProgress *Progress;
129*f6dc9357SAndroid Build Coastguard Worker HRESULT ProgressResult;
130*f6dc9357SAndroid Build Coastguard Worker
InitNFsFolder::CProgressInfo131*f6dc9357SAndroid Build Coastguard Worker void Init() { ProgressResult = S_OK; }
132*f6dc9357SAndroid Build Coastguard Worker };
133*f6dc9357SAndroid Build Coastguard Worker
134*f6dc9357SAndroid Build Coastguard Worker #ifndef PROGRESS_CONTINUE
135*f6dc9357SAndroid Build Coastguard Worker
136*f6dc9357SAndroid Build Coastguard Worker #define PROGRESS_CONTINUE 0
137*f6dc9357SAndroid Build Coastguard Worker #define PROGRESS_CANCEL 1
138*f6dc9357SAndroid Build Coastguard Worker
139*f6dc9357SAndroid Build Coastguard Worker #define COPY_FILE_FAIL_IF_EXISTS 0x00000001
140*f6dc9357SAndroid Build Coastguard Worker
141*f6dc9357SAndroid Build Coastguard Worker typedef
142*f6dc9357SAndroid Build Coastguard Worker DWORD
143*f6dc9357SAndroid Build Coastguard Worker (WINAPI* LPPROGRESS_ROUTINE)(
144*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER TotalFileSize,
145*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER TotalBytesTransferred,
146*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER StreamSize,
147*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER StreamBytesTransferred,
148*f6dc9357SAndroid Build Coastguard Worker DWORD dwStreamNumber,
149*f6dc9357SAndroid Build Coastguard Worker DWORD dwCallbackReason,
150*f6dc9357SAndroid Build Coastguard Worker HANDLE hSourceFile,
151*f6dc9357SAndroid Build Coastguard Worker HANDLE hDestinationFile,
152*f6dc9357SAndroid Build Coastguard Worker LPVOID lpData
153*f6dc9357SAndroid Build Coastguard Worker );
154*f6dc9357SAndroid Build Coastguard Worker
155*f6dc9357SAndroid Build Coastguard Worker #endif
156*f6dc9357SAndroid Build Coastguard Worker
CopyProgressRoutine(LARGE_INTEGER TotalFileSize,LARGE_INTEGER TotalBytesTransferred,LARGE_INTEGER,LARGE_INTEGER,DWORD,DWORD,HANDLE,HANDLE,LPVOID lpData)157*f6dc9357SAndroid Build Coastguard Worker static DWORD CALLBACK CopyProgressRoutine(
158*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER TotalFileSize, // file size
159*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER TotalBytesTransferred, // bytes transferred
160*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER /* StreamSize */, // bytes in stream
161*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream
162*f6dc9357SAndroid Build Coastguard Worker DWORD /* dwStreamNumber */, // current stream
163*f6dc9357SAndroid Build Coastguard Worker DWORD /* dwCallbackReason */, // callback reason
164*f6dc9357SAndroid Build Coastguard Worker HANDLE /* hSourceFile */, // handle to source file
165*f6dc9357SAndroid Build Coastguard Worker HANDLE /* hDestinationFile */, // handle to destination file
166*f6dc9357SAndroid Build Coastguard Worker LPVOID lpData // from CopyFileEx
167*f6dc9357SAndroid Build Coastguard Worker )
168*f6dc9357SAndroid Build Coastguard Worker {
169*f6dc9357SAndroid Build Coastguard Worker // StreamSize = StreamSize;
170*f6dc9357SAndroid Build Coastguard Worker // StreamBytesTransferred = StreamBytesTransferred;
171*f6dc9357SAndroid Build Coastguard Worker // dwStreamNumber = dwStreamNumber;
172*f6dc9357SAndroid Build Coastguard Worker // dwCallbackReason = dwCallbackReason;
173*f6dc9357SAndroid Build Coastguard Worker
174*f6dc9357SAndroid Build Coastguard Worker CProgressInfo &pi = *(CProgressInfo *)lpData;
175*f6dc9357SAndroid Build Coastguard Worker
176*f6dc9357SAndroid Build Coastguard Worker if ((UInt64)TotalFileSize.QuadPart > pi.FileSize)
177*f6dc9357SAndroid Build Coastguard Worker {
178*f6dc9357SAndroid Build Coastguard Worker pi.TotalSize += (UInt64)TotalFileSize.QuadPart - pi.FileSize;
179*f6dc9357SAndroid Build Coastguard Worker pi.FileSize = (UInt64)TotalFileSize.QuadPart;
180*f6dc9357SAndroid Build Coastguard Worker pi.ProgressResult = pi.Progress->SetTotal(pi.TotalSize);
181*f6dc9357SAndroid Build Coastguard Worker }
182*f6dc9357SAndroid Build Coastguard Worker const UInt64 completed = pi.StartPos + (UInt64)TotalBytesTransferred.QuadPart;
183*f6dc9357SAndroid Build Coastguard Worker pi.ProgressResult = pi.Progress->SetCompleted(&completed);
184*f6dc9357SAndroid Build Coastguard Worker return (pi.ProgressResult == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL);
185*f6dc9357SAndroid Build Coastguard Worker }
186*f6dc9357SAndroid Build Coastguard Worker
187*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // win2000
188*f6dc9357SAndroid Build Coastguard Worker #define Z7_USE_DYN_MoveFileWithProgressW
189*f6dc9357SAndroid Build Coastguard Worker #endif
190*f6dc9357SAndroid Build Coastguard Worker
191*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
192*f6dc9357SAndroid Build Coastguard Worker // nt4
193*f6dc9357SAndroid Build Coastguard Worker typedef BOOL (WINAPI * Func_CopyFileExA)(
194*f6dc9357SAndroid Build Coastguard Worker IN LPCSTR lpExistingFileName,
195*f6dc9357SAndroid Build Coastguard Worker IN LPCSTR lpNewFileName,
196*f6dc9357SAndroid Build Coastguard Worker IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
197*f6dc9357SAndroid Build Coastguard Worker IN LPVOID lpData OPTIONAL,
198*f6dc9357SAndroid Build Coastguard Worker IN LPBOOL pbCancel OPTIONAL,
199*f6dc9357SAndroid Build Coastguard Worker IN DWORD dwCopyFlags
200*f6dc9357SAndroid Build Coastguard Worker );
201*f6dc9357SAndroid Build Coastguard Worker
202*f6dc9357SAndroid Build Coastguard Worker // nt4
203*f6dc9357SAndroid Build Coastguard Worker typedef BOOL (WINAPI * Func_CopyFileExW)(
204*f6dc9357SAndroid Build Coastguard Worker IN LPCWSTR lpExistingFileName,
205*f6dc9357SAndroid Build Coastguard Worker IN LPCWSTR lpNewFileName,
206*f6dc9357SAndroid Build Coastguard Worker IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
207*f6dc9357SAndroid Build Coastguard Worker IN LPVOID lpData OPTIONAL,
208*f6dc9357SAndroid Build Coastguard Worker IN LPBOOL pbCancel OPTIONAL,
209*f6dc9357SAndroid Build Coastguard Worker IN DWORD dwCopyFlags
210*f6dc9357SAndroid Build Coastguard Worker );
211*f6dc9357SAndroid Build Coastguard Worker
212*f6dc9357SAndroid Build Coastguard Worker // win2000
213*f6dc9357SAndroid Build Coastguard Worker typedef BOOL (WINAPI * Func_MoveFileWithProgressW)(
214*f6dc9357SAndroid Build Coastguard Worker IN LPCWSTR lpExistingFileName,
215*f6dc9357SAndroid Build Coastguard Worker IN LPCWSTR lpNewFileName,
216*f6dc9357SAndroid Build Coastguard Worker IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
217*f6dc9357SAndroid Build Coastguard Worker IN LPVOID lpData OPTIONAL,
218*f6dc9357SAndroid Build Coastguard Worker IN DWORD dwFlags
219*f6dc9357SAndroid Build Coastguard Worker );
220*f6dc9357SAndroid Build Coastguard Worker #endif
221*f6dc9357SAndroid Build Coastguard Worker
222*f6dc9357SAndroid Build Coastguard Worker struct CCopyState
223*f6dc9357SAndroid Build Coastguard Worker {
224*f6dc9357SAndroid Build Coastguard Worker CProgressInfo ProgressInfo;
225*f6dc9357SAndroid Build Coastguard Worker IFolderOperationsExtractCallback *Callback;
226*f6dc9357SAndroid Build Coastguard Worker bool MoveMode;
227*f6dc9357SAndroid Build Coastguard Worker bool UseReadWriteMode;
228*f6dc9357SAndroid Build Coastguard Worker bool IsAltStreamsDest;
229*f6dc9357SAndroid Build Coastguard Worker
230*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
231*f6dc9357SAndroid Build Coastguard Worker private:
232*f6dc9357SAndroid Build Coastguard Worker Func_CopyFileExW my_CopyFileExW;
233*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
234*f6dc9357SAndroid Build Coastguard Worker Func_MoveFileWithProgressW my_MoveFileWithProgressW;
235*f6dc9357SAndroid Build Coastguard Worker #endif
236*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
237*f6dc9357SAndroid Build Coastguard Worker Func_CopyFileExA my_CopyFileExA;
238*f6dc9357SAndroid Build Coastguard Worker #endif
239*f6dc9357SAndroid Build Coastguard Worker public:
240*f6dc9357SAndroid Build Coastguard Worker CCopyState();
241*f6dc9357SAndroid Build Coastguard Worker #endif
242*f6dc9357SAndroid Build Coastguard Worker
243*f6dc9357SAndroid Build Coastguard Worker bool CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile);
244*f6dc9357SAndroid Build Coastguard Worker bool CopyFile_Sys(CFSTR oldFile, CFSTR newFile);
245*f6dc9357SAndroid Build Coastguard Worker bool MoveFile_Sys(CFSTR oldFile, CFSTR newFile);
246*f6dc9357SAndroid Build Coastguard Worker
247*f6dc9357SAndroid Build Coastguard Worker HRESULT CallProgress();
248*f6dc9357SAndroid Build Coastguard Worker
IsCallbackProgressErrorNFsFolder::CCopyState249*f6dc9357SAndroid Build Coastguard Worker bool IsCallbackProgressError() { return ProgressInfo.ProgressResult != S_OK; }
250*f6dc9357SAndroid Build Coastguard Worker };
251*f6dc9357SAndroid Build Coastguard Worker
CallProgress()252*f6dc9357SAndroid Build Coastguard Worker HRESULT CCopyState::CallProgress()
253*f6dc9357SAndroid Build Coastguard Worker {
254*f6dc9357SAndroid Build Coastguard Worker return ProgressInfo.Progress->SetCompleted(&ProgressInfo.StartPos);
255*f6dc9357SAndroid Build Coastguard Worker }
256*f6dc9357SAndroid Build Coastguard Worker
257*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
258*f6dc9357SAndroid Build Coastguard Worker
CCopyState()259*f6dc9357SAndroid Build Coastguard Worker CCopyState::CCopyState()
260*f6dc9357SAndroid Build Coastguard Worker {
261*f6dc9357SAndroid Build Coastguard Worker my_CopyFileExW = NULL;
262*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
263*f6dc9357SAndroid Build Coastguard Worker my_MoveFileWithProgressW = NULL;
264*f6dc9357SAndroid Build Coastguard Worker #endif
265*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
266*f6dc9357SAndroid Build Coastguard Worker my_CopyFileExA = NULL;
267*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
268*f6dc9357SAndroid Build Coastguard Worker {
269*f6dc9357SAndroid Build Coastguard Worker my_CopyFileExA = Z7_GET_PROC_ADDRESS(
270*f6dc9357SAndroid Build Coastguard Worker Func_CopyFileExA, ::GetModuleHandleA("kernel32.dll"),
271*f6dc9357SAndroid Build Coastguard Worker "CopyFileExA");
272*f6dc9357SAndroid Build Coastguard Worker }
273*f6dc9357SAndroid Build Coastguard Worker else
274*f6dc9357SAndroid Build Coastguard Worker #endif
275*f6dc9357SAndroid Build Coastguard Worker {
276*f6dc9357SAndroid Build Coastguard Worker const HMODULE module = ::GetModuleHandleW(
277*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
278*f6dc9357SAndroid Build Coastguard Worker L"coredll.dll"
279*f6dc9357SAndroid Build Coastguard Worker #else
280*f6dc9357SAndroid Build Coastguard Worker L"kernel32.dll"
281*f6dc9357SAndroid Build Coastguard Worker #endif
282*f6dc9357SAndroid Build Coastguard Worker );
283*f6dc9357SAndroid Build Coastguard Worker my_CopyFileExW = Z7_GET_PROC_ADDRESS(
284*f6dc9357SAndroid Build Coastguard Worker Func_CopyFileExW, module,
285*f6dc9357SAndroid Build Coastguard Worker "CopyFileExW");
286*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
287*f6dc9357SAndroid Build Coastguard Worker my_MoveFileWithProgressW = Z7_GET_PROC_ADDRESS(
288*f6dc9357SAndroid Build Coastguard Worker Func_MoveFileWithProgressW, module,
289*f6dc9357SAndroid Build Coastguard Worker "MoveFileWithProgressW");
290*f6dc9357SAndroid Build Coastguard Worker #endif
291*f6dc9357SAndroid Build Coastguard Worker }
292*f6dc9357SAndroid Build Coastguard Worker }
293*f6dc9357SAndroid Build Coastguard Worker
294*f6dc9357SAndroid Build Coastguard Worker #endif
295*f6dc9357SAndroid Build Coastguard Worker
296*f6dc9357SAndroid Build Coastguard Worker /* WinXP-64:
297*f6dc9357SAndroid Build Coastguard Worker CopyFileW(fromFile, toFile:altStream)
298*f6dc9357SAndroid Build Coastguard Worker OK - there are NO alt streams in fromFile
299*f6dc9357SAndroid Build Coastguard Worker ERROR_INVALID_PARAMETER - there are alt streams in fromFile
300*f6dc9357SAndroid Build Coastguard Worker */
301*f6dc9357SAndroid Build Coastguard Worker
CopyFile_NT(const wchar_t * oldFile,const wchar_t * newFile)302*f6dc9357SAndroid Build Coastguard Worker bool CCopyState::CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile)
303*f6dc9357SAndroid Build Coastguard Worker {
304*f6dc9357SAndroid Build Coastguard Worker BOOL cancelFlag = FALSE;
305*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
306*f6dc9357SAndroid Build Coastguard Worker if (my_CopyFileExW)
307*f6dc9357SAndroid Build Coastguard Worker #endif
308*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(
309*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
310*f6dc9357SAndroid Build Coastguard Worker my_CopyFileExW
311*f6dc9357SAndroid Build Coastguard Worker #else
312*f6dc9357SAndroid Build Coastguard Worker CopyFileExW
313*f6dc9357SAndroid Build Coastguard Worker #endif
314*f6dc9357SAndroid Build Coastguard Worker (oldFile, newFile, CopyProgressRoutine,
315*f6dc9357SAndroid Build Coastguard Worker &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS));
316*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
317*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::CopyFileW(oldFile, newFile, TRUE));
318*f6dc9357SAndroid Build Coastguard Worker #endif
319*f6dc9357SAndroid Build Coastguard Worker }
320*f6dc9357SAndroid Build Coastguard Worker
CopyFile_Sys(CFSTR oldFile,CFSTR newFile)321*f6dc9357SAndroid Build Coastguard Worker bool CCopyState::CopyFile_Sys(CFSTR oldFile, CFSTR newFile)
322*f6dc9357SAndroid Build Coastguard Worker {
323*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
324*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
325*f6dc9357SAndroid Build Coastguard Worker {
326*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
327*f6dc9357SAndroid Build Coastguard Worker if (my_CopyFileExA)
328*f6dc9357SAndroid Build Coastguard Worker #endif
329*f6dc9357SAndroid Build Coastguard Worker {
330*f6dc9357SAndroid Build Coastguard Worker BOOL cancelFlag = FALSE;
331*f6dc9357SAndroid Build Coastguard Worker if (
332*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
333*f6dc9357SAndroid Build Coastguard Worker my_CopyFileExA
334*f6dc9357SAndroid Build Coastguard Worker #else
335*f6dc9357SAndroid Build Coastguard Worker CopyFileExA
336*f6dc9357SAndroid Build Coastguard Worker #endif
337*f6dc9357SAndroid Build Coastguard Worker (fs2fas(oldFile), fs2fas(newFile),
338*f6dc9357SAndroid Build Coastguard Worker CopyProgressRoutine, &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS))
339*f6dc9357SAndroid Build Coastguard Worker return true;
340*f6dc9357SAndroid Build Coastguard Worker if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
341*f6dc9357SAndroid Build Coastguard Worker return false;
342*f6dc9357SAndroid Build Coastguard Worker }
343*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::CopyFile(fs2fas(oldFile), fs2fas(newFile), TRUE));
344*f6dc9357SAndroid Build Coastguard Worker }
345*f6dc9357SAndroid Build Coastguard Worker else
346*f6dc9357SAndroid Build Coastguard Worker #endif
347*f6dc9357SAndroid Build Coastguard Worker {
348*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH_2(oldFile, newFile)
349*f6dc9357SAndroid Build Coastguard Worker {
350*f6dc9357SAndroid Build Coastguard Worker if (CopyFile_NT(fs2us(oldFile), fs2us(newFile)))
351*f6dc9357SAndroid Build Coastguard Worker return true;
352*f6dc9357SAndroid Build Coastguard Worker }
353*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
354*f6dc9357SAndroid Build Coastguard Worker if (USE_SUPER_PATH_2)
355*f6dc9357SAndroid Build Coastguard Worker {
356*f6dc9357SAndroid Build Coastguard Worker if (IsCallbackProgressError())
357*f6dc9357SAndroid Build Coastguard Worker return false;
358*f6dc9357SAndroid Build Coastguard Worker UString superPathOld, superPathNew;
359*f6dc9357SAndroid Build Coastguard Worker if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2))
360*f6dc9357SAndroid Build Coastguard Worker return false;
361*f6dc9357SAndroid Build Coastguard Worker if (CopyFile_NT(superPathOld, superPathNew))
362*f6dc9357SAndroid Build Coastguard Worker return true;
363*f6dc9357SAndroid Build Coastguard Worker }
364*f6dc9357SAndroid Build Coastguard Worker #endif
365*f6dc9357SAndroid Build Coastguard Worker return false;
366*f6dc9357SAndroid Build Coastguard Worker }
367*f6dc9357SAndroid Build Coastguard Worker }
368*f6dc9357SAndroid Build Coastguard Worker
MoveFile_Sys(CFSTR oldFile,CFSTR newFile)369*f6dc9357SAndroid Build Coastguard Worker bool CCopyState::MoveFile_Sys(CFSTR oldFile, CFSTR newFile)
370*f6dc9357SAndroid Build Coastguard Worker {
371*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
372*f6dc9357SAndroid Build Coastguard Worker // if (IsItWindows2000orHigher())
373*f6dc9357SAndroid Build Coastguard Worker // {
374*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
375*f6dc9357SAndroid Build Coastguard Worker if (my_MoveFileWithProgressW)
376*f6dc9357SAndroid Build Coastguard Worker #endif
377*f6dc9357SAndroid Build Coastguard Worker {
378*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH_2(oldFile, newFile)
379*f6dc9357SAndroid Build Coastguard Worker {
380*f6dc9357SAndroid Build Coastguard Worker if (
381*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
382*f6dc9357SAndroid Build Coastguard Worker my_MoveFileWithProgressW
383*f6dc9357SAndroid Build Coastguard Worker #else
384*f6dc9357SAndroid Build Coastguard Worker MoveFileWithProgressW
385*f6dc9357SAndroid Build Coastguard Worker #endif
386*f6dc9357SAndroid Build Coastguard Worker (fs2us(oldFile), fs2us(newFile), CopyProgressRoutine,
387*f6dc9357SAndroid Build Coastguard Worker &ProgressInfo, MOVEFILE_COPY_ALLOWED))
388*f6dc9357SAndroid Build Coastguard Worker return true;
389*f6dc9357SAndroid Build Coastguard Worker }
390*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
391*f6dc9357SAndroid Build Coastguard Worker if ((!(USE_MAIN_PATH_2) || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) && USE_SUPER_PATH_2)
392*f6dc9357SAndroid Build Coastguard Worker {
393*f6dc9357SAndroid Build Coastguard Worker if (IsCallbackProgressError())
394*f6dc9357SAndroid Build Coastguard Worker return false;
395*f6dc9357SAndroid Build Coastguard Worker UString superPathOld, superPathNew;
396*f6dc9357SAndroid Build Coastguard Worker if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2))
397*f6dc9357SAndroid Build Coastguard Worker return false;
398*f6dc9357SAndroid Build Coastguard Worker if (
399*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_MoveFileWithProgressW
400*f6dc9357SAndroid Build Coastguard Worker my_MoveFileWithProgressW
401*f6dc9357SAndroid Build Coastguard Worker #else
402*f6dc9357SAndroid Build Coastguard Worker MoveFileWithProgressW
403*f6dc9357SAndroid Build Coastguard Worker #endif
404*f6dc9357SAndroid Build Coastguard Worker (superPathOld, superPathNew, CopyProgressRoutine,
405*f6dc9357SAndroid Build Coastguard Worker &ProgressInfo, MOVEFILE_COPY_ALLOWED))
406*f6dc9357SAndroid Build Coastguard Worker return true;
407*f6dc9357SAndroid Build Coastguard Worker }
408*f6dc9357SAndroid Build Coastguard Worker #endif
409*f6dc9357SAndroid Build Coastguard Worker if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
410*f6dc9357SAndroid Build Coastguard Worker return false;
411*f6dc9357SAndroid Build Coastguard Worker }
412*f6dc9357SAndroid Build Coastguard Worker // }
413*f6dc9357SAndroid Build Coastguard Worker // else
414*f6dc9357SAndroid Build Coastguard Worker #endif
415*f6dc9357SAndroid Build Coastguard Worker return MyMoveFile(oldFile, newFile);
416*f6dc9357SAndroid Build Coastguard Worker }
417*f6dc9357SAndroid Build Coastguard Worker
SendMessageError(IFolderOperationsExtractCallback * callback,const wchar_t * message,const FString & fileName)418*f6dc9357SAndroid Build Coastguard Worker static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
419*f6dc9357SAndroid Build Coastguard Worker const wchar_t *message, const FString &fileName)
420*f6dc9357SAndroid Build Coastguard Worker {
421*f6dc9357SAndroid Build Coastguard Worker UString s = message;
422*f6dc9357SAndroid Build Coastguard Worker s += " : ";
423*f6dc9357SAndroid Build Coastguard Worker s += fs2us(fileName);
424*f6dc9357SAndroid Build Coastguard Worker return callback->ShowMessage(s);
425*f6dc9357SAndroid Build Coastguard Worker }
426*f6dc9357SAndroid Build Coastguard Worker
SendMessageError(IFolderOperationsExtractCallback * callback,const char * message,const FString & fileName)427*f6dc9357SAndroid Build Coastguard Worker static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
428*f6dc9357SAndroid Build Coastguard Worker const char *message, const FString &fileName)
429*f6dc9357SAndroid Build Coastguard Worker {
430*f6dc9357SAndroid Build Coastguard Worker return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
431*f6dc9357SAndroid Build Coastguard Worker }
432*f6dc9357SAndroid Build Coastguard Worker
Return_LastError_or_FAIL()433*f6dc9357SAndroid Build Coastguard Worker static DWORD Return_LastError_or_FAIL()
434*f6dc9357SAndroid Build Coastguard Worker {
435*f6dc9357SAndroid Build Coastguard Worker DWORD errorCode = GetLastError();
436*f6dc9357SAndroid Build Coastguard Worker if (errorCode == 0)
437*f6dc9357SAndroid Build Coastguard Worker errorCode = (DWORD)E_FAIL;
438*f6dc9357SAndroid Build Coastguard Worker return errorCode;
439*f6dc9357SAndroid Build Coastguard Worker }
440*f6dc9357SAndroid Build Coastguard Worker
GetLastErrorMessage()441*f6dc9357SAndroid Build Coastguard Worker static UString GetLastErrorMessage()
442*f6dc9357SAndroid Build Coastguard Worker {
443*f6dc9357SAndroid Build Coastguard Worker return NError::MyFormatMessage(Return_LastError_or_FAIL());
444*f6dc9357SAndroid Build Coastguard Worker }
445*f6dc9357SAndroid Build Coastguard Worker
SendLastErrorMessage(IFolderOperationsExtractCallback * callback,const FString & fileName)446*f6dc9357SAndroid Build Coastguard Worker HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName)
447*f6dc9357SAndroid Build Coastguard Worker {
448*f6dc9357SAndroid Build Coastguard Worker return SendMessageError(callback, GetLastErrorMessage(), fileName);
449*f6dc9357SAndroid Build Coastguard Worker }
450*f6dc9357SAndroid Build Coastguard Worker
CopyFile_Ask(CCopyState & state,const FString & srcPath,const CFileInfo & srcFileInfo,const FString & destPath)451*f6dc9357SAndroid Build Coastguard Worker static HRESULT CopyFile_Ask(
452*f6dc9357SAndroid Build Coastguard Worker CCopyState &state,
453*f6dc9357SAndroid Build Coastguard Worker const FString &srcPath,
454*f6dc9357SAndroid Build Coastguard Worker const CFileInfo &srcFileInfo,
455*f6dc9357SAndroid Build Coastguard Worker const FString &destPath)
456*f6dc9357SAndroid Build Coastguard Worker {
457*f6dc9357SAndroid Build Coastguard Worker if (CompareFileNames(destPath, srcPath) == 0)
458*f6dc9357SAndroid Build Coastguard Worker {
459*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(state.Callback,
460*f6dc9357SAndroid Build Coastguard Worker state.MoveMode ?
461*f6dc9357SAndroid Build Coastguard Worker "Cannot move file onto itself" :
462*f6dc9357SAndroid Build Coastguard Worker "Cannot copy file onto itself"
463*f6dc9357SAndroid Build Coastguard Worker , destPath))
464*f6dc9357SAndroid Build Coastguard Worker return E_ABORT;
465*f6dc9357SAndroid Build Coastguard Worker }
466*f6dc9357SAndroid Build Coastguard Worker
467*f6dc9357SAndroid Build Coastguard Worker Int32 writeAskResult;
468*f6dc9357SAndroid Build Coastguard Worker CMyComBSTR destPathResult;
469*f6dc9357SAndroid Build Coastguard Worker RINOK(state.Callback->AskWrite(
470*f6dc9357SAndroid Build Coastguard Worker fs2us(srcPath),
471*f6dc9357SAndroid Build Coastguard Worker BoolToInt(false),
472*f6dc9357SAndroid Build Coastguard Worker &srcFileInfo.MTime, &srcFileInfo.Size,
473*f6dc9357SAndroid Build Coastguard Worker fs2us(destPath),
474*f6dc9357SAndroid Build Coastguard Worker &destPathResult,
475*f6dc9357SAndroid Build Coastguard Worker &writeAskResult))
476*f6dc9357SAndroid Build Coastguard Worker
477*f6dc9357SAndroid Build Coastguard Worker if (IntToBool(writeAskResult))
478*f6dc9357SAndroid Build Coastguard Worker {
479*f6dc9357SAndroid Build Coastguard Worker FString destPathNew = us2fs((LPCOLESTR)destPathResult);
480*f6dc9357SAndroid Build Coastguard Worker RINOK(state.Callback->SetCurrentFilePath(fs2us(srcPath)))
481*f6dc9357SAndroid Build Coastguard Worker
482*f6dc9357SAndroid Build Coastguard Worker if (state.UseReadWriteMode)
483*f6dc9357SAndroid Build Coastguard Worker {
484*f6dc9357SAndroid Build Coastguard Worker NFsFolder::CCopyStateIO state2;
485*f6dc9357SAndroid Build Coastguard Worker state2.Progress = state.Callback;
486*f6dc9357SAndroid Build Coastguard Worker state2.DeleteSrcFile = state.MoveMode;
487*f6dc9357SAndroid Build Coastguard Worker state2.TotalSize = state.ProgressInfo.TotalSize;
488*f6dc9357SAndroid Build Coastguard Worker state2.StartPos = state.ProgressInfo.StartPos;
489*f6dc9357SAndroid Build Coastguard Worker
490*f6dc9357SAndroid Build Coastguard Worker RINOK(state2.MyCopyFile(srcPath, destPathNew,
491*f6dc9357SAndroid Build Coastguard Worker state.IsAltStreamsDest ? INVALID_FILE_ATTRIBUTES: srcFileInfo.Attrib))
492*f6dc9357SAndroid Build Coastguard Worker
493*f6dc9357SAndroid Build Coastguard Worker if (state2.ErrorFileIndex >= 0)
494*f6dc9357SAndroid Build Coastguard Worker {
495*f6dc9357SAndroid Build Coastguard Worker if (state2.ErrorMessage.IsEmpty())
496*f6dc9357SAndroid Build Coastguard Worker state2.ErrorMessage = GetLastErrorMessage();
497*f6dc9357SAndroid Build Coastguard Worker FString errorName;
498*f6dc9357SAndroid Build Coastguard Worker if (state2.ErrorFileIndex == 0)
499*f6dc9357SAndroid Build Coastguard Worker errorName = srcPath;
500*f6dc9357SAndroid Build Coastguard Worker else
501*f6dc9357SAndroid Build Coastguard Worker errorName = destPathNew;
502*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(state.Callback, state2.ErrorMessage, errorName))
503*f6dc9357SAndroid Build Coastguard Worker return E_ABORT;
504*f6dc9357SAndroid Build Coastguard Worker }
505*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.StartPos += state2.CurrentSize;
506*f6dc9357SAndroid Build Coastguard Worker }
507*f6dc9357SAndroid Build Coastguard Worker else
508*f6dc9357SAndroid Build Coastguard Worker {
509*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.FileSize = srcFileInfo.Size;
510*f6dc9357SAndroid Build Coastguard Worker bool res;
511*f6dc9357SAndroid Build Coastguard Worker if (state.MoveMode)
512*f6dc9357SAndroid Build Coastguard Worker res = state.MoveFile_Sys(srcPath, destPathNew);
513*f6dc9357SAndroid Build Coastguard Worker else
514*f6dc9357SAndroid Build Coastguard Worker res = state.CopyFile_Sys(srcPath, destPathNew);
515*f6dc9357SAndroid Build Coastguard Worker RINOK(state.ProgressInfo.ProgressResult)
516*f6dc9357SAndroid Build Coastguard Worker if (!res)
517*f6dc9357SAndroid Build Coastguard Worker {
518*f6dc9357SAndroid Build Coastguard Worker const DWORD errorCode = GetLastError();
519*f6dc9357SAndroid Build Coastguard Worker UString errorMessage = NError::MyFormatMessage(Return_LastError_or_FAIL());
520*f6dc9357SAndroid Build Coastguard Worker if (errorCode == ERROR_INVALID_PARAMETER)
521*f6dc9357SAndroid Build Coastguard Worker {
522*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fi;
523*f6dc9357SAndroid Build Coastguard Worker if (fi.Find(srcPath) &&
524*f6dc9357SAndroid Build Coastguard Worker fi.Size > (UInt32)(Int32)-1)
525*f6dc9357SAndroid Build Coastguard Worker {
526*f6dc9357SAndroid Build Coastguard Worker // bool isFsDetected = false;
527*f6dc9357SAndroid Build Coastguard Worker // if (NSystem::Is_File_LimitedBy_4GB(destPathNew, isFsDetected) || !isFsDetected)
528*f6dc9357SAndroid Build Coastguard Worker errorMessage += " File size exceeds 4 GB";
529*f6dc9357SAndroid Build Coastguard Worker }
530*f6dc9357SAndroid Build Coastguard Worker }
531*f6dc9357SAndroid Build Coastguard Worker
532*f6dc9357SAndroid Build Coastguard Worker // GetLastError() is ERROR_REQUEST_ABORTED in case of PROGRESS_CANCEL.
533*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(state.Callback, errorMessage, destPathNew))
534*f6dc9357SAndroid Build Coastguard Worker return E_ABORT;
535*f6dc9357SAndroid Build Coastguard Worker }
536*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.StartPos += state.ProgressInfo.FileSize;
537*f6dc9357SAndroid Build Coastguard Worker }
538*f6dc9357SAndroid Build Coastguard Worker }
539*f6dc9357SAndroid Build Coastguard Worker else
540*f6dc9357SAndroid Build Coastguard Worker {
541*f6dc9357SAndroid Build Coastguard Worker if (state.ProgressInfo.TotalSize >= srcFileInfo.Size)
542*f6dc9357SAndroid Build Coastguard Worker {
543*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.TotalSize -= srcFileInfo.Size;
544*f6dc9357SAndroid Build Coastguard Worker RINOK(state.ProgressInfo.Progress->SetTotal(state.ProgressInfo.TotalSize))
545*f6dc9357SAndroid Build Coastguard Worker }
546*f6dc9357SAndroid Build Coastguard Worker }
547*f6dc9357SAndroid Build Coastguard Worker return state.CallProgress();
548*f6dc9357SAndroid Build Coastguard Worker }
549*f6dc9357SAndroid Build Coastguard Worker
CombinePath(const FString & folderPath,const FString & fileName)550*f6dc9357SAndroid Build Coastguard Worker static FString CombinePath(const FString &folderPath, const FString &fileName)
551*f6dc9357SAndroid Build Coastguard Worker {
552*f6dc9357SAndroid Build Coastguard Worker FString s (folderPath);
553*f6dc9357SAndroid Build Coastguard Worker s.Add_PathSepar(); // FCHAR_PATH_SEPARATOR
554*f6dc9357SAndroid Build Coastguard Worker s += fileName;
555*f6dc9357SAndroid Build Coastguard Worker return s;
556*f6dc9357SAndroid Build Coastguard Worker }
557*f6dc9357SAndroid Build Coastguard Worker
IsDestChild(const FString & src,const FString & dest)558*f6dc9357SAndroid Build Coastguard Worker static bool IsDestChild(const FString &src, const FString &dest)
559*f6dc9357SAndroid Build Coastguard Worker {
560*f6dc9357SAndroid Build Coastguard Worker unsigned len = src.Len();
561*f6dc9357SAndroid Build Coastguard Worker if (dest.Len() < len)
562*f6dc9357SAndroid Build Coastguard Worker return false;
563*f6dc9357SAndroid Build Coastguard Worker if (dest.Len() != len && dest[len] != FCHAR_PATH_SEPARATOR)
564*f6dc9357SAndroid Build Coastguard Worker return false;
565*f6dc9357SAndroid Build Coastguard Worker return CompareFileNames(dest.Left(len), src) == 0;
566*f6dc9357SAndroid Build Coastguard Worker }
567*f6dc9357SAndroid Build Coastguard Worker
CopyFolder(CCopyState & state,const FString & srcPath,const FString & destPath)568*f6dc9357SAndroid Build Coastguard Worker static HRESULT CopyFolder(
569*f6dc9357SAndroid Build Coastguard Worker CCopyState &state,
570*f6dc9357SAndroid Build Coastguard Worker const FString &srcPath, // without TAIL separator
571*f6dc9357SAndroid Build Coastguard Worker const FString &destPath) // without TAIL separator
572*f6dc9357SAndroid Build Coastguard Worker {
573*f6dc9357SAndroid Build Coastguard Worker RINOK(state.CallProgress())
574*f6dc9357SAndroid Build Coastguard Worker
575*f6dc9357SAndroid Build Coastguard Worker if (IsDestChild(srcPath, destPath))
576*f6dc9357SAndroid Build Coastguard Worker {
577*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(state.Callback,
578*f6dc9357SAndroid Build Coastguard Worker state.MoveMode ?
579*f6dc9357SAndroid Build Coastguard Worker "Cannot copy folder onto itself" :
580*f6dc9357SAndroid Build Coastguard Worker "Cannot move folder onto itself"
581*f6dc9357SAndroid Build Coastguard Worker , destPath))
582*f6dc9357SAndroid Build Coastguard Worker return E_ABORT;
583*f6dc9357SAndroid Build Coastguard Worker }
584*f6dc9357SAndroid Build Coastguard Worker
585*f6dc9357SAndroid Build Coastguard Worker if (state.MoveMode)
586*f6dc9357SAndroid Build Coastguard Worker {
587*f6dc9357SAndroid Build Coastguard Worker if (state.MoveFile_Sys(srcPath, destPath))
588*f6dc9357SAndroid Build Coastguard Worker return S_OK;
589*f6dc9357SAndroid Build Coastguard Worker
590*f6dc9357SAndroid Build Coastguard Worker // MSDN: MoveFile() fails for dirs on different volumes.
591*f6dc9357SAndroid Build Coastguard Worker }
592*f6dc9357SAndroid Build Coastguard Worker
593*f6dc9357SAndroid Build Coastguard Worker if (!CreateComplexDir(destPath))
594*f6dc9357SAndroid Build Coastguard Worker {
595*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(state.Callback, "Cannot create folder", destPath))
596*f6dc9357SAndroid Build Coastguard Worker return E_ABORT;
597*f6dc9357SAndroid Build Coastguard Worker }
598*f6dc9357SAndroid Build Coastguard Worker
599*f6dc9357SAndroid Build Coastguard Worker CEnumerator enumerator;
600*f6dc9357SAndroid Build Coastguard Worker enumerator.SetDirPrefix(CombinePath(srcPath, FString()));
601*f6dc9357SAndroid Build Coastguard Worker
602*f6dc9357SAndroid Build Coastguard Worker for (;;)
603*f6dc9357SAndroid Build Coastguard Worker {
604*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fi;
605*f6dc9357SAndroid Build Coastguard Worker bool found;
606*f6dc9357SAndroid Build Coastguard Worker if (!enumerator.Next(fi, found))
607*f6dc9357SAndroid Build Coastguard Worker {
608*f6dc9357SAndroid Build Coastguard Worker SendLastErrorMessage(state.Callback, srcPath);
609*f6dc9357SAndroid Build Coastguard Worker return S_OK;
610*f6dc9357SAndroid Build Coastguard Worker }
611*f6dc9357SAndroid Build Coastguard Worker if (!found)
612*f6dc9357SAndroid Build Coastguard Worker break;
613*f6dc9357SAndroid Build Coastguard Worker const FString srcPath2 = CombinePath(srcPath, fi.Name);
614*f6dc9357SAndroid Build Coastguard Worker const FString destPath2 = CombinePath(destPath, fi.Name);
615*f6dc9357SAndroid Build Coastguard Worker if (fi.IsDir())
616*f6dc9357SAndroid Build Coastguard Worker {
617*f6dc9357SAndroid Build Coastguard Worker RINOK(CopyFolder(state, srcPath2, destPath2))
618*f6dc9357SAndroid Build Coastguard Worker }
619*f6dc9357SAndroid Build Coastguard Worker else
620*f6dc9357SAndroid Build Coastguard Worker {
621*f6dc9357SAndroid Build Coastguard Worker RINOK(CopyFile_Ask(state, srcPath2, fi, destPath2))
622*f6dc9357SAndroid Build Coastguard Worker }
623*f6dc9357SAndroid Build Coastguard Worker }
624*f6dc9357SAndroid Build Coastguard Worker
625*f6dc9357SAndroid Build Coastguard Worker if (state.MoveMode)
626*f6dc9357SAndroid Build Coastguard Worker {
627*f6dc9357SAndroid Build Coastguard Worker if (!RemoveDir(srcPath))
628*f6dc9357SAndroid Build Coastguard Worker {
629*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(state.Callback, "Cannot remove folder", srcPath))
630*f6dc9357SAndroid Build Coastguard Worker return E_ABORT;
631*f6dc9357SAndroid Build Coastguard Worker }
632*f6dc9357SAndroid Build Coastguard Worker }
633*f6dc9357SAndroid Build Coastguard Worker
634*f6dc9357SAndroid Build Coastguard Worker return S_OK;
635*f6dc9357SAndroid Build Coastguard Worker }
636*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CFSFolder::CopyTo (Int32 moveMode,const UInt32 * indices,UInt32 numItems,Int32,Int32,const wchar_t * path,IFolderOperationsExtractCallback * callback))637*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
638*f6dc9357SAndroid Build Coastguard Worker Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */,
639*f6dc9357SAndroid Build Coastguard Worker const wchar_t *path, IFolderOperationsExtractCallback *callback))
640*f6dc9357SAndroid Build Coastguard Worker {
641*f6dc9357SAndroid Build Coastguard Worker if (numItems == 0)
642*f6dc9357SAndroid Build Coastguard Worker return S_OK;
643*f6dc9357SAndroid Build Coastguard Worker
644*f6dc9357SAndroid Build Coastguard Worker const FString destPath = us2fs(path);
645*f6dc9357SAndroid Build Coastguard Worker if (destPath.IsEmpty())
646*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
647*f6dc9357SAndroid Build Coastguard Worker
648*f6dc9357SAndroid Build Coastguard Worker const bool isAltDest = NName::IsAltPathPrefix(destPath);
649*f6dc9357SAndroid Build Coastguard Worker const bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
650*f6dc9357SAndroid Build Coastguard Worker
651*f6dc9357SAndroid Build Coastguard Worker if (isDirectPath)
652*f6dc9357SAndroid Build Coastguard Worker if (numItems > 1)
653*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
654*f6dc9357SAndroid Build Coastguard Worker
655*f6dc9357SAndroid Build Coastguard Worker CFsFolderStat stat;
656*f6dc9357SAndroid Build Coastguard Worker stat.Progress = callback;
657*f6dc9357SAndroid Build Coastguard Worker
658*f6dc9357SAndroid Build Coastguard Worker UInt32 i;
659*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numItems; i++)
660*f6dc9357SAndroid Build Coastguard Worker {
661*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = indices[i];
662*f6dc9357SAndroid Build Coastguard Worker /*
663*f6dc9357SAndroid Build Coastguard Worker if (index >= Files.Size())
664*f6dc9357SAndroid Build Coastguard Worker {
665*f6dc9357SAndroid Build Coastguard Worker size += Streams[index - Files.Size()].Size;
666*f6dc9357SAndroid Build Coastguard Worker // numFiles++;
667*f6dc9357SAndroid Build Coastguard Worker continue;
668*f6dc9357SAndroid Build Coastguard Worker }
669*f6dc9357SAndroid Build Coastguard Worker */
670*f6dc9357SAndroid Build Coastguard Worker const CDirItem &fi = Files[index];
671*f6dc9357SAndroid Build Coastguard Worker if (fi.IsDir())
672*f6dc9357SAndroid Build Coastguard Worker {
673*f6dc9357SAndroid Build Coastguard Worker if (!isAltDest)
674*f6dc9357SAndroid Build Coastguard Worker {
675*f6dc9357SAndroid Build Coastguard Worker stat.Path = _path;
676*f6dc9357SAndroid Build Coastguard Worker stat.Path += GetRelPath(fi);
677*f6dc9357SAndroid Build Coastguard Worker RINOK(stat.Enumerate())
678*f6dc9357SAndroid Build Coastguard Worker }
679*f6dc9357SAndroid Build Coastguard Worker stat.NumFolders++;
680*f6dc9357SAndroid Build Coastguard Worker }
681*f6dc9357SAndroid Build Coastguard Worker else
682*f6dc9357SAndroid Build Coastguard Worker {
683*f6dc9357SAndroid Build Coastguard Worker stat.NumFiles++;
684*f6dc9357SAndroid Build Coastguard Worker stat.Size += fi.Size;
685*f6dc9357SAndroid Build Coastguard Worker }
686*f6dc9357SAndroid Build Coastguard Worker }
687*f6dc9357SAndroid Build Coastguard Worker
688*f6dc9357SAndroid Build Coastguard Worker /*
689*f6dc9357SAndroid Build Coastguard Worker if (stat.NumFolders != 0 && isAltDest)
690*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
691*f6dc9357SAndroid Build Coastguard Worker */
692*f6dc9357SAndroid Build Coastguard Worker
693*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->SetTotal(stat.Size))
694*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->SetNumFiles(stat.NumFiles))
695*f6dc9357SAndroid Build Coastguard Worker
696*f6dc9357SAndroid Build Coastguard Worker UInt64 completedSize = 0;
697*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->SetCompleted(&completedSize))
698*f6dc9357SAndroid Build Coastguard Worker
699*f6dc9357SAndroid Build Coastguard Worker CCopyState state;
700*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.TotalSize = stat.Size;
701*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.StartPos = 0;
702*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.Progress = callback;
703*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.Init();
704*f6dc9357SAndroid Build Coastguard Worker state.Callback = callback;
705*f6dc9357SAndroid Build Coastguard Worker state.MoveMode = IntToBool(moveMode);
706*f6dc9357SAndroid Build Coastguard Worker state.IsAltStreamsDest = isAltDest;
707*f6dc9357SAndroid Build Coastguard Worker /* CopyFileW(fromFile, toFile:altStream) returns ERROR_INVALID_PARAMETER,
708*f6dc9357SAndroid Build Coastguard Worker if there are alt streams in fromFile.
709*f6dc9357SAndroid Build Coastguard Worker So we don't use CopyFileW() for alt Streams. */
710*f6dc9357SAndroid Build Coastguard Worker state.UseReadWriteMode = isAltDest;
711*f6dc9357SAndroid Build Coastguard Worker
712*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numItems; i++)
713*f6dc9357SAndroid Build Coastguard Worker {
714*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = indices[i];
715*f6dc9357SAndroid Build Coastguard Worker if (index >= (UInt32)Files.Size())
716*f6dc9357SAndroid Build Coastguard Worker continue;
717*f6dc9357SAndroid Build Coastguard Worker const CDirItem &fi = Files[index];
718*f6dc9357SAndroid Build Coastguard Worker FString destPath2 = destPath;
719*f6dc9357SAndroid Build Coastguard Worker if (!isDirectPath)
720*f6dc9357SAndroid Build Coastguard Worker destPath2 += fi.Name;
721*f6dc9357SAndroid Build Coastguard Worker FString srcPath;
722*f6dc9357SAndroid Build Coastguard Worker GetFullPath(fi, srcPath);
723*f6dc9357SAndroid Build Coastguard Worker
724*f6dc9357SAndroid Build Coastguard Worker if (fi.IsDir())
725*f6dc9357SAndroid Build Coastguard Worker {
726*f6dc9357SAndroid Build Coastguard Worker if (isAltDest)
727*f6dc9357SAndroid Build Coastguard Worker {
728*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(callback, k_CannotCopyDirToAltStream, srcPath))
729*f6dc9357SAndroid Build Coastguard Worker }
730*f6dc9357SAndroid Build Coastguard Worker else
731*f6dc9357SAndroid Build Coastguard Worker {
732*f6dc9357SAndroid Build Coastguard Worker RINOK(CopyFolder(state, srcPath, destPath2))
733*f6dc9357SAndroid Build Coastguard Worker }
734*f6dc9357SAndroid Build Coastguard Worker }
735*f6dc9357SAndroid Build Coastguard Worker else
736*f6dc9357SAndroid Build Coastguard Worker {
737*f6dc9357SAndroid Build Coastguard Worker RINOK(CopyFile_Ask(state, srcPath, fi, destPath2))
738*f6dc9357SAndroid Build Coastguard Worker }
739*f6dc9357SAndroid Build Coastguard Worker }
740*f6dc9357SAndroid Build Coastguard Worker return S_OK;
741*f6dc9357SAndroid Build Coastguard Worker }
742*f6dc9357SAndroid Build Coastguard Worker
743*f6dc9357SAndroid Build Coastguard Worker
744*f6dc9357SAndroid Build Coastguard Worker
745*f6dc9357SAndroid Build Coastguard Worker /* we can call CopyFileSystemItems() from CDropTarget::Drop() */
746*f6dc9357SAndroid Build Coastguard Worker
CopyFileSystemItems(const UStringVector & itemsPaths,const FString & destDirPrefix,bool moveMode,IFolderOperationsExtractCallback * callback)747*f6dc9357SAndroid Build Coastguard Worker HRESULT CopyFileSystemItems(
748*f6dc9357SAndroid Build Coastguard Worker const UStringVector &itemsPaths,
749*f6dc9357SAndroid Build Coastguard Worker const FString &destDirPrefix,
750*f6dc9357SAndroid Build Coastguard Worker bool moveMode,
751*f6dc9357SAndroid Build Coastguard Worker IFolderOperationsExtractCallback *callback)
752*f6dc9357SAndroid Build Coastguard Worker {
753*f6dc9357SAndroid Build Coastguard Worker if (itemsPaths.IsEmpty())
754*f6dc9357SAndroid Build Coastguard Worker return S_OK;
755*f6dc9357SAndroid Build Coastguard Worker
756*f6dc9357SAndroid Build Coastguard Worker if (destDirPrefix.IsEmpty())
757*f6dc9357SAndroid Build Coastguard Worker return E_INVALIDARG;
758*f6dc9357SAndroid Build Coastguard Worker
759*f6dc9357SAndroid Build Coastguard Worker const bool isAltDest = NName::IsAltPathPrefix(destDirPrefix);
760*f6dc9357SAndroid Build Coastguard Worker
761*f6dc9357SAndroid Build Coastguard Worker CFsFolderStat stat;
762*f6dc9357SAndroid Build Coastguard Worker stat.Progress = callback;
763*f6dc9357SAndroid Build Coastguard Worker
764*f6dc9357SAndroid Build Coastguard Worker {
765*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, itemsPaths)
766*f6dc9357SAndroid Build Coastguard Worker {
767*f6dc9357SAndroid Build Coastguard Worker const UString &path = itemsPaths[i];
768*f6dc9357SAndroid Build Coastguard Worker CFileInfo fi;
769*f6dc9357SAndroid Build Coastguard Worker if (!fi.Find(us2fs(path)))
770*f6dc9357SAndroid Build Coastguard Worker continue;
771*f6dc9357SAndroid Build Coastguard Worker if (fi.IsDir())
772*f6dc9357SAndroid Build Coastguard Worker {
773*f6dc9357SAndroid Build Coastguard Worker if (!isAltDest)
774*f6dc9357SAndroid Build Coastguard Worker {
775*f6dc9357SAndroid Build Coastguard Worker stat.Path = us2fs(path);
776*f6dc9357SAndroid Build Coastguard Worker RINOK(stat.Enumerate())
777*f6dc9357SAndroid Build Coastguard Worker }
778*f6dc9357SAndroid Build Coastguard Worker stat.NumFolders++;
779*f6dc9357SAndroid Build Coastguard Worker }
780*f6dc9357SAndroid Build Coastguard Worker else
781*f6dc9357SAndroid Build Coastguard Worker {
782*f6dc9357SAndroid Build Coastguard Worker stat.NumFiles++;
783*f6dc9357SAndroid Build Coastguard Worker stat.Size += fi.Size;
784*f6dc9357SAndroid Build Coastguard Worker }
785*f6dc9357SAndroid Build Coastguard Worker }
786*f6dc9357SAndroid Build Coastguard Worker }
787*f6dc9357SAndroid Build Coastguard Worker
788*f6dc9357SAndroid Build Coastguard Worker /*
789*f6dc9357SAndroid Build Coastguard Worker if (stat.NumFolders != 0 && isAltDest)
790*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
791*f6dc9357SAndroid Build Coastguard Worker */
792*f6dc9357SAndroid Build Coastguard Worker
793*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->SetTotal(stat.Size))
794*f6dc9357SAndroid Build Coastguard Worker // RINOK(progress->SetNumFiles(stat.NumFiles));
795*f6dc9357SAndroid Build Coastguard Worker
796*f6dc9357SAndroid Build Coastguard Worker UInt64 completedSize = 0;
797*f6dc9357SAndroid Build Coastguard Worker RINOK(callback->SetCompleted(&completedSize))
798*f6dc9357SAndroid Build Coastguard Worker
799*f6dc9357SAndroid Build Coastguard Worker CCopyState state;
800*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.TotalSize = stat.Size;
801*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.StartPos = 0;
802*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.Progress = callback;
803*f6dc9357SAndroid Build Coastguard Worker state.ProgressInfo.Init();
804*f6dc9357SAndroid Build Coastguard Worker state.Callback = callback;
805*f6dc9357SAndroid Build Coastguard Worker state.MoveMode = moveMode;
806*f6dc9357SAndroid Build Coastguard Worker state.IsAltStreamsDest = isAltDest;
807*f6dc9357SAndroid Build Coastguard Worker /* CopyFileW(fromFile, toFile:altStream) returns ERROR_INVALID_PARAMETER,
808*f6dc9357SAndroid Build Coastguard Worker if there are alt streams in fromFile.
809*f6dc9357SAndroid Build Coastguard Worker So we don't use CopyFileW() for alt Streams. */
810*f6dc9357SAndroid Build Coastguard Worker state.UseReadWriteMode = isAltDest;
811*f6dc9357SAndroid Build Coastguard Worker
812*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, itemsPaths)
813*f6dc9357SAndroid Build Coastguard Worker {
814*f6dc9357SAndroid Build Coastguard Worker const UString path = itemsPaths[i];
815*f6dc9357SAndroid Build Coastguard Worker CFileInfo fi;
816*f6dc9357SAndroid Build Coastguard Worker
817*f6dc9357SAndroid Build Coastguard Worker if (!fi.Find(us2fs(path)))
818*f6dc9357SAndroid Build Coastguard Worker {
819*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(callback, "Cannot find the file", us2fs(path)))
820*f6dc9357SAndroid Build Coastguard Worker continue;
821*f6dc9357SAndroid Build Coastguard Worker }
822*f6dc9357SAndroid Build Coastguard Worker
823*f6dc9357SAndroid Build Coastguard Worker FString destPath = destDirPrefix;
824*f6dc9357SAndroid Build Coastguard Worker destPath += fi.Name;
825*f6dc9357SAndroid Build Coastguard Worker
826*f6dc9357SAndroid Build Coastguard Worker if (fi.IsDir())
827*f6dc9357SAndroid Build Coastguard Worker {
828*f6dc9357SAndroid Build Coastguard Worker if (isAltDest)
829*f6dc9357SAndroid Build Coastguard Worker {
830*f6dc9357SAndroid Build Coastguard Worker RINOK(SendMessageError(callback, k_CannotCopyDirToAltStream, us2fs(path)))
831*f6dc9357SAndroid Build Coastguard Worker }
832*f6dc9357SAndroid Build Coastguard Worker else
833*f6dc9357SAndroid Build Coastguard Worker {
834*f6dc9357SAndroid Build Coastguard Worker RINOK(CopyFolder(state, us2fs(path), destPath))
835*f6dc9357SAndroid Build Coastguard Worker }
836*f6dc9357SAndroid Build Coastguard Worker }
837*f6dc9357SAndroid Build Coastguard Worker else
838*f6dc9357SAndroid Build Coastguard Worker {
839*f6dc9357SAndroid Build Coastguard Worker RINOK(CopyFile_Ask(state, us2fs(path), fi, destPath))
840*f6dc9357SAndroid Build Coastguard Worker }
841*f6dc9357SAndroid Build Coastguard Worker }
842*f6dc9357SAndroid Build Coastguard Worker return S_OK;
843*f6dc9357SAndroid Build Coastguard Worker }
844*f6dc9357SAndroid Build Coastguard Worker
845*f6dc9357SAndroid Build Coastguard Worker
846*f6dc9357SAndroid Build Coastguard Worker /* we don't use CFSFolder::CopyFrom() because the caller of CopyFrom()
847*f6dc9357SAndroid Build Coastguard Worker is optimized for IFolderArchiveUpdateCallback interface,
848*f6dc9357SAndroid Build Coastguard Worker but we want to use IFolderOperationsExtractCallback interface instead */
849*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CFSFolder::CopyFrom (Int32,const wchar_t *,const wchar_t * const *,UInt32,IProgress *))850*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
851*f6dc9357SAndroid Build Coastguard Worker const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */))
852*f6dc9357SAndroid Build Coastguard Worker {
853*f6dc9357SAndroid Build Coastguard Worker /*
854*f6dc9357SAndroid Build Coastguard Worker Z7_DECL_CMyComPtr_QI_FROM(
855*f6dc9357SAndroid Build Coastguard Worker IFolderOperationsExtractCallback,
856*f6dc9357SAndroid Build Coastguard Worker callback, progress)
857*f6dc9357SAndroid Build Coastguard Worker if (!callback)
858*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
859*f6dc9357SAndroid Build Coastguard Worker return CopyFileSystemItems(_path,
860*f6dc9357SAndroid Build Coastguard Worker moveMode, fromDirPrefix,
861*f6dc9357SAndroid Build Coastguard Worker itemsPaths, numItems, callback);
862*f6dc9357SAndroid Build Coastguard Worker */
863*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
864*f6dc9357SAndroid Build Coastguard Worker }
865*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CFSFolder::CopyFromFile (UInt32,const wchar_t *,IProgress *))866*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */))
867*f6dc9357SAndroid Build Coastguard Worker {
868*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
869*f6dc9357SAndroid Build Coastguard Worker }
870*f6dc9357SAndroid Build Coastguard Worker
871*f6dc9357SAndroid Build Coastguard Worker }
872