fix(fs): track multiple directory handles with win32 backends (#3243)

* fix(fs_win32): Track multiple directory handles

* fix(fs_stdio): Track multiple directory handles (win32)
This commit is contained in:
Ryzee119
2022-04-04 22:19:07 +09:30
committed by GitHub
parent b7b22c190c
commit 57e3697dca
2 changed files with 84 additions and 55 deletions

View File

@@ -21,10 +21,19 @@
/*********************
* DEFINES
*********************/
#define MAX_PATH_LEN 256
/**********************
* TYPEDEFS
**********************/
typedef struct {
#ifdef WIN32
HANDLE dir_p;
char next_fn[MAX_PATH_LEN];
#else
DIR * dir_p;
#endif
} dir_handle_t;
/**********************
* STATIC PROTOTYPES
@@ -105,7 +114,7 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
char buf[MAX_PATH_LEN];
lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s", path);
return fopen(buf, flags);
@@ -188,10 +197,6 @@ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
return LV_FS_RES_OK;
}
#ifdef WIN32
static char next_fn[256];
#endif
/**
* Initialize a 'DIR' or 'HANDLE' variable for directory reading
* @param drv pointer to a driver where this function belongs
@@ -201,37 +206,47 @@ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
{
LV_UNUSED(drv);
dir_handle_t * handle = (dir_handle_t *)lv_mem_alloc(sizeof(dir_handle_t));
#ifndef WIN32
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
char buf[MAX_PATH_LEN];
lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s", path);
return opendir(buf);
handle->dir_p = opendir(buf);
if(handle->dir_p == NULL) {
lv_mem_free(handle);
return NULL;
}
return handle;
#else
HANDLE d = INVALID_HANDLE_VALUE;
handle->dir_p = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA fdata;
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
char buf[MAX_PATH_LEN];
lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s\\*", path);
strcpy(next_fn, "");
d = FindFirstFile(buf, &fdata);
strcpy(handle->next_fn, "");
handle->dir_p = FindFirstFile(buf, &fdata);
do {
if(strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) {
continue;
}
else {
if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
sprintf(next_fn, "/%s", fdata.cFileName);
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName);
}
else {
sprintf(next_fn, "%s", fdata.cFileName);
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName);
}
break;
}
} while(FindNextFileA(d, &fdata));
} while(FindNextFileA(handle->dir_p, &fdata));
return d;
if(handle->dir_p == INVALID_HANDLE_VALUE) {
lv_mem_free(handle);
return INVALID_HANDLE_VALUE;
}
return handle;
#endif
}
@@ -246,13 +261,13 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn)
{
LV_UNUSED(drv);
dir_handle_t * handle = (dir_handle_t *)dir_p;
#ifndef WIN32
struct dirent * entry;
do {
entry = readdir(dir_p);
entry = readdir(handle->dir_p);
if(entry) {
if(entry->d_type == DT_DIR) sprintf(fn, "/%s", entry->d_name);
if(entry->d_type == DT_DIR) lv_snprintf(fn, MAX_PATH_LEN, "/%s", entry->d_name);
else strcpy(fn, entry->d_name);
}
else {
@@ -260,26 +275,26 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn)
}
} while(strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0);
#else
strcpy(fn, next_fn);
strcpy(fn, handle->next_fn);
strcpy(next_fn, "");
strcpy(handle->next_fn, "");
WIN32_FIND_DATA fdata;
if(FindNextFile(dir_p, &fdata) == false) return LV_FS_RES_OK;
if(FindNextFile(handle->dir_p, &fdata) == false) return LV_FS_RES_OK;
do {
if(strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) {
continue;
}
else {
if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
sprintf(next_fn, "/%s", fdata.cFileName);
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName);
}
else {
sprintf(next_fn, "%s", fdata.cFileName);
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName);
}
break;
}
} while(FindNextFile(dir_p, &fdata));
} while(FindNextFile(handle->dir_p, &fdata));
#endif
return LV_FS_RES_OK;
@@ -294,11 +309,13 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn)
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p)
{
LV_UNUSED(drv);
dir_handle_t * handle = (dir_handle_t *)dir_p;
#ifndef WIN32
closedir(dir_p);
closedir(handle->dir_p);
#else
FindClose(dir_p);
FindClose(handle->dir_p);
#endif
lv_mem_free(handle);
return LV_FS_RES_OK;
}

View File

@@ -16,10 +16,16 @@
/*********************
* DEFINES
*********************/
#define MAX_PATH_LEN 256
/**********************
* TYPEDEFS
**********************/
typedef struct {
HANDLE dir_p;
char next_fn[MAX_PATH_LEN];
lv_fs_res_t next_error;
} dir_handle_t;
/**********************
* STATIC PROTOTYPES
@@ -344,9 +350,6 @@ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
}
}
static char next_fn[256];
static lv_fs_res_t next_error = LV_FS_RES_OK;
/**
* Initialize a 'DIR' or 'HANDLE' variable for directory reading
* @param drv pointer to a driver where this function belongs
@@ -356,38 +359,45 @@ static lv_fs_res_t next_error = LV_FS_RES_OK;
static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
{
LV_UNUSED(drv);
HANDLE d = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAA fdata;
dir_handle_t * handle = (dir_handle_t *)lv_mem_alloc(sizeof(dir_handle_t));
handle->dir_p = INVALID_HANDLE_VALUE;
handle->next_error = LV_FS_RES_OK;
WIN32_FIND_DATA fdata;
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
char buf[MAX_PATH_LEN];
#ifdef LV_FS_WIN32_PATH
lv_snprintf(buf, sizeof(buf), LV_FS_WIN32_PATH "%s\\*", path);
#else
lv_snprintf(buf, sizeof(buf), "%s\\*", path);
#endif
strcpy(next_fn, "");
d = FindFirstFileA(buf, &fdata);
strcpy(handle->next_fn, "");
handle->dir_p = FindFirstFile(buf, &fdata);
do {
if(is_dots_name(fdata.cFileName)) {
continue;
}
else {
if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
sprintf(next_fn, "/%s", fdata.cFileName);
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName);
}
else {
sprintf(next_fn, "%s", fdata.cFileName);
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName);
}
break;
}
} while(FindNextFileA(handle->dir_p, &fdata));
} while(FindNextFileA(d, &fdata));
next_error = fs_error_from_win32(GetLastError());
return d;
if(handle->dir_p == INVALID_HANDLE_VALUE) {
lv_mem_free(handle);
handle->next_error = fs_error_from_win32(GetLastError());
return INVALID_HANDLE_VALUE;
}
else {
handle->next_error = LV_FS_RES_OK;
return handle;
}
}
/**
@@ -401,31 +411,30 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn)
{
LV_UNUSED(drv);
dir_handle_t * handle = (dir_handle_t *)dir_p;
strcpy(fn, handle->next_fn);
lv_fs_res_t current_error = handle->next_error;
strcpy(handle->next_fn, "");
strcpy(fn, next_fn);
lv_fs_res_t current_error = next_error;
next_error = LV_FS_RES_OK;
WIN32_FIND_DATA fdata;
strcpy(next_fn, "");
WIN32_FIND_DATAA fdata;
while(FindNextFileA(dir_p, &fdata)) {
while(FindNextFileA(handle->dir_p, &fdata)) {
if(is_dots_name(fdata.cFileName)) {
continue;
}
else {
if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
sprintf(next_fn, "/%s", fdata.cFileName);
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName);
}
else {
sprintf(next_fn, "%s", fdata.cFileName);
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName);
}
break;
}
}
if(next_fn[0] == '\0') {
next_error = fs_error_from_win32(GetLastError());
if(handle->next_fn[0] == '\0') {
handle->next_error = fs_error_from_win32(GetLastError());
}
return current_error;
@@ -440,9 +449,12 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn)
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p)
{
LV_UNUSED(drv);
return FindClose((HANDLE)dir_p)
? LV_FS_RES_OK
: fs_error_from_win32(GetLastError());
dir_handle_t * handle = (dir_handle_t *)dir_p;
lv_fs_res_t res = FindClose(handle->dir_p)
? LV_FS_RES_OK
: fs_error_from_win32(GetLastError());
lv_mem_free(handle);
return res;
}
#else /*LV_USE_FS_WIN32 == 0*/