[vlc-commits] [Git][videolan/vlc][3.0.x] win32/filesystem: fix the vlc_stat() times
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri Sep 11 07:27:14 UTC 2026
Steve Lhomme pushed to branch 3.0.x at VideoLAN / VLC
Commits:
479f8848 by Steve Lhomme at 2026-09-11T09:07:50+02:00
win32/filesystem: fix the vlc_stat() times
With MSVCRT the st_mtime value from _wstati64() depends on the Daylight Time Saving
of the machine. It gives a 3600 seconds difference depend on how the machine is configured.
GetFileTime() gives a reliable date+time regardless of the DST of the machine.
Fixes #29685
Co-authored-by: Martin Finkel <me at martinfinkel.com>
Co-authored-by: Denis Charmet <typx at dinauz.org>
(cherry picked from commit efbd05ae00d3a785186455c8ff6d5b058d81a480) (rebased)
rebased:
- the includes around are slightly different
- - - - -
1 changed file:
- src/win32/filesystem.c
Changes:
=====================================
src/win32/filesystem.c
=====================================
@@ -38,6 +38,7 @@
#include <fcntl.h>
#include <winsock2.h>
#include <direct.h>
+#include <stdckdint.h>
#include <vlc_common.h>
#include <vlc_charset.h>
@@ -291,6 +292,44 @@ const char *vlc_readdir (DIR *dir)
return p_dir->entry;
}
+#define FILETIME_UNIX_EPOCH_TICKS UINT64_C(116444736000000000)
+#define FILETIME_TICKS_PER_SECOND INT64_C(10000000)
+
+static int filetime_to_time_t(const FILETIME *ft, time_t *result)
+{
+ ULARGE_INTEGER ticks = {
+ .HighPart = ft->dwHighDateTime,
+ .LowPart = ft->dwLowDateTime,
+ };
+
+ int64_t delta, seconds;
+
+ if (ckd_sub(&delta, ticks.QuadPart, FILETIME_UNIX_EPOCH_TICKS))
+ {
+ errno = EOVERFLOW;
+ return -1;
+ }
+
+ seconds = delta / FILETIME_TICKS_PER_SECOND;
+
+ if ( unlikely(delta < 0 && delta % FILETIME_TICKS_PER_SECOND != 0) )
+ {
+ if (ckd_sub(&seconds, seconds, INT64_C(1)))
+ {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ }
+
+ // ensure the value fits in the result
+ if ( unlikely(ckd_add(result, seconds, 0)) ) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+
+ return 0;
+}
+
int vlc_stat (const char *filename, struct stat *buf)
{
wchar_t *wpath = widen_path (filename);
@@ -301,8 +340,49 @@ int vlc_stat (const char *filename, struct stat *buf)
"Mismatched struct stat definition.");
int ret = _wstati64 (wpath, buf);
+ if ( ret != 0 )
+ {
+ free (wpath);
+ return ret;
+ }
+
+ // _wstati64() can give different st_mtime values for the same file if it
+ // was created in a different Daylight Saving Time as the current time.
+ // This is not the case in UCRT builds.
+ // GetFileAttributesExW() doesn't have this problem.
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+ BOOL res = GetFileAttributesExW( wpath, GetFileExInfoStandard, &fad );
free (wpath);
- return ret;
+ if ( unlikely(!res) )
+ {
+ DWORD error = GetLastError();
+
+ switch (error) {
+ case ERROR_FILE_NOT_FOUND:
+ case ERROR_PATH_NOT_FOUND:
+ case ERROR_INVALID_NAME:
+ errno = ENOENT;
+ break;
+
+ case ERROR_ACCESS_DENIED:
+ case ERROR_SHARING_VIOLATION:
+ errno = EACCES;
+ break;
+
+ default:
+ errno = EIO;
+ break;
+ }
+
+ return -1;
+ }
+
+ if (filetime_to_time_t(&fad.ftCreationTime, &buf->st_ctime) ||
+ filetime_to_time_t(&fad.ftLastAccessTime, &buf->st_atime) ||
+ filetime_to_time_t(&fad.ftLastWriteTime, &buf->st_mtime))
+ return -1;
+
+ return 0;
}
int vlc_lstat (const char *filename, struct stat *buf)
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/479f8848770bab06da690d84c502945f1794c418
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/479f8848770bab06da690d84c502945f1794c418
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help
More information about the vlc-commits
mailing list