summaryrefslogtreecommitdiff
path: root/bsp/simulator/drivers
diff options
context:
space:
mode:
authorprife <[email protected]>2015-02-02 00:07:51 +0800
committerprife <[email protected]>2015-02-02 01:21:40 +0800
commitc6f88ef726d373d6ccf2540c4092efc9bac582a7 (patch)
treedd60fef92736f5e9d7427101acd9f9fa1a527020 /bsp/simulator/drivers
parent0f9139ecfc3fcc909130c73eb0e2bb9eff912ad3 (diff)
dfs_win32: add seekdir support
Diffstat (limited to 'bsp/simulator/drivers')
-rw-r--r--bsp/simulator/drivers/dfs_win32.c145
1 files changed, 81 insertions, 64 deletions
diff --git a/bsp/simulator/drivers/dfs_win32.c b/bsp/simulator/drivers/dfs_win32.c
index 32e09f03f7..8d6e7b0305 100644
--- a/bsp/simulator/drivers/dfs_win32.c
+++ b/bsp/simulator/drivers/dfs_win32.c
@@ -50,6 +50,14 @@
#define WIN32_DIRDISK_ROOT "." /* "F:\\Project\\svn\\rtt\\trunk\\bsp\\simulator_test" */
+typedef struct {
+ HANDLE handle;
+ char *start;
+ char *end;
+ char *curr;
+ struct _finddata_t finddata;
+} WINDIR;
+
/* There are so many error codes in windows, you'd better google for details.
* google "System Error Codes (Windows)"
* 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)
oflag = file->flags;
if (oflag & DFS_O_DIRECTORY) /* operations about dir */
{
- struct _finddata_t dir;
- int handle;
+ WINDIR *wdirp;
+ HANDLE handle;
int len;
file_path = winpath_dirdup(WIN32_DIRDISK_ROOT, file->path);
@@ -191,14 +199,24 @@ static int dfs_win32_open(struct dfs_fd *file)
strcat(file_path, "*.*");
/* _findfirst will get '.' */
- if ((handle = _findfirst(file_path, &dir)) == -1)
+ /* save this pointer,will used by dfs_win32_getdents*/
+ wdirp = rt_malloc(sizeof(WINDIR));
+ RT_ASSERT(wdirp != NULL);
+ if ((handle = _findfirst(file_path, &wdirp->finddata)) == -1)
{
+ rt_free(wdirp);
rt_free(file_path);
goto __err;
}
+ len = strlen(wdirp->finddata.name) + 1;
+ wdirp->handle = handle;
+ //wdirp->nfiles = 1;
+ wdirp->start = malloc(len); //not rt_malloc!
+ wdirp->end = wdirp->curr = wdirp->start;
+ wdirp->end += len;
+ strncpy(wdirp->curr, wdirp->finddata.name, len);
- /* save this pointer,will used by dfs_win32_getdents*/
- file->data = (void *)handle;
+ file->data = (void *)wdirp;
rt_free(file_path);
return DFS_STATUS_OK;
}
@@ -243,25 +261,22 @@ __err:
static int dfs_win32_close(struct dfs_fd *file)
{
- int oflag;
-
- oflag = file->flags;
- if (oflag & DFS_O_DIRECTORY)
+ if (file->flags & DFS_O_DIRECTORY)
{
- /* operations about dir */
- if (_findclose((intptr_t)file->data) < 0)
- goto __err;
-
- return 0;
+ WINDIR *wdirp = (WINDIR*)(file->data);
+ RT_ASSERT(wdirp != RT_NULL);
+ if (_findclose((intptr_t)wdirp->handle) == 0) {
+ free(wdirp->start); //NOTE: here we don't use rt_free!
+ rt_free(wdirp);
+ return 0;
+ }
+ }
+ else /* regular file operations */
+ {
+ if (_close((int)(file->data)) == 0)
+ return 0;
}
- /* regular file operations */
- if (_close((int)(file->data)) < 0)
- goto __err;
-
- return 0;
-
-__err:
return win32_result_to_dfs(GetLastError());
}
@@ -316,16 +331,19 @@ static int dfs_win32_seek(struct dfs_fd *file,
/* set offset as current offset */
if (file->type == FT_DIRECTORY)
{
- return -DFS_STATUS_ENOSYS;
+ WINDIR* wdirp = (WINDIR*)(file->data);
+ RT_ASSERT(wdirp != RT_NULL);
+ wdirp->curr = wdirp->start + offset;
+ return offset;
}
- else if (file->type == FT_REGULAR)
+ else //file->type == FT_REGULAR)
{
result = _lseek((int)(file->data), offset, SEEK_SET);
if (result >= 0)
return offset;
+ else
+ return win32_result_to_dfs(GetLastError());
}
-
- return win32_result_to_dfs(GetLastError());
}
/* return the size of struct dirent*/
@@ -334,53 +352,52 @@ static int dfs_win32_getdents(
struct dirent *dirp,
rt_uint32_t count)
{
- rt_uint32_t index;
- struct dirent *d;
- struct _finddata_t fileinfo;
- int handle;
+ WINDIR *wdirp;
+ struct dirent *d = dirp;
int result;
- handle = (int)(file->data);
- RT_ASSERT(handle != RT_NULL);
+ /* make integer count */
+ if (count / sizeof(struct dirent) != 1)
+ return -DFS_STATUS_EINVAL;
- /* round count, count is always 1 */
- count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
- if (count == 0) return -DFS_STATUS_EINVAL;
+ wdirp = (WINDIR*)(file->data);
+ RT_ASSERT(wdirp != RT_NULL);
+ if (wdirp->curr == NULL) //no more entries in this directory
+ return 0;
- index = 0;
- /* usually, the while loop should only be looped only once! */
- while (1)
- {
- d = dirp + index;
- if (_findnext(handle, &fileinfo) != 0) //-1 failed
- goto __err;
+ /* get the current entry */
+ if (wdirp->finddata.attrib & _A_SUBDIR)
+ d->d_type = DFS_DT_DIR;
+ else
+ d->d_type = DFS_DT_REG;
+ d->d_namlen = strlen(wdirp->curr);
+ strncpy(d->d_name, wdirp->curr, DFS_PATH_MAX);
+ d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
+ wdirp->curr += (strlen(wdirp->curr) + 1);
+ file->pos = wdirp->curr - wdirp->start + sizeof(struct dirent);//NOTE!
- if (fileinfo.attrib & _A_SUBDIR)
- d->d_type = DFS_DT_DIR; /* directory */
+ /* now set up for the next call to readdir */
+ if (wdirp->curr >= wdirp->end)
+ {
+ if (_findnext(wdirp->handle, &wdirp->finddata) == 0)
+ {
+ char* old_start = wdirp->start;
+ long name_len = strlen(wdirp->finddata.name) + 1;
+ wdirp->start = realloc(wdirp->start, wdirp->end - wdirp->start + name_len);
+ wdirp->curr = wdirp->start + (wdirp->curr - old_start);
+ wdirp->end = wdirp->curr + name_len;
+ strcpy(wdirp->curr, wdirp->finddata.name);
+ }
else
- d->d_type = DFS_DT_REG;
-
- /* write the rest arguments of struct dirent* dirp */
- d->d_namlen = strlen(fileinfo.name);
- d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
- strcpy(d->d_name, fileinfo.name);
-
- index ++;
- if (index * sizeof(struct dirent) >= count)
- break;
+ {
+ if ((result = GetLastError()) == ERROR_NO_MORE_FILES)
+ wdirp->curr = NULL;
+ else
+ return win32_result_to_dfs(result);
+ }
}
- if (index == 0)
- return 0;
-
- file->pos += index * sizeof(struct dirent);
- return index * sizeof(struct dirent);
-
-__err:
- if ((result = GetLastError()) == ERROR_NO_MORE_FILES)
- return 0;
- else
- return win32_result_to_dfs(result);
+ return sizeof(struct dirent);
}
static int dfs_win32_unlink(struct dfs_filesystem *fs, const char *path)