4 * Derived from DIRLIB.C by Matt J. Weinstein
5 * This note appears in the DIRLIB.H
6 * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
8 * Updated by Jeremy Bettis <jeremy@hksys.com>
9 * Significantly revised and rewinddir, seekdir and telldir added by Colin
10 * Peters <colin@fu.is.saga-u.ac.jp>
14 * $Date: 2002/11/13 20:51:04 $
29 # define FILENAME_MAX (260)
32 #define WIN32_LEAN_AND_MEAN
33 #include <windows.h> /* for GetFileAttributes */
41 long d_ino
; /* Always zero. */
42 unsigned short d_reclen
; /* Always zero. */
43 unsigned short d_namlen
; /* Length of name in d_name. */
44 char d_name
[FILENAME_MAX
]; /* File name. */
49 /* disk transfer area for this dir */
50 WIN32_FIND_DATA dd_dta
;
52 /* dirent struct to return from dir (NOTE: this makes this thread
53 * safe as long as only one thread uses a particular DIR struct at
62 * 0 = not started yet (next entry to read is first entry)
64 * positive = 0 based index of next entry
68 /* given path for dir with search pattern (struct is extended) */
75 * Returns a pointer to a DIR structure appropriately filled in to begin
76 * searching a directory.
79 vlc_opendir (const CHAR
*szPath
)
83 CHAR szFullPath
[MAX_PATH
];
93 if (szPath
[0] == '\0')
99 /* Attempt to determine if the given path really is a directory. */
102 wchar_t szPathTmp
[MAX_PATH
];
103 mbstowcs( szPathTmp
, szPath
, MAX_PATH
);
104 szPathTmp
[MAX_PATH
-1] = 0;
105 rc
= GetFileAttributes (szPathTmp
);
108 rc
= GetFileAttributes (szPath
);
110 if (rc
== (unsigned int)-1)
112 /* call GetLastError for more error info */
116 if (!(rc
& FILE_ATTRIBUTE_DIRECTORY
))
118 /* Error, entry exists but not a directory. */
123 /* Make an absolute pathname. */
124 #if defined( UNDER_CE )
125 if (szPath
[0] == '\\' || szPath
[0] == '/')
127 sprintf (szFullPath
, "%s", szPath
);
128 szFullPath
[0] = '\\';
132 wchar_t szFullPathTmp
[MAX_PATH
];
133 if (GetModuleFileName( NULL
, szFullPathTmp
, MAX_PATH
) )
135 wcstombs( szFullPath
, szFullPathTmp
, MAX_PATH
);
136 szFullPath
[MAX_PATH
-1] = 0;
140 /* FIXME: if I wasn't lazy, I'd check for overflows here. */
141 sprintf (szFullPath
, "\\%s", szPath
);
145 _fullpath (szFullPath
, szPath
, MAX_PATH
);
148 /* Allocate enough space to store DIR structure and the complete
149 * directory path given. */
150 nd
= (DIR *) malloc (sizeof (DIR) + strlen (szFullPath
) + sizeof (SLASH
) +
155 /* Error, out of memory. */
160 /* Create the search expression. */
161 strcpy (nd
->dd_name
, szFullPath
);
163 /* Add on a slash if the path does not end with one. */
164 if (nd
->dd_name
[0] != '\0' &&
165 nd
->dd_name
[strlen (nd
->dd_name
) - 1] != '/' &&
166 nd
->dd_name
[strlen (nd
->dd_name
) - 1] != '\\')
168 strcat (nd
->dd_name
, SLASH
);
171 /* Add on the search pattern */
172 strcat (nd
->dd_name
, SUFFIX
);
174 /* Initialize handle so that a premature closedir doesn't try
175 * to call FindClose on it. */
176 nd
->dd_handle
= INVALID_HANDLE_VALUE
;
178 /* Initialize the status. */
181 /* Initialize the dirent structure. ino and reclen are invalid under
182 * Win32, and name simply points at the appropriate part of the
183 * findfirst_t structure. */
184 nd
->dd_dir
.d_ino
= 0;
185 nd
->dd_dir
.d_reclen
= 0;
186 nd
->dd_dir
.d_namlen
= 0;
187 memset (nd
->dd_dir
.d_name
, 0, FILENAME_MAX
);
196 * Return a pointer to a dirent structure filled with the information on the
197 * next entry in the directory.
200 vlc_readdir (DIR * dirp
)
204 /* Check for valid DIR struct. */
208 return (struct dirent
*) 0;
211 if (dirp
->dd_stat
< 0)
213 /* We have already returned all files in the directory
214 * (or the structure has an invalid dd_stat). */
215 return (struct dirent
*) 0;
217 else if (dirp
->dd_stat
== 0)
220 wchar_t dd_name
[MAX_PATH
];
221 mbstowcs( dd_name
, dirp
->dd_name
, MAX_PATH
);
222 dd_name
[MAX_PATH
-1] = 0;
224 char *dd_name
= dirp
->dd_name
;
226 /* We haven't started the search yet. */
227 /* Start the search */
228 dirp
->dd_handle
= FindFirstFile (dd_name
, &(dirp
->dd_dta
));
230 if (dirp
->dd_handle
== INVALID_HANDLE_VALUE
)
232 /* Whoops! Seems there are no files in that
243 /* Get the next search entry. */
244 if (!FindNextFile ((HANDLE
)dirp
->dd_handle
, &(dirp
->dd_dta
)))
246 /* We are off the end or otherwise error. */
247 FindClose ((HANDLE
)dirp
->dd_handle
);
248 dirp
->dd_handle
= INVALID_HANDLE_VALUE
;
253 /* Update the status to indicate the correct
259 if (dirp
->dd_stat
> 0)
261 /* Successfully got an entry */
264 char d_name
[MAX_PATH
];
265 wcstombs( d_name
, dirp
->dd_dta
.cFileName
, MAX_PATH
);
266 d_name
[MAX_PATH
-1] = 0;
268 char *d_name
= dirp
->dd_dta
.cFileName
;
271 strcpy (dirp
->dd_dir
.d_name
, d_name
);
272 dirp
->dd_dir
.d_namlen
= strlen (dirp
->dd_dir
.d_name
);
273 return &dirp
->dd_dir
;
276 return (struct dirent
*) 0;
283 * Frees up resources allocated by opendir.
286 vlc_closedir (DIR * dirp
)
299 if (dirp
->dd_handle
!= INVALID_HANDLE_VALUE
)
301 rc
= FindClose ((HANDLE
)dirp
->dd_handle
);
304 /* Delete the dir structure. */
313 * Return to the beginning of the directory "stream". We simply call findclose
314 * and then reset things like an opendir.
317 vlc_rewinddir (DIR * dirp
)
327 if (dirp
->dd_handle
!= INVALID_HANDLE_VALUE
)
329 FindClose ((HANDLE
)dirp
->dd_handle
);
332 dirp
->dd_handle
= INVALID_HANDLE_VALUE
;