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);
37 *filename_w = (
wchar_t *)
av_calloc(num_chars,
sizeof(
wchar_t));
42 MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, *filename_w, num_chars);
47 static inline int wchartocp(
unsigned int code_page,
const wchar_t *filename_w,
50 DWORD
flags = code_page == CP_UTF8 ? WC_ERR_INVALID_CHARS : 0;
51 int num_chars = WideCharToMultiByte(code_page,
flags, filename_w, -1,
62 WideCharToMultiByte(code_page,
flags, filename_w, -1,
68 static inline int wchartoutf8(
const wchar_t *filename_w,
char **filename)
70 return wchartocp(CP_UTF8, filename_w, filename);
74 static inline int wchartoansi(
const wchar_t *filename_w,
char **filename)
76 return wchartocp(CP_ACP, filename_w, filename);
80 static inline int utf8toansi(
const char *filename_utf8,
char **filename)
82 wchar_t *filename_w =
NULL;
84 if (utf8towchar(filename_utf8, &filename_w))
92 ret = wchartoansi(filename_w, filename);
102 static inline int path_is_extended(
const wchar_t *path)
104 if (path[0] ==
L'\\' && (path[1] ==
L'\\' || path[1] ==
L'?') && path[2] ==
L'?' && path[3] ==
L'\\')
116 static inline int path_is_device_path(
const wchar_t *path)
118 if (path[0] ==
L'\\' && path[1] ==
L'\\' && path[2] ==
L'.' && path[3] ==
L'\\')
129 static inline int get_full_path_name(
wchar_t **ppath_w)
134 num_chars = GetFullPathNameW(*ppath_w, 0,
NULL,
NULL);
135 if (num_chars <= 0) {
140 temp_w = (
wchar_t *)
av_calloc(num_chars,
sizeof(
wchar_t));
146 num_chars = GetFullPathNameW(*ppath_w, num_chars, temp_w,
NULL);
147 if (num_chars <= 0) {
166 static inline int path_normalize(
wchar_t **ppath_w)
170 if ((
ret = get_full_path_name(ppath_w)) < 0)
191 static inline int add_extended_prefix(
wchar_t **ppath_w)
193 const wchar_t *unc_prefix =
L"\\\\?\\UNC\\";
194 const wchar_t *extended_path_prefix =
L"\\\\?\\";
195 const wchar_t *path_w = *ppath_w;
196 const size_t len = wcslen(path_w);
201 if (
len < 2 || path_is_extended(*ppath_w) || path_is_device_path(*ppath_w)) {
205 if (path_w[0] ==
L'\\' && path_w[1] ==
L'\\') {
208 temp_w = (
wchar_t *)
av_calloc(
len - 2 + 8 + 1,
sizeof(
wchar_t));
213 wcscpy(temp_w, unc_prefix);
214 wcscat(temp_w, path_w + 2);
217 temp_w = (
wchar_t *)
av_calloc(
len + 4 + 1,
sizeof(
wchar_t));
222 wcscpy(temp_w, extended_path_prefix);
223 wcscat(temp_w, path_w);
242 static inline int get_extended_win32_path(
const char *path,
wchar_t **ppath_w)
247 if ((
ret = utf8towchar(path, ppath_w)) < 0)
250 if (path_is_extended(*ppath_w)) {
257 if ((
ret = path_normalize(ppath_w)) < 0) {
265 len = wcslen(*ppath_w);
266 if (
len >= MAX_PATH) {
267 if ((
ret = add_extended_prefix(ppath_w)) < 0) {