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

Tadashi Ando ando at je-pu-pu.jp
Sun Mar 5 21:56:02 EET 2017


Hi All.
I'm Ando from Japan.
I found bug, and fixed it.
Bug is relating to multibyte. And relating to DVD .ISO.

DVDOpen() of MPlayer of Windows version requires
ANSI multibyte path as argument.
But current MPlayer using UTF-8.
( UTF-8 is internal encoding of MPlayer )
Therefore, If .ISO file path is including multibyte,
DVDOpen() ( with libdvdread & libdvdcss ) can't open file.
And MPlayer can't play .ISO file.

My patch is, convert UTF-8 to ANSI when using DVDOpen().
Please check attached patch.

Regards.


-- 
Tadashi Ando
-------------- next part --------------
Index: stream/stream_dvd.c
===================================================================
--- stream/stream_dvd.c	(???r?W???? 37926)
+++ stream/stream_dvd.c	(???R?s?[)
@@ -22,6 +22,10 @@
 #include <strings.h>
 #include <unistd.h>
 
+#if defined(__MINGW32__) || defined(__CYGWIN__)
+#include <windows.h>
+#endif
+
 #include "config.h"
 #include "mp_msg.h"
 #include "help_mp.h"
@@ -730,7 +734,57 @@
     return STREAM_UNSUPPORTED;
 }
 
+#if defined(__MINGW32__) || defined(__CYGWIN__)
+static char* win32_convert_utf8_to_ansi( char* utf8 )
+{
+    int wc_size;
+    int ansi_size;
+    int conv_size;
+    
+    wchar_t* wc = NULL;
+    char* ansi = NULL;
+    
+    int WINAPI (*mb2wc)(UINT, DWORD, LPCSTR, int, LPWSTR, int) = NULL;
+    int WINAPI (*wc2mb)(UINT, DWORD, LPCWSTR, int, LPSTR, int, LPCSTR, LPBOOL) = NULL;
+    
+    HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
+    if (!kernel32) goto err_out;
+    
+    mb2wc = GetProcAddress(kernel32, "MultiByteToWideChar");
+    wc2mb = GetProcAddress(kernel32, "WideCharToMultiByte");
+    
+    if (!mb2wc || !wc2mb) goto err_out;
+    
+    wc_size = mb2wc(CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, wc, 0);
+    if (wc_size < 0) goto err_out;
+    
+    wc = calloc(wc_size, sizeof(wchar_t));
+    if (!wc) goto err_out;
+    
+    conv_size = mb2wc(CP_UTF8, MB_ERR_INVALID_CHARS, utf8, -1, wc, wc_size);
+    if (conv_size <= 0) goto err_out;
+    
+    ansi_size = wc2mb(CP_ACP, 0, wc, -1, NULL, 0, NULL, NULL);
+    if (ansi_size < 0) goto err_out;
+    
+    ansi = calloc(1, ansi_size);
+    if (!ansi) goto err_out;
+    
+    conv_size = wc2mb(CP_ACP, 0, wc, -1, ansi, ansi_size, NULL, NULL);
+    if (conv_size < 0) goto err_out;
+    
+    free(wc);
+    
+    return ansi;
 
+err_out:
+    free(wc);
+    free(ansi);
+    
+    return 0;
+}
+#endif
+
 static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
   struct stream_priv_s* p = (struct stream_priv_s*)opts;
   int k;
@@ -789,8 +843,22 @@
       }
     } 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 = win32_convert_utf8_to_ansi(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;


More information about the MPlayer-dev-eng mailing list