[MPlayer-dev-eng] [PATCH]can not open ISO file including multibyte file path. on Windows.

Tadashi Ando ando at je-pu-pu.jp
Sun Apr 23 21:27:59 EEST 2017


I put functions stream/stream.c/h.
( The functions are defined only on Windows. )
I removed "win32_convert_" part of functions name.
I removed dynamic symbol lookups. ( also from stream_file.c. )
Now, the encoding conversion code are sharing on stream_file.c and 
stream_dvd.c.

Can you OK this patch ?


Regards,
Tadashi Ando
-------------- next part --------------
Index: stream/stream.c
===================================================================
--- stream/stream.c	(ƒŠƒrƒWƒ‡ƒ“ 37933)
+++ stream/stream.c	(ì‹ÆƒRƒs[)
@@ -746,3 +746,73 @@
   }
   return 0;
 }
+
+#if defined(__MINGW32__) || defined(__CYGWIN__)
+wchar_t* utf8_to_wide_char( const char* utf8 )
+{
+    int wide_char_size;
+    int conv_size;
+    
+    wchar_t* wide_char = NULL;
+    
+    wide_char_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, wide_char, 0);
+    if (wide_char_size < 0) goto err_out;
+    
+    wide_char = calloc(wide_char_size, sizeof(wchar_t));
+    if (!wide_char) goto err_out;
+    
+    conv_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, wide_char, wide_char_size);
+    if (conv_size <= 0) goto err_out;
+    
+    return wide_char;
+    
+err_out:
+    free(wide_char);
+    
+    return 0;
+}
+
+char* wide_char_to_local_windows_code_page( const wchar_t* wide_char )
+{
+    int ansi_size;
+    int conv_size;
+    
+    char* ansi = NULL;
+    
+    ansi_size = WideCharToMultiByte(CP_ACP, 0, wide_char, -1, NULL, 0, NULL, NULL);
+    if (ansi_size < 0) goto err_out;
+    
+    ansi = calloc(1, ansi_size);
+    if (!ansi) goto err_out;
+    
+    conv_size = WideCharToMultiByte(CP_ACP, 0, wide_char, -1, ansi, ansi_size, NULL, NULL);
+    if (conv_size < 0) goto err_out;
+    
+    return ansi;
+
+err_out:
+    free(ansi);
+    
+    return 0;
+}
+
+char* utf8_to_local_windows_code_page( const char* utf8 )
+{
+    wchar_t* wide_char = NULL;
+    char* windows_local_code_page = NULL;
+    
+    wide_char = utf8_to_wide_char(utf8);
+    if (!wide_char) goto err_out;
+    
+    windows_local_code_page = wide_char_to_local_windows_code_page(wide_char);
+    if (!windows_local_code_page) goto err_out;
+    
+    free(wide_char);
+    
+    return windows_local_code_page;
+    
+err_out:
+    free(wide_char);
+    free(windows_local_code_page);
+}
+#endif
\ No newline at end of file
Index: stream/stream.h
===================================================================
--- stream/stream.h	(ƒŠƒrƒWƒ‡ƒ“ 37933)
+++ stream/stream.h	(ì‹ÆƒRƒs[)
@@ -404,4 +404,10 @@
 
 int parse_chapter_range(const m_option_t *conf, const char *range);
 
+#if defined(__MINGW32__) || defined(__CYGWIN__)
+wchar_t* utf8_to_wide_char(const char* utf8);
+char* wide_char_to_local_windows_code_page(const wchar_t* wide_char);
+char* utf8_to_local_windows_code_page(const char* utf8);
+#endif
+
 #endif /* MPLAYER_STREAM_H */
Index: stream/stream_dvd.c
===================================================================
--- stream/stream_dvd.c	(ƒŠƒrƒWƒ‡ƒ“ 37933)
+++ stream/stream_dvd.c	(ì‹ÆƒRƒs[)
@@ -790,7 +790,20 @@
     } else
 #endif /* defined(__APPLE__) || defined(__DARWIN__) */
     {
+#if defined(__MINGW32__) || defined(__CYGWIN__)
+        char* dvd_device_current_for_open = dvd_device_current;
+        char* ansi_dvd_device_current = NULL;
+        
+        if ( ansi_dvd_device_current = utf8_to_local_windows_code_page(dvd_device_current) )
+        {
+            dvd_device_current_for_open = ansi_dvd_device_current;
+        }
+        
+        dvd = DVDOpen(dvd_device_current_for_open);
+        free(ansi_dvd_device_current);
+#else
         dvd = DVDOpen(dvd_device_current);
+#endif
         if(!dvd) {
           mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_CantOpenDVD,dvd_device_current, strerror(errno));
           goto fail;
Index: stream/stream_file.c
===================================================================
--- stream/stream_file.c	(ƒŠƒrƒWƒ‡ƒ“ 37933)
+++ stream/stream_file.c	(ì‹ÆƒRƒs[)
@@ -125,15 +125,14 @@
 {
     int cnt;
     int fd = -1;
-    wchar_t fname_w[MAX_PATH];
-    int WINAPI (*mb2wc)(UINT, DWORD, LPCSTR, int, LPWSTR, int) = NULL;
-    HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
-    if (!kernel32) goto fallback;
-    mb2wc = GetProcAddress(kernel32, "MultiByteToWideChar");
-    if (!mb2wc) goto fallback;
-    cnt = mb2wc(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, fname_w, sizeof(fname_w) / sizeof(*fname_w));
-    if (cnt <= 0) goto fallback;
+    wchar_t* fname_w = NULL;
+    
+    fname_w = utf8_to_wide_char( fname );
+    if (!fname_w) goto fallback;
+    
     fd = _wsopen(fname_w, m, SH_DENYNO, omode);
+    free(fname_w);
+    
     if (fd != -1 || (m & O_CREAT))
         return fd;
 


More information about the MPlayer-dev-eng mailing list