diff --git a/source/nand/nand.c b/source/nand/nand.c index 93c66c6..8e4b79e 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -275,6 +275,74 @@ void CryptSector0x96(u8* buffer, bool encrypt) aes_decrypt((void*) buffer, (void*) buffer, 1, mode); } +int ReadNandBytes(u8* buffer, u32 offset, u32 count, u32 keyslot, u32 nand_src) +{ + if (!(offset % 0x200) && !(count % 0x200)) { // aligned data -> simple case + // simple wrapper function for ReadNandSectors(...) + return ReadNandSectors(buffer, offset / 0x200, count / 0x200, keyslot, nand_src); + } else { // misaligned data -> -___- + u8 l_buffer[0x200]; + int errorcode = 0; + if (offset % 0x200) { // handle misaligned offset + u32 offset_fix = 0x200 - (offset % 0x200); + errorcode = ReadNandSectors(l_buffer, offset / 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; + offset += offset_fix; + buffer += offset_fix; + count -= offset_fix; + } // offset 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, offset / 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, (offset + count) / 0x200, 1, keyslot, nand_src); + if (errorcode != 0) return errorcode; + memcpy(buffer + count - count_fix, l_buffer, count_fix); + } + return errorcode; + } +} + +int WriteNandBytes(const u8* buffer, u32 offset, u32 count, u32 keyslot, u32 nand_dst) +{ + if (!(offset % 0x200) && !(count % 0x200)) { // aligned data -> simple case + // simple wrapper function for WriteNandSectors(...) + return WriteNandSectors(buffer, offset / 0x200, count / 0x200, keyslot, nand_dst); + } else { // misaligned data -> -___- + u8 l_buffer[0x200]; + int errorcode = 0; + if (offset % 0x200) { // handle misaligned offset + u32 offset_fix = 0x200 - (offset % 0x200); + errorcode = ReadNandSectors(l_buffer, offset / 0x200, 1, keyslot, nand_dst); + if (errorcode != 0) return errorcode; + memcpy(l_buffer + 0x200 - offset_fix, buffer, min(offset_fix, count)); + errorcode = WriteNandSectors((const u8*) l_buffer, offset / 0x200, 1, keyslot, nand_dst); + if (errorcode != 0) return errorcode; + if (count <= offset_fix) return 0; + offset += offset_fix; + buffer += offset_fix; + count -= offset_fix; + } // offset is now aligned and part of the data is written + if (count >= 0x200) { // otherwise this is misaligned and will be handled below + errorcode = WriteNandSectors(buffer, offset / 0x200, count / 0x200, keyslot, nand_dst); + if (errorcode != 0) return errorcode; + } + if (count % 0x200) { // handle misaligned count + u32 count_fix = count % 0x200; + errorcode = ReadNandSectors(l_buffer, (offset + count) / 0x200, 1, keyslot, nand_dst); + if (errorcode != 0) return errorcode; + memcpy(l_buffer, buffer + count - count_fix, count_fix); + errorcode = WriteNandSectors((const u8*) l_buffer, (offset + count) / 0x200, 1, keyslot, nand_dst); + if (errorcode != 0) return errorcode; + } + return errorcode; + } +} + int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, u32 nand_src) { if (!count) return 0; // <--- just to be safe diff --git a/source/nand/nand.h b/source/nand/nand.h index b73f549..9e46cc0 100644 --- a/source/nand/nand.h +++ b/source/nand/nand.h @@ -5,9 +5,10 @@ #define NAND_SYSNAND (1<<0) #define NAND_EMUNAND (1<<1) #define NAND_IMGNAND (1<<2) -#define NAND_TYPE_O3DS (1<<3) -#define NAND_TYPE_N3DS (1<<4) -#define NAND_TYPE_NO3DS (1<<5) +#define NAND_ZERONAND (1<<3) +#define NAND_TYPE_O3DS (1<<4) +#define NAND_TYPE_N3DS (1<<5) +#define NAND_TYPE_NO3DS (1<<6) bool LoadKeyFromFile(const char* folder, u8* keydata, u32 keyslot, char type, char* id); bool InitNandCrypto(void); @@ -17,6 +18,8 @@ bool CheckA9lh(void); void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot); void CryptSector0x96(u8* buffer, bool encrypt); +int ReadNandBytes(u8* buffer, u32 offset, u32 count, u32 keyslot, u32 nand_src); +int WriteNandBytes(const u8* buffer, u32 offset, u32 count, u32 keyslot, u32 nand_dst); int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, u32 src); int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, u32 dest); diff --git a/source/virtual/vnand.c b/source/virtual/vnand.c index ffee3e6..7fc9b0c 100644 --- a/source/virtual/vnand.c +++ b/source/virtual/vnand.c @@ -71,75 +71,11 @@ bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir } int ReadVNandFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count) { - u32 foffset = vfile->offset + offset; u32 nand_src = vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND); - u32 keyslot = vfile->keyslot; - - 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, keyslot, nand_src); - } else { // misaligned data -> -___- - u8 l_buffer[0x200]; - 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; - } + return ReadNandBytes(buffer, vfile->offset + offset, count, vfile->keyslot, nand_src); } int WriteVNandFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count) { - u32 foffset = vfile->offset + offset; u32 nand_dst = vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND); - u32 keyslot = vfile->keyslot; - - 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, keyslot, nand_dst); - } else { // misaligned data -> -___- - u8 l_buffer[0x200]; - int errorcode = 0; - if (foffset % 0x200) { // handle misaligned offset - u32 offset_fix = 0x200 - (foffset % 0x200); - errorcode = ReadNandSectors(l_buffer, foffset / 0x200, 1, keyslot, nand_dst); - if (errorcode != 0) return errorcode; - memcpy(l_buffer + 0x200 - offset_fix, buffer, min(offset_fix, count)); - errorcode = WriteNandSectors((const u8*) l_buffer, foffset / 0x200, 1, keyslot, nand_dst); - if (errorcode != 0) return errorcode; - 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 written - if (count >= 0x200) { // otherwise this is misaligned and will be handled below - errorcode = WriteNandSectors(buffer, foffset / 0x200, count / 0x200, keyslot, nand_dst); - 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_dst); - if (errorcode != 0) return errorcode; - memcpy(l_buffer, buffer + count - count_fix, count_fix); - errorcode = WriteNandSectors((const u8*) l_buffer, (foffset + count) / 0x200, 1, keyslot, nand_dst); - if (errorcode != 0) return errorcode; - } - return errorcode; - } + return WriteNandBytes(buffer, vfile->offset + offset, count, vfile->keyslot, nand_dst); }