FileGetData(): Also allow virtual files

This commit also enables ReadVirtualFile() to correctly process
misaligned data
This commit is contained in:
d0k3 2016-04-08 21:02:38 +02:00
parent 2d181de5bf
commit 45501d47eb
5 changed files with 79 additions and 26 deletions

View File

@ -162,16 +162,26 @@ bool FileCreateData(const char* path, u8* data, size_t size) {
return (bytes_written == size);
}
bool FileGetData(const char* path, u8* data, size_t size, size_t foffset)
size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset)
{
FIL file;
UINT bytes_read = 0;
if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return false;
f_lseek(&file, foffset);
f_read(&file, data, size, &bytes_read);
f_close(&file);
return (bytes_read == size);
if (PathToNumFS(path) >= 0) {
UINT bytes_read = 0;
FIL file;
if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return 0;
f_lseek(&file, foffset);
if (f_read(&file, data, size, &bytes_read) != FR_OK)
return 0;
f_close(&file);
return bytes_read;
} else if (IsVirtualPath(path)) {
u32 bytes_read = 0;
VirtualFile vfile;
if (!FindVirtualFile(&vfile, path, 0))
return 0;
return (ReadVirtualFile(&vfile, data, foffset, size, &bytes_read) == 0) ? bytes_read : 0;
}
return 0;
}
bool PathCopyVirtual(const char* destdir, const char* orig) {
@ -209,11 +219,11 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
if (!ShowProgress(0, 0, orig)) ret = false;
for (size_t pos = 0; (pos < osize) && ret; pos += MAIN_BUFFER_SIZE) {
UINT read_bytes = min(MAIN_BUFFER_SIZE, osize - pos);
if (ReadVirtualFile(&ovfile, MAIN_BUFFER, pos, read_bytes) != 0)
if (ReadVirtualFile(&ovfile, MAIN_BUFFER, pos, read_bytes, NULL) != 0)
ret = false;
if (!ShowProgress(pos + (read_bytes / 2), osize, orig))
ret = false;
if (WriteVirtualFile(&dvfile, MAIN_BUFFER, pos, read_bytes) != 0)
if (WriteVirtualFile(&dvfile, MAIN_BUFFER, pos, read_bytes, NULL) != 0)
ret = false;
}
ShowProgress(1, 1, orig);
@ -265,7 +275,7 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
ret = false;
if (!ShowProgress(pos + (bytes_read / 2), osize, orig))
ret = false;
if (WriteVirtualFile(&dvfile, MAIN_BUFFER, pos, bytes_read) != 0)
if (WriteVirtualFile(&dvfile, MAIN_BUFFER, pos, bytes_read, NULL) != 0)
ret = false;
}
ShowProgress(1, 1, orig);
@ -298,7 +308,7 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
for (size_t pos = 0; (pos < osize) && ret; pos += MAIN_BUFFER_SIZE) {
UINT read_bytes = min(MAIN_BUFFER_SIZE, osize - pos);
UINT bytes_written = 0;
if (ReadVirtualFile(&ovfile, MAIN_BUFFER, pos, read_bytes) != 0)
if (ReadVirtualFile(&ovfile, MAIN_BUFFER, pos, read_bytes, NULL) != 0)
ret = false;
if (!ShowProgress(pos + (read_bytes / 2), osize, orig))
ret = false;

View File

@ -42,7 +42,7 @@ u32 GetWritePermissions();
bool FileCreateData(const char* path, u8* data, size_t size);
/** Read data from file@offset **/
bool FileGetData(const char* path, u8* data, size_t size, size_t foffset);
size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset);
/** Recursively copy a file or directory **/
bool PathCopy(const char* destdir, const char* orig);

View File

@ -61,7 +61,7 @@ bool LoadKeyFromFile(const char* folder, u8* keydata, u32 keyslot, char type, ch
if (id) strncpy((char*) key_magic + 2, id, 10);
// try to find key in 'aeskeydb.bin' file
for (u32 p = 0; FileGetData(path, buffer, 32, p); p += 32) {
for (u32 p = 0; FileGetData(path, buffer, 32, p) == 32; p += 32) {
if (memcmp(buffer, key_magic, 12) == 0) {
found = true;
break;
@ -83,7 +83,7 @@ bool LoadKeyFromFile(const char* folder, u8* keydata, u32 keyslot, char type, ch
if (!found) {
snprintf(path, 256, "%s/slot0x%02XKey%.10s", folder, (unsigned int) keyslot,
(id) ? id : (type == 'X') ? "X" : (type == 'Y') ? "Y" : "");
if (FileGetData(path, key, 16, 0))
if (FileGetData(path, key, 16, 0) == 16)
found = true;
}
@ -198,6 +198,7 @@ void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot)
int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, u32 nand_src)
{
if (!count) return 0; // <--- just to be safe
if (nand_src == NAND_EMUNAND) { // EmuNAND
int errorcode = 0;
if ((sector == 0) && (emunand_base_sector % 0x200000 == 0)) { // GW EmuNAND header handling

View File

@ -91,16 +91,58 @@ bool FindVirtualFile(VirtualFile* vfile, const char* path, u32 size)
return true;
}
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count)
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count, u32* bytes_read)
{
// simple wrapper function for ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, u32 src)
return ReadNandSectors(buffer, (vfile->offset + offset) / 0x200, (count+0x1FF) / 0x200, vfile->keyslot,
vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND));
u32 foffset = vfile->offset + offset;
if (offset >= vfile->size)
return 0;
else if ((offset + count) > vfile->size)
count = vfile->size - offset;
if (bytes_read) *bytes_read = count;
if (!(foffset % 0x200) && !(count % 0x200)) { // aligned data -> simple case
// simple wrapper function for ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, u32 src)
return ReadNandSectors(buffer, foffset / 0x200, count / 0x200, vfile->keyslot,
vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND));
} else { // nonaligned data -> -___-
u8 l_buffer[0x200];
u32 nand_src = vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND);
u32 keyslot = vfile->keyslot;
int errorcode = 0;
if (foffset % 0x200) { // handle misaligned offset
u32 offset_fix = 0x200 - (foffset % 0x200);
errorcode = ReadNandSectors(l_buffer, foffset / 0x200, 1, keyslot, nand_src);
if (errorcode != 0) return errorcode;
memcpy(buffer, l_buffer + 0x200 - offset_fix, min(offset_fix, count));
if (count <= offset_fix) return 0;
foffset += offset_fix;
buffer += offset_fix;
count -= offset_fix;
} // foffset is now aligned and part of the data is read
if (count >= 0x200) { // otherwise this is misaligned and will be handled below
errorcode = ReadNandSectors(buffer, foffset / 0x200, count / 0x200, keyslot, nand_src);
if (errorcode != 0) return errorcode;
}
if (count % 0x200) { // handle misaligned count
u32 count_fix = count % 0x200;
errorcode = ReadNandSectors(l_buffer, (foffset + count) / 0x200, 1, keyslot, nand_src);
if (errorcode != 0) return errorcode;
memcpy(buffer + count - count_fix, l_buffer, count_fix);
}
return errorcode;
}
}
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count)
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count, u32* bytes_written)
{
// simple wrapper function for WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, u32 dest)
return WriteNandSectors(buffer, (vfile->offset + offset) / 0x200, (count+0x1FF) / 0x200, vfile->keyslot,
vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND));
u32 foffset = vfile->offset + offset;
if (offset >= vfile->size)
return 0;
else if ((offset + count) > vfile->size)
count = vfile->size - offset;
if (bytes_written) *bytes_written = count;
if (!(foffset % 0x200) && !(count % 0x200)) { // aligned data -> simple case
// simple wrapper function for WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, u32 dest)
return WriteNandSectors(buffer, foffset / 0x200, count / 0x200, vfile->keyslot,
vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND));
} else return -1; // misaligned data -> not implemented (!!!)
}

View File

@ -24,5 +24,5 @@ typedef struct {
u32 IsVirtualPath(const char* path);
bool CheckVirtualPath(const char* path);
bool FindVirtualFile(VirtualFile* vfile, const char* path, u32 size);
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count);
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count);
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count, u32* bytes_read);
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count, u32* bytes_written);