Skip to content

Commit bc8f1bb

Browse files
softworkzmstorsjo
authored andcommitted
avformat/os_support: Support long file names on Windows
Signed-off-by: softworkz <softworkz@hotmail.com> Signed-off-by: Martin Storsjö <martin@martin.st>
1 parent c5aba39 commit bc8f1bb

File tree

1 file changed

+91
-25
lines changed

1 file changed

+91
-25
lines changed

libavformat/os_support.h

Lines changed: 91 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,38 @@
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)
171198
DEF_FS_FUNCTION(mkdir, _wmkdir, _mkdir)
172199
DEF_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

197263
static 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

Comments
 (0)