19 #ifndef AVUTIL_WCHAR_FILENAME_H
20 #define AVUTIL_WCHAR_FILENAME_H
30 static inline int utf8towchar(
const char *filename_utf8,
wchar_t **filename_w)
33 num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1,
NULL, 0);
39 *filename_w = (
wchar_t *)
av_calloc(num_chars,
sizeof(
wchar_t));
44 MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, *filename_w, num_chars);
49 static inline int wchartocp(
unsigned int code_page,
const wchar_t *filename_w,
52 DWORD
flags = code_page == CP_UTF8 ? WC_ERR_INVALID_CHARS : 0;
53 int num_chars = WideCharToMultiByte(code_page,
flags, filename_w, -1,
65 WideCharToMultiByte(code_page,
flags, filename_w, -1,
71 static inline int wchartoutf8(
const wchar_t *filename_w,
char **filename)
73 return wchartocp(CP_UTF8, filename_w, filename);
77 static inline int wchartoansi(
const wchar_t *filename_w,
char **filename)
79 return wchartocp(CP_ACP, filename_w, filename);
83 static inline int utf8toansi(
const char *filename_utf8,
char **filename)
85 wchar_t *filename_w =
NULL;
87 if (utf8towchar(filename_utf8, &filename_w))
95 ret = wchartoansi(filename_w, filename);
105 static inline int path_is_extended(
const wchar_t *path)
107 if (path[0] ==
L'\\' && (path[1] ==
L'\\' || path[1] ==
L'?') && path[2] ==
L'?' && path[3] ==
L'\\')
119 static inline int path_is_device_path(
const wchar_t *path)
121 if (path[0] ==
L'\\' && path[1] ==
L'\\' && path[2] ==
L'.' && path[3] ==
L'\\')
132 static inline int get_full_path_name(
wchar_t **ppath_w)
137 num_chars = GetFullPathNameW(*ppath_w, 0,
NULL,
NULL);
138 if (num_chars <= 0) {
143 temp_w = (
wchar_t *)
av_calloc(num_chars,
sizeof(
wchar_t));
149 num_chars = GetFullPathNameW(*ppath_w, num_chars, temp_w,
NULL);
150 if (num_chars <= 0) {
169 static inline int path_normalize(
wchar_t **ppath_w)
173 if ((
ret = get_full_path_name(ppath_w)) < 0)
194 static inline int add_extended_prefix(
wchar_t **ppath_w)
196 const wchar_t *unc_prefix =
L"\\\\?\\UNC\\";
197 const wchar_t *extended_path_prefix =
L"\\\\?\\";
198 const wchar_t *path_w = *ppath_w;
199 const size_t len = wcslen(path_w);
204 if (
len < 2 || path_is_extended(*ppath_w) || path_is_device_path(*ppath_w)) {
208 if (path_w[0] ==
L'\\' && path_w[1] ==
L'\\') {
211 temp_w = (
wchar_t *)
av_calloc(
len - 2 + 8 + 1,
sizeof(
wchar_t));
216 wcscpy(temp_w, unc_prefix);
217 wcscat(temp_w, path_w + 2);
220 temp_w = (
wchar_t *)
av_calloc(
len + 4 + 1,
sizeof(
wchar_t));
225 wcscpy(temp_w, extended_path_prefix);
226 wcscat(temp_w, path_w);
245 static inline int get_extended_win32_path(
const char *path,
wchar_t **ppath_w)
250 if ((
ret = utf8towchar(path, ppath_w)) < 0)
253 if (path_is_extended(*ppath_w)) {
260 if ((
ret = path_normalize(ppath_w)) < 0) {
268 len = wcslen(*ppath_w);
269 if (
len >= MAX_PATH) {
270 if ((
ret = add_extended_prefix(ppath_w)) < 0) {