VFAT: use retro_dir and retro_stat instead of additional fs- layer

This commit is contained in:
zeromus 2016-04-22 01:38:45 +00:00
parent b03347dc48
commit 73f5067ebc
6 changed files with 37 additions and 294 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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");

View File

@ -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" />

View File

@ -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>