1*f6dc9357SAndroid Build Coastguard Worker // Windows/FileDir.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker
6*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
7*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
8*f6dc9357SAndroid Build Coastguard Worker #include <stdlib.h>
9*f6dc9357SAndroid Build Coastguard Worker #include <errno.h>
10*f6dc9357SAndroid Build Coastguard Worker #include <limits.h>
11*f6dc9357SAndroid Build Coastguard Worker #include <unistd.h>
12*f6dc9357SAndroid Build Coastguard Worker #include <time.h>
13*f6dc9357SAndroid Build Coastguard Worker #include <utime.h>
14*f6dc9357SAndroid Build Coastguard Worker #include <fcntl.h>
15*f6dc9357SAndroid Build Coastguard Worker #include <sys/stat.h>
16*f6dc9357SAndroid Build Coastguard Worker #include <sys/types.h>
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker #include "../Common/C_FileIO.h"
19*f6dc9357SAndroid Build Coastguard Worker #include "../Common/MyBuffer2.h"
20*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StringConvert.h"
21*f6dc9357SAndroid Build Coastguard Worker #endif
22*f6dc9357SAndroid Build Coastguard Worker
23*f6dc9357SAndroid Build Coastguard Worker #include "FileDir.h"
24*f6dc9357SAndroid Build Coastguard Worker #include "FileFind.h"
25*f6dc9357SAndroid Build Coastguard Worker #include "FileName.h"
26*f6dc9357SAndroid Build Coastguard Worker
27*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
28*f6dc9357SAndroid Build Coastguard Worker extern bool g_IsNT;
29*f6dc9357SAndroid Build Coastguard Worker #endif
30*f6dc9357SAndroid Build Coastguard Worker
31*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
32*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
33*f6dc9357SAndroid Build Coastguard Worker using namespace NName;
34*f6dc9357SAndroid Build Coastguard Worker
35*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
36*f6dc9357SAndroid Build Coastguard Worker
FiTime_To_timespec(const CFiTime * ft,timespec & ts)37*f6dc9357SAndroid Build Coastguard Worker static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts)
38*f6dc9357SAndroid Build Coastguard Worker {
39*f6dc9357SAndroid Build Coastguard Worker if (ft)
40*f6dc9357SAndroid Build Coastguard Worker {
41*f6dc9357SAndroid Build Coastguard Worker #if defined(_AIX)
42*f6dc9357SAndroid Build Coastguard Worker ts.tv_sec = ft->tv_sec;
43*f6dc9357SAndroid Build Coastguard Worker ts.tv_nsec = ft->tv_nsec;
44*f6dc9357SAndroid Build Coastguard Worker #else
45*f6dc9357SAndroid Build Coastguard Worker ts = *ft;
46*f6dc9357SAndroid Build Coastguard Worker #endif
47*f6dc9357SAndroid Build Coastguard Worker return true;
48*f6dc9357SAndroid Build Coastguard Worker }
49*f6dc9357SAndroid Build Coastguard Worker // else
50*f6dc9357SAndroid Build Coastguard Worker {
51*f6dc9357SAndroid Build Coastguard Worker ts.tv_sec = 0;
52*f6dc9357SAndroid Build Coastguard Worker ts.tv_nsec =
53*f6dc9357SAndroid Build Coastguard Worker #ifdef UTIME_OMIT
54*f6dc9357SAndroid Build Coastguard Worker UTIME_OMIT; // -2 keep old timesptamp
55*f6dc9357SAndroid Build Coastguard Worker #else
56*f6dc9357SAndroid Build Coastguard Worker // UTIME_NOW; -1 // set to the current time
57*f6dc9357SAndroid Build Coastguard Worker 0;
58*f6dc9357SAndroid Build Coastguard Worker #endif
59*f6dc9357SAndroid Build Coastguard Worker return false;
60*f6dc9357SAndroid Build Coastguard Worker }
61*f6dc9357SAndroid Build Coastguard Worker }
62*f6dc9357SAndroid Build Coastguard Worker #endif
63*f6dc9357SAndroid Build Coastguard Worker
64*f6dc9357SAndroid Build Coastguard Worker namespace NWindows {
65*f6dc9357SAndroid Build Coastguard Worker namespace NFile {
66*f6dc9357SAndroid Build Coastguard Worker namespace NDir {
67*f6dc9357SAndroid Build Coastguard Worker
68*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
69*f6dc9357SAndroid Build Coastguard Worker
70*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
71*f6dc9357SAndroid Build Coastguard Worker
GetWindowsDir(FString & path)72*f6dc9357SAndroid Build Coastguard Worker bool GetWindowsDir(FString &path)
73*f6dc9357SAndroid Build Coastguard Worker {
74*f6dc9357SAndroid Build Coastguard Worker const unsigned kBufSize = MAX_PATH + 16;
75*f6dc9357SAndroid Build Coastguard Worker UINT len;
76*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
77*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
78*f6dc9357SAndroid Build Coastguard Worker {
79*f6dc9357SAndroid Build Coastguard Worker TCHAR s[kBufSize + 1];
80*f6dc9357SAndroid Build Coastguard Worker s[0] = 0;
81*f6dc9357SAndroid Build Coastguard Worker len = ::GetWindowsDirectory(s, kBufSize);
82*f6dc9357SAndroid Build Coastguard Worker path = fas2fs(s);
83*f6dc9357SAndroid Build Coastguard Worker }
84*f6dc9357SAndroid Build Coastguard Worker else
85*f6dc9357SAndroid Build Coastguard Worker #endif
86*f6dc9357SAndroid Build Coastguard Worker {
87*f6dc9357SAndroid Build Coastguard Worker WCHAR s[kBufSize + 1];
88*f6dc9357SAndroid Build Coastguard Worker s[0] = 0;
89*f6dc9357SAndroid Build Coastguard Worker len = ::GetWindowsDirectoryW(s, kBufSize);
90*f6dc9357SAndroid Build Coastguard Worker path = us2fs(s);
91*f6dc9357SAndroid Build Coastguard Worker }
92*f6dc9357SAndroid Build Coastguard Worker return (len != 0 && len < kBufSize);
93*f6dc9357SAndroid Build Coastguard Worker }
94*f6dc9357SAndroid Build Coastguard Worker
95*f6dc9357SAndroid Build Coastguard Worker
96*f6dc9357SAndroid Build Coastguard Worker /*
97*f6dc9357SAndroid Build Coastguard Worker new DOCs for GetSystemDirectory:
98*f6dc9357SAndroid Build Coastguard Worker returned path does not end with a backslash unless the
99*f6dc9357SAndroid Build Coastguard Worker system directory is the root directory.
100*f6dc9357SAndroid Build Coastguard Worker */
101*f6dc9357SAndroid Build Coastguard Worker
GetSystemDir(FString & path)102*f6dc9357SAndroid Build Coastguard Worker bool GetSystemDir(FString &path)
103*f6dc9357SAndroid Build Coastguard Worker {
104*f6dc9357SAndroid Build Coastguard Worker const unsigned kBufSize = MAX_PATH + 16;
105*f6dc9357SAndroid Build Coastguard Worker UINT len;
106*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
107*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
108*f6dc9357SAndroid Build Coastguard Worker {
109*f6dc9357SAndroid Build Coastguard Worker TCHAR s[kBufSize + 1];
110*f6dc9357SAndroid Build Coastguard Worker s[0] = 0;
111*f6dc9357SAndroid Build Coastguard Worker len = ::GetSystemDirectory(s, kBufSize);
112*f6dc9357SAndroid Build Coastguard Worker path = fas2fs(s);
113*f6dc9357SAndroid Build Coastguard Worker }
114*f6dc9357SAndroid Build Coastguard Worker else
115*f6dc9357SAndroid Build Coastguard Worker #endif
116*f6dc9357SAndroid Build Coastguard Worker {
117*f6dc9357SAndroid Build Coastguard Worker WCHAR s[kBufSize + 1];
118*f6dc9357SAndroid Build Coastguard Worker s[0] = 0;
119*f6dc9357SAndroid Build Coastguard Worker len = ::GetSystemDirectoryW(s, kBufSize);
120*f6dc9357SAndroid Build Coastguard Worker path = us2fs(s);
121*f6dc9357SAndroid Build Coastguard Worker }
122*f6dc9357SAndroid Build Coastguard Worker return (len != 0 && len < kBufSize);
123*f6dc9357SAndroid Build Coastguard Worker }
124*f6dc9357SAndroid Build Coastguard Worker #endif // UNDER_CE
125*f6dc9357SAndroid Build Coastguard Worker
126*f6dc9357SAndroid Build Coastguard Worker
SetDirTime(CFSTR path,const CFiTime * cTime,const CFiTime * aTime,const CFiTime * mTime)127*f6dc9357SAndroid Build Coastguard Worker bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
128*f6dc9357SAndroid Build Coastguard Worker {
129*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
130*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
131*f6dc9357SAndroid Build Coastguard Worker {
132*f6dc9357SAndroid Build Coastguard Worker ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
133*f6dc9357SAndroid Build Coastguard Worker return false;
134*f6dc9357SAndroid Build Coastguard Worker }
135*f6dc9357SAndroid Build Coastguard Worker #endif
136*f6dc9357SAndroid Build Coastguard Worker
137*f6dc9357SAndroid Build Coastguard Worker HANDLE hDir = INVALID_HANDLE_VALUE;
138*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH
139*f6dc9357SAndroid Build Coastguard Worker hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
140*f6dc9357SAndroid Build Coastguard Worker NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
141*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
142*f6dc9357SAndroid Build Coastguard Worker if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
143*f6dc9357SAndroid Build Coastguard Worker {
144*f6dc9357SAndroid Build Coastguard Worker UString superPath;
145*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPath(path, superPath, USE_MAIN_PATH))
146*f6dc9357SAndroid Build Coastguard Worker hDir = ::CreateFileW(superPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
147*f6dc9357SAndroid Build Coastguard Worker NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
148*f6dc9357SAndroid Build Coastguard Worker }
149*f6dc9357SAndroid Build Coastguard Worker #endif
150*f6dc9357SAndroid Build Coastguard Worker
151*f6dc9357SAndroid Build Coastguard Worker bool res = false;
152*f6dc9357SAndroid Build Coastguard Worker if (hDir != INVALID_HANDLE_VALUE)
153*f6dc9357SAndroid Build Coastguard Worker {
154*f6dc9357SAndroid Build Coastguard Worker res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime));
155*f6dc9357SAndroid Build Coastguard Worker ::CloseHandle(hDir);
156*f6dc9357SAndroid Build Coastguard Worker }
157*f6dc9357SAndroid Build Coastguard Worker return res;
158*f6dc9357SAndroid Build Coastguard Worker }
159*f6dc9357SAndroid Build Coastguard Worker
160*f6dc9357SAndroid Build Coastguard Worker
161*f6dc9357SAndroid Build Coastguard Worker
SetFileAttrib(CFSTR path,DWORD attrib)162*f6dc9357SAndroid Build Coastguard Worker bool SetFileAttrib(CFSTR path, DWORD attrib)
163*f6dc9357SAndroid Build Coastguard Worker {
164*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
165*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
166*f6dc9357SAndroid Build Coastguard Worker {
167*f6dc9357SAndroid Build Coastguard Worker if (::SetFileAttributes(fs2fas(path), attrib))
168*f6dc9357SAndroid Build Coastguard Worker return true;
169*f6dc9357SAndroid Build Coastguard Worker }
170*f6dc9357SAndroid Build Coastguard Worker else
171*f6dc9357SAndroid Build Coastguard Worker #endif
172*f6dc9357SAndroid Build Coastguard Worker {
173*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH
174*f6dc9357SAndroid Build Coastguard Worker if (::SetFileAttributesW(fs2us(path), attrib))
175*f6dc9357SAndroid Build Coastguard Worker return true;
176*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
177*f6dc9357SAndroid Build Coastguard Worker if (USE_SUPER_PATH)
178*f6dc9357SAndroid Build Coastguard Worker {
179*f6dc9357SAndroid Build Coastguard Worker UString superPath;
180*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPath(path, superPath, USE_MAIN_PATH))
181*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::SetFileAttributesW(superPath, attrib));
182*f6dc9357SAndroid Build Coastguard Worker }
183*f6dc9357SAndroid Build Coastguard Worker #endif
184*f6dc9357SAndroid Build Coastguard Worker }
185*f6dc9357SAndroid Build Coastguard Worker return false;
186*f6dc9357SAndroid Build Coastguard Worker }
187*f6dc9357SAndroid Build Coastguard Worker
188*f6dc9357SAndroid Build Coastguard Worker
SetFileAttrib_PosixHighDetect(CFSTR path,DWORD attrib)189*f6dc9357SAndroid Build Coastguard Worker bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib)
190*f6dc9357SAndroid Build Coastguard Worker {
191*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
192*f6dc9357SAndroid Build Coastguard Worker if ((attrib & 0xF0000000) != 0)
193*f6dc9357SAndroid Build Coastguard Worker attrib &= 0x3FFF;
194*f6dc9357SAndroid Build Coastguard Worker #endif
195*f6dc9357SAndroid Build Coastguard Worker return SetFileAttrib(path, attrib);
196*f6dc9357SAndroid Build Coastguard Worker }
197*f6dc9357SAndroid Build Coastguard Worker
198*f6dc9357SAndroid Build Coastguard Worker
RemoveDir(CFSTR path)199*f6dc9357SAndroid Build Coastguard Worker bool RemoveDir(CFSTR path)
200*f6dc9357SAndroid Build Coastguard Worker {
201*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
202*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
203*f6dc9357SAndroid Build Coastguard Worker {
204*f6dc9357SAndroid Build Coastguard Worker if (::RemoveDirectory(fs2fas(path)))
205*f6dc9357SAndroid Build Coastguard Worker return true;
206*f6dc9357SAndroid Build Coastguard Worker }
207*f6dc9357SAndroid Build Coastguard Worker else
208*f6dc9357SAndroid Build Coastguard Worker #endif
209*f6dc9357SAndroid Build Coastguard Worker {
210*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH
211*f6dc9357SAndroid Build Coastguard Worker if (::RemoveDirectoryW(fs2us(path)))
212*f6dc9357SAndroid Build Coastguard Worker return true;
213*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
214*f6dc9357SAndroid Build Coastguard Worker if (USE_SUPER_PATH)
215*f6dc9357SAndroid Build Coastguard Worker {
216*f6dc9357SAndroid Build Coastguard Worker UString superPath;
217*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPath(path, superPath, USE_MAIN_PATH))
218*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::RemoveDirectoryW(superPath));
219*f6dc9357SAndroid Build Coastguard Worker }
220*f6dc9357SAndroid Build Coastguard Worker #endif
221*f6dc9357SAndroid Build Coastguard Worker }
222*f6dc9357SAndroid Build Coastguard Worker return false;
223*f6dc9357SAndroid Build Coastguard Worker }
224*f6dc9357SAndroid Build Coastguard Worker
225*f6dc9357SAndroid Build Coastguard Worker
226*f6dc9357SAndroid Build Coastguard Worker // When moving a directory, oldFile and newFile must be on the same drive.
227*f6dc9357SAndroid Build Coastguard Worker
MyMoveFile(CFSTR oldFile,CFSTR newFile)228*f6dc9357SAndroid Build Coastguard Worker bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
229*f6dc9357SAndroid Build Coastguard Worker {
230*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
231*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
232*f6dc9357SAndroid Build Coastguard Worker {
233*f6dc9357SAndroid Build Coastguard Worker if (::MoveFile(fs2fas(oldFile), fs2fas(newFile)))
234*f6dc9357SAndroid Build Coastguard Worker return true;
235*f6dc9357SAndroid Build Coastguard Worker }
236*f6dc9357SAndroid Build Coastguard Worker else
237*f6dc9357SAndroid Build Coastguard Worker #endif
238*f6dc9357SAndroid Build Coastguard Worker {
239*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH_2(oldFile, newFile)
240*f6dc9357SAndroid Build Coastguard Worker {
241*f6dc9357SAndroid Build Coastguard Worker if (::MoveFileW(fs2us(oldFile), fs2us(newFile)))
242*f6dc9357SAndroid Build Coastguard Worker return true;
243*f6dc9357SAndroid Build Coastguard Worker }
244*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
245*f6dc9357SAndroid Build Coastguard Worker if (USE_SUPER_PATH_2)
246*f6dc9357SAndroid Build Coastguard Worker {
247*f6dc9357SAndroid Build Coastguard Worker UString d1, d2;
248*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2))
249*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::MoveFileW(d1, d2));
250*f6dc9357SAndroid Build Coastguard Worker }
251*f6dc9357SAndroid Build Coastguard Worker #endif
252*f6dc9357SAndroid Build Coastguard Worker }
253*f6dc9357SAndroid Build Coastguard Worker return false;
254*f6dc9357SAndroid Build Coastguard Worker }
255*f6dc9357SAndroid Build Coastguard Worker
256*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_WIN32_WINNT_MIN) && Z7_WIN32_WINNT_MIN >= 0x0500
CopyProgressRoutine_to_ICopyFileProgress(LARGE_INTEGER TotalFileSize,LARGE_INTEGER TotalBytesTransferred,LARGE_INTEGER,LARGE_INTEGER,DWORD,DWORD,HANDLE,HANDLE,LPVOID lpData)257*f6dc9357SAndroid Build Coastguard Worker static DWORD WINAPI CopyProgressRoutine_to_ICopyFileProgress(
258*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER TotalFileSize, // file size
259*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER TotalBytesTransferred, // bytes transferred
260*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER /* StreamSize */, // bytes in stream
261*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream
262*f6dc9357SAndroid Build Coastguard Worker DWORD /* dwStreamNumber */, // current stream
263*f6dc9357SAndroid Build Coastguard Worker DWORD /* dwCallbackReason */, // callback reason
264*f6dc9357SAndroid Build Coastguard Worker HANDLE /* hSourceFile */, // handle to source file
265*f6dc9357SAndroid Build Coastguard Worker HANDLE /* hDestinationFile */, // handle to destination file
266*f6dc9357SAndroid Build Coastguard Worker LPVOID lpData // from CopyFileEx
267*f6dc9357SAndroid Build Coastguard Worker )
268*f6dc9357SAndroid Build Coastguard Worker {
269*f6dc9357SAndroid Build Coastguard Worker return ((ICopyFileProgress *)lpData)->CopyFileProgress(
270*f6dc9357SAndroid Build Coastguard Worker (UInt64)TotalFileSize.QuadPart,
271*f6dc9357SAndroid Build Coastguard Worker (UInt64)TotalBytesTransferred.QuadPart);
272*f6dc9357SAndroid Build Coastguard Worker }
273*f6dc9357SAndroid Build Coastguard Worker #endif
274*f6dc9357SAndroid Build Coastguard Worker
MyMoveFile_with_Progress(CFSTR oldFile,CFSTR newFile,ICopyFileProgress * progress)275*f6dc9357SAndroid Build Coastguard Worker bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile,
276*f6dc9357SAndroid Build Coastguard Worker ICopyFileProgress *progress)
277*f6dc9357SAndroid Build Coastguard Worker {
278*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_WIN32_WINNT_MIN) && Z7_WIN32_WINNT_MIN >= 0x0500
279*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
280*f6dc9357SAndroid Build Coastguard Worker if (g_IsNT)
281*f6dc9357SAndroid Build Coastguard Worker #endif
282*f6dc9357SAndroid Build Coastguard Worker if (progress)
283*f6dc9357SAndroid Build Coastguard Worker {
284*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH_2(oldFile, newFile)
285*f6dc9357SAndroid Build Coastguard Worker {
286*f6dc9357SAndroid Build Coastguard Worker if (::MoveFileWithProgressW(fs2us(oldFile), fs2us(newFile),
287*f6dc9357SAndroid Build Coastguard Worker CopyProgressRoutine_to_ICopyFileProgress, progress, MOVEFILE_COPY_ALLOWED))
288*f6dc9357SAndroid Build Coastguard Worker return true;
289*f6dc9357SAndroid Build Coastguard Worker if (::GetLastError() == ERROR_REQUEST_ABORTED)
290*f6dc9357SAndroid Build Coastguard Worker return false;
291*f6dc9357SAndroid Build Coastguard Worker }
292*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
293*f6dc9357SAndroid Build Coastguard Worker if (USE_SUPER_PATH_2)
294*f6dc9357SAndroid Build Coastguard Worker {
295*f6dc9357SAndroid Build Coastguard Worker UString d1, d2;
296*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2))
297*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::MoveFileWithProgressW(d1, d2,
298*f6dc9357SAndroid Build Coastguard Worker CopyProgressRoutine_to_ICopyFileProgress, progress, MOVEFILE_COPY_ALLOWED));
299*f6dc9357SAndroid Build Coastguard Worker }
300*f6dc9357SAndroid Build Coastguard Worker #endif
301*f6dc9357SAndroid Build Coastguard Worker return false;
302*f6dc9357SAndroid Build Coastguard Worker }
303*f6dc9357SAndroid Build Coastguard Worker #else
304*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(progress)
305*f6dc9357SAndroid Build Coastguard Worker #endif
306*f6dc9357SAndroid Build Coastguard Worker return MyMoveFile(oldFile, newFile);
307*f6dc9357SAndroid Build Coastguard Worker }
308*f6dc9357SAndroid Build Coastguard Worker
309*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
310*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // Win2000
311*f6dc9357SAndroid Build Coastguard Worker #define Z7_USE_DYN_CreateHardLink
312*f6dc9357SAndroid Build Coastguard Worker #endif
313*f6dc9357SAndroid Build Coastguard Worker
314*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_CreateHardLink
315*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
316*f6dc9357SAndroid Build Coastguard Worker typedef BOOL (WINAPI *Func_CreateHardLinkW)(
317*f6dc9357SAndroid Build Coastguard Worker LPCWSTR lpFileName,
318*f6dc9357SAndroid Build Coastguard Worker LPCWSTR lpExistingFileName,
319*f6dc9357SAndroid Build Coastguard Worker LPSECURITY_ATTRIBUTES lpSecurityAttributes
320*f6dc9357SAndroid Build Coastguard Worker );
321*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
322*f6dc9357SAndroid Build Coastguard Worker #endif
323*f6dc9357SAndroid Build Coastguard Worker #endif // UNDER_CE
324*f6dc9357SAndroid Build Coastguard Worker
MyCreateHardLink(CFSTR newFileName,CFSTR existFileName)325*f6dc9357SAndroid Build Coastguard Worker bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
326*f6dc9357SAndroid Build Coastguard Worker {
327*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
328*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
329*f6dc9357SAndroid Build Coastguard Worker {
330*f6dc9357SAndroid Build Coastguard Worker SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
331*f6dc9357SAndroid Build Coastguard Worker return false;
332*f6dc9357SAndroid Build Coastguard Worker /*
333*f6dc9357SAndroid Build Coastguard Worker if (::CreateHardLink(fs2fas(newFileName), fs2fas(existFileName), NULL))
334*f6dc9357SAndroid Build Coastguard Worker return true;
335*f6dc9357SAndroid Build Coastguard Worker */
336*f6dc9357SAndroid Build Coastguard Worker }
337*f6dc9357SAndroid Build Coastguard Worker else
338*f6dc9357SAndroid Build Coastguard Worker #endif
339*f6dc9357SAndroid Build Coastguard Worker {
340*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_CreateHardLink
341*f6dc9357SAndroid Build Coastguard Worker const
342*f6dc9357SAndroid Build Coastguard Worker Func_CreateHardLinkW
343*f6dc9357SAndroid Build Coastguard Worker my_CreateHardLinkW = Z7_GET_PROC_ADDRESS(
344*f6dc9357SAndroid Build Coastguard Worker Func_CreateHardLinkW, ::GetModuleHandleW(L"kernel32.dll"),
345*f6dc9357SAndroid Build Coastguard Worker "CreateHardLinkW");
346*f6dc9357SAndroid Build Coastguard Worker if (!my_CreateHardLinkW)
347*f6dc9357SAndroid Build Coastguard Worker return false;
348*f6dc9357SAndroid Build Coastguard Worker #define MY_CreateHardLinkW my_CreateHardLinkW
349*f6dc9357SAndroid Build Coastguard Worker #else
350*f6dc9357SAndroid Build Coastguard Worker #define MY_CreateHardLinkW CreateHardLinkW
351*f6dc9357SAndroid Build Coastguard Worker #endif
352*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH_2(newFileName, existFileName)
353*f6dc9357SAndroid Build Coastguard Worker {
354*f6dc9357SAndroid Build Coastguard Worker if (MY_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL))
355*f6dc9357SAndroid Build Coastguard Worker return true;
356*f6dc9357SAndroid Build Coastguard Worker }
357*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
358*f6dc9357SAndroid Build Coastguard Worker if (USE_SUPER_PATH_2)
359*f6dc9357SAndroid Build Coastguard Worker {
360*f6dc9357SAndroid Build Coastguard Worker UString d1, d2;
361*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPaths(newFileName, existFileName, d1, d2, USE_MAIN_PATH_2))
362*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(MY_CreateHardLinkW(d1, d2, NULL));
363*f6dc9357SAndroid Build Coastguard Worker }
364*f6dc9357SAndroid Build Coastguard Worker #endif
365*f6dc9357SAndroid Build Coastguard Worker }
366*f6dc9357SAndroid Build Coastguard Worker return false;
367*f6dc9357SAndroid Build Coastguard Worker }
368*f6dc9357SAndroid Build Coastguard Worker
369*f6dc9357SAndroid Build Coastguard Worker
370*f6dc9357SAndroid Build Coastguard Worker /*
371*f6dc9357SAndroid Build Coastguard Worker WinXP-64 CreateDir():
372*f6dc9357SAndroid Build Coastguard Worker "" - ERROR_PATH_NOT_FOUND
373*f6dc9357SAndroid Build Coastguard Worker \ - ERROR_ACCESS_DENIED
374*f6dc9357SAndroid Build Coastguard Worker C:\ - ERROR_ACCESS_DENIED, if there is such drive,
375*f6dc9357SAndroid Build Coastguard Worker
376*f6dc9357SAndroid Build Coastguard Worker D:\folder - ERROR_PATH_NOT_FOUND, if there is no such drive,
377*f6dc9357SAndroid Build Coastguard Worker C:\nonExistent\folder - ERROR_PATH_NOT_FOUND
378*f6dc9357SAndroid Build Coastguard Worker
379*f6dc9357SAndroid Build Coastguard Worker C:\existFolder - ERROR_ALREADY_EXISTS
380*f6dc9357SAndroid Build Coastguard Worker C:\existFolder\ - ERROR_ALREADY_EXISTS
381*f6dc9357SAndroid Build Coastguard Worker
382*f6dc9357SAndroid Build Coastguard Worker C:\folder - OK
383*f6dc9357SAndroid Build Coastguard Worker C:\folder\ - OK
384*f6dc9357SAndroid Build Coastguard Worker
385*f6dc9357SAndroid Build Coastguard Worker \\Server\nonExistent - ERROR_BAD_NETPATH
386*f6dc9357SAndroid Build Coastguard Worker \\Server\Share_Readonly - ERROR_ACCESS_DENIED
387*f6dc9357SAndroid Build Coastguard Worker \\Server\Share - ERROR_ALREADY_EXISTS
388*f6dc9357SAndroid Build Coastguard Worker
389*f6dc9357SAndroid Build Coastguard Worker \\Server\Share_NTFS_drive - ERROR_ACCESS_DENIED
390*f6dc9357SAndroid Build Coastguard Worker \\Server\Share_FAT_drive - ERROR_ALREADY_EXISTS
391*f6dc9357SAndroid Build Coastguard Worker */
392*f6dc9357SAndroid Build Coastguard Worker
CreateDir(CFSTR path)393*f6dc9357SAndroid Build Coastguard Worker bool CreateDir(CFSTR path)
394*f6dc9357SAndroid Build Coastguard Worker {
395*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
396*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
397*f6dc9357SAndroid Build Coastguard Worker {
398*f6dc9357SAndroid Build Coastguard Worker if (::CreateDirectory(fs2fas(path), NULL))
399*f6dc9357SAndroid Build Coastguard Worker return true;
400*f6dc9357SAndroid Build Coastguard Worker }
401*f6dc9357SAndroid Build Coastguard Worker else
402*f6dc9357SAndroid Build Coastguard Worker #endif
403*f6dc9357SAndroid Build Coastguard Worker {
404*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH
405*f6dc9357SAndroid Build Coastguard Worker if (::CreateDirectoryW(fs2us(path), NULL))
406*f6dc9357SAndroid Build Coastguard Worker return true;
407*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
408*f6dc9357SAndroid Build Coastguard Worker if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
409*f6dc9357SAndroid Build Coastguard Worker {
410*f6dc9357SAndroid Build Coastguard Worker UString superPath;
411*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPath(path, superPath, USE_MAIN_PATH))
412*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::CreateDirectoryW(superPath, NULL));
413*f6dc9357SAndroid Build Coastguard Worker }
414*f6dc9357SAndroid Build Coastguard Worker #endif
415*f6dc9357SAndroid Build Coastguard Worker }
416*f6dc9357SAndroid Build Coastguard Worker return false;
417*f6dc9357SAndroid Build Coastguard Worker }
418*f6dc9357SAndroid Build Coastguard Worker
419*f6dc9357SAndroid Build Coastguard Worker /*
420*f6dc9357SAndroid Build Coastguard Worker CreateDir2 returns true, if directory can contain files after the call (two cases):
421*f6dc9357SAndroid Build Coastguard Worker 1) the directory already exists
422*f6dc9357SAndroid Build Coastguard Worker 2) the directory was created
423*f6dc9357SAndroid Build Coastguard Worker path must be WITHOUT trailing path separator.
424*f6dc9357SAndroid Build Coastguard Worker
425*f6dc9357SAndroid Build Coastguard Worker We need CreateDir2, since fileInfo.Find() for reserved names like "com8"
426*f6dc9357SAndroid Build Coastguard Worker returns FILE instead of DIRECTORY. And we need to use SuperPath */
427*f6dc9357SAndroid Build Coastguard Worker
CreateDir2(CFSTR path)428*f6dc9357SAndroid Build Coastguard Worker static bool CreateDir2(CFSTR path)
429*f6dc9357SAndroid Build Coastguard Worker {
430*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
431*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
432*f6dc9357SAndroid Build Coastguard Worker {
433*f6dc9357SAndroid Build Coastguard Worker if (::CreateDirectory(fs2fas(path), NULL))
434*f6dc9357SAndroid Build Coastguard Worker return true;
435*f6dc9357SAndroid Build Coastguard Worker }
436*f6dc9357SAndroid Build Coastguard Worker else
437*f6dc9357SAndroid Build Coastguard Worker #endif
438*f6dc9357SAndroid Build Coastguard Worker {
439*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH
440*f6dc9357SAndroid Build Coastguard Worker if (::CreateDirectoryW(fs2us(path), NULL))
441*f6dc9357SAndroid Build Coastguard Worker return true;
442*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
443*f6dc9357SAndroid Build Coastguard Worker if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
444*f6dc9357SAndroid Build Coastguard Worker {
445*f6dc9357SAndroid Build Coastguard Worker UString superPath;
446*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPath(path, superPath, USE_MAIN_PATH))
447*f6dc9357SAndroid Build Coastguard Worker {
448*f6dc9357SAndroid Build Coastguard Worker if (::CreateDirectoryW(superPath, NULL))
449*f6dc9357SAndroid Build Coastguard Worker return true;
450*f6dc9357SAndroid Build Coastguard Worker if (::GetLastError() != ERROR_ALREADY_EXISTS)
451*f6dc9357SAndroid Build Coastguard Worker return false;
452*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fi;
453*f6dc9357SAndroid Build Coastguard Worker if (!fi.Find(us2fs(superPath)))
454*f6dc9357SAndroid Build Coastguard Worker return false;
455*f6dc9357SAndroid Build Coastguard Worker return fi.IsDir();
456*f6dc9357SAndroid Build Coastguard Worker }
457*f6dc9357SAndroid Build Coastguard Worker }
458*f6dc9357SAndroid Build Coastguard Worker #endif
459*f6dc9357SAndroid Build Coastguard Worker }
460*f6dc9357SAndroid Build Coastguard Worker if (::GetLastError() != ERROR_ALREADY_EXISTS)
461*f6dc9357SAndroid Build Coastguard Worker return false;
462*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fi;
463*f6dc9357SAndroid Build Coastguard Worker if (!fi.Find(path))
464*f6dc9357SAndroid Build Coastguard Worker return false;
465*f6dc9357SAndroid Build Coastguard Worker return fi.IsDir();
466*f6dc9357SAndroid Build Coastguard Worker }
467*f6dc9357SAndroid Build Coastguard Worker
468*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
469*f6dc9357SAndroid Build Coastguard Worker
470*f6dc9357SAndroid Build Coastguard Worker static bool CreateDir2(CFSTR path);
471*f6dc9357SAndroid Build Coastguard Worker
CreateComplexDir(CFSTR _path)472*f6dc9357SAndroid Build Coastguard Worker bool CreateComplexDir(CFSTR _path)
473*f6dc9357SAndroid Build Coastguard Worker {
474*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
475*f6dc9357SAndroid Build Coastguard Worker
476*f6dc9357SAndroid Build Coastguard Worker {
477*f6dc9357SAndroid Build Coastguard Worker const DWORD attrib = NFind::GetFileAttrib(_path);
478*f6dc9357SAndroid Build Coastguard Worker if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
479*f6dc9357SAndroid Build Coastguard Worker return true;
480*f6dc9357SAndroid Build Coastguard Worker }
481*f6dc9357SAndroid Build Coastguard Worker
482*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
483*f6dc9357SAndroid Build Coastguard Worker
484*f6dc9357SAndroid Build Coastguard Worker if (IsDriveRootPath_SuperAllowed(_path))
485*f6dc9357SAndroid Build Coastguard Worker return false;
486*f6dc9357SAndroid Build Coastguard Worker
487*f6dc9357SAndroid Build Coastguard Worker const unsigned prefixSize = GetRootPrefixSize(_path);
488*f6dc9357SAndroid Build Coastguard Worker
489*f6dc9357SAndroid Build Coastguard Worker #endif // UNDER_CE
490*f6dc9357SAndroid Build Coastguard Worker
491*f6dc9357SAndroid Build Coastguard Worker #else // _WIN32
492*f6dc9357SAndroid Build Coastguard Worker
493*f6dc9357SAndroid Build Coastguard Worker // Posix
494*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fi;
495*f6dc9357SAndroid Build Coastguard Worker if (fi.Find(_path))
496*f6dc9357SAndroid Build Coastguard Worker {
497*f6dc9357SAndroid Build Coastguard Worker if (fi.IsDir())
498*f6dc9357SAndroid Build Coastguard Worker return true;
499*f6dc9357SAndroid Build Coastguard Worker }
500*f6dc9357SAndroid Build Coastguard Worker
501*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
502*f6dc9357SAndroid Build Coastguard Worker
503*f6dc9357SAndroid Build Coastguard Worker FString path (_path);
504*f6dc9357SAndroid Build Coastguard Worker
505*f6dc9357SAndroid Build Coastguard Worker int pos = path.ReverseFind_PathSepar();
506*f6dc9357SAndroid Build Coastguard Worker if (pos >= 0 && (unsigned)pos == path.Len() - 1)
507*f6dc9357SAndroid Build Coastguard Worker {
508*f6dc9357SAndroid Build Coastguard Worker if (path.Len() == 1)
509*f6dc9357SAndroid Build Coastguard Worker return true;
510*f6dc9357SAndroid Build Coastguard Worker path.DeleteBack();
511*f6dc9357SAndroid Build Coastguard Worker }
512*f6dc9357SAndroid Build Coastguard Worker
513*f6dc9357SAndroid Build Coastguard Worker const FString path2 (path);
514*f6dc9357SAndroid Build Coastguard Worker pos = (int)path.Len();
515*f6dc9357SAndroid Build Coastguard Worker
516*f6dc9357SAndroid Build Coastguard Worker for (;;)
517*f6dc9357SAndroid Build Coastguard Worker {
518*f6dc9357SAndroid Build Coastguard Worker if (CreateDir2(path))
519*f6dc9357SAndroid Build Coastguard Worker break;
520*f6dc9357SAndroid Build Coastguard Worker if (::GetLastError() == ERROR_ALREADY_EXISTS)
521*f6dc9357SAndroid Build Coastguard Worker return false;
522*f6dc9357SAndroid Build Coastguard Worker pos = path.ReverseFind_PathSepar();
523*f6dc9357SAndroid Build Coastguard Worker if (pos < 0 || pos == 0)
524*f6dc9357SAndroid Build Coastguard Worker return false;
525*f6dc9357SAndroid Build Coastguard Worker
526*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
527*f6dc9357SAndroid Build Coastguard Worker if (pos == 1 && IS_PATH_SEPAR(path[0]))
528*f6dc9357SAndroid Build Coastguard Worker return false;
529*f6dc9357SAndroid Build Coastguard Worker if (prefixSize >= (unsigned)pos + 1)
530*f6dc9357SAndroid Build Coastguard Worker return false;
531*f6dc9357SAndroid Build Coastguard Worker #endif
532*f6dc9357SAndroid Build Coastguard Worker
533*f6dc9357SAndroid Build Coastguard Worker path.DeleteFrom((unsigned)pos);
534*f6dc9357SAndroid Build Coastguard Worker }
535*f6dc9357SAndroid Build Coastguard Worker
536*f6dc9357SAndroid Build Coastguard Worker while (pos < (int)path2.Len())
537*f6dc9357SAndroid Build Coastguard Worker {
538*f6dc9357SAndroid Build Coastguard Worker int pos2 = NName::FindSepar(path2.Ptr((unsigned)pos + 1));
539*f6dc9357SAndroid Build Coastguard Worker if (pos2 < 0)
540*f6dc9357SAndroid Build Coastguard Worker pos = (int)path2.Len();
541*f6dc9357SAndroid Build Coastguard Worker else
542*f6dc9357SAndroid Build Coastguard Worker pos += 1 + pos2;
543*f6dc9357SAndroid Build Coastguard Worker path.SetFrom(path2, (unsigned)pos);
544*f6dc9357SAndroid Build Coastguard Worker if (!CreateDir(path))
545*f6dc9357SAndroid Build Coastguard Worker return false;
546*f6dc9357SAndroid Build Coastguard Worker }
547*f6dc9357SAndroid Build Coastguard Worker
548*f6dc9357SAndroid Build Coastguard Worker return true;
549*f6dc9357SAndroid Build Coastguard Worker }
550*f6dc9357SAndroid Build Coastguard Worker
551*f6dc9357SAndroid Build Coastguard Worker
552*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
553*f6dc9357SAndroid Build Coastguard Worker
DeleteFileAlways(CFSTR path)554*f6dc9357SAndroid Build Coastguard Worker bool DeleteFileAlways(CFSTR path)
555*f6dc9357SAndroid Build Coastguard Worker {
556*f6dc9357SAndroid Build Coastguard Worker /* If alt stream, we also need to clear READ-ONLY attribute of main file before delete.
557*f6dc9357SAndroid Build Coastguard Worker SetFileAttrib("name:stream", ) changes attributes of main file. */
558*f6dc9357SAndroid Build Coastguard Worker {
559*f6dc9357SAndroid Build Coastguard Worker DWORD attrib = NFind::GetFileAttrib(path);
560*f6dc9357SAndroid Build Coastguard Worker if (attrib != INVALID_FILE_ATTRIBUTES
561*f6dc9357SAndroid Build Coastguard Worker && (attrib & FILE_ATTRIBUTE_DIRECTORY) == 0
562*f6dc9357SAndroid Build Coastguard Worker && (attrib & FILE_ATTRIBUTE_READONLY) != 0)
563*f6dc9357SAndroid Build Coastguard Worker {
564*f6dc9357SAndroid Build Coastguard Worker if (!SetFileAttrib(path, attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY))
565*f6dc9357SAndroid Build Coastguard Worker return false;
566*f6dc9357SAndroid Build Coastguard Worker }
567*f6dc9357SAndroid Build Coastguard Worker }
568*f6dc9357SAndroid Build Coastguard Worker
569*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
570*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
571*f6dc9357SAndroid Build Coastguard Worker {
572*f6dc9357SAndroid Build Coastguard Worker if (::DeleteFile(fs2fas(path)))
573*f6dc9357SAndroid Build Coastguard Worker return true;
574*f6dc9357SAndroid Build Coastguard Worker }
575*f6dc9357SAndroid Build Coastguard Worker else
576*f6dc9357SAndroid Build Coastguard Worker #endif
577*f6dc9357SAndroid Build Coastguard Worker {
578*f6dc9357SAndroid Build Coastguard Worker /* DeleteFile("name::$DATA") deletes all alt streams (same as delete DeleteFile("name")).
579*f6dc9357SAndroid Build Coastguard Worker Maybe it's better to open "name::$DATA" and clear data for unnamed stream? */
580*f6dc9357SAndroid Build Coastguard Worker IF_USE_MAIN_PATH
581*f6dc9357SAndroid Build Coastguard Worker if (::DeleteFileW(fs2us(path)))
582*f6dc9357SAndroid Build Coastguard Worker return true;
583*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
584*f6dc9357SAndroid Build Coastguard Worker if (USE_SUPER_PATH)
585*f6dc9357SAndroid Build Coastguard Worker {
586*f6dc9357SAndroid Build Coastguard Worker UString superPath;
587*f6dc9357SAndroid Build Coastguard Worker if (GetSuperPath(path, superPath, USE_MAIN_PATH))
588*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::DeleteFileW(superPath));
589*f6dc9357SAndroid Build Coastguard Worker }
590*f6dc9357SAndroid Build Coastguard Worker #endif
591*f6dc9357SAndroid Build Coastguard Worker }
592*f6dc9357SAndroid Build Coastguard Worker return false;
593*f6dc9357SAndroid Build Coastguard Worker }
594*f6dc9357SAndroid Build Coastguard Worker
595*f6dc9357SAndroid Build Coastguard Worker
596*f6dc9357SAndroid Build Coastguard Worker
RemoveDirWithSubItems(const FString & path)597*f6dc9357SAndroid Build Coastguard Worker bool RemoveDirWithSubItems(const FString &path)
598*f6dc9357SAndroid Build Coastguard Worker {
599*f6dc9357SAndroid Build Coastguard Worker bool needRemoveSubItems = true;
600*f6dc9357SAndroid Build Coastguard Worker {
601*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fi;
602*f6dc9357SAndroid Build Coastguard Worker if (!fi.Find(path))
603*f6dc9357SAndroid Build Coastguard Worker return false;
604*f6dc9357SAndroid Build Coastguard Worker if (!fi.IsDir())
605*f6dc9357SAndroid Build Coastguard Worker {
606*f6dc9357SAndroid Build Coastguard Worker ::SetLastError(ERROR_DIRECTORY);
607*f6dc9357SAndroid Build Coastguard Worker return false;
608*f6dc9357SAndroid Build Coastguard Worker }
609*f6dc9357SAndroid Build Coastguard Worker if (fi.HasReparsePoint())
610*f6dc9357SAndroid Build Coastguard Worker needRemoveSubItems = false;
611*f6dc9357SAndroid Build Coastguard Worker }
612*f6dc9357SAndroid Build Coastguard Worker
613*f6dc9357SAndroid Build Coastguard Worker if (needRemoveSubItems)
614*f6dc9357SAndroid Build Coastguard Worker {
615*f6dc9357SAndroid Build Coastguard Worker FString s (path);
616*f6dc9357SAndroid Build Coastguard Worker s.Add_PathSepar();
617*f6dc9357SAndroid Build Coastguard Worker const unsigned prefixSize = s.Len();
618*f6dc9357SAndroid Build Coastguard Worker NFind::CEnumerator enumerator;
619*f6dc9357SAndroid Build Coastguard Worker enumerator.SetDirPrefix(s);
620*f6dc9357SAndroid Build Coastguard Worker NFind::CDirEntry fi;
621*f6dc9357SAndroid Build Coastguard Worker bool isError = false;
622*f6dc9357SAndroid Build Coastguard Worker DWORD lastError = 0;
623*f6dc9357SAndroid Build Coastguard Worker while (enumerator.Next(fi))
624*f6dc9357SAndroid Build Coastguard Worker {
625*f6dc9357SAndroid Build Coastguard Worker s.DeleteFrom(prefixSize);
626*f6dc9357SAndroid Build Coastguard Worker s += fi.Name;
627*f6dc9357SAndroid Build Coastguard Worker if (fi.IsDir())
628*f6dc9357SAndroid Build Coastguard Worker {
629*f6dc9357SAndroid Build Coastguard Worker if (!RemoveDirWithSubItems(s))
630*f6dc9357SAndroid Build Coastguard Worker {
631*f6dc9357SAndroid Build Coastguard Worker lastError = GetLastError();
632*f6dc9357SAndroid Build Coastguard Worker isError = true;
633*f6dc9357SAndroid Build Coastguard Worker }
634*f6dc9357SAndroid Build Coastguard Worker }
635*f6dc9357SAndroid Build Coastguard Worker else if (!DeleteFileAlways(s))
636*f6dc9357SAndroid Build Coastguard Worker {
637*f6dc9357SAndroid Build Coastguard Worker lastError = GetLastError();
638*f6dc9357SAndroid Build Coastguard Worker isError = false;
639*f6dc9357SAndroid Build Coastguard Worker }
640*f6dc9357SAndroid Build Coastguard Worker }
641*f6dc9357SAndroid Build Coastguard Worker if (isError)
642*f6dc9357SAndroid Build Coastguard Worker {
643*f6dc9357SAndroid Build Coastguard Worker SetLastError(lastError);
644*f6dc9357SAndroid Build Coastguard Worker return false;
645*f6dc9357SAndroid Build Coastguard Worker }
646*f6dc9357SAndroid Build Coastguard Worker }
647*f6dc9357SAndroid Build Coastguard Worker
648*f6dc9357SAndroid Build Coastguard Worker // we clear read-only attrib to remove read-only dir
649*f6dc9357SAndroid Build Coastguard Worker if (!SetFileAttrib(path, 0))
650*f6dc9357SAndroid Build Coastguard Worker return false;
651*f6dc9357SAndroid Build Coastguard Worker return RemoveDir(path);
652*f6dc9357SAndroid Build Coastguard Worker }
653*f6dc9357SAndroid Build Coastguard Worker
654*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
655*f6dc9357SAndroid Build Coastguard Worker
656*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
657*f6dc9357SAndroid Build Coastguard Worker
MyGetFullPathName(CFSTR path,FString & resFullPath)658*f6dc9357SAndroid Build Coastguard Worker bool MyGetFullPathName(CFSTR path, FString &resFullPath)
659*f6dc9357SAndroid Build Coastguard Worker {
660*f6dc9357SAndroid Build Coastguard Worker resFullPath = path;
661*f6dc9357SAndroid Build Coastguard Worker return true;
662*f6dc9357SAndroid Build Coastguard Worker }
663*f6dc9357SAndroid Build Coastguard Worker
664*f6dc9357SAndroid Build Coastguard Worker #else
665*f6dc9357SAndroid Build Coastguard Worker
MyGetFullPathName(CFSTR path,FString & resFullPath)666*f6dc9357SAndroid Build Coastguard Worker bool MyGetFullPathName(CFSTR path, FString &resFullPath)
667*f6dc9357SAndroid Build Coastguard Worker {
668*f6dc9357SAndroid Build Coastguard Worker return GetFullPath(path, resFullPath);
669*f6dc9357SAndroid Build Coastguard Worker }
670*f6dc9357SAndroid Build Coastguard Worker
671*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
672*f6dc9357SAndroid Build Coastguard Worker
673*f6dc9357SAndroid Build Coastguard Worker /* Win10: SetCurrentDirectory() doesn't support long paths and
674*f6dc9357SAndroid Build Coastguard Worker doesn't support super prefix "\\?\", if long path behavior is not
675*f6dc9357SAndroid Build Coastguard Worker enabled in registry (LongPathsEnabled) and in manifest (longPathAware). */
676*f6dc9357SAndroid Build Coastguard Worker
SetCurrentDir(CFSTR path)677*f6dc9357SAndroid Build Coastguard Worker bool SetCurrentDir(CFSTR path)
678*f6dc9357SAndroid Build Coastguard Worker {
679*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
680*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
681*f6dc9357SAndroid Build Coastguard Worker {
682*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::SetCurrentDirectory(fs2fas(path)));
683*f6dc9357SAndroid Build Coastguard Worker }
684*f6dc9357SAndroid Build Coastguard Worker else
685*f6dc9357SAndroid Build Coastguard Worker #endif
686*f6dc9357SAndroid Build Coastguard Worker {
687*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(::SetCurrentDirectoryW(fs2us(path)));
688*f6dc9357SAndroid Build Coastguard Worker }
689*f6dc9357SAndroid Build Coastguard Worker }
690*f6dc9357SAndroid Build Coastguard Worker
691*f6dc9357SAndroid Build Coastguard Worker
692*f6dc9357SAndroid Build Coastguard Worker /*
693*f6dc9357SAndroid Build Coastguard Worker we use system function GetCurrentDirectory()
694*f6dc9357SAndroid Build Coastguard Worker new GetCurrentDirectory() DOCs:
695*f6dc9357SAndroid Build Coastguard Worker - If the function fails, the return value is zero.
696*f6dc9357SAndroid Build Coastguard Worker - If the function succeeds, the return value specifies
697*f6dc9357SAndroid Build Coastguard Worker the number of characters that are written to the buffer,
698*f6dc9357SAndroid Build Coastguard Worker not including the terminating null character.
699*f6dc9357SAndroid Build Coastguard Worker - If the buffer is not large enough, the return value specifies
700*f6dc9357SAndroid Build Coastguard Worker the required size of the buffer, in characters,
701*f6dc9357SAndroid Build Coastguard Worker including the null-terminating character.
702*f6dc9357SAndroid Build Coastguard Worker
703*f6dc9357SAndroid Build Coastguard Worker GetCurrentDir() calls GetCurrentDirectory().
704*f6dc9357SAndroid Build Coastguard Worker GetCurrentDirectory() in win10 in tests:
705*f6dc9357SAndroid Build Coastguard Worker the returned (path) does not end with a backslash, if
706*f6dc9357SAndroid Build Coastguard Worker current directory is not root directory of drive.
707*f6dc9357SAndroid Build Coastguard Worker But that behavior is not guarantied in specification docs.
708*f6dc9357SAndroid Build Coastguard Worker */
709*f6dc9357SAndroid Build Coastguard Worker
GetCurrentDir(FString & path)710*f6dc9357SAndroid Build Coastguard Worker bool GetCurrentDir(FString &path)
711*f6dc9357SAndroid Build Coastguard Worker {
712*f6dc9357SAndroid Build Coastguard Worker const unsigned kBufSize = MAX_PATH + 16;
713*f6dc9357SAndroid Build Coastguard Worker path.Empty();
714*f6dc9357SAndroid Build Coastguard Worker
715*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
716*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
717*f6dc9357SAndroid Build Coastguard Worker {
718*f6dc9357SAndroid Build Coastguard Worker TCHAR s[kBufSize + 1];
719*f6dc9357SAndroid Build Coastguard Worker s[0] = 0;
720*f6dc9357SAndroid Build Coastguard Worker const DWORD len = ::GetCurrentDirectory(kBufSize, s);
721*f6dc9357SAndroid Build Coastguard Worker if (len == 0 || len >= kBufSize)
722*f6dc9357SAndroid Build Coastguard Worker return false;
723*f6dc9357SAndroid Build Coastguard Worker s[kBufSize] = 0; // optional guard
724*f6dc9357SAndroid Build Coastguard Worker path = fas2fs(s);
725*f6dc9357SAndroid Build Coastguard Worker return true;
726*f6dc9357SAndroid Build Coastguard Worker }
727*f6dc9357SAndroid Build Coastguard Worker else
728*f6dc9357SAndroid Build Coastguard Worker #endif
729*f6dc9357SAndroid Build Coastguard Worker {
730*f6dc9357SAndroid Build Coastguard Worker DWORD len;
731*f6dc9357SAndroid Build Coastguard Worker {
732*f6dc9357SAndroid Build Coastguard Worker WCHAR s[kBufSize + 1];
733*f6dc9357SAndroid Build Coastguard Worker s[0] = 0;
734*f6dc9357SAndroid Build Coastguard Worker len = ::GetCurrentDirectoryW(kBufSize, s);
735*f6dc9357SAndroid Build Coastguard Worker if (len == 0)
736*f6dc9357SAndroid Build Coastguard Worker return false;
737*f6dc9357SAndroid Build Coastguard Worker if (len < kBufSize)
738*f6dc9357SAndroid Build Coastguard Worker {
739*f6dc9357SAndroid Build Coastguard Worker s[kBufSize] = 0; // optional guard
740*f6dc9357SAndroid Build Coastguard Worker path = us2fs(s);
741*f6dc9357SAndroid Build Coastguard Worker return true;
742*f6dc9357SAndroid Build Coastguard Worker }
743*f6dc9357SAndroid Build Coastguard Worker }
744*f6dc9357SAndroid Build Coastguard Worker UString temp;
745*f6dc9357SAndroid Build Coastguard Worker const DWORD len2 = ::GetCurrentDirectoryW(len, temp.GetBuf(len));
746*f6dc9357SAndroid Build Coastguard Worker if (len2 == 0)
747*f6dc9357SAndroid Build Coastguard Worker return false;
748*f6dc9357SAndroid Build Coastguard Worker temp.ReleaseBuf_CalcLen(len);
749*f6dc9357SAndroid Build Coastguard Worker if (temp.Len() != len2 || len - 1 != len2)
750*f6dc9357SAndroid Build Coastguard Worker {
751*f6dc9357SAndroid Build Coastguard Worker /* it's unexpected case, if current dir of process
752*f6dc9357SAndroid Build Coastguard Worker was changed between two function calls,
753*f6dc9357SAndroid Build Coastguard Worker or some unexpected function implementation */
754*f6dc9357SAndroid Build Coastguard Worker // SetLastError((DWORD)E_FAIL); // we can set some error code
755*f6dc9357SAndroid Build Coastguard Worker return false;
756*f6dc9357SAndroid Build Coastguard Worker }
757*f6dc9357SAndroid Build Coastguard Worker path = us2fs(temp);
758*f6dc9357SAndroid Build Coastguard Worker return true;
759*f6dc9357SAndroid Build Coastguard Worker }
760*f6dc9357SAndroid Build Coastguard Worker }
761*f6dc9357SAndroid Build Coastguard Worker
762*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
763*f6dc9357SAndroid Build Coastguard Worker #endif // UNDER_CE
764*f6dc9357SAndroid Build Coastguard Worker
765*f6dc9357SAndroid Build Coastguard Worker
GetFullPathAndSplit(CFSTR path,FString & resDirPrefix,FString & resFileName)766*f6dc9357SAndroid Build Coastguard Worker bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName)
767*f6dc9357SAndroid Build Coastguard Worker {
768*f6dc9357SAndroid Build Coastguard Worker bool res = MyGetFullPathName(path, resDirPrefix);
769*f6dc9357SAndroid Build Coastguard Worker if (!res)
770*f6dc9357SAndroid Build Coastguard Worker resDirPrefix = path;
771*f6dc9357SAndroid Build Coastguard Worker int pos = resDirPrefix.ReverseFind_PathSepar();
772*f6dc9357SAndroid Build Coastguard Worker pos++;
773*f6dc9357SAndroid Build Coastguard Worker resFileName = resDirPrefix.Ptr((unsigned)pos);
774*f6dc9357SAndroid Build Coastguard Worker resDirPrefix.DeleteFrom((unsigned)pos);
775*f6dc9357SAndroid Build Coastguard Worker return res;
776*f6dc9357SAndroid Build Coastguard Worker }
777*f6dc9357SAndroid Build Coastguard Worker
GetOnlyDirPrefix(CFSTR path,FString & resDirPrefix)778*f6dc9357SAndroid Build Coastguard Worker bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix)
779*f6dc9357SAndroid Build Coastguard Worker {
780*f6dc9357SAndroid Build Coastguard Worker FString resFileName;
781*f6dc9357SAndroid Build Coastguard Worker return GetFullPathAndSplit(path, resDirPrefix, resFileName);
782*f6dc9357SAndroid Build Coastguard Worker }
783*f6dc9357SAndroid Build Coastguard Worker
784*f6dc9357SAndroid Build Coastguard Worker
785*f6dc9357SAndroid Build Coastguard Worker
MyGetTempPath(FString & path)786*f6dc9357SAndroid Build Coastguard Worker bool MyGetTempPath(FString &path)
787*f6dc9357SAndroid Build Coastguard Worker {
788*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
789*f6dc9357SAndroid Build Coastguard Worker
790*f6dc9357SAndroid Build Coastguard Worker /*
791*f6dc9357SAndroid Build Coastguard Worker new DOCs for GetTempPathW():
792*f6dc9357SAndroid Build Coastguard Worker - The returned string ends with a backslash.
793*f6dc9357SAndroid Build Coastguard Worker - The maximum possible return value is MAX_PATH+1 (261).
794*f6dc9357SAndroid Build Coastguard Worker */
795*f6dc9357SAndroid Build Coastguard Worker
796*f6dc9357SAndroid Build Coastguard Worker const unsigned kBufSize = MAX_PATH + 16;
797*f6dc9357SAndroid Build Coastguard Worker DWORD len;
798*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
799*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
800*f6dc9357SAndroid Build Coastguard Worker {
801*f6dc9357SAndroid Build Coastguard Worker TCHAR s[kBufSize + 1];
802*f6dc9357SAndroid Build Coastguard Worker s[0] = 0;
803*f6dc9357SAndroid Build Coastguard Worker len = ::GetTempPath(kBufSize, s);
804*f6dc9357SAndroid Build Coastguard Worker path = fas2fs(s);
805*f6dc9357SAndroid Build Coastguard Worker }
806*f6dc9357SAndroid Build Coastguard Worker else
807*f6dc9357SAndroid Build Coastguard Worker #endif
808*f6dc9357SAndroid Build Coastguard Worker {
809*f6dc9357SAndroid Build Coastguard Worker WCHAR s[kBufSize + 1];
810*f6dc9357SAndroid Build Coastguard Worker s[0] = 0;
811*f6dc9357SAndroid Build Coastguard Worker len = ::GetTempPathW(kBufSize, s);
812*f6dc9357SAndroid Build Coastguard Worker path = us2fs(s);
813*f6dc9357SAndroid Build Coastguard Worker }
814*f6dc9357SAndroid Build Coastguard Worker /* win10: GetTempPathW() doesn't set backslash at the end of path,
815*f6dc9357SAndroid Build Coastguard Worker if (buffer_size == len_of(path_with_backslash)).
816*f6dc9357SAndroid Build Coastguard Worker So we normalize path here: */
817*f6dc9357SAndroid Build Coastguard Worker NormalizeDirPathPrefix(path);
818*f6dc9357SAndroid Build Coastguard Worker return (len != 0 && len < kBufSize);
819*f6dc9357SAndroid Build Coastguard Worker
820*f6dc9357SAndroid Build Coastguard Worker #else // !_WIN32
821*f6dc9357SAndroid Build Coastguard Worker
822*f6dc9357SAndroid Build Coastguard Worker // FIXME: improve that code
823*f6dc9357SAndroid Build Coastguard Worker path = STRING_PATH_SEPARATOR "tmp";
824*f6dc9357SAndroid Build Coastguard Worker const char *s;
825*f6dc9357SAndroid Build Coastguard Worker if (NFind::DoesDirExist_FollowLink(path))
826*f6dc9357SAndroid Build Coastguard Worker s = STRING_PATH_SEPARATOR "tmp" STRING_PATH_SEPARATOR;
827*f6dc9357SAndroid Build Coastguard Worker else
828*f6dc9357SAndroid Build Coastguard Worker s = "." STRING_PATH_SEPARATOR;
829*f6dc9357SAndroid Build Coastguard Worker path = s;
830*f6dc9357SAndroid Build Coastguard Worker return true;
831*f6dc9357SAndroid Build Coastguard Worker
832*f6dc9357SAndroid Build Coastguard Worker #endif
833*f6dc9357SAndroid Build Coastguard Worker }
834*f6dc9357SAndroid Build Coastguard Worker
835*f6dc9357SAndroid Build Coastguard Worker
CreateTempFile2(CFSTR prefix,bool addRandom,AString & postfix,NIO::COutFile * outFile)836*f6dc9357SAndroid Build Coastguard Worker bool CreateTempFile2(CFSTR prefix, bool addRandom, AString &postfix, NIO::COutFile *outFile)
837*f6dc9357SAndroid Build Coastguard Worker {
838*f6dc9357SAndroid Build Coastguard Worker UInt32 d =
839*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
840*f6dc9357SAndroid Build Coastguard Worker (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
841*f6dc9357SAndroid Build Coastguard Worker #else
842*f6dc9357SAndroid Build Coastguard Worker (UInt32)(time(NULL) << 12) ^ ((UInt32)getppid() << 14) ^ (UInt32)(getpid());
843*f6dc9357SAndroid Build Coastguard Worker #endif
844*f6dc9357SAndroid Build Coastguard Worker
845*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < 100; i++)
846*f6dc9357SAndroid Build Coastguard Worker {
847*f6dc9357SAndroid Build Coastguard Worker postfix.Empty();
848*f6dc9357SAndroid Build Coastguard Worker if (addRandom)
849*f6dc9357SAndroid Build Coastguard Worker {
850*f6dc9357SAndroid Build Coastguard Worker char s[16];
851*f6dc9357SAndroid Build Coastguard Worker UInt32 val = d;
852*f6dc9357SAndroid Build Coastguard Worker unsigned k;
853*f6dc9357SAndroid Build Coastguard Worker for (k = 0; k < 8; k++)
854*f6dc9357SAndroid Build Coastguard Worker {
855*f6dc9357SAndroid Build Coastguard Worker const unsigned t = (unsigned)val & 0xF;
856*f6dc9357SAndroid Build Coastguard Worker val >>= 4;
857*f6dc9357SAndroid Build Coastguard Worker s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
858*f6dc9357SAndroid Build Coastguard Worker }
859*f6dc9357SAndroid Build Coastguard Worker s[k] = '\0';
860*f6dc9357SAndroid Build Coastguard Worker if (outFile)
861*f6dc9357SAndroid Build Coastguard Worker postfix.Add_Dot();
862*f6dc9357SAndroid Build Coastguard Worker postfix += s;
863*f6dc9357SAndroid Build Coastguard Worker UInt32 step = GetTickCount() + 2;
864*f6dc9357SAndroid Build Coastguard Worker if (step == 0)
865*f6dc9357SAndroid Build Coastguard Worker step = 1;
866*f6dc9357SAndroid Build Coastguard Worker d += step;
867*f6dc9357SAndroid Build Coastguard Worker }
868*f6dc9357SAndroid Build Coastguard Worker addRandom = true;
869*f6dc9357SAndroid Build Coastguard Worker if (outFile)
870*f6dc9357SAndroid Build Coastguard Worker postfix += ".tmp";
871*f6dc9357SAndroid Build Coastguard Worker FString path (prefix);
872*f6dc9357SAndroid Build Coastguard Worker path += postfix;
873*f6dc9357SAndroid Build Coastguard Worker if (NFind::DoesFileOrDirExist(path))
874*f6dc9357SAndroid Build Coastguard Worker {
875*f6dc9357SAndroid Build Coastguard Worker SetLastError(ERROR_ALREADY_EXISTS);
876*f6dc9357SAndroid Build Coastguard Worker continue;
877*f6dc9357SAndroid Build Coastguard Worker }
878*f6dc9357SAndroid Build Coastguard Worker if (outFile)
879*f6dc9357SAndroid Build Coastguard Worker {
880*f6dc9357SAndroid Build Coastguard Worker if (outFile->Create_NEW(path))
881*f6dc9357SAndroid Build Coastguard Worker return true;
882*f6dc9357SAndroid Build Coastguard Worker }
883*f6dc9357SAndroid Build Coastguard Worker else
884*f6dc9357SAndroid Build Coastguard Worker {
885*f6dc9357SAndroid Build Coastguard Worker if (CreateDir(path))
886*f6dc9357SAndroid Build Coastguard Worker return true;
887*f6dc9357SAndroid Build Coastguard Worker }
888*f6dc9357SAndroid Build Coastguard Worker const DWORD error = GetLastError();
889*f6dc9357SAndroid Build Coastguard Worker if (error != ERROR_FILE_EXISTS &&
890*f6dc9357SAndroid Build Coastguard Worker error != ERROR_ALREADY_EXISTS)
891*f6dc9357SAndroid Build Coastguard Worker break;
892*f6dc9357SAndroid Build Coastguard Worker }
893*f6dc9357SAndroid Build Coastguard Worker postfix.Empty();
894*f6dc9357SAndroid Build Coastguard Worker return false;
895*f6dc9357SAndroid Build Coastguard Worker }
896*f6dc9357SAndroid Build Coastguard Worker
Create(CFSTR prefix,NIO::COutFile * outFile)897*f6dc9357SAndroid Build Coastguard Worker bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile)
898*f6dc9357SAndroid Build Coastguard Worker {
899*f6dc9357SAndroid Build Coastguard Worker if (!Remove())
900*f6dc9357SAndroid Build Coastguard Worker return false;
901*f6dc9357SAndroid Build Coastguard Worker _path.Empty();
902*f6dc9357SAndroid Build Coastguard Worker AString postfix;
903*f6dc9357SAndroid Build Coastguard Worker if (!CreateTempFile2(prefix, false, postfix, outFile))
904*f6dc9357SAndroid Build Coastguard Worker return false;
905*f6dc9357SAndroid Build Coastguard Worker _path = prefix;
906*f6dc9357SAndroid Build Coastguard Worker _path += postfix;
907*f6dc9357SAndroid Build Coastguard Worker _mustBeDeleted = true;
908*f6dc9357SAndroid Build Coastguard Worker return true;
909*f6dc9357SAndroid Build Coastguard Worker }
910*f6dc9357SAndroid Build Coastguard Worker
CreateRandomInTempFolder(CFSTR namePrefix,NIO::COutFile * outFile)911*f6dc9357SAndroid Build Coastguard Worker bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile)
912*f6dc9357SAndroid Build Coastguard Worker {
913*f6dc9357SAndroid Build Coastguard Worker if (!Remove())
914*f6dc9357SAndroid Build Coastguard Worker return false;
915*f6dc9357SAndroid Build Coastguard Worker _path.Empty();
916*f6dc9357SAndroid Build Coastguard Worker FString tempPath;
917*f6dc9357SAndroid Build Coastguard Worker if (!MyGetTempPath(tempPath))
918*f6dc9357SAndroid Build Coastguard Worker return false;
919*f6dc9357SAndroid Build Coastguard Worker AString postfix;
920*f6dc9357SAndroid Build Coastguard Worker tempPath += namePrefix;
921*f6dc9357SAndroid Build Coastguard Worker if (!CreateTempFile2(tempPath, true, postfix, outFile))
922*f6dc9357SAndroid Build Coastguard Worker return false;
923*f6dc9357SAndroid Build Coastguard Worker _path = tempPath;
924*f6dc9357SAndroid Build Coastguard Worker _path += postfix;
925*f6dc9357SAndroid Build Coastguard Worker _mustBeDeleted = true;
926*f6dc9357SAndroid Build Coastguard Worker return true;
927*f6dc9357SAndroid Build Coastguard Worker }
928*f6dc9357SAndroid Build Coastguard Worker
Remove()929*f6dc9357SAndroid Build Coastguard Worker bool CTempFile::Remove()
930*f6dc9357SAndroid Build Coastguard Worker {
931*f6dc9357SAndroid Build Coastguard Worker if (!_mustBeDeleted)
932*f6dc9357SAndroid Build Coastguard Worker return true;
933*f6dc9357SAndroid Build Coastguard Worker _mustBeDeleted = !DeleteFileAlways(_path);
934*f6dc9357SAndroid Build Coastguard Worker return !_mustBeDeleted;
935*f6dc9357SAndroid Build Coastguard Worker }
936*f6dc9357SAndroid Build Coastguard Worker
MoveTo(CFSTR name,bool deleteDestBefore,ICopyFileProgress * progress)937*f6dc9357SAndroid Build Coastguard Worker bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore,
938*f6dc9357SAndroid Build Coastguard Worker ICopyFileProgress *progress)
939*f6dc9357SAndroid Build Coastguard Worker {
940*f6dc9357SAndroid Build Coastguard Worker if (deleteDestBefore)
941*f6dc9357SAndroid Build Coastguard Worker {
942*f6dc9357SAndroid Build Coastguard Worker if (NFind::DoesFileExist_Raw(name))
943*f6dc9357SAndroid Build Coastguard Worker {
944*f6dc9357SAndroid Build Coastguard Worker // attrib = NFind::GetFileAttrib(name);
945*f6dc9357SAndroid Build Coastguard Worker if (!DeleteFileAlways(name))
946*f6dc9357SAndroid Build Coastguard Worker return false;
947*f6dc9357SAndroid Build Coastguard Worker }
948*f6dc9357SAndroid Build Coastguard Worker }
949*f6dc9357SAndroid Build Coastguard Worker DisableDeleting();
950*f6dc9357SAndroid Build Coastguard Worker // if (!progress) return MyMoveFile(_path, name);
951*f6dc9357SAndroid Build Coastguard Worker return MyMoveFile_with_Progress(_path, name, progress);
952*f6dc9357SAndroid Build Coastguard Worker /*
953*f6dc9357SAndroid Build Coastguard Worker if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY))
954*f6dc9357SAndroid Build Coastguard Worker {
955*f6dc9357SAndroid Build Coastguard Worker DWORD attrib2 = NFind::GetFileAttrib(name);
956*f6dc9357SAndroid Build Coastguard Worker if (attrib2 != INVALID_FILE_ATTRIBUTES)
957*f6dc9357SAndroid Build Coastguard Worker SetFileAttrib(name, attrib2 | FILE_ATTRIBUTE_READONLY);
958*f6dc9357SAndroid Build Coastguard Worker }
959*f6dc9357SAndroid Build Coastguard Worker */
960*f6dc9357SAndroid Build Coastguard Worker }
961*f6dc9357SAndroid Build Coastguard Worker
962*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
Create(CFSTR prefix)963*f6dc9357SAndroid Build Coastguard Worker bool CTempDir::Create(CFSTR prefix)
964*f6dc9357SAndroid Build Coastguard Worker {
965*f6dc9357SAndroid Build Coastguard Worker if (!Remove())
966*f6dc9357SAndroid Build Coastguard Worker return false;
967*f6dc9357SAndroid Build Coastguard Worker _path.Empty();
968*f6dc9357SAndroid Build Coastguard Worker FString tempPath;
969*f6dc9357SAndroid Build Coastguard Worker if (!MyGetTempPath(tempPath))
970*f6dc9357SAndroid Build Coastguard Worker return false;
971*f6dc9357SAndroid Build Coastguard Worker tempPath += prefix;
972*f6dc9357SAndroid Build Coastguard Worker AString postfix;
973*f6dc9357SAndroid Build Coastguard Worker if (!CreateTempFile2(tempPath, true, postfix, NULL))
974*f6dc9357SAndroid Build Coastguard Worker return false;
975*f6dc9357SAndroid Build Coastguard Worker _path = tempPath;
976*f6dc9357SAndroid Build Coastguard Worker _path += postfix;
977*f6dc9357SAndroid Build Coastguard Worker _mustBeDeleted = true;
978*f6dc9357SAndroid Build Coastguard Worker return true;
979*f6dc9357SAndroid Build Coastguard Worker }
980*f6dc9357SAndroid Build Coastguard Worker
Remove()981*f6dc9357SAndroid Build Coastguard Worker bool CTempDir::Remove()
982*f6dc9357SAndroid Build Coastguard Worker {
983*f6dc9357SAndroid Build Coastguard Worker if (!_mustBeDeleted)
984*f6dc9357SAndroid Build Coastguard Worker return true;
985*f6dc9357SAndroid Build Coastguard Worker _mustBeDeleted = !RemoveDirWithSubItems(_path);
986*f6dc9357SAndroid Build Coastguard Worker return !_mustBeDeleted;
987*f6dc9357SAndroid Build Coastguard Worker }
988*f6dc9357SAndroid Build Coastguard Worker #endif
989*f6dc9357SAndroid Build Coastguard Worker
990*f6dc9357SAndroid Build Coastguard Worker
991*f6dc9357SAndroid Build Coastguard Worker
992*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
993*f6dc9357SAndroid Build Coastguard Worker
RemoveDir(CFSTR path)994*f6dc9357SAndroid Build Coastguard Worker bool RemoveDir(CFSTR path)
995*f6dc9357SAndroid Build Coastguard Worker {
996*f6dc9357SAndroid Build Coastguard Worker return (rmdir(path) == 0);
997*f6dc9357SAndroid Build Coastguard Worker }
998*f6dc9357SAndroid Build Coastguard Worker
999*f6dc9357SAndroid Build Coastguard Worker
My_CopyFile(CFSTR oldFile,CFSTR newFile,ICopyFileProgress * progress)1000*f6dc9357SAndroid Build Coastguard Worker static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile, ICopyFileProgress *progress)
1001*f6dc9357SAndroid Build Coastguard Worker {
1002*f6dc9357SAndroid Build Coastguard Worker {
1003*f6dc9357SAndroid Build Coastguard Worker NIO::COutFile outFile;
1004*f6dc9357SAndroid Build Coastguard Worker if (!outFile.Create_NEW(newFile))
1005*f6dc9357SAndroid Build Coastguard Worker return FALSE;
1006*f6dc9357SAndroid Build Coastguard Worker NIO::CInFile inFile;
1007*f6dc9357SAndroid Build Coastguard Worker if (!inFile.Open(oldFile))
1008*f6dc9357SAndroid Build Coastguard Worker return FALSE;
1009*f6dc9357SAndroid Build Coastguard Worker
1010*f6dc9357SAndroid Build Coastguard Worker const size_t k_BufSize = 1 << 16;
1011*f6dc9357SAndroid Build Coastguard Worker CAlignedBuffer1 buf(k_BufSize);
1012*f6dc9357SAndroid Build Coastguard Worker
1013*f6dc9357SAndroid Build Coastguard Worker UInt64 length = 0;
1014*f6dc9357SAndroid Build Coastguard Worker if (progress && !inFile.GetLength(length))
1015*f6dc9357SAndroid Build Coastguard Worker length = 0;
1016*f6dc9357SAndroid Build Coastguard Worker UInt64 prev = 0;
1017*f6dc9357SAndroid Build Coastguard Worker UInt64 cur = 0;
1018*f6dc9357SAndroid Build Coastguard Worker for (;;)
1019*f6dc9357SAndroid Build Coastguard Worker {
1020*f6dc9357SAndroid Build Coastguard Worker const ssize_t num = inFile.read_part(buf, k_BufSize);
1021*f6dc9357SAndroid Build Coastguard Worker if (num == 0)
1022*f6dc9357SAndroid Build Coastguard Worker return TRUE;
1023*f6dc9357SAndroid Build Coastguard Worker if (num < 0)
1024*f6dc9357SAndroid Build Coastguard Worker break;
1025*f6dc9357SAndroid Build Coastguard Worker size_t processed;
1026*f6dc9357SAndroid Build Coastguard Worker const ssize_t num2 = outFile.write_full(buf, (size_t)num, processed);
1027*f6dc9357SAndroid Build Coastguard Worker if (num2 != num || processed != (size_t)num)
1028*f6dc9357SAndroid Build Coastguard Worker break;
1029*f6dc9357SAndroid Build Coastguard Worker cur += (size_t)num2;
1030*f6dc9357SAndroid Build Coastguard Worker if (progress && cur - prev >= (1u << 20))
1031*f6dc9357SAndroid Build Coastguard Worker {
1032*f6dc9357SAndroid Build Coastguard Worker prev = cur;
1033*f6dc9357SAndroid Build Coastguard Worker if (progress->CopyFileProgress(length, cur) != PROGRESS_CONTINUE)
1034*f6dc9357SAndroid Build Coastguard Worker {
1035*f6dc9357SAndroid Build Coastguard Worker errno = EINTR; // instead of WIN32::ERROR_REQUEST_ABORTED
1036*f6dc9357SAndroid Build Coastguard Worker break;
1037*f6dc9357SAndroid Build Coastguard Worker }
1038*f6dc9357SAndroid Build Coastguard Worker }
1039*f6dc9357SAndroid Build Coastguard Worker }
1040*f6dc9357SAndroid Build Coastguard Worker }
1041*f6dc9357SAndroid Build Coastguard Worker // There is file IO error or process was interrupted by user.
1042*f6dc9357SAndroid Build Coastguard Worker // We close output file and delete it.
1043*f6dc9357SAndroid Build Coastguard Worker // DeleteFileAlways doesn't change errno (if successed), but we restore errno.
1044*f6dc9357SAndroid Build Coastguard Worker const int errno_save = errno;
1045*f6dc9357SAndroid Build Coastguard Worker DeleteFileAlways(newFile);
1046*f6dc9357SAndroid Build Coastguard Worker errno = errno_save;
1047*f6dc9357SAndroid Build Coastguard Worker return FALSE;
1048*f6dc9357SAndroid Build Coastguard Worker }
1049*f6dc9357SAndroid Build Coastguard Worker
1050*f6dc9357SAndroid Build Coastguard Worker
MyMoveFile_with_Progress(CFSTR oldFile,CFSTR newFile,ICopyFileProgress * progress)1051*f6dc9357SAndroid Build Coastguard Worker bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile,
1052*f6dc9357SAndroid Build Coastguard Worker ICopyFileProgress *progress)
1053*f6dc9357SAndroid Build Coastguard Worker {
1054*f6dc9357SAndroid Build Coastguard Worker int res = rename(oldFile, newFile);
1055*f6dc9357SAndroid Build Coastguard Worker if (res == 0)
1056*f6dc9357SAndroid Build Coastguard Worker return true;
1057*f6dc9357SAndroid Build Coastguard Worker if (errno != EXDEV) // (oldFile and newFile are not on the same mounted filesystem)
1058*f6dc9357SAndroid Build Coastguard Worker return false;
1059*f6dc9357SAndroid Build Coastguard Worker
1060*f6dc9357SAndroid Build Coastguard Worker if (My_CopyFile(oldFile, newFile, progress) == FALSE)
1061*f6dc9357SAndroid Build Coastguard Worker return false;
1062*f6dc9357SAndroid Build Coastguard Worker
1063*f6dc9357SAndroid Build Coastguard Worker struct stat info_file;
1064*f6dc9357SAndroid Build Coastguard Worker res = stat(oldFile, &info_file);
1065*f6dc9357SAndroid Build Coastguard Worker if (res != 0)
1066*f6dc9357SAndroid Build Coastguard Worker return false;
1067*f6dc9357SAndroid Build Coastguard Worker
1068*f6dc9357SAndroid Build Coastguard Worker /*
1069*f6dc9357SAndroid Build Coastguard Worker ret = chmod(dst,info_file.st_mode & g_umask.mask);
1070*f6dc9357SAndroid Build Coastguard Worker */
1071*f6dc9357SAndroid Build Coastguard Worker return (unlink(oldFile) == 0);
1072*f6dc9357SAndroid Build Coastguard Worker }
1073*f6dc9357SAndroid Build Coastguard Worker
MyMoveFile(CFSTR oldFile,CFSTR newFile)1074*f6dc9357SAndroid Build Coastguard Worker bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
1075*f6dc9357SAndroid Build Coastguard Worker {
1076*f6dc9357SAndroid Build Coastguard Worker return MyMoveFile_with_Progress(oldFile, newFile, NULL);
1077*f6dc9357SAndroid Build Coastguard Worker }
1078*f6dc9357SAndroid Build Coastguard Worker
1079*f6dc9357SAndroid Build Coastguard Worker
CreateDir(CFSTR path)1080*f6dc9357SAndroid Build Coastguard Worker bool CreateDir(CFSTR path)
1081*f6dc9357SAndroid Build Coastguard Worker {
1082*f6dc9357SAndroid Build Coastguard Worker return (mkdir(path, 0777) == 0); // change it
1083*f6dc9357SAndroid Build Coastguard Worker }
1084*f6dc9357SAndroid Build Coastguard Worker
CreateDir2(CFSTR path)1085*f6dc9357SAndroid Build Coastguard Worker static bool CreateDir2(CFSTR path)
1086*f6dc9357SAndroid Build Coastguard Worker {
1087*f6dc9357SAndroid Build Coastguard Worker return (mkdir(path, 0777) == 0); // change it
1088*f6dc9357SAndroid Build Coastguard Worker }
1089*f6dc9357SAndroid Build Coastguard Worker
1090*f6dc9357SAndroid Build Coastguard Worker
DeleteFileAlways(CFSTR path)1091*f6dc9357SAndroid Build Coastguard Worker bool DeleteFileAlways(CFSTR path)
1092*f6dc9357SAndroid Build Coastguard Worker {
1093*f6dc9357SAndroid Build Coastguard Worker return (remove(path) == 0);
1094*f6dc9357SAndroid Build Coastguard Worker }
1095*f6dc9357SAndroid Build Coastguard Worker
SetCurrentDir(CFSTR path)1096*f6dc9357SAndroid Build Coastguard Worker bool SetCurrentDir(CFSTR path)
1097*f6dc9357SAndroid Build Coastguard Worker {
1098*f6dc9357SAndroid Build Coastguard Worker return (chdir(path) == 0);
1099*f6dc9357SAndroid Build Coastguard Worker }
1100*f6dc9357SAndroid Build Coastguard Worker
1101*f6dc9357SAndroid Build Coastguard Worker
GetCurrentDir(FString & path)1102*f6dc9357SAndroid Build Coastguard Worker bool GetCurrentDir(FString &path)
1103*f6dc9357SAndroid Build Coastguard Worker {
1104*f6dc9357SAndroid Build Coastguard Worker path.Empty();
1105*f6dc9357SAndroid Build Coastguard Worker
1106*f6dc9357SAndroid Build Coastguard Worker #define MY_PATH_MAX PATH_MAX
1107*f6dc9357SAndroid Build Coastguard Worker // #define MY_PATH_MAX 1024
1108*f6dc9357SAndroid Build Coastguard Worker
1109*f6dc9357SAndroid Build Coastguard Worker char s[MY_PATH_MAX + 1];
1110*f6dc9357SAndroid Build Coastguard Worker char *res = getcwd(s, MY_PATH_MAX);
1111*f6dc9357SAndroid Build Coastguard Worker if (res)
1112*f6dc9357SAndroid Build Coastguard Worker {
1113*f6dc9357SAndroid Build Coastguard Worker path = fas2fs(s);
1114*f6dc9357SAndroid Build Coastguard Worker return true;
1115*f6dc9357SAndroid Build Coastguard Worker }
1116*f6dc9357SAndroid Build Coastguard Worker {
1117*f6dc9357SAndroid Build Coastguard Worker // if (errno != ERANGE) return false;
1118*f6dc9357SAndroid Build Coastguard Worker #if defined(__GLIBC__) || defined(__APPLE__)
1119*f6dc9357SAndroid Build Coastguard Worker /* As an extension to the POSIX.1-2001 standard, glibc's getcwd()
1120*f6dc9357SAndroid Build Coastguard Worker allocates the buffer dynamically using malloc(3) if buf is NULL. */
1121*f6dc9357SAndroid Build Coastguard Worker res = getcwd(NULL, 0);
1122*f6dc9357SAndroid Build Coastguard Worker if (res)
1123*f6dc9357SAndroid Build Coastguard Worker {
1124*f6dc9357SAndroid Build Coastguard Worker path = fas2fs(res);
1125*f6dc9357SAndroid Build Coastguard Worker ::free(res);
1126*f6dc9357SAndroid Build Coastguard Worker return true;
1127*f6dc9357SAndroid Build Coastguard Worker }
1128*f6dc9357SAndroid Build Coastguard Worker #endif
1129*f6dc9357SAndroid Build Coastguard Worker return false;
1130*f6dc9357SAndroid Build Coastguard Worker }
1131*f6dc9357SAndroid Build Coastguard Worker }
1132*f6dc9357SAndroid Build Coastguard Worker
1133*f6dc9357SAndroid Build Coastguard Worker
1134*f6dc9357SAndroid Build Coastguard Worker
1135*f6dc9357SAndroid Build Coastguard Worker // #undef UTIME_OMIT // to debug
1136*f6dc9357SAndroid Build Coastguard Worker
1137*f6dc9357SAndroid Build Coastguard Worker #ifndef UTIME_OMIT
1138*f6dc9357SAndroid Build Coastguard Worker /* we can define UTIME_OMIT for debian and another systems.
1139*f6dc9357SAndroid Build Coastguard Worker Is it OK to define UTIME_OMIT to -2 here, if UTIME_OMIT is not defined? */
1140*f6dc9357SAndroid Build Coastguard Worker // #define UTIME_OMIT -2
1141*f6dc9357SAndroid Build Coastguard Worker #endif
1142*f6dc9357SAndroid Build Coastguard Worker
1143*f6dc9357SAndroid Build Coastguard Worker
1144*f6dc9357SAndroid Build Coastguard Worker
1145*f6dc9357SAndroid Build Coastguard Worker
1146*f6dc9357SAndroid Build Coastguard Worker
SetDirTime(CFSTR path,const CFiTime * cTime,const CFiTime * aTime,const CFiTime * mTime)1147*f6dc9357SAndroid Build Coastguard Worker bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
1148*f6dc9357SAndroid Build Coastguard Worker {
1149*f6dc9357SAndroid Build Coastguard Worker // need testing
1150*f6dc9357SAndroid Build Coastguard Worker /*
1151*f6dc9357SAndroid Build Coastguard Worker struct utimbuf buf;
1152*f6dc9357SAndroid Build Coastguard Worker struct stat st;
1153*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(cTime)
1154*f6dc9357SAndroid Build Coastguard Worker
1155*f6dc9357SAndroid Build Coastguard Worker printf("\nstat = %s\n", path);
1156*f6dc9357SAndroid Build Coastguard Worker int ret = stat(path, &st);
1157*f6dc9357SAndroid Build Coastguard Worker
1158*f6dc9357SAndroid Build Coastguard Worker if (ret == 0)
1159*f6dc9357SAndroid Build Coastguard Worker {
1160*f6dc9357SAndroid Build Coastguard Worker buf.actime = st.st_atime;
1161*f6dc9357SAndroid Build Coastguard Worker buf.modtime = st.st_mtime;
1162*f6dc9357SAndroid Build Coastguard Worker }
1163*f6dc9357SAndroid Build Coastguard Worker else
1164*f6dc9357SAndroid Build Coastguard Worker {
1165*f6dc9357SAndroid Build Coastguard Worker time_t cur_time = time(0);
1166*f6dc9357SAndroid Build Coastguard Worker buf.actime = cur_time;
1167*f6dc9357SAndroid Build Coastguard Worker buf.modtime = cur_time;
1168*f6dc9357SAndroid Build Coastguard Worker }
1169*f6dc9357SAndroid Build Coastguard Worker
1170*f6dc9357SAndroid Build Coastguard Worker if (aTime)
1171*f6dc9357SAndroid Build Coastguard Worker {
1172*f6dc9357SAndroid Build Coastguard Worker UInt32 ut;
1173*f6dc9357SAndroid Build Coastguard Worker if (NTime::FileTimeToUnixTime(*aTime, ut))
1174*f6dc9357SAndroid Build Coastguard Worker buf.actime = ut;
1175*f6dc9357SAndroid Build Coastguard Worker }
1176*f6dc9357SAndroid Build Coastguard Worker
1177*f6dc9357SAndroid Build Coastguard Worker if (mTime)
1178*f6dc9357SAndroid Build Coastguard Worker {
1179*f6dc9357SAndroid Build Coastguard Worker UInt32 ut;
1180*f6dc9357SAndroid Build Coastguard Worker if (NTime::FileTimeToUnixTime(*mTime, ut))
1181*f6dc9357SAndroid Build Coastguard Worker buf.modtime = ut;
1182*f6dc9357SAndroid Build Coastguard Worker }
1183*f6dc9357SAndroid Build Coastguard Worker
1184*f6dc9357SAndroid Build Coastguard Worker return utime(path, &buf) == 0;
1185*f6dc9357SAndroid Build Coastguard Worker */
1186*f6dc9357SAndroid Build Coastguard Worker
1187*f6dc9357SAndroid Build Coastguard Worker // if (!aTime && !mTime) return true;
1188*f6dc9357SAndroid Build Coastguard Worker
1189*f6dc9357SAndroid Build Coastguard Worker struct timespec times[2];
1190*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(cTime)
1191*f6dc9357SAndroid Build Coastguard Worker
1192*f6dc9357SAndroid Build Coastguard Worker bool needChange;
1193*f6dc9357SAndroid Build Coastguard Worker needChange = FiTime_To_timespec(aTime, times[0]);
1194*f6dc9357SAndroid Build Coastguard Worker needChange |= FiTime_To_timespec(mTime, times[1]);
1195*f6dc9357SAndroid Build Coastguard Worker
1196*f6dc9357SAndroid Build Coastguard Worker /*
1197*f6dc9357SAndroid Build Coastguard Worker if (mTime)
1198*f6dc9357SAndroid Build Coastguard Worker {
1199*f6dc9357SAndroid Build Coastguard Worker printf("\n time = %ld.%9ld\n", mTime->tv_sec, mTime->tv_nsec);
1200*f6dc9357SAndroid Build Coastguard Worker }
1201*f6dc9357SAndroid Build Coastguard Worker */
1202*f6dc9357SAndroid Build Coastguard Worker
1203*f6dc9357SAndroid Build Coastguard Worker if (!needChange)
1204*f6dc9357SAndroid Build Coastguard Worker return true;
1205*f6dc9357SAndroid Build Coastguard Worker const int flags = 0; // follow link
1206*f6dc9357SAndroid Build Coastguard Worker // = AT_SYMLINK_NOFOLLOW; // don't follow link
1207*f6dc9357SAndroid Build Coastguard Worker return utimensat(AT_FDCWD, path, times, flags) == 0;
1208*f6dc9357SAndroid Build Coastguard Worker }
1209*f6dc9357SAndroid Build Coastguard Worker
1210*f6dc9357SAndroid Build Coastguard Worker
1211*f6dc9357SAndroid Build Coastguard Worker
1212*f6dc9357SAndroid Build Coastguard Worker struct C_umask
1213*f6dc9357SAndroid Build Coastguard Worker {
1214*f6dc9357SAndroid Build Coastguard Worker mode_t mask;
1215*f6dc9357SAndroid Build Coastguard Worker
C_umaskNWindows::NFile::NDir::C_umask1216*f6dc9357SAndroid Build Coastguard Worker C_umask()
1217*f6dc9357SAndroid Build Coastguard Worker {
1218*f6dc9357SAndroid Build Coastguard Worker /* by security reasons we restrict attributes according
1219*f6dc9357SAndroid Build Coastguard Worker with process's file mode creation mask (umask) */
1220*f6dc9357SAndroid Build Coastguard Worker const mode_t um = umask(0); // octal :0022 is expected
1221*f6dc9357SAndroid Build Coastguard Worker mask = 0777 & (~um); // octal: 0755 is expected
1222*f6dc9357SAndroid Build Coastguard Worker umask(um); // restore the umask
1223*f6dc9357SAndroid Build Coastguard Worker // printf("\n umask = 0%03o mask = 0%03o\n", um, mask);
1224*f6dc9357SAndroid Build Coastguard Worker
1225*f6dc9357SAndroid Build Coastguard Worker // mask = 0777; // debug we can disable the restriction:
1226*f6dc9357SAndroid Build Coastguard Worker }
1227*f6dc9357SAndroid Build Coastguard Worker };
1228*f6dc9357SAndroid Build Coastguard Worker
1229*f6dc9357SAndroid Build Coastguard Worker static C_umask g_umask;
1230*f6dc9357SAndroid Build Coastguard Worker
1231*f6dc9357SAndroid Build Coastguard Worker // #define PRF(x) x;
1232*f6dc9357SAndroid Build Coastguard Worker #define PRF(x)
1233*f6dc9357SAndroid Build Coastguard Worker
1234*f6dc9357SAndroid Build Coastguard Worker #define TRACE_SetFileAttrib(msg) \
1235*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\nSetFileAttrib(%s, %x) : %s\n", (const char *)path, attrib, msg);)
1236*f6dc9357SAndroid Build Coastguard Worker
1237*f6dc9357SAndroid Build Coastguard Worker #define TRACE_chmod(s, mode) \
1238*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\n chmod(%s, %o)\n", (const char *)path, (unsigned)(mode));)
1239*f6dc9357SAndroid Build Coastguard Worker
my_chown(CFSTR path,uid_t owner,gid_t group)1240*f6dc9357SAndroid Build Coastguard Worker int my_chown(CFSTR path, uid_t owner, gid_t group)
1241*f6dc9357SAndroid Build Coastguard Worker {
1242*f6dc9357SAndroid Build Coastguard Worker return chown(path, owner, group);
1243*f6dc9357SAndroid Build Coastguard Worker }
1244*f6dc9357SAndroid Build Coastguard Worker
SetFileAttrib_PosixHighDetect(CFSTR path,DWORD attrib)1245*f6dc9357SAndroid Build Coastguard Worker bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib)
1246*f6dc9357SAndroid Build Coastguard Worker {
1247*f6dc9357SAndroid Build Coastguard Worker TRACE_SetFileAttrib("")
1248*f6dc9357SAndroid Build Coastguard Worker
1249*f6dc9357SAndroid Build Coastguard Worker struct stat st;
1250*f6dc9357SAndroid Build Coastguard Worker
1251*f6dc9357SAndroid Build Coastguard Worker bool use_lstat = true;
1252*f6dc9357SAndroid Build Coastguard Worker if (use_lstat)
1253*f6dc9357SAndroid Build Coastguard Worker {
1254*f6dc9357SAndroid Build Coastguard Worker if (lstat(path, &st) != 0)
1255*f6dc9357SAndroid Build Coastguard Worker {
1256*f6dc9357SAndroid Build Coastguard Worker TRACE_SetFileAttrib("bad lstat()")
1257*f6dc9357SAndroid Build Coastguard Worker return false;
1258*f6dc9357SAndroid Build Coastguard Worker }
1259*f6dc9357SAndroid Build Coastguard Worker // TRACE_chmod("lstat", st.st_mode);
1260*f6dc9357SAndroid Build Coastguard Worker }
1261*f6dc9357SAndroid Build Coastguard Worker else
1262*f6dc9357SAndroid Build Coastguard Worker {
1263*f6dc9357SAndroid Build Coastguard Worker if (stat(path, &st) != 0)
1264*f6dc9357SAndroid Build Coastguard Worker {
1265*f6dc9357SAndroid Build Coastguard Worker TRACE_SetFileAttrib("bad stat()")
1266*f6dc9357SAndroid Build Coastguard Worker return false;
1267*f6dc9357SAndroid Build Coastguard Worker }
1268*f6dc9357SAndroid Build Coastguard Worker }
1269*f6dc9357SAndroid Build Coastguard Worker
1270*f6dc9357SAndroid Build Coastguard Worker if (attrib & FILE_ATTRIBUTE_UNIX_EXTENSION)
1271*f6dc9357SAndroid Build Coastguard Worker {
1272*f6dc9357SAndroid Build Coastguard Worker TRACE_SetFileAttrib("attrib & FILE_ATTRIBUTE_UNIX_EXTENSION")
1273*f6dc9357SAndroid Build Coastguard Worker st.st_mode = attrib >> 16;
1274*f6dc9357SAndroid Build Coastguard Worker if (S_ISDIR(st.st_mode))
1275*f6dc9357SAndroid Build Coastguard Worker {
1276*f6dc9357SAndroid Build Coastguard Worker // user/7z must be able to create files in this directory
1277*f6dc9357SAndroid Build Coastguard Worker st.st_mode |= (S_IRUSR | S_IWUSR | S_IXUSR);
1278*f6dc9357SAndroid Build Coastguard Worker }
1279*f6dc9357SAndroid Build Coastguard Worker else if (!S_ISREG(st.st_mode))
1280*f6dc9357SAndroid Build Coastguard Worker return true;
1281*f6dc9357SAndroid Build Coastguard Worker }
1282*f6dc9357SAndroid Build Coastguard Worker else if (S_ISLNK(st.st_mode))
1283*f6dc9357SAndroid Build Coastguard Worker {
1284*f6dc9357SAndroid Build Coastguard Worker /* for most systems: permissions for symlinks are fixed to rwxrwxrwx.
1285*f6dc9357SAndroid Build Coastguard Worker so we don't need chmod() for symlinks. */
1286*f6dc9357SAndroid Build Coastguard Worker return true;
1287*f6dc9357SAndroid Build Coastguard Worker // SetLastError(ENOSYS);
1288*f6dc9357SAndroid Build Coastguard Worker // return false;
1289*f6dc9357SAndroid Build Coastguard Worker }
1290*f6dc9357SAndroid Build Coastguard Worker else
1291*f6dc9357SAndroid Build Coastguard Worker {
1292*f6dc9357SAndroid Build Coastguard Worker TRACE_SetFileAttrib("Only Windows Attributes")
1293*f6dc9357SAndroid Build Coastguard Worker // Only Windows Attributes
1294*f6dc9357SAndroid Build Coastguard Worker if (S_ISDIR(st.st_mode)
1295*f6dc9357SAndroid Build Coastguard Worker || (attrib & FILE_ATTRIBUTE_READONLY) == 0)
1296*f6dc9357SAndroid Build Coastguard Worker return true;
1297*f6dc9357SAndroid Build Coastguard Worker st.st_mode &= ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH); // octal: ~0222; // disable write permissions
1298*f6dc9357SAndroid Build Coastguard Worker }
1299*f6dc9357SAndroid Build Coastguard Worker
1300*f6dc9357SAndroid Build Coastguard Worker int res;
1301*f6dc9357SAndroid Build Coastguard Worker /*
1302*f6dc9357SAndroid Build Coastguard Worker if (S_ISLNK(st.st_mode))
1303*f6dc9357SAndroid Build Coastguard Worker {
1304*f6dc9357SAndroid Build Coastguard Worker printf("\nfchmodat()\n");
1305*f6dc9357SAndroid Build Coastguard Worker TRACE_chmod(path, (st.st_mode) & g_umask.mask)
1306*f6dc9357SAndroid Build Coastguard Worker // AT_SYMLINK_NOFOLLOW is not implemted still in Linux.
1307*f6dc9357SAndroid Build Coastguard Worker res = fchmodat(AT_FDCWD, path, (st.st_mode) & g_umask.mask,
1308*f6dc9357SAndroid Build Coastguard Worker S_ISLNK(st.st_mode) ? AT_SYMLINK_NOFOLLOW : 0);
1309*f6dc9357SAndroid Build Coastguard Worker }
1310*f6dc9357SAndroid Build Coastguard Worker else
1311*f6dc9357SAndroid Build Coastguard Worker */
1312*f6dc9357SAndroid Build Coastguard Worker {
1313*f6dc9357SAndroid Build Coastguard Worker TRACE_chmod(path, (st.st_mode) & g_umask.mask)
1314*f6dc9357SAndroid Build Coastguard Worker res = chmod(path, (st.st_mode) & g_umask.mask);
1315*f6dc9357SAndroid Build Coastguard Worker }
1316*f6dc9357SAndroid Build Coastguard Worker // TRACE_SetFileAttrib("End")
1317*f6dc9357SAndroid Build Coastguard Worker return (res == 0);
1318*f6dc9357SAndroid Build Coastguard Worker }
1319*f6dc9357SAndroid Build Coastguard Worker
1320*f6dc9357SAndroid Build Coastguard Worker
MyCreateHardLink(CFSTR newFileName,CFSTR existFileName)1321*f6dc9357SAndroid Build Coastguard Worker bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
1322*f6dc9357SAndroid Build Coastguard Worker {
1323*f6dc9357SAndroid Build Coastguard Worker PRF(printf("\nhard link() %s -> %s\n", newFileName, existFileName);)
1324*f6dc9357SAndroid Build Coastguard Worker return (link(existFileName, newFileName) == 0);
1325*f6dc9357SAndroid Build Coastguard Worker }
1326*f6dc9357SAndroid Build Coastguard Worker
1327*f6dc9357SAndroid Build Coastguard Worker #endif // !_WIN32
1328*f6dc9357SAndroid Build Coastguard Worker
1329*f6dc9357SAndroid Build Coastguard Worker // #endif
1330*f6dc9357SAndroid Build Coastguard Worker
1331*f6dc9357SAndroid Build Coastguard Worker }}}
1332