diff options
| author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2025-08-03 00:00:00 +0000 |
|---|---|---|
| committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2025-08-03 16:14:59 +0500 |
| commit | 5e96a8279489832924056b1fa82f29d5837c9469 (patch) | |
| tree | d73ec17c25ab91a1938662bff0c37332fe521b70 /CPP/Windows | |
| parent | 395149956d696e6e3099d8b76d797437f94a6942 (diff) | |
| download | 7zip-main.tar.gz 7zip-main.tar.bz2 7zip-main.zip | |
Diffstat (limited to 'CPP/Windows')
| -rw-r--r-- | CPP/Windows/FileDir.cpp | 44 | ||||
| -rw-r--r-- | CPP/Windows/FileDir.h | 13 |
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 | ||
| 127 | bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) | 127 | static 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 | ||
| 160 | bool 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 | |||
| 165 | bool 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 | ||
| 162 | bool SetFileAttrib(CFSTR path, DWORD attrib) | 171 | bool SetFileAttrib(CFSTR path, DWORD attrib) |
| @@ -1173,17 +1182,15 @@ bool GetCurrentDir(FString &path) | |||
| 1173 | 1182 | ||
| 1174 | 1183 | ||
| 1175 | 1184 | ||
| 1176 | bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) | 1185 | static 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 | ||
| 1232 | bool 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 | |||
| 1237 | bool 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 | ||
| 1241 | struct C_umask | 1243 | struct 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); | |||
| 18 | WIN32 API : SetFileTime() doesn't allow to set zero timestamps in file | 18 | WIN32 API : SetFileTime() doesn't allow to set zero timestamps in file |
| 19 | but linux : allows unix time = 0 in filesystem | 19 | but linux : allows unix time = 0 in filesystem |
| 20 | */ | 20 | */ |
| 21 | 21 | /* | |
| 22 | SetDirTime() can be used to set time for file or for dir. | ||
| 23 | If path is symbolic link, SetDirTime() will follow symbolic link, | ||
| 24 | and it will set timestamps of symbolic link's target file or dir. | ||
| 25 | */ | ||
| 22 | bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime); | 26 | bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime); |
| 23 | 27 | ||
| 28 | /* | ||
| 29 | SetLinkFileTime() doesn't follow symbolic link, | ||
| 30 | and it sets timestamps for symbolic link file itself. | ||
| 31 | If (path) is not symbolic link, it still can work (at least in some new OS versions). | ||
| 32 | */ | ||
| 33 | bool SetLinkFileTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime); | ||
| 34 | |||
| 24 | 35 | ||
| 25 | #ifdef _WIN32 | 36 | #ifdef _WIN32 |
| 26 | 37 | ||
