[vlc-commits] Win32: handle file paths of arbitrary length (in file system code)

Rémi Denis-Courmont git at videolan.org
Tue Jul 12 19:09:32 CEST 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jul 12 20:07:20 2011 +0300| [9197cdff553e29ca08295b52ab3e219989bc094f] | committer: Rémi Denis-Courmont

Win32: handle file paths of arbitrary length (in file system code)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9197cdff553e29ca08295b52ab3e219989bc094f
---

 src/win32/filesystem.c |   98 +++++++++++++++++++++++++++++++++---------------
 src/win32/plugin.c     |   13 +++---
 2 files changed, 75 insertions(+), 36 deletions(-)

diff --git a/src/win32/filesystem.c b/src/win32/filesystem.c
index 0ba5e0a..7128781 100644
--- a/src/win32/filesystem.c
+++ b/src/win32/filesystem.c
@@ -48,20 +48,25 @@
 # include <tchar.h>
 #endif
 
-static int convert_path (const char *restrict path, wchar_t *restrict wpath)
+static wchar_t *widen_path (const char *path)
 {
-    if (!MultiByteToWideChar (CP_UTF8, 0, path, -1, wpath, MAX_PATH))
+    wchar_t *wpath;
+
+    errno = 0;
+    wpath = ToWide (path);
+    if (wpath == NULL)
     {
-        errno = ENOENT;
-        return -1;
+        if (errno == 0)
+            errno = ENOENT;
+        return NULL;
     }
-    wpath[MAX_PATH] = L'\0';
-    return 0;
+    return wpath;
 }
+
 #define CONVERT_PATH(path, wpath, err) \
-  wchar_t wpath[MAX_PATH+1]; \
-  if (convert_path (path, wpath)) \
-      return (err)
+    wchar_t *wpath = wide_path(path); \
+    if (wpath == NULL) return (err)
+
 
 int vlc_open (const char *filename, int flags, ...)
 {
@@ -81,9 +86,13 @@ int vlc_open (const char *filename, int flags, ...)
      * open() cannot open files with non-“ANSI” characters on Windows.
      * We use _wopen() instead. Same thing for mkdir() and stat().
      */
-    CONVERT_PATH(filename, wpath, -1);
-    return _wopen (wpath, flags, mode);
+    wchar_t *wpath = widen_path (filename);
+    if (wpath == NULL)
+        return -1;
 
+    int fd = _wopen (wpath, flags, mode);
+    free (wpath);
+    return fd;
 #endif
 }
 
@@ -101,10 +110,14 @@ int vlc_mkdir( const char *dirname, mode_t mode )
     /* mkdir converts internally to wchar */
     return _mkdir(dirname);
 #else
-    (void) mode;
-    CONVERT_PATH (dirname, wpath, -1);
-    return _wmkdir (wpath);
+    wchar_t *wpath = widen_path (dirname);
+    if (wpath == NULL)
+        return -1;
 
+    int ret = _wmkdir (wpath);
+    free (wpath);
+    (void) mode;
+    return ret;
 #endif
 }
 
@@ -134,15 +147,20 @@ typedef struct vlc_DIR
 
 DIR *vlc_opendir (const char *dirname)
 {
-    CONVERT_PATH (dirname, wpath, NULL);
+    wchar_t *wpath = widen_path (dirname);
+    if (wpath == NULL)
+        return NULL;
 
     vlc_DIR *p_dir = malloc (sizeof (*p_dir));
     if (unlikely(p_dir == NULL))
+    {
+        free(wpath);
         return NULL;
+    }
 
-    if (wpath == NULL || wpath[0] == '\0'
-     || (wcscmp (wpath, L"\\") == 0))
+    if (wpath[0] == L'\0' || (wcscmp (wpath, L"\\") == 0))
     {
+        free (wpath);
         /* Special mode to list drive letters */
         p_dir->wdir = NULL;
 #ifdef UNDER_CE
@@ -153,16 +171,17 @@ DIR *vlc_opendir (const char *dirname)
         return (void *)p_dir;
     }
 
+    assert (wpath[0]); // wpath[1] is defined
+    p_dir->u.insert_dot_dot = !wcscmp (wpath + 1, L":\\");
+
     _WDIR *wdir = _wopendir (wpath);
+    free (wpath);
     if (wdir == NULL)
     {
         free (p_dir);
         return NULL;
     }
-
     p_dir->wdir = wdir;
-    assert (wpath[0]); // wpath[1] is defined
-    p_dir->u.insert_dot_dot = !wcscmp (wpath + 1, L":\\");
     return (void *)p_dir;
 }
 
@@ -212,8 +231,13 @@ int vlc_stat (const char *filename, struct stat *buf)
     /* _stat translates to wchar internally on WinCE */
     return _stat (filename, buf);
 #else
-    CONVERT_PATH (filename, wpath, -1);
-    return _wstati64 (wpath, buf);
+    wchar_t *wpath = widen_path (filename);
+    if (wpath == NULL)
+        return -1;
+
+    int ret = _wstati64 (wpath, buf);
+    free (wpath);
+    return ret;
 #endif
 }
 
@@ -228,31 +252,45 @@ int vlc_unlink (const char *filename)
     /*_open translates to wchar internally on WinCE*/
     return _unlink( filename );
 #else
-    CONVERT_PATH (filename, wpath, -1);
-    return _wunlink (wpath);
+    wchar_t *wpath = widen_path (filename);
+    if (wpath == NULL)
+        return -1;
+
+    int ret = _wunlink (wpath);
+    free (wpath);
+    return ret;
 #endif
 }
 
 int vlc_rename (const char *oldpath, const char *newpath)
 {
-    CONVERT_PATH (oldpath, wold, -1);
-    CONVERT_PATH (newpath, wnew, -1);
+    int ret = -1;
+
+    wchar_t *wold = widen_path (oldpath), *wnew = widen_path (newpath);
+    if (wold == NULL || wnew == NULL)
+        goto out;
+
 # ifdef UNDER_CE
     /* FIXME: errno support */
-    return MoveFileW (wold, wnew) ? 0 : -1;
+    if (MoveFileW (wold, wnew))
+        ret = 0;
 #else
     if (_wrename (wold, wnew) && (errno == EACCES || errno == EEXIST))
     {   /* Windows does not allow atomic file replacement */
         if (_wremove (wnew))
         {
             errno = EACCES; /* restore errno */
-            return -1;
+            goto out;
         }
         if (_wrename (wold, wnew))
-            return -1;
+            goto out;
     }
-    return 0;
+    ret = 0;
 #endif
+out:
+    free (wnew);
+    free (wold);
+    return ret;
 }
 
 int vlc_dup (int oldfd)
diff --git a/src/win32/plugin.c b/src/win32/plugin.c
index 445dc66..0d59205 100644
--- a/src/win32/plugin.c
+++ b/src/win32/plugin.c
@@ -53,23 +53,23 @@ static char *GetWindowsError( void )
 int module_Load( vlc_object_t *p_this, const char *psz_file,
                  module_handle_t *p_handle, bool lazy )
 {
-    module_handle_t handle;
-
-    wchar_t psz_wfile[MAX_PATH];
-    MultiByteToWideChar( CP_UTF8, 0, psz_file, -1, psz_wfile, MAX_PATH );
+    wchar_t *wfile = ToWide (psz_file);
+    if (wfile == NULL)
+        return -1;
 
-    (void) lazy;
+    module_handle_t handle;
 #ifndef UNDER_CE
     /* FIXME: this is not thread-safe -- Courmisch */
     UINT mode = SetErrorMode (SEM_FAILCRITICALERRORS);
     SetErrorMode (mode|SEM_FAILCRITICALERRORS);
 #endif
 
-    handle = LoadLibraryW( psz_wfile );
+    handle = LoadLibraryW (wfile);
 
 #ifndef UNDER_CE
     SetErrorMode (mode);
 #endif
+    free (wfile);
 
     if( handle == NULL )
     {
@@ -80,6 +80,7 @@ int module_Load( vlc_object_t *p_this, const char *psz_file,
     }
 
     *p_handle = handle;
+    (void) lazy;
     return 0;
 }
 



More information about the vlc-commits mailing list