Commit 44d1c20e authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont
Browse files

Win32: expand, simplify and (hopefully) fix vlc_w*dir() functions

parent 485d0ebd
......@@ -57,127 +57,8 @@
#if defined(WIN32) || defined(UNDER_CE)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <dirent.h>
#endif
/*****************************************************************************
* vlc_*dir_wrapper: wrapper under Windows to return the list of drive letters
* when called with an empty argument or just '\'
*****************************************************************************/
#if defined(WIN32)
# include <assert.h>
typedef struct vlc_DIR
{
_WDIR *p_real_dir;
int i_drives;
struct _wdirent dd_dir;
bool b_insert_back;
} vlc_DIR;
void *vlc_wopendir( const wchar_t *wpath )
{
vlc_DIR *p_dir = NULL;
_WDIR *p_real_dir = NULL;
if ( wpath == NULL || wpath[0] == '\0'
|| (wcscmp (wpath, L"\\") == 0) )
{
/* Special mode to list drive letters */
p_dir = malloc( sizeof(vlc_DIR) );
if( !p_dir )
return NULL;
p_dir->p_real_dir = NULL;
#if defined(UNDER_CE)
p_dir->i_drives = NULL;
#else
p_dir->i_drives = GetLogicalDrives();
#endif
return (void *)p_dir;
}
p_real_dir = _wopendir( wpath );
if ( p_real_dir == NULL )
return NULL;
p_dir = malloc( sizeof(vlc_DIR) );
if( !p_dir )
{
_wclosedir( p_real_dir );
return NULL;
}
p_dir->p_real_dir = p_real_dir;
assert (wpath[0]); // wpath[1] is defined
p_dir->b_insert_back = !wcscmp (wpath + 1, L":\\");
return (void *)p_dir;
}
struct _wdirent *vlc_wreaddir( void *_p_dir )
{
vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
DWORD i_drives;
if ( p_dir->p_real_dir != NULL )
{
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;
wcscpy( p_dir->dd_dir.d_name, L".." );
p_dir->b_insert_back = false;
return &p_dir->dd_dir;
}
return _wreaddir( p_dir->p_real_dir );
}
/* Drive letters mode */
i_drives = p_dir->i_drives;
#ifdef UNDER_CE
swprintf( p_dir->dd_dir.d_name, L"\\");
p_dir->dd_dir.d_namlen = wcslen(p_dir->dd_dir.d_name);
#else
unsigned int i;
if ( !i_drives )
return NULL; /* end */
for ( i = 0; i < sizeof(DWORD)*8; i++, i_drives >>= 1 )
if ( i_drives & 1 ) break;
if ( i >= 26 )
return NULL; /* this should not happen */
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);
#endif
return &p_dir->dd_dir;
}
void vlc_rewinddir( void *_p_dir )
{
vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
if ( p_dir->p_real_dir != NULL )
_wrewinddir( p_dir->p_real_dir );
}
/* This one is in the libvlccore exported symbol list */
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 )
i_ret = _wclosedir( p_dir->p_real_dir );
free( p_dir );
return i_ret;
}
#endif
#ifdef ENABLE_NLS
......
......@@ -319,19 +319,4 @@ VLC_EXPORT( void, stats_ComputeInputStats, (input_thread_t*, input_stats_t*) );
VLC_EXPORT( void, stats_ReinitInputStats, (input_stats_t *) );
VLC_EXPORT( void, stats_DumpInputStats, (input_stats_t *) );
/*
* Replacement functions
*/
#if defined (WIN32)
# include <dirent.h>
void *vlc_wopendir (const wchar_t *);
void *vlc_wclosedir (void *);
struct _wdirent *vlc_wreaddir (void *);
void vlc_rewinddir (void *);
# define _wopendir vlc_wopendir
# define _wreaddir vlc_wreaddir
# define _wclosedir vlc_wclosedir
# define rewinddir vlc_rewinddir
#endif
#endif
......@@ -108,21 +108,120 @@ int vlc_mkdir( const char *dirname, mode_t mode )
#endif
}
DIR *vlc_opendir( const char *dirname )
/* Under Windows, these wrappers return the list of drive letters
* when called with an empty argument or just '\'. */
typedef struct vlc_DIR
{
_WDIR *p_real_dir;
int i_drives;
bool b_insert_back;
} vlc_DIR;
DIR *vlc_opendir (const char *dirname)
{
CONVERT_PATH (dirname, wpath, NULL);
return (DIR *)vlc_wopendir (wpath);
vlc_DIR *p_dir = malloc (sizeof (*p_dir));
if (unlikely(p_dir == NULL))
return NULL;
if (wpath == NULL || wpath[0] == '\0'
|| (wcscmp (wpath, L"\\") == 0))
{
/* Special mode to list drive letters */
p_dir->p_real_dir = NULL;
#ifdef UNDER_CE
p_dir->i_drives = 1;
#else
p_dir->i_drives = GetLogicalDrives ();
#endif
return (void *)p_dir;
}
_WDIR *p_real_dir = _wopendir (wpath);
if (p_real_dir == NULL)
{
free (p_dir);
return NULL;
}
p_dir->p_real_dir = p_real_dir;
assert (wpath[0]); // wpath[1] is defined
p_dir->b_insert_back = !wcscmp (wpath + 1, L":\\");
return (void *)p_dir;
}
char *vlc_readdir( DIR *dir )
char *vlc_readdir (DIR *dir)
{
struct _wdirent *ent = vlc_wreaddir (dir);
vlc_DIR *p_dir = (vlc_DIR *)dir;
if (p_dir->p_real_dir == NULL)
{
/* Drive letters mode */
DWORD drives = p_dir->i_drives;
if (drives == 0)
return NULL; /* end */
#ifdef UNDER_CE
p_dir->i_drives = 0;
return strdup ("\\");
#else
unsigned int i;
for (i = 0; !(drives & 1); i++)
drives >>= 1;
p_dir->i_drives &= ~(1UL << i);
assert (i < 26);
char *ret;
if (asprintf (&ret, "%c:\\", 'A' + i) == -1)
return NULL;
return ret;
#endif
}
if (p_dir->b_insert_back)
{
/* Adds "..", gruik! */
p_dir->b_insert_back = false;
return strdup ("..");
}
struct _wdirent *ent = _wreaddir (p_dir->p_real_dir);
if (ent == NULL)
return NULL;
return FromWide (ent->d_name);
}
#if 0
void vlc_rewinddir (DIR *dir)
{
vlc_DIR *p_dir = (DIR *)dir;
if (p_dir->p_real_dir == NULL)
p_dir->i_drives = GetLogicalDrives ();
else
_wrewinddir (p_dir->p_real_dir);
}
#endif
/* FIXME XXX TODO: needs to replace closedir() with this!!! */
#warning THIS REALLY NEEDS FIXING!!!
int vlc_wclosedir (DIR *dir)
{
vlc_DIR *p_dir = (vlc_DIR *)dir;
int ret;
if (p_dir->p_real_dir == NULL)
ret = 0;
else
ret = _wclosedir (p_dir->p_real_dir);
free (p_dir);
return ret;
}
int vlc_stat (const char *filename, struct stat *buf)
{
#ifdef UNDER_CE
......
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