/*
* dirent.c
*
- * Derived from DIRLIB.C by Matt J. Weinstein
+ * Derived from DIRLIB.C by Matt J. Weinstein
* This note appears in the DIRLIB.H
* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
*
* Updated by Jeremy Bettis <jeremy@hksys.com>
* Significantly revised and rewinddir, seekdir and telldir added by Colin
* Peters <colin@fu.is.saga-u.ac.jp>
- *
- * $Revision: 1.2 $
+ *
+ * $Revision: 1.6 $
* $Author: sam $
- * $Date: 2002/11/09 17:44:09 $
+ * $Date: 2002/11/13 20:51:04 $
*
*/
+#include "config.h"
+
#include <stdlib.h>
+#include <stdio.h>
+
#include <errno.h>
#include <string.h>
-#include <io.h>
-#include <direct.h>
-#include "dirent.h"
+#ifndef UNDER_CE
+# include <io.h>
+# include <direct.h>
+#else
+# define FILENAME_MAX (260)
+#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h> /* for GetFileAttributes */
-#define SUFFIX "*"
-#define SLASH "\\"
+#include <tchar.h>
+#define SUFFIX "*"
+#define SLASH "\\"
+
+struct dirent
+{
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ char d_name[FILENAME_MAX]; /* File name. */
+};
+
+typedef struct
+{
+ /* disk transfer area for this dir */
+ WIN32_FIND_DATA dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct dirent dd_dir;
+
+ /* findnext handle */
+ HANDLE dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ int dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ char dd_name[1];
+} DIR;
/*
* opendir
* Returns a pointer to a DIR structure appropriately filled in to begin
* searching a directory.
*/
-DIR *
-opendir (const CHAR *szPath)
+DIR *
+vlc_opendir (const CHAR *szPath)
{
DIR *nd;
unsigned int rc;
CHAR szFullPath[MAX_PATH];
-
+
errno = 0;
if (!szPath)
}
/* Attempt to determine if the given path really is a directory. */
+#ifdef UNICODE
+ {
+ wchar_t szPathTmp[MAX_PATH];
+ mbstowcs( szPathTmp, szPath, MAX_PATH );
+ szPathTmp[MAX_PATH-1] = 0;
+ rc = GetFileAttributes (szPathTmp);
+ }
+#else
rc = GetFileAttributes (szPath);
- if (rc == -1)
+#endif
+ if (rc == (unsigned int)-1)
{
/* call GetLastError for more error info */
errno = ENOENT;
}
/* Make an absolute pathname. */
+#if defined( UNDER_CE )
+ if (szPath[0] == '\\' || szPath[0] == '/')
+ {
+ sprintf (szFullPath, "%s", szPath);
+ szFullPath[0] = '\\';
+ }
+ else
+ {
+ wchar_t szFullPathTmp[MAX_PATH];
+ if (GetModuleFileName( NULL, szFullPathTmp, MAX_PATH ) )
+ {
+ wcstombs( szFullPath, szFullPathTmp, MAX_PATH );
+ szFullPath[MAX_PATH-1] = 0;
+ }
+ else
+ {
+ /* FIXME: if I wasn't lazy, I'd check for overflows here. */
+ sprintf (szFullPath, "\\%s", szPath );
+ }
+ }
+#else
_fullpath (szFullPath, szPath, MAX_PATH);
+#endif
/* Allocate enough space to store DIR structure and the complete
* directory path given. */
- nd = (DIR *) malloc (sizeof (DIR) + strlen (szFullPath) + strlen (SLASH) +
- strlen (SUFFIX));
+ nd = (DIR *) malloc (sizeof (DIR) + strlen (szFullPath) + sizeof (SLASH) +
+ sizeof (SUFFIX));
if (!nd)
{
/* Add on the search pattern */
strcat (nd->dd_name, SUFFIX);
- /* Initialize handle to -1 so that a premature closedir doesn't try
- * to call _findclose on it. */
- nd->dd_handle = -1;
+ /* Initialize handle so that a premature closedir doesn't try
+ * to call FindClose on it. */
+ nd->dd_handle = INVALID_HANDLE_VALUE;
/* Initialize the status. */
nd->dd_stat = 0;
nd->dd_dir.d_ino = 0;
nd->dd_dir.d_reclen = 0;
nd->dd_dir.d_namlen = 0;
- nd->dd_dir.d_name = nd->dd_dta.name;
+ memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
return nd;
}
* next entry in the directory.
*/
struct dirent *
-readdir (DIR * dirp)
+vlc_readdir (DIR * dirp)
{
errno = 0;
return (struct dirent *) 0;
}
- if (dirp->dd_dir.d_name != dirp->dd_dta.name)
- {
- /* The structure does not seem to be set up correctly. */
- errno = EINVAL;
- return (struct dirent *) 0;
- }
-
if (dirp->dd_stat < 0)
{
/* We have already returned all files in the directory
}
else if (dirp->dd_stat == 0)
{
+#ifdef UNICODE
+ wchar_t dd_name[MAX_PATH];
+ mbstowcs( dd_name, dirp->dd_name, MAX_PATH );
+ dd_name[MAX_PATH-1] = 0;
+#else
+ char *dd_name = dirp->dd_name;
+#endif
/* We haven't started the search yet. */
/* Start the search */
- dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
-
- if (dirp->dd_handle == -1)
- {
- /* Whoops! Seems there are no files in that
- * directory. */
- dirp->dd_stat = -1;
- }
+ dirp->dd_handle = FindFirstFile (dd_name, &(dirp->dd_dta));
+
+ if (dirp->dd_handle == INVALID_HANDLE_VALUE)
+ {
+ /* Whoops! Seems there are no files in that
+ * directory. */
+ dirp->dd_stat = -1;
+ }
else
- {
- dirp->dd_stat = 1;
- }
+ {
+ dirp->dd_stat = 1;
+ }
}
else
{
/* Get the next search entry. */
- if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
- {
- /* We are off the end or otherwise error. */
- _findclose (dirp->dd_handle);
- dirp->dd_handle = -1;
- dirp->dd_stat = -1;
- }
+ if (!FindNextFile ((HANDLE)dirp->dd_handle, &(dirp->dd_dta)))
+ {
+ /* We are off the end or otherwise error. */
+ FindClose ((HANDLE)dirp->dd_handle);
+ dirp->dd_handle = INVALID_HANDLE_VALUE;
+ dirp->dd_stat = -1;
+ }
else
- {
- /* Update the status to indicate the correct
- * number. */
- dirp->dd_stat++;
- }
+ {
+ /* Update the status to indicate the correct
+ * number. */
+ dirp->dd_stat++;
+ }
}
if (dirp->dd_stat > 0)
{
- /* Successfully got an entry. Everything about the file is
- * already appropriately filled in except the length of the
- * file name. */
+ /* Successfully got an entry */
+
+#ifdef UNICODE
+ char d_name[MAX_PATH];
+ wcstombs( d_name, dirp->dd_dta.cFileName, MAX_PATH );
+ d_name[MAX_PATH-1] = 0;
+#else
+ char *d_name = dirp->dd_dta.cFileName;
+#endif
+
+ strcpy (dirp->dd_dir.d_name, d_name);
dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
return &dirp->dd_dir;
}
* Frees up resources allocated by opendir.
*/
int
-closedir (DIR * dirp)
+vlc_closedir (DIR * dirp)
{
int rc;
return -1;
}
- if (dirp->dd_handle != -1)
+ if (dirp->dd_handle != INVALID_HANDLE_VALUE)
{
- rc = _findclose (dirp->dd_handle);
+ rc = FindClose ((HANDLE)dirp->dd_handle);
}
/* Delete the dir structure. */
* and then reset things like an opendir.
*/
void
-rewinddir (DIR * dirp)
+vlc_rewinddir (DIR * dirp)
{
errno = 0;
return;
}
- if (dirp->dd_handle != -1)
+ if (dirp->dd_handle != INVALID_HANDLE_VALUE)
{
- _findclose (dirp->dd_handle);
+ FindClose ((HANDLE)dirp->dd_handle);
}
- dirp->dd_handle = -1;
+ dirp->dd_handle = INVALID_HANDLE_VALUE;
dirp->dd_stat = 0;
}
-
-/*
- * telldir
- *
- * Returns the "position" in the "directory stream" which can be used with
- * seekdir to go back to an old entry. We simply return the value in stat.
- */
-long
-telldir (DIR * dirp)
-{
- errno = 0;
-
- if (!dirp)
- {
- errno = EFAULT;
- return -1;
- }
- return dirp->dd_stat;
-}
-
-/*
- * seekdir
- *
- * Seek to an entry previously returned by telldir. We rewind the directory
- * and call readdir repeatedly until either dd_stat is the position number
- * or -1 (off the end). This is not perfect, in that the directory may
- * have changed while we weren't looking. But that is probably the case with
- * any such system.
- */
-void
-seekdir (DIR * dirp, long lPos)
-{
- errno = 0;
-
- if (!dirp)
- {
- errno = EFAULT;
- return;
- }
-
- if (lPos < -1)
- {
- /* Seeking to an invalid position. */
- errno = EINVAL;
- return;
- }
- else if (lPos == -1)
- {
- /* Seek past end. */
- if (dirp->dd_handle != -1)
- {
- _findclose (dirp->dd_handle);
- }
- dirp->dd_handle = -1;
- dirp->dd_stat = -1;
- }
- else
- {
- /* Rewind and read forward to the appropriate index. */
- rewinddir (dirp);
-
- while ((dirp->dd_stat < lPos) && readdir (dirp))
- ;
- }
-}