19 #ifndef AVUTIL_WCHAR_FILENAME_H
20 #define AVUTIL_WCHAR_FILENAME_H
24 #define WIN32_LEAN_AND_MEAN
29 static inline int utf8towchar(
const char *filename_utf8,
wchar_t **filename_w)
32 num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1,
NULL, 0);
38 *filename_w = (
wchar_t *)
av_calloc(num_chars,
sizeof(
wchar_t));
43 MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, *filename_w, num_chars);
48 static inline int wchartocp(
unsigned int code_page,
const wchar_t *filename_w,
51 DWORD
flags = code_page == CP_UTF8 ? WC_ERR_INVALID_CHARS : 0;
52 int num_chars = WideCharToMultiByte(code_page,
flags, filename_w, -1,
64 WideCharToMultiByte(code_page,
flags, filename_w, -1,
70 static inline int wchartoutf8(
const wchar_t *filename_w,
char **filename)
72 return wchartocp(CP_UTF8, filename_w, filename);
76 static inline int wchartoansi(
const wchar_t *filename_w,
char **filename)
78 return wchartocp(CP_ACP, filename_w, filename);
82 static inline int utf8toansi(
const char *filename_utf8,
char **filename)
84 wchar_t *filename_w =
NULL;
86 if (utf8towchar(filename_utf8, &filename_w))
94 ret = wchartoansi(filename_w, filename);
104 static inline int path_is_extended(
const wchar_t *path)
106 if (path[0] ==
L'\\' && (path[1] ==
L'\\' || path[1] ==
L'?') && path[2] ==
L'?' && path[3] ==
L'\\')
118 static inline int path_is_device_path(
const wchar_t *path)
120 if (path[0] ==
L'\\' && path[1] ==
L'\\' && path[2] ==
L'.' && path[3] ==
L'\\')
131 static inline int get_full_path_name(
wchar_t **ppath_w)
136 num_chars = GetFullPathNameW(*ppath_w, 0,
NULL,
NULL);
137 if (num_chars <= 0) {
142 temp_w = (
wchar_t *)
av_calloc(num_chars,
sizeof(
wchar_t));
148 num_chars = GetFullPathNameW(*ppath_w, num_chars, temp_w,
NULL);
149 if (num_chars <= 0) {
168 static inline int path_normalize(
wchar_t **ppath_w)
172 if ((
ret = get_full_path_name(ppath_w)) < 0)
193 static inline int add_extended_prefix(
wchar_t **ppath_w)
195 const wchar_t *unc_prefix =
L"\\\\?\\UNC\\";
196 const wchar_t *extended_path_prefix =
L"\\\\?\\";
197 const wchar_t *path_w = *ppath_w;
198 const size_t len = wcslen(path_w);
203 if (
len < 2 || path_is_extended(*ppath_w) || path_is_device_path(*ppath_w)) {
207 if (path_w[0] ==
L'\\' && path_w[1] ==
L'\\') {
210 temp_w = (
wchar_t *)
av_calloc(
len - 2 + 8 + 1,
sizeof(
wchar_t));
215 wcscpy(temp_w, unc_prefix);
216 wcscat(temp_w, path_w + 2);
219 temp_w = (
wchar_t *)
av_calloc(
len + 4 + 1,
sizeof(
wchar_t));
224 wcscpy(temp_w, extended_path_prefix);
225 wcscat(temp_w, path_w);
244 static inline int get_extended_win32_path(
const char *path,
wchar_t **ppath_w)
249 if ((
ret = utf8towchar(path, ppath_w)) < 0)
252 if (path_is_extended(*ppath_w)) {
259 if ((
ret = path_normalize(ppath_w)) < 0) {
267 len = wcslen(*ppath_w);
268 if (
len >= MAX_PATH) {
269 if ((
ret = add_extended_prefix(ppath_w)) < 0) {