Various improvements to virtual file handling

This commit is contained in:
d0k3 2016-03-22 14:30:11 +01:00
parent 4d4a037874
commit 0b735edc49
5 changed files with 47 additions and 21 deletions

View File

@ -70,7 +70,7 @@ bool CheckWritePermissions(const char* path) {
int pdrv = PathToNumFS(path);
if (pdrv < 0) {
if (IsVirtualPath(path)) // this is a hack, but okay for now
pdrv = (*path == 'S') ? 1 : 4;
pdrv = (IsVirtualPath(path) == VRT_SYSNAND) ? 1 : 4;
else return false;
}
@ -208,10 +208,17 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
char dsizestr[32];
FormatBytes(osizestr, osize);
FormatBytes(dsizestr, dvfile.size);
ShowPrompt(false, "File size mismatch:\n%s (%s)\n%s (%s)", origstr, osizestr, deststr, dsizestr);
if (dvfile.size > osize) {
if (!ShowPrompt(true, "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", origstr, osizestr, deststr, dsizestr)) {
f_close(&ofile);
return false;
}
} else {
ShowPrompt(false, "File bigger than available space:\n%s (%s)\n%s (%s)", origstr, osizestr, deststr, dsizestr);
f_close(&ofile);
return false;
}
}
DeinitNandFS();
if (!ShowProgress(0, 0, orig)) ret = false;

View File

@ -163,12 +163,18 @@ u8 CheckNandType(bool check_emunand)
return NAND_TYPE_UNK;
}
u64 GetNandSizeSectors(bool size_emunand)
{
if (size_emunand) { // for EmuNAND
u32 emunand_max_sectors = GetPartitionOffsetSector("0:") - (emunand_base_sector + 1); // +1 for safety
u32 emunand_min_sectors = (emunand_base_sector % 0x200000 == 0) ? getMMCDevice(0)->total_size :
(GetUnitPlatform() == PLATFORM_N3DS) ? 0x26C000 : 0x1D7800;
return (emunand_min_sectors > emunand_max_sectors) ? 0 : emunand_min_sectors;
} else return getMMCDevice(0)->total_size; // for SysNAND
}
bool InitEmuNandBase(void)
{
emunand_base_sector = 0x000000;
if (GetPartitionOffsetSector("0:") <= getMMCDevice(0)->total_size)
return false;
emunand_base_sector = 0x000000; // GW type EmuNAND
if (CheckNandType(true) != NAND_TYPE_UNK)
return true;
@ -177,6 +183,6 @@ bool InitEmuNandBase(void)
if (CheckNandType(true) != NAND_TYPE_UNK)
return true;
emunand_base_sector = 0x000000;
if (GetPartitionOffsetSector("0:") > getMMCDevice(0)->total_size)
return false;
}

View File

@ -13,9 +13,7 @@ void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot);
int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, bool read_emunand);
int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, bool write_emunand);
u64 GetNandSizeSectors(bool size_emunand);
u8 CheckNandType(bool check_emunand);
bool InitEmuNandBase(void);
u32 GetEmuNandBase(void);
u32 SwitchEmuNandBase(int start_sector);

View File

@ -1,5 +1,4 @@
#include "virtual.h"
#include "sdmmc.h"
#define VFLAG_ON_O3DS NAND_TYPE_O3DS
#define VFLAG_ON_N3DS NAND_TYPE_N3DS
@ -27,24 +26,33 @@ VirtualFile virtualFileTemplates[] = {
{ "sector0x96.bin" , 0x00012C00, 0x00000200, 0xFF, VFLAG_ON_ALL }
};
bool IsVirtualPath(const char* path) {
return (strncmp(path, "S:", 2) == 0) || (strncmp(path, "E:", 2) == 0);
u32 IsVirtualPath(const char* path) {
u32 plen = strnlen(path, 16);
if (strncmp(path, "S:/", (plen >= 3) ? 3 : 2) == 0)
return VRT_SYSNAND;
else if (strncmp(path, "E:/", (plen >= 3) ? 3 : 2) == 0)
return VRT_EMUNAND;
return 0;
}
bool FindVirtualFile(VirtualFile* vfile, const char* path)
{
char* fname = strchr(path, '/');
bool on_emunand = (*path == 'E');
u8 nand_type = CheckNandType(on_emunand);
bool on_emunand = false;
u8 nand_type = 0;
// fix the name
if (!fname) return false;
fname++;
// more safety checks
// check path vailidity
if (!IsVirtualPath(path) || (fname - path != 3))
return false;
// check NAND type
on_emunand = (IsVirtualPath(path) == VRT_EMUNAND);
nand_type = CheckNandType(on_emunand);
// parse the template list, get the correct one
u32 n_templates = sizeof(virtualFileTemplates) / sizeof(VirtualFile);
VirtualFile* curr_template = NULL;
@ -60,8 +68,11 @@ bool FindVirtualFile(VirtualFile* vfile, const char* path)
memcpy(vfile, curr_template, sizeof(VirtualFile));
// process special flags
if (vfile->flags & VFLAG_NAND_SIZE)
vfile->size = getMMCDevice(0)->total_size * 0x200;
if (vfile->flags & VFLAG_NAND_SIZE) {
if (on_emunand && (GetNandSizeSectors(false) != GetNandSizeSectors(true)))
return false; // EmuNAND is too small
vfile->size = GetNandSizeSectors(false) * 0x200;
}
if (on_emunand) vfile->flags |= VFLAG_ON_EMUNAND;
return true;

View File

@ -3,6 +3,10 @@
#include "common.h"
#include "nand.h"
#define VRT_NONE 0
#define VRT_SYSNAND 1
#define VRT_EMUNAND 2
static const char* virtualFileList[] = { // must have a match in virtualFileTemplates[]
"twln.bin", "twlp.bin", "agbsave.bin", "firm0.bin", "firm1.bin", "ctrnand_fat.bin", "ctrnand_full.bin",
"nand.bin", "nand_minsize.bin", "nand_hdr.bin", "sector0x96.bin"
@ -17,7 +21,7 @@ typedef struct {
u32 flags;
} __attribute__((packed)) VirtualFile;
bool IsVirtualPath(const char* path);
u32 IsVirtualPath(const char* path);
bool FindVirtualFile(VirtualFile* vfile, const char* path);
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count);
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count);