This allows getting the normal unix semantics, where a rename
allows replacing an existing file.

Based on a suggestion by Reimar Döffinger.
---
Changed the CP_ACP fallback codepath to convert the string to
wchar_t and use MoveFileExW, since MoveFileExA isn't available
on Windows Phone.
---
 libavformat/os_support.h   | 25 +++++++++++++++++++++++--
 libavutil/wchar_filename.h | 12 +++++++++---
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index 4aa98bd..163295f 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -170,14 +170,35 @@ static inline int win32_rename(const char *src_utf8, 
const char *dest_utf8)
         goto fallback;
     }
 
-    ret = _wrename(src_w, dest_w);
+    ret = MoveFileExW(src_w, dest_w, MOVEFILE_REPLACE_EXISTING);
     av_free(src_w);
     av_free(dest_w);
+    // Lacking proper mapping from GetLastError() error codes to errno codes
+    if (ret)
+        errno = EPERM;
     return ret;
 
 fallback:
     /* filename may be be in CP_ACP */
-    return rename(src_utf8, dest_utf8);
+    if (stringtowchar(src_utf8, &src_w, CP_ACP))
+        return -1;
+    if (stringtowchar(dest_utf8, &dest_w, CP_ACP)) {
+        av_free(src_w);
+        return -1;
+    }
+    if (!src_w || !dest_w) {
+        av_free(src_w);
+        av_free(dest_w);
+        errno = EINVAL;
+        return -1;
+    }
+    // MoveFileExA isn't available on Windows Phone
+    ret = MoveFileExW(src_w, dest_w, MOVEFILE_REPLACE_EXISTING);
+    av_free(src_w);
+    av_free(dest_w);
+    if (ret)
+        errno = EPERM;
+    return ret;
 }
 
 #define mkdir(a, b) win32_mkdir(a)
diff --git a/libavutil/wchar_filename.h b/libavutil/wchar_filename.h
index 2781773..2f9058c 100644
--- a/libavutil/wchar_filename.h
+++ b/libavutil/wchar_filename.h
@@ -23,10 +23,11 @@
 #include <windows.h>
 #include "mem.h"
 
-static inline int utf8towchar(const char *filename_utf8, wchar_t **filename_w)
+static inline int stringtowchar(const char *filename_utf8, wchar_t 
**filename_w,
+                                int codepage)
 {
     int num_chars;
-    num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, 
filename_utf8, -1, NULL, 0);
+    num_chars = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, 
filename_utf8, -1, NULL, 0);
     if (num_chars <= 0) {
         *filename_w = NULL;
         return 0;
@@ -36,9 +37,14 @@ static inline int utf8towchar(const char *filename_utf8, 
wchar_t **filename_w)
         errno = ENOMEM;
         return -1;
     }
-    MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, *filename_w, num_chars);
+    MultiByteToWideChar(codepage, 0, filename_utf8, -1, *filename_w, 
num_chars);
     return 0;
 }
+
+static inline int utf8towchar(const char *filename_utf8, wchar_t **filename_w)
+{
+    return stringtowchar(filename_utf8, filename_w, CP_UTF8);
+}
 #endif
 
 #endif /* AVUTIL_WCHAR_FILENAME_H */
-- 
1.9.3 (Apple Git-50)

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to