+ 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;
+ p_dir->i_drives = GetLogicalDrives();
+ 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;
+ unsigned int i;
+ 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;
+ 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);
+ 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 );