mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 21:52:48 +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);
|
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;
|
UINT bytes_read = 0;
|
||||||
|
FIL file;
|
||||||
if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
|
if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
|
||||||
return false;
|
return 0;
|
||||||
f_lseek(&file, foffset);
|
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);
|
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) {
|
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;
|
if (!ShowProgress(0, 0, orig)) ret = false;
|
||||||
for (size_t pos = 0; (pos < osize) && ret; pos += MAIN_BUFFER_SIZE) {
|
for (size_t pos = 0; (pos < osize) && ret; pos += MAIN_BUFFER_SIZE) {
|
||||||
UINT read_bytes = min(MAIN_BUFFER_SIZE, osize - pos);
|
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;
|
ret = false;
|
||||||
if (!ShowProgress(pos + (read_bytes / 2), osize, orig))
|
if (!ShowProgress(pos + (read_bytes / 2), osize, orig))
|
||||||
ret = false;
|
ret = false;
|
||||||
if (WriteVirtualFile(&dvfile, MAIN_BUFFER, pos, read_bytes) != 0)
|
if (WriteVirtualFile(&dvfile, MAIN_BUFFER, pos, read_bytes, NULL) != 0)
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
ShowProgress(1, 1, orig);
|
ShowProgress(1, 1, orig);
|
||||||
@ -265,7 +275,7 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
|
|||||||
ret = false;
|
ret = false;
|
||||||
if (!ShowProgress(pos + (bytes_read / 2), osize, orig))
|
if (!ShowProgress(pos + (bytes_read / 2), osize, orig))
|
||||||
ret = false;
|
ret = false;
|
||||||
if (WriteVirtualFile(&dvfile, MAIN_BUFFER, pos, bytes_read) != 0)
|
if (WriteVirtualFile(&dvfile, MAIN_BUFFER, pos, bytes_read, NULL) != 0)
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
ShowProgress(1, 1, orig);
|
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) {
|
for (size_t pos = 0; (pos < osize) && ret; pos += MAIN_BUFFER_SIZE) {
|
||||||
UINT read_bytes = min(MAIN_BUFFER_SIZE, osize - pos);
|
UINT read_bytes = min(MAIN_BUFFER_SIZE, osize - pos);
|
||||||
UINT bytes_written = 0;
|
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;
|
ret = false;
|
||||||
if (!ShowProgress(pos + (read_bytes / 2), osize, orig))
|
if (!ShowProgress(pos + (read_bytes / 2), osize, orig))
|
||||||
ret = false;
|
ret = false;
|
||||||
|
@ -42,7 +42,7 @@ u32 GetWritePermissions();
|
|||||||
bool FileCreateData(const char* path, u8* data, size_t size);
|
bool FileCreateData(const char* path, u8* data, size_t size);
|
||||||
|
|
||||||
/** Read data from file@offset **/
|
/** 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 **/
|
/** Recursively copy a file or directory **/
|
||||||
bool PathCopy(const char* destdir, const char* orig);
|
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);
|
if (id) strncpy((char*) key_magic + 2, id, 10);
|
||||||
|
|
||||||
// try to find key in 'aeskeydb.bin' file
|
// 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) {
|
if (memcmp(buffer, key_magic, 12) == 0) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -83,7 +83,7 @@ bool LoadKeyFromFile(const char* folder, u8* keydata, u32 keyslot, char type, ch
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
snprintf(path, 256, "%s/slot0x%02XKey%.10s", folder, (unsigned int) keyslot,
|
snprintf(path, 256, "%s/slot0x%02XKey%.10s", folder, (unsigned int) keyslot,
|
||||||
(id) ? id : (type == 'X') ? "X" : (type == 'Y') ? "Y" : "");
|
(id) ? id : (type == 'X') ? "X" : (type == 'Y') ? "Y" : "");
|
||||||
if (FileGetData(path, key, 16, 0))
|
if (FileGetData(path, key, 16, 0) == 16)
|
||||||
found = true;
|
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)
|
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
|
if (nand_src == NAND_EMUNAND) { // EmuNAND
|
||||||
int errorcode = 0;
|
int errorcode = 0;
|
||||||
if ((sector == 0) && (emunand_base_sector % 0x200000 == 0)) { // GW EmuNAND header handling
|
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;
|
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)
|
// 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));
|
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)
|
// 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));
|
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);
|
u32 IsVirtualPath(const char* path);
|
||||||
bool CheckVirtualPath(const char* path);
|
bool CheckVirtualPath(const char* path);
|
||||||
bool FindVirtualFile(VirtualFile* vfile, const char* path, u32 size);
|
bool FindVirtualFile(VirtualFile* vfile, const char* path, u32 size);
|
||||||
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);
|
||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user