mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
FileGetData(): Also allow virtual files
This commit also enables ReadVirtualFile() to correctly process misaligned data
This commit is contained in:
parent
2d181de5bf
commit
45501d47eb
28
source/fs.c
28
source/fs.c
@ -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;
|
||||
if (PathToNumFS(path) >= 0) {
|
||||
UINT bytes_read = 0;
|
||||
FIL file;
|
||||
if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
|
||||
return false;
|
||||
return 0;
|
||||
f_lseek(&file, foffset);
|
||||
f_read(&file, data, size, &bytes_read);
|
||||
if (f_read(&file, data, size, &bytes_read) != FR_OK)
|
||||
return 0;
|
||||
f_close(&file);
|
||||
return (bytes_read == size);
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
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, (vfile->offset + offset) / 0x200, (count+0x1FF) / 0x200, vfile->keyslot,
|
||||
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)
|
||||
{
|
||||
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, (vfile->offset + offset) / 0x200, (count+0x1FF) / 0x200, vfile->keyslot,
|
||||
return WriteNandSectors(buffer, foffset / 0x200, count / 0x200, vfile->keyslot,
|
||||
vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND));
|
||||
} else return -1; // misaligned data -> not implemented (!!!)
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user