more intelligence regarding volume size
This commit is contained in:
parent
71f15f99f6
commit
b96b0297d4
|
@ -16,13 +16,7 @@
|
||||||
with melonDS. If not, see http://www.gnu.org/licenses/.
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __WIN32__
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif // __WIN32__
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "FATStorage.h"
|
#include "FATStorage.h"
|
||||||
|
@ -31,26 +25,11 @@
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
|
||||||
static int GetDirEntryType(const char* path, struct dirent* entry)
|
|
||||||
{
|
|
||||||
#ifdef __WIN32__
|
|
||||||
DWORD res = GetFileAttributesA(path);
|
|
||||||
if (res == INVALID_FILE_ATTRIBUTES) return -1;
|
|
||||||
if (res & FILE_ATTRIBUTE_DIRECTORY) return 1;
|
|
||||||
if (res & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_VIRTUAL)) return -1;
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
if (entry->d_type == DT_DIR) return 1;
|
|
||||||
if (entry->d_type == DT_REG) return 0;
|
|
||||||
return -1;
|
|
||||||
#endif // __WIN32__
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FATStorage::FATStorage()
|
FATStorage::FATStorage()
|
||||||
{
|
{
|
||||||
printf("FATStorage begin\n");
|
printf("FATStorage begin\n");
|
||||||
bool res = Build("dldi", 0x20000000, "melonDLDI.bin");
|
//bool res = Build("dldi", 0x20000000, "melonDLDI.bin");
|
||||||
|
bool res = Build("dldi", 0x3F000000, "melonDLDI.bin");
|
||||||
printf("FATStorage result: %d\n", res);
|
printf("FATStorage result: %d\n", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +107,15 @@ void FATStorage::LoadIndex()
|
||||||
if (fgets(linebuf, 1536, f) == nullptr)
|
if (fgets(linebuf, 1536, f) == nullptr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (linebuf[0] == 'D')
|
if (linebuf[0] == 'S')
|
||||||
|
{
|
||||||
|
u64 fsize;
|
||||||
|
int ret = sscanf(linebuf, "SIZE %" PRIu64, &fsize);
|
||||||
|
if (ret < 1) continue;
|
||||||
|
|
||||||
|
FileSize = fsize;
|
||||||
|
}
|
||||||
|
else if (linebuf[0] == 'D')
|
||||||
{
|
{
|
||||||
u32 readonly;
|
u32 readonly;
|
||||||
char fpath[1536] = {0};
|
char fpath[1536] = {0};
|
||||||
|
@ -246,6 +233,8 @@ void FATStorage::SaveIndex()
|
||||||
FILE* f = Platform::OpenLocalFile(IndexPath.c_str(), "w");
|
FILE* f = Platform::OpenLocalFile(IndexPath.c_str(), "w");
|
||||||
if (!f) return;
|
if (!f) return;
|
||||||
|
|
||||||
|
fprintf(f, "SIZE %" PRIu64 "\r\n", FileSize);
|
||||||
|
|
||||||
for (const auto& [key, val] : DirIndex)
|
for (const auto& [key, val] : DirIndex)
|
||||||
{
|
{
|
||||||
fprintf(f, "DIR %u %s\r\n",
|
fprintf(f, "DIR %u %s\r\n",
|
||||||
|
@ -862,37 +851,62 @@ bool FATStorage::Build(const char* sourcedir, u64 size, const char* filename)
|
||||||
FilePath = filename;
|
FilePath = filename;
|
||||||
FileSize = size;
|
FileSize = size;
|
||||||
|
|
||||||
|
bool isnew = false;
|
||||||
FF_File = Platform::OpenLocalFile(filename, "r+b");
|
FF_File = Platform::OpenLocalFile(filename, "r+b");
|
||||||
if (!FF_File)
|
if (!FF_File)
|
||||||
{
|
{
|
||||||
FF_File = Platform::OpenLocalFile(filename, "w+b");
|
FF_File = Platform::OpenLocalFile(filename, "w+b");
|
||||||
if (!FF_File)
|
if (!FF_File)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
isnew = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexPath = FilePath + ".idx";
|
IndexPath = FilePath + ".idx";
|
||||||
LoadIndex();
|
if (isnew)
|
||||||
|
{
|
||||||
|
DirIndex.clear();
|
||||||
|
FileIndex.clear();
|
||||||
|
SaveIndex();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LoadIndex();
|
||||||
|
|
||||||
FF_FileSize = size;
|
FF_FileSize = size;
|
||||||
ff_disk_open(FF_ReadStorage, FF_WriteStorage, (LBA_t)(size>>9));
|
ff_disk_open(FF_ReadStorage, FF_WriteStorage, (LBA_t)(size>>9));
|
||||||
|
|
||||||
FRESULT res;
|
FRESULT res;
|
||||||
FATFS fs;
|
FATFS fs;
|
||||||
|
bool needformat = false;
|
||||||
|
|
||||||
res = f_mount(&fs, "0:", 1);
|
res = f_mount(&fs, "0:", 1);
|
||||||
if (res != FR_OK)
|
if (res != FR_OK)
|
||||||
{
|
{
|
||||||
// TODO: determine proper FAT type!
|
needformat = true;
|
||||||
// for example: libfat tries to determine the FAT type from the number of clusters
|
}
|
||||||
// which doesn't match the way fatfs handles autodetection
|
else if (size != FileSize)
|
||||||
//
|
{
|
||||||
// partition->dataStart = partition->rootDirStart + (( u8array_to_u16(sectorBuffer, BPB_rootEntries) * DIR_ENTRY_DATA_SIZE) / partition->bytesPerSector);
|
printf("VOLUME NEEDS REFORMATTING BECAUSE SIZE CHANGED (%016llX != %016llX)\n", size, FileSize);
|
||||||
// uint32_t clusterCount = (partition->numberOfSectors - (uint32_t)(partition->dataStart - startSector)) / partition->sectorsPerCluster;
|
needformat = true;
|
||||||
// FAT12: max cluster count 4085
|
}
|
||||||
// FAT16; max cluster count: 65525
|
|
||||||
//
|
if (needformat)
|
||||||
|
{
|
||||||
|
FileSize = size;
|
||||||
|
DirIndex.clear();
|
||||||
|
FileIndex.clear();
|
||||||
|
SaveIndex();
|
||||||
|
|
||||||
FF_MKFS_PARM fsopt;
|
FF_MKFS_PARM fsopt;
|
||||||
fsopt.fmt = FM_FAT;// | FM_FAT32;
|
|
||||||
|
// FAT type: we force it to FAT32 for any volume that is 1GB or more
|
||||||
|
// libfat attempts to determine the FAT type from the volume size and other parameters
|
||||||
|
// which can lead to it trying to interpret a FAT16 volume as FAT32
|
||||||
|
if (size >= 0x40000000ULL)
|
||||||
|
fsopt.fmt = FM_FAT32;
|
||||||
|
else
|
||||||
|
fsopt.fmt = FM_FAT;
|
||||||
|
|
||||||
fsopt.au_size = 0;
|
fsopt.au_size = 0;
|
||||||
fsopt.align = 1;
|
fsopt.align = 1;
|
||||||
fsopt.n_fat = 1;
|
fsopt.n_fat = 1;
|
||||||
|
|
Loading…
Reference in New Issue