Skip to content

Commit 1158fba

Browse files
committed
Merge pull request #424 from prife/master
dfs_win32: add seekdir support, fix #346
2 parents 0f9139e + c6f88ef commit 1158fba

File tree

1 file changed

+82
-65
lines changed

1 file changed

+82
-65
lines changed

bsp/simulator/drivers/dfs_win32.c

+82-65
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@
5050

5151
#define WIN32_DIRDISK_ROOT "." /* "F:\\Project\\svn\\rtt\\trunk\\bsp\\simulator_test" */
5252

53+
typedef struct {
54+
HANDLE handle;
55+
char *start;
56+
char *end;
57+
char *curr;
58+
struct _finddata_t finddata;
59+
} WINDIR;
60+
5361
/* There are so many error codes in windows, you'd better google for details.
5462
* google "System Error Codes (Windows)"
5563
* http://msdn.microsoft.com/ZH-CN/library/windows/desktop/ms681381(v=vs.85).aspx
@@ -166,8 +174,8 @@ static int dfs_win32_open(struct dfs_fd *file)
166174
oflag = file->flags;
167175
if (oflag & DFS_O_DIRECTORY) /* operations about dir */
168176
{
169-
struct _finddata_t dir;
170-
int handle;
177+
WINDIR *wdirp;
178+
HANDLE handle;
171179
int len;
172180

173181
file_path = winpath_dirdup(WIN32_DIRDISK_ROOT, file->path);
@@ -191,14 +199,24 @@ static int dfs_win32_open(struct dfs_fd *file)
191199

192200
strcat(file_path, "*.*");
193201
/* _findfirst will get '.' */
194-
if ((handle = _findfirst(file_path, &dir)) == -1)
202+
/* save this pointer,will used by dfs_win32_getdents*/
203+
wdirp = rt_malloc(sizeof(WINDIR));
204+
RT_ASSERT(wdirp != NULL);
205+
if ((handle = _findfirst(file_path, &wdirp->finddata)) == -1)
195206
{
207+
rt_free(wdirp);
196208
rt_free(file_path);
197209
goto __err;
198210
}
199-
200-
/* save this pointer,will used by dfs_win32_getdents*/
201-
file->data = (void *)handle;
211+
len = strlen(wdirp->finddata.name) + 1;
212+
wdirp->handle = handle;
213+
//wdirp->nfiles = 1;
214+
wdirp->start = malloc(len); //not rt_malloc!
215+
wdirp->end = wdirp->curr = wdirp->start;
216+
wdirp->end += len;
217+
strncpy(wdirp->curr, wdirp->finddata.name, len);
218+
219+
file->data = (void *)wdirp;
202220
rt_free(file_path);
203221
return DFS_STATUS_OK;
204222
}
@@ -243,25 +261,22 @@ static int dfs_win32_open(struct dfs_fd *file)
243261

244262
static int dfs_win32_close(struct dfs_fd *file)
245263
{
246-
int oflag;
247-
248-
oflag = file->flags;
249-
if (oflag & DFS_O_DIRECTORY)
264+
if (file->flags & DFS_O_DIRECTORY)
250265
{
251-
/* operations about dir */
252-
if (_findclose((intptr_t)file->data) < 0)
253-
goto __err;
254-
255-
return 0;
266+
WINDIR *wdirp = (WINDIR*)(file->data);
267+
RT_ASSERT(wdirp != RT_NULL);
268+
if (_findclose((intptr_t)wdirp->handle) == 0) {
269+
free(wdirp->start); //NOTE: here we don't use rt_free!
270+
rt_free(wdirp);
271+
return 0;
272+
}
273+
}
274+
else /* regular file operations */
275+
{
276+
if (_close((int)(file->data)) == 0)
277+
return 0;
256278
}
257279

258-
/* regular file operations */
259-
if (_close((int)(file->data)) < 0)
260-
goto __err;
261-
262-
return 0;
263-
264-
__err:
265280
return win32_result_to_dfs(GetLastError());
266281
}
267282

@@ -316,16 +331,19 @@ static int dfs_win32_seek(struct dfs_fd *file,
316331
/* set offset as current offset */
317332
if (file->type == FT_DIRECTORY)
318333
{
319-
return -DFS_STATUS_ENOSYS;
334+
WINDIR* wdirp = (WINDIR*)(file->data);
335+
RT_ASSERT(wdirp != RT_NULL);
336+
wdirp->curr = wdirp->start + offset;
337+
return offset;
320338
}
321-
else if (file->type == FT_REGULAR)
339+
else //file->type == FT_REGULAR)
322340
{
323341
result = _lseek((int)(file->data), offset, SEEK_SET);
324342
if (result >= 0)
325343
return offset;
344+
else
345+
return win32_result_to_dfs(GetLastError());
326346
}
327-
328-
return win32_result_to_dfs(GetLastError());
329347
}
330348

331349
/* return the size of struct dirent*/
@@ -334,53 +352,52 @@ static int dfs_win32_getdents(
334352
struct dirent *dirp,
335353
rt_uint32_t count)
336354
{
337-
rt_uint32_t index;
338-
struct dirent *d;
339-
struct _finddata_t fileinfo;
340-
int handle;
355+
WINDIR *wdirp;
356+
struct dirent *d = dirp;
341357
int result;
342358

343-
handle = (int)(file->data);
344-
RT_ASSERT(handle != RT_NULL);
359+
/* make integer count */
360+
if (count / sizeof(struct dirent) != 1)
361+
return -DFS_STATUS_EINVAL;
345362

346-
/* round count, count is always 1 */
347-
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
348-
if (count == 0) return -DFS_STATUS_EINVAL;
363+
wdirp = (WINDIR*)(file->data);
364+
RT_ASSERT(wdirp != RT_NULL);
365+
if (wdirp->curr == NULL) //no more entries in this directory
366+
return 0;
349367

350-
index = 0;
351-
/* usually, the while loop should only be looped only once! */
352-
while (1)
368+
/* get the current entry */
369+
if (wdirp->finddata.attrib & _A_SUBDIR)
370+
d->d_type = DFS_DT_DIR;
371+
else
372+
d->d_type = DFS_DT_REG;
373+
d->d_namlen = strlen(wdirp->curr);
374+
strncpy(d->d_name, wdirp->curr, DFS_PATH_MAX);
375+
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
376+
wdirp->curr += (strlen(wdirp->curr) + 1);
377+
file->pos = wdirp->curr - wdirp->start + sizeof(struct dirent);//NOTE!
378+
379+
/* now set up for the next call to readdir */
380+
if (wdirp->curr >= wdirp->end)
353381
{
354-
d = dirp + index;
355-
if (_findnext(handle, &fileinfo) != 0) //-1 failed
356-
goto __err;
357-
358-
if (fileinfo.attrib & _A_SUBDIR)
359-
d->d_type = DFS_DT_DIR; /* directory */
382+
if (_findnext(wdirp->handle, &wdirp->finddata) == 0)
383+
{
384+
char* old_start = wdirp->start;
385+
long name_len = strlen(wdirp->finddata.name) + 1;
386+
wdirp->start = realloc(wdirp->start, wdirp->end - wdirp->start + name_len);
387+
wdirp->curr = wdirp->start + (wdirp->curr - old_start);
388+
wdirp->end = wdirp->curr + name_len;
389+
strcpy(wdirp->curr, wdirp->finddata.name);
390+
}
360391
else
361-
d->d_type = DFS_DT_REG;
362-
363-
/* write the rest arguments of struct dirent* dirp */
364-
d->d_namlen = strlen(fileinfo.name);
365-
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
366-
strcpy(d->d_name, fileinfo.name);
367-
368-
index ++;
369-
if (index * sizeof(struct dirent) >= count)
370-
break;
392+
{
393+
if ((result = GetLastError()) == ERROR_NO_MORE_FILES)
394+
wdirp->curr = NULL;
395+
else
396+
return win32_result_to_dfs(result);
397+
}
371398
}
372-
if (index == 0)
373-
return 0;
374-
375-
file->pos += index * sizeof(struct dirent);
376399

377-
return index * sizeof(struct dirent);
378-
379-
__err:
380-
if ((result = GetLastError()) == ERROR_NO_MORE_FILES)
381-
return 0;
382-
else
383-
return win32_result_to_dfs(result);
400+
return sizeof(struct dirent);
384401
}
385402

386403
static int dfs_win32_unlink(struct dfs_filesystem *fs, const char *path)

0 commit comments

Comments
 (0)