2016-03-21 18:29:55 +01:00
|
|
|
#include "virtual.h"
|
2016-11-14 22:24:20 +01:00
|
|
|
#include "vnand.h"
|
|
|
|
#include "vmem.h"
|
2016-03-21 18:29:55 +01:00
|
|
|
|
2016-11-14 22:24:20 +01:00
|
|
|
typedef struct {
|
|
|
|
char drv_letter;
|
|
|
|
u32 virtual_src;
|
|
|
|
} __attribute__((packed)) VirtualDrive;
|
2016-03-21 18:29:55 +01:00
|
|
|
|
2016-11-14 22:24:20 +01:00
|
|
|
static const VirtualDrive virtualDrives[] = { {'S', VRT_SYSNAND}, {'E', VRT_EMUNAND}, {'I', VRT_IMGNAND}, {'M', VRT_MEMORY} };
|
2016-03-21 18:29:55 +01:00
|
|
|
|
2016-04-09 21:56:42 +02:00
|
|
|
u32 GetVirtualSource(const char* path) {
|
2016-11-14 22:24:20 +01:00
|
|
|
// check path validity
|
|
|
|
if ((strnlen(path, 16) < 2) || (path[1] != ':') || ((path[2] != '/') && (path[2] != '\0')))
|
|
|
|
return 0;
|
|
|
|
// search for virtual source
|
|
|
|
for (u32 i = 0; i < (sizeof(virtualDrives) / sizeof(VirtualDrive)); i++)
|
|
|
|
if (*path == virtualDrives[i].drv_letter) return virtualDrives[i].virtual_src;
|
2016-03-22 14:30:11 +01:00
|
|
|
return 0;
|
2016-03-21 18:29:55 +01:00
|
|
|
}
|
|
|
|
|
2016-04-09 21:56:42 +02:00
|
|
|
bool CheckVirtualDrive(const char* path) {
|
|
|
|
u32 virtual_src = GetVirtualSource(path);
|
2016-11-14 22:24:20 +01:00
|
|
|
if (virtual_src & (VRT_EMUNAND|VRT_IMGNAND))
|
|
|
|
return CheckVNandDrive(virtual_src); // check virtual NAND drive for EmuNAND / ImgNAND
|
2016-04-09 21:50:50 +02:00
|
|
|
return virtual_src; // this is safe for SysNAND & memory
|
2016-03-22 19:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-03-22 19:44:21 +01:00
|
|
|
bool FindVirtualFile(VirtualFile* vfile, const char* path, u32 size)
|
2016-03-21 18:29:55 +01:00
|
|
|
{
|
2016-11-14 22:24:20 +01:00
|
|
|
// get / fix the name
|
2016-03-21 18:29:55 +01:00
|
|
|
char* fname = strchr(path, '/');
|
|
|
|
if (!fname) return false;
|
|
|
|
fname++;
|
|
|
|
|
2016-11-14 22:24:20 +01:00
|
|
|
// check path validity / get virtual source
|
|
|
|
u32 virtual_src = 0;
|
2016-04-09 21:56:42 +02:00
|
|
|
virtual_src = GetVirtualSource(path);
|
2016-04-09 21:50:50 +02:00
|
|
|
if (!virtual_src || (fname - path != 3))
|
2016-03-21 18:29:55 +01:00
|
|
|
return false;
|
|
|
|
|
2016-11-14 22:24:20 +01:00
|
|
|
// get virtual file struct from appropriate function
|
|
|
|
if (virtual_src & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND)) {
|
|
|
|
if (!FindVNandFile(vfile, virtual_src, fname, size)) return false;
|
|
|
|
} else if (virtual_src & VRT_MEMORY) {
|
|
|
|
if (!FindVMemFile(vfile, fname, size)) return false;
|
|
|
|
} else return false;
|
2016-03-22 14:30:11 +01:00
|
|
|
|
2016-11-14 22:24:20 +01:00
|
|
|
// add the virtual source to the virtual file flags
|
2016-04-09 21:50:50 +02:00
|
|
|
vfile->flags |= virtual_src;
|
2016-03-21 18:29:55 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-04-08 21:02:38 +02:00
|
|
|
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count, u32* bytes_read)
|
2016-03-21 18:29:55 +01:00
|
|
|
{
|
2016-11-14 22:24:20 +01:00
|
|
|
// basic check of offset / count
|
2016-04-08 21:02:38 +02:00
|
|
|
if (offset >= vfile->size)
|
|
|
|
return 0;
|
|
|
|
else if ((offset + count) > vfile->size)
|
|
|
|
count = vfile->size - offset;
|
|
|
|
if (bytes_read) *bytes_read = count;
|
2016-04-09 21:50:50 +02:00
|
|
|
|
2016-11-14 22:24:20 +01:00
|
|
|
if (vfile->flags & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND)) {
|
|
|
|
return ReadVNandFile(vfile, buffer, offset, count);
|
|
|
|
} else if (vfile->flags & VRT_MEMORY) {
|
|
|
|
return ReadVMemFile(vfile, buffer, offset, count);
|
2016-04-08 21:02:38 +02:00
|
|
|
}
|
2016-04-09 21:50:50 +02:00
|
|
|
|
|
|
|
return -1;
|
2016-03-21 18:29:55 +01:00
|
|
|
}
|
|
|
|
|
2016-04-08 21:02:38 +02:00
|
|
|
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count, u32* bytes_written)
|
2016-03-21 18:29:55 +01:00
|
|
|
{
|
2016-11-14 22:24:20 +01:00
|
|
|
// basic check of offset / count
|
2016-04-08 21:02:38 +02:00
|
|
|
if (offset >= vfile->size)
|
|
|
|
return 0;
|
|
|
|
else if ((offset + count) > vfile->size)
|
|
|
|
count = vfile->size - offset;
|
|
|
|
if (bytes_written) *bytes_written = count;
|
2016-04-09 21:50:50 +02:00
|
|
|
|
2016-11-14 22:24:20 +01:00
|
|
|
if (vfile->flags & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND)) {
|
|
|
|
return WriteVNandFile(vfile, buffer, offset, count);
|
|
|
|
} else if (vfile->flags & VRT_MEMORY) {
|
|
|
|
return WriteVMemFile(vfile, buffer, offset, count);
|
2016-04-09 21:50:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
2016-03-21 18:29:55 +01:00
|
|
|
}
|