aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/Windows')
-rw-r--r--CPP/Windows/FileDir.cpp44
-rw-r--r--CPP/Windows/FileDir.h13
2 files changed, 35 insertions, 22 deletions
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
index 10c4e98..ad0d8c9 100644
--- a/CPP/Windows/FileDir.cpp
+++ b/CPP/Windows/FileDir.cpp
@@ -124,7 +124,7 @@ bool GetSystemDir(FString &path)
124#endif // UNDER_CE 124#endif // UNDER_CE
125 125
126 126
127bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) 127static bool SetFileTime_Base(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime, DWORD dwFlagsAndAttributes)
128{ 128{
129 #ifndef _UNICODE 129 #ifndef _UNICODE
130 if (!g_IsNT) 130 if (!g_IsNT)
@@ -137,14 +137,14 @@ bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CF
137 HANDLE hDir = INVALID_HANDLE_VALUE; 137 HANDLE hDir = INVALID_HANDLE_VALUE;
138 IF_USE_MAIN_PATH 138 IF_USE_MAIN_PATH
139 hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 139 hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
140 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 140 NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
141 #ifdef Z7_LONG_PATH 141 #ifdef Z7_LONG_PATH
142 if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH) 142 if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
143 { 143 {
144 UString superPath; 144 UString superPath;
145 if (GetSuperPath(path, superPath, USE_MAIN_PATH)) 145 if (GetSuperPath(path, superPath, USE_MAIN_PATH))
146 hDir = ::CreateFileW(superPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 146 hDir = ::CreateFileW(superPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
147 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 147 NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
148 } 148 }
149 #endif 149 #endif
150 150
@@ -157,6 +157,15 @@ bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CF
157 return res; 157 return res;
158} 158}
159 159
160bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
161{
162 return SetFileTime_Base(path, cTime, aTime, mTime, FILE_FLAG_BACKUP_SEMANTICS);
163}
164
165bool SetLinkFileTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
166{
167 return SetFileTime_Base(path, cTime, aTime, mTime, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT);
168}
160 169
161 170
162bool SetFileAttrib(CFSTR path, DWORD attrib) 171bool SetFileAttrib(CFSTR path, DWORD attrib)
@@ -1173,17 +1182,15 @@ bool GetCurrentDir(FString &path)
1173 1182
1174 1183
1175 1184
1176bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) 1185static bool SetFileTime_Base(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime, const int flags)
1177{ 1186{
1178 // need testing 1187 // need testing
1179 /* 1188 /*
1180 struct utimbuf buf; 1189 struct utimbuf buf;
1181 struct stat st; 1190 struct stat st;
1182 UNUSED_VAR(cTime) 1191 UNUSED_VAR(cTime)
1183
1184 printf("\nstat = %s\n", path); 1192 printf("\nstat = %s\n", path);
1185 int ret = stat(path, &st); 1193 int ret = stat(path, &st);
1186
1187 if (ret == 0) 1194 if (ret == 0)
1188 { 1195 {
1189 buf.actime = st.st_atime; 1196 buf.actime = st.st_atime;
@@ -1195,47 +1202,42 @@ bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CF
1195 buf.actime = cur_time; 1202 buf.actime = cur_time;
1196 buf.modtime = cur_time; 1203 buf.modtime = cur_time;
1197 } 1204 }
1198
1199 if (aTime) 1205 if (aTime)
1200 { 1206 {
1201 UInt32 ut; 1207 UInt32 ut;
1202 if (NTime::FileTimeToUnixTime(*aTime, ut)) 1208 if (NTime::FileTimeToUnixTime(*aTime, ut))
1203 buf.actime = ut; 1209 buf.actime = ut;
1204 } 1210 }
1205
1206 if (mTime) 1211 if (mTime)
1207 { 1212 {
1208 UInt32 ut; 1213 UInt32 ut;
1209 if (NTime::FileTimeToUnixTime(*mTime, ut)) 1214 if (NTime::FileTimeToUnixTime(*mTime, ut))
1210 buf.modtime = ut; 1215 buf.modtime = ut;
1211 } 1216 }
1212
1213 return utime(path, &buf) == 0; 1217 return utime(path, &buf) == 0;
1214 */ 1218 */
1215 1219
1216 // if (!aTime && !mTime) return true; 1220 // if (!aTime && !mTime) return true;
1217
1218 struct timespec times[2]; 1221 struct timespec times[2];
1219 UNUSED_VAR(cTime) 1222 UNUSED_VAR(cTime)
1220
1221 bool needChange; 1223 bool needChange;
1222 needChange = FiTime_To_timespec(aTime, times[0]); 1224 needChange = FiTime_To_timespec(aTime, times[0]);
1223 needChange |= FiTime_To_timespec(mTime, times[1]); 1225 needChange |= FiTime_To_timespec(mTime, times[1]);
1224 1226 // if (mTime) { printf("\n time = %ld.%9ld\n", mTime->tv_sec, mTime->tv_nsec); }
1225 /*
1226 if (mTime)
1227 {
1228 printf("\n time = %ld.%9ld\n", mTime->tv_sec, mTime->tv_nsec);
1229 }
1230 */
1231
1232 if (!needChange) 1227 if (!needChange)
1233 return true; 1228 return true;
1234 const int flags = 0; // follow link
1235 // = AT_SYMLINK_NOFOLLOW; // don't follow link
1236 return utimensat(AT_FDCWD, path, times, flags) == 0; 1229 return utimensat(AT_FDCWD, path, times, flags) == 0;
1237} 1230}
1238 1231
1232bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
1233{
1234 return SetFileTime_Base(path, cTime, aTime, mTime, 0); // (flags = 0) means follow_link
1235}
1236
1237bool SetLinkFileTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
1238{
1239 return SetFileTime_Base(path, cTime, aTime, mTime, AT_SYMLINK_NOFOLLOW);
1240}
1239 1241
1240 1242
1241struct C_umask 1243struct C_umask
diff --git a/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h
index 65e6368..9ba98fc 100644
--- a/CPP/Windows/FileDir.h
+++ b/CPP/Windows/FileDir.h
@@ -18,9 +18,20 @@ bool GetSystemDir(FString &path);
18WIN32 API : SetFileTime() doesn't allow to set zero timestamps in file 18WIN32 API : SetFileTime() doesn't allow to set zero timestamps in file
19but linux : allows unix time = 0 in filesystem 19but linux : allows unix time = 0 in filesystem
20*/ 20*/
21 21/*
22SetDirTime() can be used to set time for file or for dir.
23If path is symbolic link, SetDirTime() will follow symbolic link,
24and it will set timestamps of symbolic link's target file or dir.
25*/
22bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime); 26bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime);
23 27
28/*
29SetLinkFileTime() doesn't follow symbolic link,
30and it sets timestamps for symbolic link file itself.
31If (path) is not symbolic link, it still can work (at least in some new OS versions).
32*/
33bool SetLinkFileTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime);
34
24 35
25#ifdef _WIN32 36#ifdef _WIN32
26 37