4949# ifdef stat
5050# undef stat
5151# endif
52- # define stat _stati64
52+
53+ # define stat win32_stat
54+
55+ /*
56+ * The POSIX definition for the stat() function uses a struct of the
57+ * same name (struct stat), that why it takes this extra effort for
58+ * redirecting/replacing the stat() function with our own one which
59+ * is capable to handle long path names on Windows.
60+ * The struct below roughly follows the POSIX definition. Time values
61+ * are 64bit, but in cases when _USE_32BIT_TIME_T is defined, they
62+ * will be set to values no larger than INT32_MAX which corresponds
63+ * to file times up to the year 2038.
64+ */
65+ struct win32_stat
66+ {
67+ _dev_t st_dev ; /* ID of device containing file */
68+ _ino_t st_ino ; /* inode number */
69+ unsigned short st_mode ; /* protection */
70+ short st_nlink ; /* number of hard links */
71+ short st_uid ; /* user ID of owner */
72+ short st_gid ; /* group ID of owner */
73+ _dev_t st_rdev ; /* device ID (if special file) */
74+ int64_t st_size ; /* total size, in bytes */
75+ int64_t st_atime ; /* time of last access */
76+ int64_t st_mtime ; /* time of last modification */
77+ int64_t st_ctime ; /* time of last status change */
78+ };
79+
5380# ifdef fstat
5481# undef fstat
5582# endif
56- # define fstat ( f , s ) _fstati64((f), (s))
83+ # define fstat win32_fstat
5784#endif /* defined(_WIN32) */
5885
5986
@@ -153,7 +180,7 @@ static inline int win32_##name(const char *filename_utf8) \
153180 wchar_t *filename_w; \
154181 int ret; \
155182 \
156- if (utf8towchar (filename_utf8, &filename_w)) \
183+ if (get_extended_win32_path (filename_utf8, &filename_w)) \
157184 return -1; \
158185 if (!filename_w) \
159186 goto fallback; \
@@ -171,37 +198,76 @@ DEF_FS_FUNCTION(unlink, _wunlink, _unlink)
171198DEF_FS_FUNCTION (mkdir , _wmkdir , _mkdir )
172199DEF_FS_FUNCTION (rmdir , _wrmdir , _rmdir )
173200
174- #define DEF_FS_FUNCTION2 (name , wfunc , afunc , partype ) \
175- static inline int win32_##name(const char *filename_utf8, partype par) \
176- { \
177- wchar_t *filename_w; \
178- int ret; \
179- \
180- if (utf8towchar(filename_utf8, &filename_w)) \
181- return -1; \
182- if (!filename_w) \
183- goto fallback; \
184- \
185- ret = wfunc(filename_w, par); \
186- av_free(filename_w); \
187- return ret; \
188- \
189- fallback: \
190- /* filename may be be in CP_ACP */ \
191- return afunc (filename_utf8 , par ); \
201+ static inline int win32_access (const char * filename_utf8 , int mode )
202+ {
203+ wchar_t * filename_w ;
204+ int ret ;
205+ if (get_extended_win32_path (filename_utf8 , & filename_w ))
206+ return -1 ;
207+ if (!filename_w )
208+ goto fallback ;
209+ ret = _waccess (filename_w , mode );
210+ av_free (filename_w );
211+ return ret ;
212+ fallback :
213+ return _access (filename_utf8 , mode );
214+ }
215+
216+ static inline void copy_stat (struct _stati64 * crtstat , struct win32_stat * buf )
217+ {
218+ buf -> st_dev = crtstat -> st_dev ;
219+ buf -> st_ino = crtstat -> st_ino ;
220+ buf -> st_mode = crtstat -> st_mode ;
221+ buf -> st_nlink = crtstat -> st_nlink ;
222+ buf -> st_uid = crtstat -> st_uid ;
223+ buf -> st_gid = crtstat -> st_gid ;
224+ buf -> st_rdev = crtstat -> st_rdev ;
225+ buf -> st_size = crtstat -> st_size ;
226+ buf -> st_atime = crtstat -> st_atime ;
227+ buf -> st_mtime = crtstat -> st_mtime ;
228+ buf -> st_ctime = crtstat -> st_ctime ;
192229}
193230
194- DEF_FS_FUNCTION2 (access , _waccess , _access , int )
195- DEF_FS_FUNCTION2 (stat , _wstati64 , _stati64 , struct stat * )
231+ static inline int win32_stat (const char * filename_utf8 , struct win32_stat * buf )
232+ {
233+ struct _stati64 crtstat = { 0 };
234+ wchar_t * filename_w ;
235+ int ret ;
236+
237+ if (get_extended_win32_path (filename_utf8 , & filename_w ))
238+ return -1 ;
239+
240+ if (filename_w ) {
241+ ret = _wstat64 (filename_w , & crtstat );
242+ av_free (filename_w );
243+ } else
244+ ret = _stat64 (filename_utf8 , & crtstat );
245+
246+ copy_stat (& crtstat , buf );
247+
248+ return ret ;
249+ }
250+
251+ static inline int win32_fstat (int fd , struct win32_stat * buf )
252+ {
253+ struct _stati64 crtstat = { 0 };
254+ int ret ;
255+
256+ ret = _fstat64 (fd , & crtstat );
257+
258+ copy_stat (& crtstat , buf );
259+
260+ return ret ;
261+ }
196262
197263static inline int win32_rename (const char * src_utf8 , const char * dest_utf8 )
198264{
199265 wchar_t * src_w , * dest_w ;
200266 int ret ;
201267
202- if (utf8towchar (src_utf8 , & src_w ))
268+ if (get_extended_win32_path (src_utf8 , & src_w ))
203269 return -1 ;
204- if (utf8towchar (dest_utf8 , & dest_w )) {
270+ if (get_extended_win32_path (dest_utf8 , & dest_w )) {
205271 av_free (src_w );
206272 return -1 ;
207273 }
0 commit comments