Commit 2f680550 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Attempt to use wide directory indexing on Win32

Might break stuff, but I cannot test much because of DBus vs Win32 breakage(!)
parent 63883f0c
......@@ -37,7 +37,7 @@ VLC_EXPORT( char *, ToLocale, ( const char * ) );
VLC_EXPORT( int, utf8_open, ( const char *filename, int flags, mode_t mode ) );
VLC_EXPORT( FILE *, utf8_fopen, ( const char *filename, const char *mode ) );
VLC_EXPORT( DIR *, utf8_opendir, ( const char *dirname ) );
VLC_EXPORT( char *, utf8_readdir, ( void *dir ) );
VLC_EXPORT( char *, utf8_readdir, ( DIR *dir ) );
VLC_EXPORT( int, utf8_scandir, ( const char *dirname, char ***namelist, int (*select)( const char * ), int (*compar)( const char **, const char ** ) ) );
#ifdef WIN32
......
......@@ -969,9 +969,18 @@ static inline void _SetQWBE( uint8_t *p, uint64_t i_qw )
# endif
#endif
VLC_INTERNAL( void *, vlc_opendir_wrapper, ( const char * ) );
VLC_INTERNAL( struct dirent *, vlc_readdir_wrapper, ( void * ) );
VLC_INTERNAL( int, vlc_closedir_wrapper, ( void * ) );
#if defined (WIN32)
# include <dirent.h>
VLC_INTERNAL( void *, vlc_wopendir, ( const wchar_t * ) );
VLC_INTERNAL( struct _wdirent *, vlc_wreaddir, ( void * ) );
VLC_INTERNAL( int, vlc_wclosedir, ( void * ) );
# define opendir Use_utf8_opendir_or_vlc_wopendir_instead!
# define readdir Use_utf8_readdir_or_vlc_wreaddir_instead!
# define closedir vlc_wclosedir
# define _wopendir vlc_wopendir
# define _wreaddir vlc_wreaddir
# define _wclosedir vlc_wclosedir
#endif
/* Format type specifiers for 64 bits numbers */
#if defined(__CYGWIN32__) || (!defined(WIN32) && !defined(UNDER_CE))
......
......@@ -468,7 +468,7 @@ struct module_symbols_t
void *vlc_HashRetrieve_deprecated;
DIR * (*utf8_opendir_inner) (const char *dirname);
FILE * (*utf8_fopen_inner) (const char *filename, const char *mode);
char * (*utf8_readdir_inner) (void *dir);
char * (*utf8_readdir_inner) (DIR *dir);
int (*utf8_stat_inner) (const char *filename, struct stat *buf);
int (*utf8_lstat_inner) (const char *filename, struct stat *buf);
char * (*FromLocaleDup_inner) (const char *);
......
......@@ -393,21 +393,23 @@ extern size_t vlc_strlcpy (char *tgt, const char *src, size_t bufsize)
* when called with an empty argument or just '\'
*****************************************************************************/
#if defined(WIN32) && !defined(UNDER_CE)
# include <assert.h>
typedef struct vlc_DIR
{
DIR *p_real_dir;
_WDIR *p_real_dir;
int i_drives;
struct dirent dd_dir;
struct _wdirent dd_dir;
vlc_bool_t b_insert_back;
} vlc_DIR;
void *vlc_opendir_wrapper( const char *psz_path )
void *vlc_wopendir( const wchar_t *wpath )
{
vlc_DIR *p_dir;
DIR *p_real_dir;
_WDIR *p_real_dir;
if ( psz_path == NULL || psz_path[0] == '\0'
|| (psz_path[0] == '\\' && psz_path[1] == '\0') )
if ( wpath == NULL || wpath[0] == '\0'
|| (wcscmp (wpath, L"\\") == 0) )
{
/* Special mode to list drive letters */
p_dir = malloc( sizeof(vlc_DIR) );
......@@ -416,18 +418,19 @@ void *vlc_opendir_wrapper( const char *psz_path )
return (void *)p_dir;
}
p_real_dir = opendir( psz_path );
p_real_dir = _wopendir( wpath );
if ( p_real_dir == NULL )
return NULL;
p_dir = malloc( sizeof(vlc_DIR) );
p_dir->p_real_dir = p_real_dir;
p_dir->b_insert_back = ( psz_path[1] == ':' && psz_path[2] == '\\'
&& psz_path[3] =='\0' );
assert (wpath[0]); // wpath[1] is defined
p_dir->b_insert_back = !wcscmp (wpath + 1, L":\\");
return (void *)p_dir;
}
struct dirent *vlc_readdir_wrapper( void *_p_dir )
struct _wdirent *vlc_wreaddir( void *_p_dir )
{
vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
unsigned int i;
......@@ -437,15 +440,16 @@ struct dirent *vlc_readdir_wrapper( void *_p_dir )
{
if ( p_dir->b_insert_back )
{
/* Adds "..", gruik! */
p_dir->dd_dir.d_ino = 0;
p_dir->dd_dir.d_reclen = 0;
p_dir->dd_dir.d_namlen = 2;
strcpy( p_dir->dd_dir.d_name, ".." );
wcscpy( p_dir->dd_dir.d_name, L".." );
p_dir->b_insert_back = VLC_FALSE;
return &p_dir->dd_dir;
}
return readdir( p_dir->p_real_dir );
return _wreaddir( p_dir->p_real_dir );
}
/* Drive letters mode */
......@@ -459,38 +463,22 @@ struct dirent *vlc_readdir_wrapper( void *_p_dir )
if ( i >= 26 )
return NULL; /* this should not happen */
sprintf( p_dir->dd_dir.d_name, "%c:\\", 'A' + i );
p_dir->dd_dir.d_namlen = strlen(p_dir->dd_dir.d_name);
swprintf( p_dir->dd_dir.d_name, L"%c:\\", 'A' + i );
p_dir->dd_dir.d_namlen = wcslen(p_dir->dd_dir.d_name);
p_dir->i_drives &= ~(1UL << i);
return &p_dir->dd_dir;
}
int vlc_closedir_wrapper( void *_p_dir )
int vlc_wclosedir( void *_p_dir )
{
vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
int i_ret = 0;
if ( p_dir->p_real_dir != NULL )
{
int i_ret = closedir( p_dir->p_real_dir );
free( p_dir );
return i_ret;
}
i_ret = _wclosedir( p_dir->p_real_dir );
free( p_dir );
return 0;
}
#else
void *vlc_opendir_wrapper( const char *psz_path )
{
return (void *)opendir( psz_path );
}
struct dirent *vlc_readdir_wrapper( void *_p_dir )
{
return readdir( (DIR *)_p_dir );
}
int vlc_closedir_wrapper( void *_p_dir )
{
return closedir( (DIR *)_p_dir );
return i_ret;
}
#endif
......@@ -498,6 +486,12 @@ int vlc_closedir_wrapper( void *_p_dir )
* scandir: scan a directory alpha-sorted
*****************************************************************************/
#if !defined( HAVE_SCANDIR )
/* FIXME: I suspect this is dead code -> utf8_scandir */
#ifdef WIN32
# undef opendir
# undef readdir
# undef closedir
#endif
int vlc_alphasort( const struct dirent **a, const struct dirent **b )
{
return strcoll( (*a)->d_name, (*b)->d_name );
......@@ -513,11 +507,11 @@ int vlc_scandir( const char *name, struct dirent ***namelist,
struct dirent ** pp_list;
int ret, size;
if( !namelist || !( p_dir = vlc_opendir_wrapper( name ) ) ) return -1;
if( !namelist || !( p_dir = opendir( name ) ) ) return -1;
ret = 0;
pp_list = NULL;
while( ( p_content = vlc_readdir_wrapper( p_dir ) ) )
while( ( p_content = readdir( p_dir ) ) )
{
if( filter && !filter( p_content ) )
{
......@@ -530,7 +524,7 @@ int vlc_scandir( const char *name, struct dirent ***namelist,
ret++;
}
vlc_closedir_wrapper( p_dir );
closedir( p_dir );
if( compar )
{
......
......@@ -810,6 +810,12 @@ static void AllocateAllPlugins( vlc_object_t *p_this )
static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir,
int i_maxdepth )
{
/* FIXME: Needs to be ported to wide char on ALL Windows builds */
#ifdef WIN32
# undef opendir
# undef closedir
# undef readdir
#endif
#if defined( UNDER_CE ) || defined( _MSC_VER )
#ifdef UNDER_CE
wchar_t psz_wpath[MAX_PATH + 256];
......
......@@ -429,7 +429,15 @@ int utf8_mkdir( const char *dirname )
DIR *utf8_opendir( const char *dirname )
{
/* TODO: support for WinNT non-ACP filenames */
#ifdef WIN32
wchar_t wname[MAX_PATH + 1];
if (MultiByteToWideChar (CP_UTF8, 0, dirname, -1, wname, MAX_PATH))
{
wname[MAX_PATH] = L'\0';
return (DIR *)vlc_wopendir (wname);
}
#else
const char *local_name = ToLocale( dirname );
if( local_name != NULL )
......@@ -438,14 +446,22 @@ DIR *utf8_opendir( const char *dirname )
LocaleFree( local_name );
return dir;
}
else
#endif
errno = ENOENT;
return NULL;
}
char *utf8_readdir( void *dir )
char *utf8_readdir( DIR *dir )
{
#ifdef WIN32
struct _wdirent *ent = vlc_wreaddir (dir);
if (ent == NULL)
return NULL;
return FromWide (ent->d_name);
#else
struct dirent *ent;
ent = readdir( (DIR *)dir );
......@@ -453,6 +469,7 @@ char *utf8_readdir( void *dir )
return NULL;
return vlc_fix_readdir( ent->d_name );
#endif
}
static int dummy_select( const char *str )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment