From 0caf9f4214686f78b54ca400cb79313982add953 Mon Sep 17 00:00:00 2001 From: Aurora Date: Fri, 7 Oct 2016 14:27:30 +0200 Subject: [PATCH] Add safety checks, support booting from CTRNAND --- exceptions/arm11/Makefile | 2 +- exceptions/arm11/source/mainHandler.c | 6 +-- haxloader/source/fatfs/diskio.c | 4 +- haxloader/source/fatfs/sdmmc/sdmmc.c | 24 ++++----- haxloader/source/fatfs/sdmmc/sdmmc.h | 2 +- patches/reboot.s | 24 ++++++--- source/config.c | 12 +++-- source/config.h | 2 +- source/crypto.c | 24 ++++----- source/crypto.h | 2 +- source/draw.c | 4 +- source/fatfs/diskio.c | 37 +++++--------- source/fatfs/sdmmc/sdmmc.c | 25 +++++---- source/fatfs/sdmmc/sdmmc.h | 2 +- source/firm.c | 21 ++++++-- source/fs.c | 74 ++++++++++++++------------- source/fs.h | 2 +- source/patches.c | 2 +- source/pin.c | 2 +- source/screen.c | 12 +---- 20 files changed, 142 insertions(+), 141 deletions(-) diff --git a/exceptions/arm11/Makefile b/exceptions/arm11/Makefile index 3f32620..5906331 100644 --- a/exceptions/arm11/Makefile +++ b/exceptions/arm11/Makefile @@ -18,7 +18,7 @@ dir_build := build dir_out := ../../$(dir_build) ASFLAGS := -mcpu=mpcore -mfpu=vfp -CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -Os -flto -ffast-math +CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math LDFLAGS := -nostdlib objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ diff --git a/exceptions/arm11/source/mainHandler.c b/exceptions/arm11/source/mainHandler.c index e538155..3e231b8 100644 --- a/exceptions/arm11/source/mainHandler.c +++ b/exceptions/arm11/source/mainHandler.c @@ -47,7 +47,7 @@ void __attribute__((noreturn)) mainHandler(u32 *regs, u32 type, u32 cpuId) u32 registerDump[REG_DUMP_SIZE / 4]; u8 codeDump[CODE_DUMP_SIZE]; - u8 *const finalBuffer = cannotAccessVA((const void *)0xE5000000) ? (u8 *)0xF5000000 : (u8 *)0xE5000000; //VA for 0x25000000 + u8 *finalBuffer = cannotAccessVA((void *)0xE5000000) ? (u8 *)0xF5000000 : (u8 *)0xE5000000; //VA for 0x25000000 u8 *final = finalBuffer; while(*(vu32 *)final == 0xDEADC0DE && *((vu32 *)final + 1) == 0xDEADCAFE); @@ -88,7 +88,7 @@ void __attribute__((noreturn)) mainHandler(u32 *regs, u32 type, u32 cpuId) dumpHeader.stackDumpSize = copyMemory(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF), 1); final += dumpHeader.stackDumpSize; - if(!cannotAccessVA((u8 *)0xFFFF9004)) + if(!cannotAccessVA((void *)0xFFFF9004)) { vu64 *additionalData = (vu64 *)final; dumpHeader.additionalDataSize = 16; @@ -106,4 +106,4 @@ void __attribute__((noreturn)) mainHandler(u32 *regs, u32 type, u32 cpuId) cleanInvalidateDCacheAndDMB(); mcuReboot(); //Also contains DCache-cleaning code -} +} \ No newline at end of file diff --git a/haxloader/source/fatfs/diskio.c b/haxloader/source/fatfs/diskio.c index 4dda526..38d626e 100644 --- a/haxloader/source/fatfs/diskio.c +++ b/haxloader/source/fatfs/diskio.c @@ -33,9 +33,7 @@ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - sdmmc_sdcard_init(); - - return RES_OK; + return sdmmc_sdcard_init() ? RES_OK : RES_PARERR; } diff --git a/haxloader/source/fatfs/sdmmc/sdmmc.c b/haxloader/source/fatfs/sdmmc/sdmmc.c index ae14ab2..e5f189f 100644 --- a/haxloader/source/fatfs/sdmmc/sdmmc.c +++ b/haxloader/source/fatfs/sdmmc/sdmmc.c @@ -274,17 +274,17 @@ static u32 calcSDSize(u8 *csd, int type) switch(type) { case 0: - { - u32 block_len = csd[9] & 0xF; - block_len = 1u << block_len; - u32 mult = (u32)((csd[4] >> 7) | ((csd[5] & 3) << 1)); - mult = 1u << (mult + 2); - result = csd[8] & 3; - result = (result << 8) | csd[7]; - result = (result << 2) | (csd[6] >> 6); - result = (result + 1) * mult * block_len / 512; - } + { + u32 block_len = csd[9] & 0xF; + block_len = 1u << block_len; + u32 mult = (u32)((csd[4] >> 7) | ((csd[5] & 3) << 1)); + mult = 1u << (mult + 2); + result = csd[8] & 3; + result = (result << 8) | csd[7]; + result = (result << 2) | (csd[6] >> 6); + result = (result + 1) * mult * block_len / 512; break; + } case 1: result = csd[7] & 0x3F; result = (result << 8) | csd[6]; @@ -482,9 +482,9 @@ void sdmmc_get_cid(bool isNand, u32 *info) } */ -void sdmmc_sdcard_init() +bool sdmmc_sdcard_init() { InitSD(); //Nand_Init(); - SD_Init(); + return SD_Init() == 0; } \ No newline at end of file diff --git a/haxloader/source/fatfs/sdmmc/sdmmc.h b/haxloader/source/fatfs/sdmmc/sdmmc.h index eb268c3..213a0e0 100644 --- a/haxloader/source/fatfs/sdmmc/sdmmc.h +++ b/haxloader/source/fatfs/sdmmc/sdmmc.h @@ -91,7 +91,7 @@ typedef struct mmcdevice { u32 res; } mmcdevice; -void sdmmc_sdcard_init(); +bool sdmmc_sdcard_init(); int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out); //int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in); //int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out); diff --git a/patches/reboot.s b/patches/reboot.s index aac1b99..e64cc49 100644 --- a/patches/reboot.s +++ b/patches/reboot.s @@ -25,13 +25,18 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB cmp r0, r2 bne pxi_wait_recv - ; Open file - add r0, r7, #8 - adr r1, fname - mov r2, #1 - ldr r6, [fopen] - orr r6, 1 - blx r6 + adr r1, sd_fname + + open_payload: + ; Open file + add r0, r7, #8 + mov r2, #1 + ldr r6, [fopen] + orr r6, 1 + blx r6 + cmp r0, #0 + adrne r1, nand_fname + bne open_payload ; Read file mov r0, r7 @@ -71,8 +76,11 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB bytes_read: .word 0 fopen: .ascii "OPEN" .pool -fname: .dcw "sdmc:/arm9loaderhax.bin" +sd_fname: .dcw "sdmc:/arm9loaderhax.bin" .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.pool +nand_fname: .dcw "nand:/arm9loaderhax.bin" + .word 0 .align 4 kernelcode_start: diff --git a/source/config.c b/source/config.c index a105078..7fc1de4 100644 --- a/source/config.c +++ b/source/config.c @@ -29,18 +29,22 @@ #include "buttons.h" #include "pin.h" -bool readConfig(void) +bool readConfig(bool isSdMounted) { - if(fileRead(&configData, CONFIG_PATH, sizeof(CfgData)) != sizeof(CfgData) || + bool ret; + + if(!isSdMounted || + fileRead(&configData, CONFIG_PATH, sizeof(CfgData)) != sizeof(CfgData) || memcmp(configData.magic, "CONF", 4) != 0 || configData.formatVersionMajor != CONFIG_VERSIONMAJOR || configData.formatVersionMinor != CONFIG_VERSIONMINOR) { configData.config = 0; - return false; + ret = !isSdMounted; } + else ret = true; - return true; + return ret; } void writeConfig(ConfigurationStatus needConfig, u32 configTemp) diff --git a/source/config.h b/source/config.h index 3aa814b..a781e41 100644 --- a/source/config.h +++ b/source/config.h @@ -78,6 +78,6 @@ typedef enum ConfigurationStatus extern CfgData configData; extern bool isN3DS; -bool readConfig(void); +bool readConfig(bool isSdMounted); void writeConfig(ConfigurationStatus needConfig, u32 configTemp); void configMenu(bool oldPinStatus, u32 oldPinMode); \ No newline at end of file diff --git a/source/crypto.c b/source/crypto.c index ce03646..76de1e9 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -82,7 +82,7 @@ __asm__\ static void aes_setkey(u8 keyslot, const void *key, u32 keyType, u32 mode) { - if(keyslot <= 0x03) return; // Ignore TWL keys for now + if(keyslot <= 0x03) return; //Ignore TWL keys for now u32 *key32 = (u32 *)key; *REG_AESCNT = (*REG_AESCNT & ~(AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER)) | mode; *REG_AESKEYCNT = (*REG_AESKEYCNT >> 6 << 6) | keyslot | AES_KEYCNT_WRITE; @@ -107,7 +107,7 @@ static void aes_setiv(const void *iv, u32 mode) const u32 *iv32 = (const u32 *)iv; *REG_AESCNT = (*REG_AESCNT & ~(AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER)) | mode; - // Word order for IV can't be changed in REG_AESCNT and always default to reversed + //Word order for IV can't be changed in REG_AESCNT and always default to reversed if(mode & AES_INPUT_NORMAL) { REG_AESCTR[0] = iv32[3]; @@ -131,7 +131,7 @@ static void aes_advctr(void *ctr, u32 val, u32 mode) int i; if(mode & AES_INPUT_BE) { - for(i = 0; i < 4; ++i) // Endian swap + for(i = 0; i < 4; ++i) //Endian swap BSWAP32(ctr32[i]); } @@ -146,7 +146,7 @@ static void aes_advctr(void *ctr, u32 val, u32 mode) if(mode & AES_INPUT_BE) { - for(i = 0; i < 4; ++i) // Endian swap + for(i = 0; i < 4; ++i) //Endian swap BSWAP32(ctr32[i]); } } @@ -186,7 +186,7 @@ static void aes_batch(void *dst, const void *src, u32 blockCount) while(rbc) { - if(wbc && ((*REG_AESCNT & 0x1F) <= 0xC)) // There's space for at least 4 ints + if(wbc && ((*REG_AESCNT & 0x1F) <= 0xC)) //There's space for at least 4 ints { *REG_AESWRFIFO = *src32++; *REG_AESWRFIFO = *src32++; @@ -195,7 +195,7 @@ static void aes_batch(void *dst, const void *src, u32 blockCount) wbc--; } - if(rbc && ((*REG_AESCNT & (0x1F << 0x5)) >= (0x4 << 0x5))) // At least 4 ints available for read + if(rbc && ((*REG_AESCNT & (0x1F << 0x5)) >= (0x4 << 0x5))) //At least 4 ints available for read { *dst32++ = *REG_AESRDFIFO; *dst32++ = *REG_AESRDFIFO; @@ -222,24 +222,24 @@ static void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, blocks = (blockCount >= 0xFFFF) ? 0xFFFF : blockCount; - // Save the last block for the next decryption CBC batch's iv + //Save the last block for the next decryption CBC batch's iv if((mode & AES_ALL_MODES) == AES_CBC_DECRYPT_MODE) { memcpy(iv, src + (blocks - 1) * AES_BLOCK_SIZE, AES_BLOCK_SIZE); aes_change_ctrmode(iv, AES_INPUT_BE | AES_INPUT_NORMAL, ivMode); } - // Process the current batch + //Process the current batch aes_batch(dst, src, blocks); - // Save the last block for the next encryption CBC batch's iv + //Save the last block for the next encryption CBC batch's iv if((mode & AES_ALL_MODES) == AES_CBC_ENCRYPT_MODE) { memcpy(iv, dst + (blocks - 1) * AES_BLOCK_SIZE, AES_BLOCK_SIZE); aes_change_ctrmode(iv, AES_INPUT_BE | AES_INPUT_NORMAL, ivMode); } - // Advance counter for CTR mode + //Advance counter for CTR mode else if((mode & AES_ALL_MODES) == AES_CTR_MODE) aes_advctr(iv, blocks, ivMode); @@ -324,14 +324,14 @@ void ctrNandInit(void) } } -u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf) +int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf) { u8 __attribute__((aligned(4))) tmpCtr[sizeof(nandCtr)]; memcpy(tmpCtr, nandCtr, sizeof(nandCtr)); aes_advctr(tmpCtr, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL); //Read - u32 result; + int result; if(firmSource == FIRMWARE_SYSNAND) result = sdmmc_nand_readsectors(sector + fatStart, sectorCount, outbuf); else diff --git a/source/crypto.h b/source/crypto.h index b64aaa7..52f1084 100755 --- a/source/crypto.h +++ b/source/crypto.h @@ -106,7 +106,7 @@ extern bool isN3DS, isDevUnit, isA9lh; extern FirmwareSource firmSource; void ctrNandInit(void); -u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf); +int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf); void set6x7xKeys(void); void decryptExeFs(u8 *inbuf); void decryptNusFirm(const u8 *inbuf, u8 *outbuf, u32 ncchSize); diff --git a/source/draw.c b/source/draw.c index 568a4b4..2746a7c 100644 --- a/source/draw.c +++ b/source/draw.c @@ -47,8 +47,8 @@ bool loadSplash(void) initScreens(); clearScreens(true, true, true); - if(isTopSplashValid) fileRead(fbs[1].top_left, topSplashPath, 0); - if(isBottomSplashValid) fileRead(fbs[1].bottom, bottomSplashPath, 0); + if(isTopSplashValid) fileRead(fbs[1].top_left, topSplashPath, SCREEN_TOP_FBSIZE); + if(isBottomSplashValid) fileRead(fbs[1].bottom, bottomSplashPath, SCREEN_BOTTOM_FBSIZE); swapFramebuffers(true); diff --git a/source/fatfs/diskio.c b/source/fatfs/diskio.c index 68d0de6..003c4ba 100644 --- a/source/fatfs/diskio.c +++ b/source/fatfs/diskio.c @@ -37,17 +37,18 @@ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - switch(pdrv) + DRESULT ret = RES_OK; + static bool sdmmcInited = false; + + if(!sdmmcInited) { - case SDCARD: - sdmmc_sdcard_init(); - break; - case CTRNAND: - ctrNandInit(); - break; + if(!sdmmc_sdcard_init()) ret = RES_PARERR; + else sdmmcInited = true; } - return RES_OK; + if(pdrv == CTRNAND) ctrNandInit(); + + return ret; } @@ -63,19 +64,8 @@ DRESULT disk_read ( UINT count /* Number of sectors to read */ ) { - switch(pdrv) - { - case SDCARD: - if(sdmmc_sdcard_readsectors(sector, count, (BYTE *)buff)) - return RES_PARERR; - break; - case CTRNAND: - if(ctrNandRead(sector, count, (BYTE *)buff)) - return RES_PARERR; - break; - } - - return RES_OK; + return ((pdrv == SDCARD && !sdmmc_sdcard_readsectors(sector, count, (BYTE *)buff)) || + (pdrv == CTRNAND && !ctrNandRead(sector, count, (BYTE *)buff))) ? RES_OK : RES_PARERR; } @@ -92,10 +82,7 @@ DRESULT disk_write ( UINT count /* Number of sectors to write */ ) { - if(pdrv == SDCARD && sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) - return RES_PARERR; - - return RES_OK; + return (pdrv == SDCARD && !sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) ? RES_OK : RES_PARERR; } #endif diff --git a/source/fatfs/sdmmc/sdmmc.c b/source/fatfs/sdmmc/sdmmc.c index 9f7eb71..c7b825b 100644 --- a/source/fatfs/sdmmc/sdmmc.c +++ b/source/fatfs/sdmmc/sdmmc.c @@ -268,17 +268,17 @@ static u32 calcSDSize(u8 *csd, int type) switch(type) { case 0: - { - u32 block_len = csd[9] & 0xF; - block_len = 1u << block_len; - u32 mult = (u32)((csd[4] >> 7) | ((csd[5] & 3) << 1)); - mult = 1u << (mult + 2); - result = csd[8] & 3; - result = (result << 8) | csd[7]; - result = (result << 2) | (csd[6] >> 6); - result = (result + 1) * mult * block_len / 512; - } + { + u32 block_len = csd[9] & 0xF; + block_len = 1u << block_len; + u32 mult = (u32)((csd[4] >> 7) | ((csd[5] & 3) << 1)); + mult = 1u << (mult + 2); + result = csd[8] & 3; + result = (result << 8) | csd[7]; + result = (result << 2) | (csd[6] >> 6); + result = (result + 1) * mult * block_len / 512; break; + } case 1: result = csd[7] & 0x3F; result = (result << 8) | csd[6]; @@ -472,9 +472,8 @@ void sdmmc_get_cid(bool isNand, u32 *info) sdmmc_send_command(device, 0x10507, device->initarg << 0x10); } -void sdmmc_sdcard_init() +bool sdmmc_sdcard_init() { InitSD(); - Nand_Init(); - SD_Init(); + return (Nand_Init() | SD_Init()) == 0; } \ No newline at end of file diff --git a/source/fatfs/sdmmc/sdmmc.h b/source/fatfs/sdmmc/sdmmc.h index e34c02e..42ef9ae 100644 --- a/source/fatfs/sdmmc/sdmmc.h +++ b/source/fatfs/sdmmc/sdmmc.h @@ -91,7 +91,7 @@ typedef struct mmcdevice { u32 res; } mmcdevice; -void sdmmc_sdcard_init(); +bool sdmmc_sdcard_init(); int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out); int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in); int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out); diff --git a/source/firm.c b/source/firm.c index a33e48e..f5c65a9 100755 --- a/source/firm.c +++ b/source/firm.c @@ -64,11 +64,11 @@ void main(void) //Detect dev units isDevUnit = CFG_UNITINFO != 0; - //Mount filesystems. CTRNAND will be mounted only if/when needed - mountFs(); + //Mount SD + bool isSdMounted = mountFs(true); //Attempt to read the configuration file - needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION; + needConfig = readConfig(isSdMounted) ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION; u32 devMode = MULTICONFIG(DEVOPTIONS); @@ -102,8 +102,15 @@ void main(void) //Save old options and begin saving the new boot configuration configTemp = (configData.config & 0xFFFFFE00) | ((u32)isA9lh << 6); + if(!isSdMounted) + { + nandType = FIRMWARE_SYSNAND; + firmSource = FIRMWARE_SYSNAND; + needConfig = DONT_CONFIGURE; + } + //If it's a MCU reboot, try to force boot options - if(isA9lh && CFG_BOOTENV) + else if(isA9lh && CFG_BOOTENV) { //Always force a sysNAND boot when quitting AGB_FIRM if(CFG_BOOTENV == 7) @@ -241,7 +248,7 @@ void main(void) else if(firmSource != FIRMWARE_SYSNAND) locateEmuNand(&emuHeader, &firmSource); - if(!isFirmlaunch) + if(isSdMounted && !isFirmlaunch) { configTemp |= (u32)nandType | ((u32)firmSource << 3); writeConfig(needConfig, configTemp); @@ -284,9 +291,13 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo "/luma/cetk_safe" }; + if(!mountFs(false)) error("Error mounting CTRNAND."); + //Load FIRM from CTRNAND u32 firmVersion = firmRead(firm, (u32)*firmType); + if(firmVersion == 0xFFFFFFFF) error("Error getting the CTRNAND FIRM."); + bool mustLoadFromSd = false; if(!isN3DS && *firmType == NATIVE_FIRM) diff --git a/source/fs.c b/source/fs.c index 8541cfd..b58520a 100644 --- a/source/fs.c +++ b/source/fs.c @@ -33,10 +33,9 @@ static FATFS sdFs, nandFs; -void mountFs(void) +bool mountFs(bool isSd) { - f_mount(&sdFs, "0:", 1); - f_mount(&nandFs, "1:", 0); + return isSd ? f_mount(&sdFs, "0:", 1) == FR_OK : f_mount(&nandFs, "1:", 1) == FR_OK; } u32 fileRead(void *dest, const char *path, u32 maxSize) @@ -48,7 +47,7 @@ u32 fileRead(void *dest, const char *path, u32 maxSize) { u32 size = f_size(&file); if(dest == NULL) ret = size; - else if(!(maxSize > 0 && size > maxSize)) + else if(size <= maxSize) f_read(&file, dest, size, (unsigned int *)&ret); f_close(&file); } @@ -64,6 +63,7 @@ u32 getFileSize(const char *path) bool fileWrite(const void *buffer, const char *path, u32 size) { FIL file; + bool ret; FRESULT result = f_open(&file, path, FA_WRITE | FA_OPEN_ALWAYS); @@ -74,10 +74,9 @@ bool fileWrite(const void *buffer, const char *path, u32 size) f_truncate(&file); f_close(&file); - return true; + ret = (u32)written == size; } - - if(result == FR_NO_PATH) + else if(result == FR_NO_PATH) { for(u32 i = 1; path[i] != 0; i++) if(path[i] == '/') @@ -85,13 +84,15 @@ bool fileWrite(const void *buffer, const char *path, u32 size) char folder[i + 1]; memcpy(folder, path, i); folder[i] = 0; - f_mkdir(folder); + ret = f_mkdir(folder) == FR_OK; + if(!ret) break; } - return fileWrite(buffer, path, size); + if(ret) ret = fileWrite(buffer, path, size); } + else ret = false; - return false; + return ret; } void fileDelete(const char *path) @@ -163,39 +164,42 @@ u32 firmRead(void *dest, u32 firmType) DIR dir; FILINFO info; - - f_opendir(&dir, path); - u32 firmVersion = 0xFFFFFFFF; - //Parse the target directory - while(f_readdir(&dir, &info) == FR_OK && info.fname[0] != 0) + if(f_opendir(&dir, path) == FR_OK) { - //Not a cxi - if(info.fname[9] != 'a' || strlen(info.fname) != 12) continue; - - //Convert the .app name to an integer - u32 tempVersion = 0; - for(char *tmp = info.altname; *tmp != '.'; tmp++) + //Parse the target directory + while(f_readdir(&dir, &info) == FR_OK && info.fname[0] != 0) { - tempVersion <<= 4; - tempVersion += *tmp > '9' ? *tmp - 'A' + 10 : *tmp - '0'; + //Not a cxi + if(info.fname[9] != 'a' || strlen(info.fname) != 12) continue; + + //Convert the .app name to an integer + u32 tempVersion = 0; + for(char *tmp = info.altname; *tmp != '.'; tmp++) + { + tempVersion <<= 4; + tempVersion += *tmp > '9' ? *tmp - 'A' + 10 : *tmp - '0'; + } + + //Found an older cxi + if(tempVersion < firmVersion) firmVersion = tempVersion; } - //Found an older cxi - if(tempVersion < firmVersion) firmVersion = tempVersion; + f_closedir(&dir); + + if(firmVersion != 0xFFFFFFFF) + { + //Complete the string with the .app name + concatenateStrings(path, "/00000000.app"); + + //Convert back the .app name from integer to array + hexItoa(firmVersion, &path[35], 8); + + if(!fileRead(dest, path, 0x400200)) firmVersion = 0xFFFFFFFF; + } } - f_closedir(&dir); - - //Complete the string with the .app name - concatenateStrings(path, "/00000000.app"); - - //Convert back the .app name from integer to array - hexItoa(firmVersion, &path[35], 8); - - fileRead(dest, path, 0); - return firmVersion; } diff --git a/source/fs.h b/source/fs.h index 0682fb5..637beb6 100644 --- a/source/fs.h +++ b/source/fs.h @@ -28,7 +28,7 @@ extern bool isN3DS, isA9lh; -void mountFs(void); +bool mountFs(bool isSd); u32 fileRead(void *dest, const char *path, u32 maxSize); u32 getFileSize(const char *path); bool fileWrite(const void *buffer, const char *path, u32 size); diff --git a/source/patches.c b/source/patches.c index 37003e7..c7954ac 100644 --- a/source/patches.c +++ b/source/patches.c @@ -100,7 +100,7 @@ void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr) if(pathSize > 5 && pathSize < 58) { u8 path[pathSize]; - fileRead(path, pathPath, 0); + fileRead(path, pathPath, pathSize); if(path[pathSize - 1] == 0xA) pathSize--; if(path[pathSize - 1] == 0xD) pathSize--; diff --git a/source/pin.c b/source/pin.c index 36f5fe5..68f8369 100644 --- a/source/pin.c +++ b/source/pin.c @@ -139,7 +139,7 @@ bool verifyPin(u32 pinMode) if(messageSize > 0 && messageSize <= 800) { char message[messageSize + 1]; - fileRead(message, messagePath, 0); + fileRead(message, messagePath, messageSize); message[messageSize] = 0; drawString(message, false, 10, 10, COLOR_WHITE); } diff --git a/source/screen.c b/source/screen.c index f49314d..13bd373 100644 --- a/source/screen.c +++ b/source/screen.c @@ -41,7 +41,7 @@ #include "cache.h" #include "i2c.h" -vu32 *const arm11Entry = (vu32 *)BRAHMA_ARM11_ENTRY; +vu32 *arm11Entry = (vu32 *)BRAHMA_ARM11_ENTRY; static const u32 brightness[4] = {0x5F, 0x4C, 0x39, 0x26}; void __attribute__((naked)) arm11Stub(void) @@ -167,16 +167,6 @@ void clearScreens(bool clearTop, bool clearBottom, bool clearAlternate) while(!((!clearTopTmp || (REGs_PSC0[3] & 2)) && (!clearBottomTmp || (REGs_PSC1[3] & 2)))); - if(fbTmp->top_right != fbTmp->top_left && clearTopTmp) - { - REGs_PSC0[0] = (u32)fbTmp->top_right >> 3; //Start address - REGs_PSC0[1] = (u32)(fbTmp->top_right + SCREEN_TOP_FBSIZE) >> 3; //End address - REGs_PSC0[2] = 0; //Fill value - REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start - - while(!(REGs_PSC0[3] & 2)); - } - WAIT_FOR_ARM9(); }