VFAT: use retro_dir and retro_stat instead of additional fs- layer
This commit is contained in:
parent
b03347dc48
commit
73f5067ebc
|
@ -1,118 +0,0 @@
|
||||||
/* Copyright (C) 2006 Guillaume Duhamel
|
|
||||||
|
|
||||||
This file is part of DeSmuME
|
|
||||||
|
|
||||||
DeSmuME is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
DeSmuME is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with DeSmuME; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "fs.h"
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DIR * dir;
|
|
||||||
char * path;
|
|
||||||
} FsLinuxDir;
|
|
||||||
|
|
||||||
const char FS_SEPARATOR = '/';
|
|
||||||
|
|
||||||
void * FsReadFirst(const char * path, FsEntry * entry) {
|
|
||||||
FsLinuxDir * dir;
|
|
||||||
struct dirent * e;
|
|
||||||
struct stat s;
|
|
||||||
char buffer[512+1]; /* DirSpec[256] + '/' + dirent.d_name[256] */
|
|
||||||
DIR * tmp;
|
|
||||||
|
|
||||||
dir = (FsLinuxDir*)malloc(sizeof(FsLinuxDir));
|
|
||||||
if (!dir)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
tmp = opendir(path);
|
|
||||||
if (!tmp) {
|
|
||||||
free(dir);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
dir->dir = tmp;
|
|
||||||
|
|
||||||
e = readdir(tmp);
|
|
||||||
if (!e) {
|
|
||||||
closedir(tmp);
|
|
||||||
free(dir);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
strcpy(entry->cFileName, e->d_name);
|
|
||||||
// there's no 8.3 file names support on linux :)
|
|
||||||
strcpy(entry->cAlternateFileName, "");
|
|
||||||
entry->flags = 0;
|
|
||||||
|
|
||||||
dir->path = strdup(path);
|
|
||||||
sprintf(buffer, "%s/%s", dir->path, e->d_name);
|
|
||||||
|
|
||||||
stat(buffer, &s);
|
|
||||||
if (S_ISDIR(s.st_mode)) {
|
|
||||||
entry->flags = FS_IS_DIR;
|
|
||||||
entry->fileSize = 0;
|
|
||||||
} else {
|
|
||||||
entry->fileSize = s.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FsReadNext(void * search, FsEntry * entry) {
|
|
||||||
FsLinuxDir * dir = (FsLinuxDir*)search;
|
|
||||||
struct dirent * e;
|
|
||||||
struct stat s;
|
|
||||||
char buffer[1024];
|
|
||||||
|
|
||||||
e = readdir(dir->dir);
|
|
||||||
if (!e)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
strcpy(entry->cFileName, e->d_name);
|
|
||||||
// there's no 8.3 file names support on linux :)
|
|
||||||
strcpy(entry->cAlternateFileName, "");
|
|
||||||
entry->flags = 0;
|
|
||||||
|
|
||||||
sprintf(buffer, "%s/%s", dir->path, e->d_name);
|
|
||||||
|
|
||||||
stat(buffer, &s);
|
|
||||||
if (S_ISDIR(s.st_mode)) {
|
|
||||||
entry->flags = FS_IS_DIR;
|
|
||||||
entry->fileSize = 0;
|
|
||||||
} else {
|
|
||||||
entry->fileSize = s.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FsClose(void * search) {
|
|
||||||
FsLinuxDir *linuxdir = (FsLinuxDir *) search;
|
|
||||||
DIR * dir = linuxdir->dir;
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
free(linuxdir->path);
|
|
||||||
free(search);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FsError(void) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2006 Guillaume Duhamel
|
|
||||||
Copyright (C) 2006-2009 DeSmuME team
|
|
||||||
|
|
||||||
This file is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This file is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "fs.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
const char FS_SEPARATOR = '\\';
|
|
||||||
|
|
||||||
void * FsReadFirst(const char * p, FsEntry * entry) {
|
|
||||||
WIN32_FIND_DATA FindFileData;
|
|
||||||
HANDLE hFind;
|
|
||||||
HANDLE * ret;
|
|
||||||
char path[1024];
|
|
||||||
if (strlen(p)+3 >sizeof(path)) return NULL ;
|
|
||||||
|
|
||||||
sprintf(path, "%s\\*", p);
|
|
||||||
|
|
||||||
hFind = FindFirstFile(path, &FindFileData);
|
|
||||||
if (hFind == INVALID_HANDLE_VALUE)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
strncpy(entry->cFileName, FindFileData.cFileName,256);
|
|
||||||
entry->cFileName[255] = 0 ;
|
|
||||||
strncpy(entry->cAlternateFileName, FindFileData.cAlternateFileName,14);
|
|
||||||
entry->cAlternateFileName[13] = 0 ;
|
|
||||||
entry->flags = 0;
|
|
||||||
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
||||||
entry->flags = FS_IS_DIR;
|
|
||||||
entry->fileSize = 0;
|
|
||||||
} else {
|
|
||||||
entry->fileSize = FindFileData.nFileSizeLow;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = (void**)malloc(sizeof(HANDLE));
|
|
||||||
*ret = hFind;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FsReadNext(void * search, FsEntry * entry) {
|
|
||||||
WIN32_FIND_DATA FindFileData;
|
|
||||||
HANDLE * h = (HANDLE *) search;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = FindNextFile(*h, &FindFileData);
|
|
||||||
|
|
||||||
strncpy(entry->cFileName, FindFileData.cFileName,256);
|
|
||||||
entry->cFileName[255] = 0 ;
|
|
||||||
strncpy(entry->cAlternateFileName, FindFileData.cAlternateFileName,14);
|
|
||||||
entry->cAlternateFileName[13] = 0 ;
|
|
||||||
entry->flags = 0;
|
|
||||||
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
||||||
entry->flags = FS_IS_DIR;
|
|
||||||
entry->fileSize = 0;
|
|
||||||
} else {
|
|
||||||
entry->fileSize = FindFileData.nFileSizeLow;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FsClose(void * search) {
|
|
||||||
FindClose(*((HANDLE *) search));
|
|
||||||
}
|
|
||||||
|
|
||||||
int FsError(void) {
|
|
||||||
if (GetLastError() == ERROR_NO_MORE_FILES)
|
|
||||||
return FS_ERR_NO_MORE_FILES;
|
|
||||||
|
|
||||||
return FS_ERR_UNKNOWN;
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2006 Guillaume Duhamel
|
|
||||||
Copyright (C) 2007-2010 DeSmuME team
|
|
||||||
|
|
||||||
This file is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This file is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FS_H
|
|
||||||
#define FS_H
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
#define FS_IS_DIR 1
|
|
||||||
|
|
||||||
#define FS_ERR_UNKNOWN -1
|
|
||||||
#define FS_ERR_NO_MORE_FILES 1
|
|
||||||
|
|
||||||
extern const char FS_SEPARATOR;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char cFileName[256];
|
|
||||||
char cAlternateFileName[14];
|
|
||||||
u32 flags;
|
|
||||||
u32 fileSize;
|
|
||||||
} FsEntry;
|
|
||||||
|
|
||||||
void * FsReadFirst(const char * path, FsEntry * entry);
|
|
||||||
int FsReadNext(void * search, FsEntry * entry);
|
|
||||||
void FsClose(void * search);
|
|
||||||
int FsError(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2006 yopyop
|
Copyright (C) 2006 yopyop
|
||||||
Copyright (C) 2006 Mic
|
Copyright (C) 2006 Mic
|
||||||
Copyright (C) 2010-2015 DeSmuME team
|
Copyright (C) 2010-2016 DeSmuME team
|
||||||
|
|
||||||
This file is free software: you can redistribute it and/or modify
|
This file is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -27,7 +27,9 @@
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "../emufile.h"
|
#include "../emufile.h"
|
||||||
#include "../fs.h"
|
#include "retro_dirent.h"
|
||||||
|
#include "retro_stat.h"
|
||||||
|
#include "file/file_path.h"
|
||||||
|
|
||||||
#include "emufat.h"
|
#include "emufat.h"
|
||||||
#include "vfat.h"
|
#include "vfat.h"
|
||||||
|
@ -38,54 +40,56 @@ enum EListCallbackArg {
|
||||||
EListCallbackArg_Item, EListCallbackArg_Pop
|
EListCallbackArg_Item, EListCallbackArg_Pop
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*ListCallback)(FsEntry* fs, EListCallbackArg);
|
typedef void (*ListCallback)(RDIR* rdir, EListCallbackArg);
|
||||||
|
|
||||||
// List all files and subdirectories recursively
|
// List all files and subdirectories recursively
|
||||||
static void list_files(const char *filepath, ListCallback list_callback)
|
static void list_files(const char *filepath, ListCallback list_callback)
|
||||||
{
|
{
|
||||||
char DirSpec[255+1], SubDir[255+1];
|
|
||||||
FsEntry entry;
|
|
||||||
void * hFind;
|
void * hFind;
|
||||||
char *fname;
|
char *fname;
|
||||||
u32 dwError;
|
u32 dwError;
|
||||||
|
|
||||||
strncpy(DirSpec, filepath, ARRAY_SIZE(DirSpec));
|
RDIR* rdir = retro_opendir(filepath);
|
||||||
DirSpec[255] = 0 ; // hard limit the string here
|
if(!rdir) return;
|
||||||
|
if(retro_dirent_error(rdir))
|
||||||
hFind = FsReadFirst(DirSpec, &entry);
|
|
||||||
if (hFind == NULL) return;
|
|
||||||
|
|
||||||
do {
|
|
||||||
fname = (strlen(entry.cAlternateFileName)>0) ? entry.cAlternateFileName : entry.cFileName;
|
|
||||||
list_callback(&entry,EListCallbackArg_Item);
|
|
||||||
printf("cflash added %s\n",entry.cFileName);
|
|
||||||
|
|
||||||
if ((entry.flags & FS_IS_DIR) && (strcmp(fname, ".")) && (strcmp(fname, "..")))
|
|
||||||
{
|
{
|
||||||
if (strlen(fname)+strlen(filepath)+2 < 256)
|
retro_closedir(rdir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
{
|
{
|
||||||
sprintf(SubDir, "%s%c%s", filepath, FS_SEPARATOR, fname);
|
if(!retro_readdir(rdir))
|
||||||
list_files(SubDir, list_callback);
|
break;
|
||||||
list_callback(&entry, EListCallbackArg_Pop);
|
|
||||||
|
const char* fname = retro_dirent_get_name(rdir);
|
||||||
|
list_callback(rdir,EListCallbackArg_Item);
|
||||||
|
|
||||||
|
if(retro_dirent_is_dir(rdir) && (strcmp(fname, ".")) && (strcmp(fname, "..")))
|
||||||
|
{
|
||||||
|
std::string subdir = (std::string)filepath + path_default_slash() + fname;
|
||||||
|
list_files(subdir.c_str(), list_callback);
|
||||||
|
list_callback(rdir, EListCallbackArg_Pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (FsReadNext(hFind, &entry) != 0);
|
|
||||||
|
|
||||||
dwError = FsError();
|
retro_closedir(rdir);
|
||||||
FsClose(hFind);
|
|
||||||
if (dwError != FS_ERR_NO_MORE_FILES) return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 dataSectors = 0;
|
static u64 dataSectors = 0;
|
||||||
void count_ListCallback(FsEntry* fs, EListCallbackArg arg)
|
void count_ListCallback(RDIR* rdir, EListCallbackArg arg)
|
||||||
{
|
{
|
||||||
if(arg == EListCallbackArg_Pop) return;
|
if(arg == EListCallbackArg_Pop) return;
|
||||||
u32 sectors = 1;
|
u32 sectors = 1;
|
||||||
if(fs->flags & FS_IS_DIR)
|
if(retro_dirent_is_dir(rdir))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sectors += (fs->fileSize+511)/512 + 1;
|
{
|
||||||
|
//allocate sectors for file
|
||||||
|
int32_t fileSize = path_get_size(retro_dirent_get_name(rdir));
|
||||||
|
sectors += (fileSize+511)/512 + 1;
|
||||||
|
}
|
||||||
dataSectors += sectors;
|
dataSectors += sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,12 +97,9 @@ static std::string currPath;
|
||||||
static std::stack<std::string> pathStack;
|
static std::stack<std::string> pathStack;
|
||||||
static std::stack<std::string> virtPathStack;
|
static std::stack<std::string> virtPathStack;
|
||||||
static std::string currVirtPath;
|
static std::string currVirtPath;
|
||||||
void build_ListCallback(FsEntry* fs, EListCallbackArg arg)
|
void build_ListCallback(RDIR* rdir, EListCallbackArg arg)
|
||||||
{
|
{
|
||||||
char* fname = (strlen(fs->cAlternateFileName)>0) ? fs->cAlternateFileName : fs->cFileName;
|
const char* fname = retro_dirent_get_name(rdir);
|
||||||
|
|
||||||
//we use cFileName always because it is a LFN and we are making sure that we always make a fat32 image
|
|
||||||
fname = fs->cFileName;
|
|
||||||
|
|
||||||
if(arg == EListCallbackArg_Pop)
|
if(arg == EListCallbackArg_Pop)
|
||||||
{
|
{
|
||||||
|
@ -109,7 +110,7 @@ void build_ListCallback(FsEntry* fs, EListCallbackArg arg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fs->flags & FS_IS_DIR)
|
if(retro_dirent_is_dir(rdir))
|
||||||
{
|
{
|
||||||
if(!strcmp(fname,".")) return;
|
if(!strcmp(fname,".")) return;
|
||||||
if(!strcmp(fname,"..")) return;
|
if(!strcmp(fname,"..")) return;
|
||||||
|
@ -123,12 +124,12 @@ void build_ListCallback(FsEntry* fs, EListCallbackArg arg)
|
||||||
if(!ok)
|
if(!ok)
|
||||||
printf("ERROR adding dir %s via libfat\n",currVirtPath.c_str());
|
printf("ERROR adding dir %s via libfat\n",currVirtPath.c_str());
|
||||||
|
|
||||||
currPath = currPath + std::string(1,FS_SEPARATOR) + fname;
|
currPath = currPath + path_default_slash() + fname;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string path = currPath + std::string(1,FS_SEPARATOR) + fname;
|
std::string path = currPath + path_default_slash() + fname;
|
||||||
|
|
||||||
FILE* inf = fopen(path.c_str(),"rb");
|
FILE* inf = fopen(path.c_str(),"rb");
|
||||||
if(inf)
|
if(inf)
|
||||||
|
@ -141,7 +142,7 @@ void build_ListCallback(FsEntry* fs, EListCallbackArg arg)
|
||||||
fclose(inf);
|
fclose(inf);
|
||||||
|
|
||||||
std::string path = currVirtPath + "/" + fname;
|
std::string path = currVirtPath + "/" + fname;
|
||||||
printf("adding path %s for libfat\n",path.c_str());
|
printf("FAT + (%10.2f KB) %s \n",len/1024.f,path.c_str());
|
||||||
bool ok = LIBFAT::WriteFile(path.c_str(),buf,len);
|
bool ok = LIBFAT::WriteFile(path.c_str(),buf,len);
|
||||||
if(!ok)
|
if(!ok)
|
||||||
printf("ERROR adding file to fat\n");
|
printf("ERROR adding file to fat\n");
|
||||||
|
|
|
@ -95,7 +95,6 @@
|
||||||
<ClCompile Include="..\filter\xbrz.cpp" />
|
<ClCompile Include="..\filter\xbrz.cpp" />
|
||||||
<ClCompile Include="..\firmware.cpp" />
|
<ClCompile Include="..\firmware.cpp" />
|
||||||
<ClCompile Include="..\frontend\modules\ImageOut.cpp" />
|
<ClCompile Include="..\frontend\modules\ImageOut.cpp" />
|
||||||
<ClCompile Include="..\fs-windows.cpp" />
|
|
||||||
<ClCompile Include="..\gfx3d.cpp" />
|
<ClCompile Include="..\gfx3d.cpp" />
|
||||||
<ClCompile Include="..\GPU.cpp" />
|
<ClCompile Include="..\GPU.cpp" />
|
||||||
<ClCompile Include="..\GPU_OSD.cpp" />
|
<ClCompile Include="..\GPU_OSD.cpp" />
|
||||||
|
@ -364,7 +363,6 @@
|
||||||
<ClInclude Include="..\filter\xbrz.h" />
|
<ClInclude Include="..\filter\xbrz.h" />
|
||||||
<ClInclude Include="..\firmware.h" />
|
<ClInclude Include="..\firmware.h" />
|
||||||
<ClInclude Include="..\frontend\modules\ImageOut.h" />
|
<ClInclude Include="..\frontend\modules\ImageOut.h" />
|
||||||
<ClInclude Include="..\fs.h" />
|
|
||||||
<ClInclude Include="..\gfx3d.h" />
|
<ClInclude Include="..\gfx3d.h" />
|
||||||
<ClInclude Include="..\GPU.h" />
|
<ClInclude Include="..\GPU.h" />
|
||||||
<ClInclude Include="..\GPU_osd.h" />
|
<ClInclude Include="..\GPU_osd.h" />
|
||||||
|
|
|
@ -165,9 +165,6 @@
|
||||||
<ClCompile Include="..\firmware.cpp">
|
<ClCompile Include="..\firmware.cpp">
|
||||||
<Filter>Core</Filter>
|
<Filter>Core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\fs-windows.cpp">
|
|
||||||
<Filter>Core</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\gfx3d.cpp">
|
<ClCompile Include="..\gfx3d.cpp">
|
||||||
<Filter>Core</Filter>
|
<Filter>Core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1010,9 +1007,6 @@
|
||||||
<ClInclude Include="..\firmware.h">
|
<ClInclude Include="..\firmware.h">
|
||||||
<Filter>Core</Filter>
|
<Filter>Core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\fs.h">
|
|
||||||
<Filter>Core</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\gfx3d.h">
|
<ClInclude Include="..\gfx3d.h">
|
||||||
<Filter>Core</Filter>
|
<Filter>Core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
Loading…
Reference in New Issue