mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
lavf: Use wchar functions for filenames on windows for mkdir/rmdir/rename/unlink
This makes sure that the internal utf8 path names are handled properly - the normal file handling functions assume path names are in the native codepage, which isn't utf8. This assumes that the tools outside of lavf don't use the mkdir definition. (The tools don't do the same reading of command line parameters as wchar either - they probably won't handle all possible unicode file parameters properly, but at least work more predictably if no utf8/wchar conversion is involved.) This is moved further down in os_support.h, since windows.h shouldn't be included before winsock2.h, while io.h needs to be included before the manual defines for lseek functions. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
b9d08c77a4
commit
960aff379d
@ -23,6 +23,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "avformat.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#define MAX_URL_SIZE 4096
|
||||
|
||||
|
@ -31,6 +31,15 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if HAVE_DIRECT_H
|
||||
#include <direct.h>
|
||||
#endif
|
||||
#if HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32CE__)
|
||||
# include <fcntl.h>
|
||||
# undef lseek
|
||||
@ -41,15 +50,6 @@
|
||||
# define fstat(f,s) _fstati64((f), (s))
|
||||
#endif /* defined(_WIN32) && !defined(__MINGW32CE__) */
|
||||
|
||||
#ifdef _WIN32
|
||||
#if HAVE_DIRECT_H
|
||||
#include <direct.h>
|
||||
#elif HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
#define mkdir(a, b) _mkdir(a)
|
||||
#endif
|
||||
|
||||
static inline int is_dos_path(const char *path)
|
||||
{
|
||||
#if HAVE_DOS_PATHS
|
||||
@ -122,4 +122,86 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout);
|
||||
#endif /* HAVE_POLL_H */
|
||||
#endif /* CONFIG_NETWORK */
|
||||
|
||||
#if defined(__MINGW32CE__)
|
||||
#define mkdir(a, b) _mkdir(a)
|
||||
#elif defined(_WIN32)
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
static inline int utf8towchar(const char *filename_utf8, wchar_t **filename_w)
|
||||
{
|
||||
int num_chars;
|
||||
num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
|
||||
if (num_chars <= 0) {
|
||||
*filename_w = NULL;
|
||||
return 0;
|
||||
}
|
||||
*filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
|
||||
if (!*filename_w) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, *filename_w, num_chars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DEF_FS_FUNCTION(name, wfunc, afunc) \
|
||||
static inline int win32_##name(const char *filename_utf8) \
|
||||
{ \
|
||||
wchar_t *filename_w; \
|
||||
int ret; \
|
||||
\
|
||||
if (utf8towchar(filename_utf8, &filename_w)) \
|
||||
return -1; \
|
||||
if (!filename_w) \
|
||||
goto fallback; \
|
||||
\
|
||||
ret = wfunc(filename_w); \
|
||||
av_free(filename_w); \
|
||||
return ret; \
|
||||
\
|
||||
fallback: \
|
||||
/* filename may be be in CP_ACP */ \
|
||||
return afunc(filename_utf8); \
|
||||
}
|
||||
|
||||
DEF_FS_FUNCTION(unlink, _wunlink, _unlink)
|
||||
DEF_FS_FUNCTION(mkdir, _wmkdir, _mkdir)
|
||||
DEF_FS_FUNCTION(rmdir, _wrmdir , _rmdir)
|
||||
|
||||
static inline int win32_rename(const char *src_utf8, const char *dest_utf8)
|
||||
{
|
||||
wchar_t *src_w, *dest_w;
|
||||
int ret;
|
||||
|
||||
if (utf8towchar(src_utf8, &src_w))
|
||||
return -1;
|
||||
if (utf8towchar(dest_utf8, &dest_w)) {
|
||||
av_free(src_w);
|
||||
return -1;
|
||||
}
|
||||
if (!src_w || !dest_w) {
|
||||
av_free(src_w);
|
||||
av_free(dest_w);
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
ret = _wrename(src_w, dest_w);
|
||||
av_free(src_w);
|
||||
av_free(dest_w);
|
||||
return ret;
|
||||
|
||||
fallback:
|
||||
/* filename may be be in CP_ACP */
|
||||
return rename(src_utf8, dest_utf8);
|
||||
}
|
||||
|
||||
#define mkdir(a, b) win32_mkdir(a)
|
||||
#define rename win32_rename
|
||||
#define rmdir win32_rmdir
|
||||
#define unlink win32_unlink
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* AVFORMAT_OS_SUPPORT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user